|
1 | 1 | import Tricks: static_fieldnames
|
| 2 | +import LinearAlgebra: norm |
2 | 3 |
|
3 | 4 | function map_dimensions(f::F, args::AbstractDimensions...) where {F<:Function}
|
4 | 5 | dimension_type = promote_type(typeof(args).parameters...)
|
@@ -57,21 +58,35 @@ for f in (:iszero, :isfinite, :isinf, :isnan, :isreal, :sign, :signbit, :eps)
|
57 | 58 | end
|
58 | 59 | Base.eps(::Type{Q}) where {T,Q<:AbstractQuantity{T}} = eps(T)
|
59 | 60 |
|
60 |
| -# Multiplicative identities: |
61 |
| -Base.one(::Type{Q}) where {T,R,Q<:AbstractQuantity{T,R}} = new_quantity(Q, one(T), R) |
62 |
| -Base.one(::Type{Q}) where {T,Q<:AbstractQuantity{T}} = new_quantity(Q, one(T), DEFAULT_DIM_TYPE) |
63 |
| -Base.one(::Type{Q}) where {Q<:AbstractQuantity} = new_quantity(Q, one(DEFAULT_VALUE_TYPE), DEFAULT_DIM_TYPE) |
| 61 | +# Simple operations which return a full quantity (same dimensions) |
| 62 | +norm(q::AbstractQuantity, p::Real=2) = new_quantity(typeof(q), norm(ustrip(q), p), dimension(q)) |
| 63 | +for f in (:real, :imag, :conj, :adjoint, :unsigned, :nextfloat, :prevfloat) |
| 64 | + @eval Base.$f(q::AbstractQuantity) = new_quantity(typeof(q), $f(ustrip(q)), dimension(q)) |
| 65 | +end |
| 66 | + |
| 67 | +# Base.one, typemin, typemax |
| 68 | +for f in (:one, :typemin, :typemax) |
| 69 | + @eval begin |
| 70 | + Base.$f(::Type{Q}) where {T,R,Q<:AbstractQuantity{T,R}} = new_quantity(Q, $f(T), R) |
| 71 | + Base.$f(::Type{Q}) where {T,Q<:AbstractQuantity{T}} = $f(Q{T, DEFAULT_DIM_TYPE}) |
| 72 | + Base.$f(::Type{Q}) where {Q<:AbstractQuantity} = $f(Q{DEFAULT_VALUE_TYPE, DEFAULT_DIM_TYPE}) |
| 73 | + end |
| 74 | + if f == :one # Return empty dimensions, as should be multiplicative identity. |
| 75 | + @eval Base.$f(q::Q) where {Q<:AbstractQuantity} = new_quantity(Q, $f(ustrip(q)), one(dimension(q))) |
| 76 | + else |
| 77 | + @eval Base.$f(q::Q) where {Q<:AbstractQuantity} = new_quantity(Q, $f(ustrip(q)), dimension(q)) |
| 78 | + end |
| 79 | +end |
64 | 80 | Base.one(::Type{D}) where {D<:AbstractDimensions} = D()
|
65 |
| -Base.one(q::Q) where {Q<:AbstractQuantity} = new_quantity(Q, one(ustrip(q)), one(dimension(q))) |
66 | 81 | Base.one(::D) where {D<:AbstractDimensions} = one(D)
|
67 | 82 |
|
68 |
| -# Additive identities: |
| 83 | +# Additive identities (zero) |
69 | 84 | Base.zero(q::Q) where {Q<:AbstractQuantity} = new_quantity(Q, zero(ustrip(q)), dimension(q))
|
70 | 85 | Base.zero(::AbstractDimensions) = error("There is no such thing as an additive identity for a `AbstractDimensions` object, as + is only defined for `AbstractQuantity`.")
|
71 | 86 | Base.zero(::Type{<:AbstractQuantity}) = error("Cannot create an additive identity for a `AbstractQuantity` type, as the dimensions are unknown. Please use `zero(::AbstractQuantity)` instead.")
|
72 | 87 | Base.zero(::Type{<:AbstractDimensions}) = error("There is no such thing as an additive identity for a `AbstractDimensions` type, as + is only defined for `AbstractQuantity`.")
|
73 | 88 |
|
74 |
| -# Dimensionful 1: |
| 89 | +# Dimensionful 1 (oneunit) |
75 | 90 | Base.oneunit(q::Q) where {Q<:AbstractQuantity} = new_quantity(Q, oneunit(ustrip(q)), dimension(q))
|
76 | 91 | Base.oneunit(::AbstractDimensions) = error("There is no such thing as a dimensionful 1 for a `AbstractDimensions` object, as + is only defined for `AbstractQuantity`.")
|
77 | 92 | Base.oneunit(::Type{<:AbstractQuantity}) = error("Cannot create a dimensionful 1 for a `AbstractQuantity` type without knowing the dimensions. Please use `oneunit(::AbstractQuantity)` instead.")
|
|
0 commit comments