# Unitful.jl and DifferentialEquations.jl: compatibility?

**URL:** <https://discourse.julialang.org/t/unitful-jl-and-differentialequations-jl-compatibility/68594>\
**Category:** New to Julia\
**Tags:** unitful, differentialequation\
**Created:** [September 22, 2021, 4:56pm UTC](https://discourse.julialang.org/t/unitful-jl-and-differentialequations-jl-compatibility/68594 "2021-09-22T16:56:23Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ickaser](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ickaser/32/28852_2.png) [@Ickaser](https://discourse.julialang.org/u/Ickaser)\
**Post date:** [September 22, 2021, 4:56pm UTC](https://discourse.julialang.org/t/unitful-jl-and-differentialequations-jl-compatibility/68594/1 "2021-09-22T16:56:23Z")

</div>

I’ve been using Julia for a little while, long enough to have successfully solved ODEs before. I’m trying to use DifferentialEquations together with Unitful, which I thought I had read should work, but it doesn’t seem to be as simple as I thought. Here’s an example mostly like what I’m trying to do:

```julia
using Unitful
using DifferentialEquations
k1 = 0.1u"1/s"
k2 = 2.0u"K/s"
ode3a = @ode_def begin
    dTb = Tb*k1 + k2
end k1 k2
tspan = (0.0u"s", 6.0u"s")
params = [k1, k2]
prob = ODEProblem(ode3a, [300u"K"], tspan, params)
solve(prob)

```

And the result I get is

```julia
InexactError: Int64(1731//50000)

```

.

I’ve used a units package in Python that didn’t play nicely with solvers, so inside the RHS function I had to add units at the start and strip units away before passing back to the solver; I can do that here, but hoped to avoid that. Is there an obvious answer I’m missing?

---

<div class="post-metadata">

**Author:** ![vettert](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vettert/32/30599_2.png) [@vettert](https://discourse.julialang.org/u/vettert)\
**Post date:** [September 22, 2021, 5:33pm UTC](https://discourse.julialang.org/t/unitful-jl-and-differentialequations-jl-compatibility/68594/2 "2021-09-22T17:33:15Z")

</div>

Can’t try it right now, but the error indicates that a non-integer gets put into a variable that is defined as an integer.

So, I would check whether changing your initial condition to 300.0u”K” helps.

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [September 22, 2021, 5:36pm UTC](https://discourse.julialang.org/t/unitful-jl-and-differentialequations-jl-compatibility/68594/3 "2021-09-22T17:36:45Z")

</div>

This works:

```julia
julia> prob = ODEProblem(ode3a, [300.0u"K"], tspan, params)
ODEProblem with uType Vector{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, nothing}}} and tType Quantity{Float64, 𝐓, Unitful.FreeUnits{(s,), 𝐓, nothing}}. In-place: true
timespan: (0.0 s, 6.0 s)
u0: 1-element Vector{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, nothing}}}:
 300.0 K

julia> solve(prob, Tsit5())
retcode: Success
Interpolation: specialized 4th order "free" interpolation
t: 5-element Vector{Quantity{Float64, 𝐓, Unitful.FreeUnits{(s,), 𝐓, nothing}}}:
                0.0 s
 ...

```

Note the `300.0` and the `Tsit5`. The former is necessary to get the IC in the right format. The latter is using an explicit solver (specifying none seems to select `Rodas5`). This makes it much easier as there is no autodiff happening, which again adds constraints on the types.

It can still be done, but gets a bit tricker. Potentially easier, if you need an implicit solver, is to set autodiff=false, although this still throws an error:

```julia
                                                                                                                                                                                                
julia> solve(prob, Rodas5(autodiff=false))                                                                                                                                                      
ERROR: DimensionError: K and false are not dimensionally compatible.                                                                                                                            
Stacktrace:                                                                                                                                                                                     
  [1] convert(#unused#::Type{Quantity{Float64, 𝚯, Unitful.FreeUnits{(K,), 𝚯, nothing}}}, x::Bool)                                                                                               

```

not sure what’s the problem there.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [September 22, 2021, 5:39pm UTC](https://discourse.julialang.org/t/unitful-jl-and-differentialequations-jl-compatibility/68594/4 "2021-09-22T17:39:49Z")

</div>

> [@mauro3](#):
>
> not sure what’s the problem there.

Unitful can’t do linear algebra well.

---

<div class="post-metadata">

**Author:** ![Ickaser](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ickaser/32/28852_2.png) [@Ickaser](https://discourse.julialang.org/u/Ickaser)\
**Post date:** [September 23, 2021, 12:31am UTC](https://discourse.julialang.org/t/unitful-jl-and-differentialequations-jl-compatibility/68594/5 "2021-09-23T00:31:47Z")

</div>

> [@mauro3](#):
>
> The former is necessary to get the IC in the right format. The latter is using an explicit solver (specifying none seems to select `Rodas5` ).

Thanks! I figured it was something like this. I think I assumed that Unitful automatically treated these numbers as floats. An explicit solver is just fine for what I need, at least for now, so this fixes everything I have.

> [@ChrisRackauckas](#):
>
> Unitful can’t do linear algebra well.

Are there any better packages for doing unit-aware calculation? Probably when performance really matters it’s better to sanitize inputs and do without the units, I’m guessing, but I would love to be able to use something like Unitful more of the time.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [September 23, 2021, 1:19am UTC](https://discourse.julialang.org/t/unitful-jl-and-differentialequations-jl-compatibility/68594/6 "2021-09-23T01:19:21Z")

</div>

> [@Ickaser](#):
>
> Are there any better packages for doing unit-aware calculation? Probably when performance really matters it’s better to sanitize inputs and do without the units, I’m guessing, but I would love to be able to use something like Unitful more of the time.

Unitful.jl’s approach does not have a runtime cost. It’s the best we have right now.

---

<div class="post-metadata">

**Author:** ![Melvin879](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/melvin879/32/29481_2.png) [@Melvin879](https://discourse.julialang.org/u/Melvin879)\
**Post date:** [September 25, 2021, 6:20am UTC](https://discourse.julialang.org/t/unitful-jl-and-differentialequations-jl-compatibility/68594/7 "2021-09-25T06:20:08Z")

</div>

The function signature should be `twoBodyNew(t, y, μ, dy)` . It’s always `((du),u,p,t)` . The docs on that linked page have been fixed[.](https://www.prepaidgiftbalance.vip/www-prepaidgiftbalance-com/)

---

<div class="post-metadata">

**Author:** ![bilderbuchi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bilderbuchi/32/13562_2.png) [@bilderbuchi](https://discourse.julialang.org/u/bilderbuchi)\
**Post date:** [September 25, 2021, 11:31am UTC](https://discourse.julialang.org/t/unitful-jl-and-differentialequations-jl-compatibility/68594/8 "2021-09-25T11:31:27Z")

</div>

> [@ChrisRackauckas](#):
>
> Unitful can’t do linear algebra well.

Why does it need to? I was under the (probably too simplistic) impression that _that_ problem is solved/avoided by multiple dispatch/julias unreasonable effectiveness? Meaning, unitful needs to know about units, and linear algebra packages about linear algebra.

Why does this fall down here, are a number of operation implementations missing in unitful or some such?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [September 25, 2021, 11:38am UTC](https://discourse.julialang.org/t/unitful-jl-and-differentialequations-jl-compatibility/68594/9 "2021-09-25T11:38:16Z")

</div>

Not for unitful. For unitful it would need to check units and then reinterpret to unitless, apply the linear function, and then reinterpret back to the correct units. So all linear algebra would need an overload. Otherwise every linear algebra call falls back to not use BLAS (slow) and requires generic linear algebra to all be unit-compatible (which it is not).

---

<div class="post-metadata">

**Author:** ![bilderbuchi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bilderbuchi/32/13562_2.png) [@bilderbuchi](https://discourse.julialang.org/u/bilderbuchi)\
**Post date:** [September 25, 2021, 3:06pm UTC](https://discourse.julialang.org/t/unitful-jl-and-differentialequations-jl-compatibility/68594/10 "2021-09-25T15:06:11Z")

</div>

Huhu, interesting, Thanks for clearing that up.  
I wonder how python’s Pint units package achieves that - iirc, most (all?) of numpy’s operations nowadays work with units transparently, maybe using ufuncs or another mechanism.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [September 25, 2021, 5:56pm UTC](https://discourse.julialang.org/t/unitful-jl-and-differentialequations-jl-compatibility/68594/11 "2021-09-25T17:56:53Z")

</div>

Pint is built in a way that’s really slow though. I’ll do a write-up on unit implementations soon to show what needs to be done. I’ve been meaning to get to it for like, 2 years.

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [September 25, 2021, 6:10pm UTC](https://discourse.julialang.org/t/unitful-jl-and-differentialequations-jl-compatibility/68594/12 "2021-09-25T18:10:06Z")

</div>

> [@bilderbuchi](#):
>
> Why does this fall down here, are a number of operation implementations missing in unitful or some such?

> <https://github.com/PainterQubits/Unitful.jl/issues/46#issuecomment-265611553>
>
> Some linear algebra operations like \`\\\` have a hard time with unitful numbers. T…ake the following case:
> 
> \`\`\`julia
> a = \[1.0u"N" 2.0u"N"
> 3.0u"N" 1.0u"N"\]
> b = \[1.0u"N";3.0u"N"\]
> \`\`\`
> 
> If you try \`\\\` it gives a dimension error. If you try \`\*\` then it uses the generic \`\*\` fallback and not BLAS. The same is true if you use:
> 
> \`\`\`julia
> A = rand(100,100)u"N"
> b = rand(100)u"N"
> \`\`\`
> 
> I suggest trying something like, performing a dimensional analysis, strip the units, use the general \`\*\` or \`\\\`, and then re-apply units. 
> 
> To do this properly, you might need a \`UnitfulArray\` instead of an array of Unitful values. I am not sure if stripping the units on an array of Unitful numbers can be done without making a temporary.

The code shown in the comment assumes that the number and its inverse have the same type, assumption which fails when the unit dimension is encoded in the type domain, which is what `Unitful.jl` does. Another approach would be to have a type which doesn’t embed the unit and unit dimension in the type as parameters, which is what Chris would prefer.

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [September 25, 2021, 7:34pm UTC](https://discourse.julialang.org/t/unitful-jl-and-differentialequations-jl-compatibility/68594/13 "2021-09-25T19:34:06Z")

</div>

> [@bilderbuchi](#):
>
> I wonder how python’s Pint units package achieves that

Pint has a [700-line module](https://github.com/hgrecco/pint/blob/c99ed1f537dea91af36c756dccef49e26d4f6447/pint/numpy_func.py) to manually wrap Numpy functions. Most of those functions work out-of-the-box for `Unitful.jl`, in particular the elementwise ones like `sin`, `cos`, etc, thanks to the fact [broadcasting in Julia is explicit](https://julialang.org/blog/2017/01/moredots/#why_does_julia_need_dots_to_fuse_the_loops) and you don’t need to write a different function to opt into [“vectorization”](https://en.wikipedia.org/wiki/Array_programming).

The only problematic functions for `Unitful.jl` are the linear algebra ones where the functions defined in the standard library `LinearAlgebra` make assumptions that don’t play nicely with unit dimensions in the type domain, as explained in the message above. Some simple functions on homogeneous arrays already work though:

```julia
julia> using Unitful, LinearAlgebra

julia> M = [1u"m" 2u"m"; 3u"m" 4u"m"]
2×2 Matrix{Quantity{Int64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}:
 1 m 2 m
 3 m 4 m

julia> det(M)
-2.0 m²

julia> tr(M)
5 m

```

---

<div class="post-metadata">

**Author:** ![bilderbuchi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bilderbuchi/32/13562_2.png) [@bilderbuchi](https://discourse.julialang.org/u/bilderbuchi)\
**Post date:** [September 26, 2021, 12:38pm UTC](https://discourse.julialang.org/t/unitful-jl-and-differentialequations-jl-compatibility/68594/14 "2021-09-26T12:38:38Z")

</div>

Interesting, thanks for the insight & links!

---

<div class="post-metadata">

**Author:** ![Eben60](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eben60/32/13475_2.png) [@Eben60](https://discourse.julialang.org/u/Eben60)\
**Post date:** [January 28, 2022, 8:45pm UTC](https://discourse.julialang.org/t/unitful-jl-and-differentialequations-jl-compatibility/68594/15 "2022-01-28T20:45:57Z")

</div>

Trying to use DiffEqOperators and Unitful together throws an error. Do I understand it correctly that it’s it just the current state of the things?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [January 28, 2022, 8:52pm UTC](https://discourse.julialang.org/t/unitful-jl-and-differentialequations-jl-compatibility/68594/16 "2022-01-28T20:52:54Z")

</div>

Probably yeah. Open an issue

---

<div class="post-metadata">

**Author:** ![Deduction42](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/deduction42/32/9206_2.png) [@Deduction42](https://discourse.julialang.org/u/Deduction42)\
**Post date:** [February 13, 2026, 11:56pm UTC](https://discourse.julialang.org/t/unitful-jl-and-differentialequations-jl-compatibility/68594/17 "2026-02-13T23:56:04Z")

</div>

I know a lot of time has elapsed, but I just created a units package FlexUnits.jl that resembles Unitful but handles linear algebra and can even handle implicit methods like Rodas5P as shown in [this tutorial](https://deduction42.github.io/FlexUnits.jl/dev/examples/#Solving-Differential-Equations).
