-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #85 from SymbolicML/real-quantity-2
Add AbstractRealQuantity
- Loading branch information
Showing
16 changed files
with
644 additions
and
196 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,108 @@ | ||
Base.isless(::AbstractQuantity, ::Missing) = missing | ||
Base.isless(::Missing, ::AbstractQuantity) = missing | ||
Base.:(==)(::AbstractQuantity, ::Missing) = missing | ||
Base.:(==)(::Missing, ::AbstractQuantity) = missing | ||
Base.isapprox(::AbstractQuantity, ::Missing; kws...) = missing | ||
Base.isapprox(::Missing, ::AbstractQuantity; kws...) = missing | ||
for op in (:isless, :(==), :isequal, :(<)), (type, _, _) in ABSTRACT_QUANTITY_TYPES | ||
@eval begin | ||
Base.$(op)(::$type, ::Missing) = missing | ||
Base.$(op)(::Missing, ::$type) = missing | ||
end | ||
end | ||
for op in (:isapprox,), (type, _, _) in ABSTRACT_QUANTITY_TYPES | ||
@eval begin | ||
Base.$(op)(::$type, ::Missing; kws...) = missing | ||
Base.$(op)(::Missing, ::$type; kws...) = missing | ||
end | ||
end | ||
|
||
Base.:(==)(::AbstractQuantity, ::WeakRef) = error("Cannot compare a quantity to a weakref") | ||
Base.:(==)(::WeakRef, ::AbstractQuantity) = error("Cannot compare a weakref to a quantity") | ||
for (type, _, _) in ABSTRACT_QUANTITY_TYPES | ||
@eval begin | ||
Base.:(==)(::$type, ::WeakRef) = error("Cannot compare a quantity to a weakref") | ||
Base.:(==)(::WeakRef, ::$type) = error("Cannot compare a weakref to a quantity") | ||
end | ||
end | ||
|
||
Base.:*(l::AbstractDimensions, r::Number) = error("Please use an `UnionAbstractQuantity` for multiplication. You used multiplication on types: $(typeof(l)) and $(typeof(r)).") | ||
Base.:*(l::Number, r::AbstractDimensions) = error("Please use an `UnionAbstractQuantity` for multiplication. You used multiplication on types: $(typeof(l)) and $(typeof(r)).") | ||
Base.:/(l::AbstractDimensions, r::Number) = error("Please use an `UnionAbstractQuantity` for division. You used division on types: $(typeof(l)) and $(typeof(r)).") | ||
Base.:/(l::Number, r::AbstractDimensions) = error("Please use an `UnionAbstractQuantity` for division. You used division on types: $(typeof(l)) and $(typeof(r)).") | ||
|
||
# Promotion ambiguities | ||
function Base.promote_rule(::Type{F}, ::Type{Bool}) where {F<:FixedRational} | ||
return F | ||
end | ||
function Base.promote_rule(::Type{Bool}, ::Type{F}) where {F<:FixedRational} | ||
return F | ||
end | ||
function Base.promote_rule(::Type{F}, ::Type{BigFloat}) where {F<:FixedRational} | ||
return promote_type(Rational{eltype(F)}, BigFloat) | ||
end | ||
function Base.promote_rule(::Type{BigFloat}, ::Type{F}) where {F<:FixedRational} | ||
return promote_type(Rational{eltype(F)}, BigFloat) | ||
end | ||
function Base.promote_rule(::Type{F}, ::Type{T}) where {F<:FixedRational,T<:AbstractIrrational} | ||
return promote_type(Rational{eltype(F)}, T) | ||
end | ||
function Base.promote_rule(::Type{T}, ::Type{F}) where {F<:FixedRational,T<:AbstractIrrational} | ||
return promote_type(Rational{eltype(F)}, T) | ||
end | ||
|
||
################################################################################ | ||
# Assorted calls found by Aqua: ################################################ | ||
################################################################################ | ||
|
||
for type in (Signed, Float64, Float32, Rational), op in (:flipsign, :copysign) | ||
@eval function Base.$(op)(x::$type, y::AbstractRealQuantity) | ||
return $(op)(x, ustrip(y)) | ||
end | ||
end | ||
for type in (:(Complex), :(Complex{Bool})) | ||
@eval begin | ||
function Base.:*(l::$type, r::AbstractRealQuantity) | ||
new_quantity(typeof(r), l * ustrip(r), dimension(r)) | ||
end | ||
function Base.:*(l::AbstractRealQuantity, r::$type) | ||
new_quantity(typeof(l), ustrip(l) * r, dimension(l)) | ||
end | ||
end | ||
end | ||
function Complex{T}(q::AbstractRealQuantity) where {T<:Real} | ||
@assert iszero(dimension(q)) "$(typeof(q)): $(q) has dimensions! Use `ustrip` instead." | ||
return Complex{T}(ustrip(q)) | ||
end | ||
for type in (:Bool, :Complex) | ||
@eval function $type(q::AbstractRealQuantity) | ||
@assert iszero(dimension(q)) "$(typeof(q)): $(q) has dimensions! Use `ustrip` instead." | ||
return $type(ustrip(q)) | ||
end | ||
end | ||
function Base.:/(l::Complex, r::AbstractRealQuantity) | ||
new_quantity(typeof(r), l / ustrip(r), inv(dimension(r))) | ||
end | ||
function Base.:/(l::AbstractRealQuantity, r::Complex) | ||
new_quantity(typeof(l), ustrip(l) / r, dimension(l)) | ||
end | ||
for op in (:(==), :isequal), base_type in (AbstractIrrational, AbstractFloat) | ||
@eval begin | ||
function Base.$(op)(l::AbstractRealQuantity, r::$base_type) | ||
return $(op)(ustrip(l), r) && iszero(dimension(l)) | ||
end | ||
function Base.$(op)(l::$base_type, r::AbstractRealQuantity) | ||
return $(op)(l, ustrip(r)) && iszero(dimension(r)) | ||
end | ||
end | ||
end | ||
function Base.isless(l::AbstractRealQuantity, r::AbstractFloat) | ||
iszero(dimension(l)) || throw(DimensionError(l, r)) | ||
return isless(ustrip(l), r) | ||
end | ||
function Base.isless(l::AbstractFloat, r::AbstractRealQuantity) | ||
iszero(dimension(r)) || throw(DimensionError(l, r)) | ||
return isless(l, ustrip(r)) | ||
end | ||
for (type, _, _) in ABSTRACT_QUANTITY_TYPES, numeric_type in (Bool, BigFloat) | ||
@eval begin | ||
function Base.promote_rule(::Type{Q}, ::Type{$numeric_type}) where {T,D,Q<:$type{T,D}} | ||
return with_type_parameters(promote_quantity_on_value(Q, $numeric_type), promote_type(T, $numeric_type), D) | ||
end | ||
function Base.promote_rule(::Type{$numeric_type}, ::Type{Q}) where {T,D,Q<:$type{T,D}} | ||
return with_type_parameters(promote_quantity_on_value(Q, $numeric_type), promote_type(T, $numeric_type), D) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.