Make Unitful simplify expressions like 1μm/1m to a unitless value by default

I freguently perform computations like 1μm/1m and would like Unitful to return a unitless number by default rather than having to do NoUnits(1μm/1m).

Is there a setting to make this the default?

1 Like

I’m not sure you can set a default, but FWIW, you might not need to, e.g.:

julia> using Unitful: μm, m

julia> 1μm/1m + 0
1.0e-6

For this purpose, I’m using a small piece of code listed below. It allows me to use for example // as a unit stripping operator.

After including the code below, I can just define the unit stripping operator and use it in a pretty readable way - this way I keep variables tagged with units as long as possible and strip the units just before printing or plotting, so I know exactly if I’m plotting in ns, microseconds or seconds

julia> @stripunits_operator //
julia> u = 15u"V"; d = 5u"mm"; E = u/d
julia> println("The field intensity is \$(E // u"V/m") [V/m] in a gap of \$(d // u"m") [m]")
The field intensity is 3000.0 [V/m] in a gap of 0.005 [m]

julia> typeof(E // u"V/m")
Float64

The code to include:

function stripunits(a::Unitful.Quantity, u::Unitful.Units)
    try
        return _stripunits(a,u)
    catch
       throw(ArgumentError("Cannot convert $a / $u to a Float64"))
    end
end

function _stripunits(a::Unitful.Quantity{T,D,UA}, u::Unitful.Units{UU,D}) where {T, D, UA,  UU}
    return a.val * Float64(Unitful.convfact(u, UA()))
end

macro stripunits_operator(op)
    blk = quote
        import Base.$op
        function Base.$op(a::Unitful.Quantity{T,D,UA}, u::Unitful.Units{UU,D}) where {T, D, UA,  UU}
            _stripunits(a, u)
        end
    end
    push!(blk.args, :nothing)
    blk.head = :toplevel
    return blk
end
1 Like

Would a “unit simplification” function be useful? For example, something like:

usimplify(x) = typeof(dimension(x)) == Unitful.Dimensions{()} ? ustrip(x) : x

I like

x |> upreferred

If it’s unitless, that will strip units. If it’s united it will make it SI. Very useful.

3 Likes

Perhaps, one thing that might be annoying about upreferred is the zeal it can have with accuracy:

3u"μm" |> upreferred

3//1000000 m
2 Likes

You could overload show for Unitful Quantity to perform the simplification before printing the value to the terminal or otherwise displaying it.

1 Like

You can solve this easily:

float(3u"μm" |> upreferred)

3.0e-6 m

3u"μm" |> upreferred |> float if you don’t want to mix styles.

1 Like

https://painterqubits.github.io/Unitful.jl/stable/conversion/

Exact conversions between units are respected where possible. If rational arithmetic would result in an overflow, then floating-point conversion should proceed. Use of floating-point numbers inhibits exact conversion.

julia> 3.0u"μm" |> upreferred
3.0e-6 m
1 Like