# Is there a \ operator for Unitful?

I was running into a problem using the \ (linear system solver) operator in Julia. I guess I wrongly assumed the \ operator was overloaded for matrices/vectors with entries of type <: Number (witch unitful types are). Is there any way to easily overload the \ operator to accept unitful types, or perhaps a different operator/function that works for all types that are subtypes of Number (since I plan on using Sym and Float/Integer types in my code as well)

Environment: Pluto on MacOS
Packages: Unitful, Sympy, Plots, PlutoUI
Code:

``````let
a11 = 1u"m"
a12 = 2u"ft"
a21 = 5u"mm"
a22 = 0u"inch"
A = [a11 a12; a21 a22]
b = [3u"inch"; 1u"mm"]
x  = A \ b # This line throws error
end
``````

Error:
`MethodError: no method matching (Unitful.Quantity{Rational{Int64}})(::Rational{Int64})`

1 Like

I don’t think there is an easy way to define a unique, unambiguous solution to that example problem. Which should the units of the elements of `x`? Moreover, in this case it’s only a matter of scale between units of the same kind, but for arbitrary units in `A` and `b`, it might be impossible to solve.

1 Like

Maybe something along these lines:

``````using LinearAlgebra, Unitful
import LinearAlgebra: \

(\)(A::Matrix{Quantity{T,U,V}}, B::AbstractVecOrMat) where {T,U,V} =
Quantity.(ustrip(A)\ustrip(B), unit(eltype(B))/unit(eltype(A)))
``````

With this definition:

``````julia> A\b
2-element Vector{Rational{Int64}}:
1//5
-619//3048

julia> c = ustrip(b)
2-element reinterpret(Rational{Int64}...):
381//5000
1//1000

julia> A\c
2-element Vector{Quantity{Rational{Int64}...}}:
1//5 m^-1
-619//3048 m^-1
``````

But this was a quick sketch, might be ins-and-outs to fix yet.

Oh yeah, it makes sense that the ‘b’ vector would be in units of Length*mysteryunit since Ax = b, and x is unknown. Maybe x can be solved given the units of b?

Using the one-argument `ustrip` method is generally a bad idea: you don’t know what you’re stripping, it works well only for the trivial case where you have all homogeneous quantities.

2 Likes

Thanks for the advice! I changed up the method a little bit to ensure that all unit of elements in the matrices A and B are the same before using the system solver.

``````function Base.:\(A::Matrix{Quantity{T,U,V}}, B::AbstractVecOrMat) where {T,U,V}
if typeof(unit(eltype(A))) ≠ Unitful.FreeUnits{(), NoDims, nothing}
A = map(x -> uconvert(unit(eltype(A)), x), A)
B = map(x -> uconvert(unit(eltype(B)), x), B)
return Quantity.(ustrip(A)\ustrip(B), unit(eltype(B))/unit(eltype(A)))
end
end
``````

There should be another definition of `\` covering the case when `A` is a non-Unitful matrix and `B` is Unitful. Should be pretty similar to the one already defined.