SymbolicML / DynamicQuantities.jl

Efficient and type-stable physical quantities in Julia
https://symbolicml.org/DynamicQuantities.jl/dev/
Apache License 2.0
120 stars 15 forks source link

Inconsistency between one(x::Quantity) and zero(x::Quantity) #138

Closed FerreolS closed 1 month ago

FerreolS commented 1 month ago

If t is a Quantity, the dimension is present in zero(t) but not in one(t) as in the following example:

               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.10.3 (2024-04-30)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia> using DynamicQuantities

julia> t=1u"m"
1.0 m

julia> one(t)
1.0 

julia> zero(t)
0.0 m

julia> oneunit(t)
1.0 m
MilesCranmer commented 1 month ago

This is the difference between one and oneunit. See https://docs.julialang.org/en/v1/base/numbers/#Base.oneunit

If you want a quantity that is of the same type as x, or of type T, even if x is dimensionful, use oneunit instead.

The way these are defined is that one is a multiplicative identity and zero is an additive identity. This is why one does not have units but zero does.

For example:

julia> t = 1u"m"
1.0 m

julia> t + zero(t)
1.0 m

julia> t * one(t)
1.0 m

And we can see that the output is equal to t. (This is how one(x) and zero(x) are defined in Julia)

Whereas if you tried to add with a normal 0:

julia> t + 0
ERROR: DimensionError: 1.0 m and 0 have incompatible dimensions

This is also why zero(x) works on vectors:

julia> x = [1, 2, 3]
3-element Vector{Int64}:
 1
 2
 3

julia> x + zero(x)
3-element Vector{Int64}:
 1
 2
 3

julia> zero(x)
3-element Vector{Int64}:
 0
 0
 0

but one(x) does not:

julia> one(x)
ERROR: MethodError: no method matching one(::Vector{Int64})