Skip to content

Affine Units Functionality #159

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 72 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
3f37480
Basic arithmatic between AffineUnits and other units
Deduction42 Jan 29, 2025
93d065c
Successful exponentiation
Deduction42 Jan 29, 2025
24f7966
Better constructors
Deduction42 Jan 29, 2025
be23440
added affine units parsing
Deduction42 Jan 29, 2025
ebf0fd5
Modified settings
Deduction42 Jan 30, 2025
b611801
Updated plan for unit display
RGonTheNoble Jan 30, 2025
8613bc1
@register_unit now populates AffineUnits
RGonTheNoble Jan 30, 2025
4d07529
Completed unit registration strategy
RGonTheNoble Jan 30, 2025
e811c1c
Better macro documentation
RGonTheNoble Jan 30, 2025
e2eb10f
Fixed ambiguity issues, all unit tests pass
Deduction42 Jan 31, 2025
bcf26df
More robust constructors
Deduction42 Jan 31, 2025
d3c0f6c
More informative dimension mismatch errors
Deduction42 Jan 31, 2025
270ce0e
Fixed some unit conversion bugs
Deduction42 Jan 31, 2025
1565b51
Overloaded approx and equals for AffineQuantities
Deduction42 Jan 31, 2025
0e8b6d8
First ound of unit tests
Deduction42 Feb 3, 2025
0eab0f0
Very strong affine_dimensions.jl coverage
Deduction42 Feb 4, 2025
70cff63
100% coverage of affine_dimensions.jl
Deduction42 Feb 4, 2025
c94ffc9
Renamed AffineUnitsParse to AffineUnits (for convention)
Deduction42 Feb 4, 2025
24bfebd
register_units now 100% covered
Deduction42 Feb 4, 2025
bb6a70f
Added documentation
Deduction42 Feb 4, 2025
39ac03a
Added docu for @register_affine_unit
Deduction42 Feb 4, 2025
782c1bf
Fixed indentation issue
Deduction42 Feb 4, 2025
e8197bd
Fixed documenter typo
Deduction42 Feb 4, 2025
fa1709b
Delete lcov.info
Deduction42 Feb 4, 2025
c1c4045
Added "psig" to affine unit tests, added warning tests
Deduction42 Feb 4, 2025
b9c1328
Fixed a counting issue in tests
Deduction42 Feb 4, 2025
be7df25
Registered degC and degF, tested them
Deduction42 Feb 5, 2025
ed6e0ab
AffineDimension equality ignores symbolic name
Deduction42 Feb 10, 2025
b3484d0
Update README.md
Deduction42 Feb 18, 2025
3934787
Update README.md
Deduction42 Feb 18, 2025
513d7f3
Changed order of inclusion for affine_dimensions.jl
Deduction42 Feb 18, 2025
9e261a1
Style changes and moved operators to map_dimensions
Deduction42 Feb 19, 2025
a26d653
Improvements to unit display
Deduction42 Feb 19, 2025
a970379
Added fallback map_dimensions with testing, style changes
Deduction42 Feb 19, 2025
e76f52e
Changed "begin" block to "let" for scoping
Deduction42 Feb 19, 2025
defde7b
Registered AffineUnits constants, modified "constructorof"
Deduction42 Mar 8, 2025
5183bc6
Removed @kwdef macro
Deduction42 Mar 8, 2025
5099ad9
Merge branch 'main' into main
Deduction42 Mar 8, 2025
4f5d757
Bump version
Deduction42 Mar 8, 2025
fe37122
eliminated siunits(), renamed scale(), offset(), basedim()
Deduction42 Mar 11, 2025
9d460f0
Corrected "constructorof" behaviour
Deduction42 Mar 11, 2025
ce96ea2
Merge branch 'main' into main
Deduction42 Mar 11, 2025
a4ae557
Docs simplification, uscale etc renaming, removed generic map_dimensi…
Deduction42 Mar 11, 2025
0e3ef3c
Modified headers
Deduction42 Mar 11, 2025
832df27
refactor: reduce complexity of affine dimensions
MilesCranmer Mar 11, 2025
ab21637
refactor: remove `affine_quantity`
MilesCranmer Mar 11, 2025
a305a35
refactor: more cleanup of affine dimensions
MilesCranmer Mar 11, 2025
6f88c9e
refactor: more cleanup of affine dimensions
MilesCranmer Mar 11, 2025
0b27482
refactor: more cleanup of affine dimensions
MilesCranmer Mar 11, 2025
a9c4f68
refactor: more cleanup of affine dimensions
MilesCranmer Mar 11, 2025
5281f53
refactor: tweak error message
MilesCranmer Mar 11, 2025
3769ce6
refactor: remove fancy printing for affine dimensions
MilesCranmer Mar 11, 2025
d8b7546
fix: error from refactor
MilesCranmer Mar 11, 2025
c553c95
refactor: further cleanup
MilesCranmer Mar 11, 2025
8874df0
fix: refactoring error
MilesCranmer Mar 11, 2025
9efdf5c
refactor: condense
MilesCranmer Mar 11, 2025
2fd1e32
fix: ambiguity
MilesCranmer Mar 11, 2025
0178d59
refactor: further cleanup
MilesCranmer Mar 11, 2025
762e411
docs: shorten mention of affine units
MilesCranmer Mar 11, 2025
5547fea
docs: reduce verbosity by pointing to `@register_unit`
MilesCranmer Mar 11, 2025
677d79f
refactor: small cleanup
MilesCranmer Mar 11, 2025
97804ce
Re-registering different units now throws an error, does not warn if …
Deduction42 Mar 13, 2025
31c8bfe
refactor: further cleanup
MilesCranmer Mar 13, 2025
76ce32c
Merge branch 'main' of https://github.com/deduction42/dynamicquantiti…
MilesCranmer Mar 13, 2025
212d2ed
Lumped "mod" behaviour with "+" in a metaprogramming loop
Deduction42 Mar 13, 2025
5f33445
Merge branch 'main' of https://github.com/Deduction42/DynamicQuantiti…
Deduction42 Mar 13, 2025
bbee66b
Removed minus special case, added mod.
Deduction42 Mar 13, 2025
59fc5bf
Removed minus special case, included mod
Deduction42 Mar 13, 2025
0a74898
Better units display for ua_str macro
Deduction42 Mar 13, 2025
1138d0f
Broke `ustrip` for safety, patched up the pices
Deduction42 Mar 14, 2025
da84df7
Merged previous refactoring
Deduction42 Mar 15, 2025
e36a4ca
Fixed some missing imports
Deduction42 Mar 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "DynamicQuantities"
uuid = "06fc5a27-2a28-4c7c-a15d-362465fb6821"
authors = ["MilesCranmer <[email protected]> and contributors"]
version = "1.5.1"
version = "1.6.0"

[deps]
DispatchDoctor = "8d63f2c5-f18a-4cf2-ba9d-b3f60fc568c8"
Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,21 @@ julia> 3us"V" |> us"OneFiveV"
2.0 OneFiveV
```

#### Affine Units

You can also use "*affine*" units such as Celsius or Fahrenheit,
using the `ua"..."` string macro:

```julia
julia> room_temp = 22ua"degC"
22.0 °C

julia> room_temp |> ua"degF" |> round
72.0 °F

julia> room_temp |> uexpand |> round
295.0 K
```

### Arrays

Expand Down
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ makedocs(;
"Units" => "units.md",
"Constants" => "constants.md",
"Symbolic Units" => "symbolic_units.md",
"Affine Units" => "affine_units.md",
"Types" => "types.md",
],
warnonly = [:missing_docs]
Expand Down
53 changes: 53 additions & 0 deletions docs/src/affine_units.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Affine Dimensions
Units that have an offset (such as °C = K + 273.15) are an unfortunate fact of life: they are used extensively but often result in ambiguous mathematical operations (many other packages, such as Unitful.jl only support limited operations for affine dimensions). `AffineDimensions` seeks to extend DynamicQuantities.jl to reduce dependence on Unitful.jl, and enable handling/converting such units in a flexible, type-stable manner.

`AffineDimensions` are a generalization of `Dimensions` and `SymbolicDimensions`. While SymbolicDimensions essentially add a scale to Dimensions, AffineDimensions will add both a scale and an offset. Verious constructors can be used to construct `AffineDimensions` from other dimensions.
```
kelvin = AffineDimensions(basedim=u"K") #Assumes a scale of 1 and offset 0
rankine = AffineDimensions(scale=5/9, offset=0.0, basedim=dimension(u"K")) #Rankine is a scaled version of Kelvin, offset is assumed to be of units 'basedim'
fahrenheit = AffineDimensions(scale=1.0, offset=Quantity(459.67, rankine), basedim=rankine) #Its best to make offset a `Quantity` to be explicit
celsius = AffineDimensions(scale=9/5, offset=Quantity(32.0, rankine), basedim=fahrenheit) #When AffineDimensiosn are used, offset starts with basedim's offset
```
## Registration and parsing
To access units from the affine unit registry, the string macro `ua"..."` can be used. This macro will always return quantities with AffineDimensions, even if a non-affine unit is called (it will simply have an offset of 0). Because AffineDimensions are a generalization of SymbolicDimensions, the affine unit registry will mirror the symbolic unit registry.
```
@register_unit psi 6.89476us"kPa"
u"psi"
>> 6894.76 m⁻¹ kg s⁻²
us"psi"
>> 1.0 psi
ua"psi"
>> 1.0 psi
```
However, strictly affine units cannot belong to the symbolic registry, so a different macro must be used on an AffineDimension (or quantity thereof)
```
@register_affine_unit psig AffineDimensions(offset=u"Constants.atm", basedim=u"psi") #Gauge pressure implies atmospheric offset
ua"psig"
>> 1.0 psig
us"psig"
>> ERROR: LoadError: ArgumentError: Symbol psig not found in `Units` or `Constants`.
```
Affine unit parsing can also be done outside of a macro using `aff_uparse(str::AbstractString)`
```
aff_uparse("°C")
>> 1.0 °C
```
```@docs
@ua_str
@register_affine_unit
aff_uparse
```
## Operations
In Unitful.jl, multiplication of affine quantities is not supported for affine dimensions:
```
using Unitful
u"R"*0u"°C"
>> ERROR: AffineError: an invalid operation was attempted with affine units: °C
```
This behaviour is mimicked in DynamicQuantities:
```
using DynamicQuantities
u"Constants.R"*(0ua"°C")
>> AssertionError: AffineDimensions °C has a non-zero offset, implicit conversion is not allowed due to ambiguity. Use uexpand(x) to explicitly convert
```
In general, it's best to treat quantities with AffineDimensions as placeholders and use `uexpand(q)` or `uconvert(units, q)` as soon as possible. The main objective of AffineDimesnions is to provide you with convenient, type-stable tools to do this conversion before applying mathematical operations.
5 changes: 4 additions & 1 deletion src/DynamicQuantities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ export Quantity, GenericQuantity, RealQuantity
export FixedRational
export AbstractDimensions, Dimensions, NoDims
export AbstractSymbolicDimensions, SymbolicDimensions, SymbolicDimensionsSingleton
export AbstractAffineDimensions, AffineDimensions
export QuantityArray
export DimensionError
export ustrip, dimension, uexpand, uconvert, ustripexpand
export ulength, umass, utime, ucurrent, utemperature, uluminosity, uamount
export uparse, @u_str, sym_uparse, @us_str, @register_unit
export uparse, @u_str, sym_uparse, @us_str, @register_unit, aff_uparse, @ua_str, @register_affine_unit

# Deprecated:
export expand_units
Expand All @@ -29,9 +30,11 @@ using DispatchDoctor: @stable
include("constants.jl")
include("uparse.jl")
include("symbolic_dimensions.jl")
include("affine_dimensions.jl")
include("complex.jl")
include("register_units.jl")
include("disambiguities.jl")


include("deprecated.jl")
end
Expand Down
Loading
Loading