1- import Ratios: SimpleRatio
2- import SaferIntegers: SafeInt
3-
4- const INT_TYPE = SafeInt
5- const R = SimpleRatio{INT_TYPE}
6- const ZERO = R (0 )
7- const DIMENSION_NAMES = (:length , :mass , :time , :current , :temperature , :luminosity , :amount )
8- const DIMENSION_SYNONYMS = (:𝐋 , :𝐌 , :𝐓 , :𝐈 , :𝚯 , :𝐉 , :𝐍 )
9- const SYNONYM_MAPPING = NamedTuple (DIMENSION_NAMES .=> DIMENSION_SYNONYMS)
1+ const DEFAULT_DIM_TYPE = Rational{Int16}
2+ const DEFAULT_VALUE_TYPE = Float64
103
114"""
125 Dimensions
@@ -17,15 +10,15 @@ example, the dimensions of velocity are `Dimensions(length=1, time=-1)`.
1710
1811# Fields
1912
20- - `length::Rational{Int} `: length dimension (i.e., meters^(length))
21- - `mass::Rational{Int} `: mass dimension (i.e., kg^(mass))
22- - `time::Rational{Int} `: time dimension (i.e., s^(time))
23- - `current::Rational{Int} `: current dimension (i.e., A^(current))
24- - `temperature::Rational{Int} `: temperature dimension (i.e., K^(temperature))
25- - `luminosity::Rational{Int} `: luminosity dimension (i.e., cd^(luminosity))
26- - `amount::Rational{Int} `: amount dimension (i.e., mol^(amount))
13+ - `length`: length dimension (i.e., meters^(length))
14+ - `mass`: mass dimension (i.e., kg^(mass))
15+ - `time`: time dimension (i.e., s^(time))
16+ - `current`: current dimension (i.e., A^(current))
17+ - `temperature`: temperature dimension (i.e., K^(temperature))
18+ - `luminosity`: luminosity dimension (i.e., cd^(luminosity))
19+ - `amount`: amount dimension (i.e., mol^(amount))
2720"""
28- struct Dimensions
21+ struct Dimensions{R <: Real }
2922 length:: R
3023 mass:: R
3124 time:: R
@@ -34,27 +27,40 @@ struct Dimensions
3427 luminosity:: R
3528 amount:: R
3629
37- Dimensions (length:: R , mass:: R , time:: R , current:: R , temperature:: R , luminosity:: R , amount:: R ) =
38- new (length, mass, time, current, temperature, luminosity, amount)
39- Dimensions (; kws... ) = Dimensions (
40- tryrationalize (R, get (kws, :length , ZERO)),
41- tryrationalize (R, get (kws, :mass , ZERO)),
42- tryrationalize (R, get (kws, :time , ZERO)),
43- tryrationalize (R, get (kws, :current , ZERO)),
44- tryrationalize (R, get (kws, :temperature , ZERO)),
45- tryrationalize (R, get (kws, :luminosity , ZERO)),
46- tryrationalize (R, get (kws, :amount , ZERO)),
30+ function Dimensions (length:: _R ,
31+ mass:: _R ,
32+ time:: _R ,
33+ current:: _R ,
34+ temperature:: _R ,
35+ luminosity:: _R ,
36+ amount:: _R ) where {_R<: Real }
37+ new {_R} (length, mass, time, current, temperature, luminosity, amount)
38+ end
39+ Dimensions (; kws... ) = Dimensions (DEFAULT_DIM_TYPE; kws... )
40+ Dimensions (:: Type{_R} ; kws... ) where {_R} = Dimensions (
41+ tryrationalize (_R, get (kws, :length , zero (_R))),
42+ tryrationalize (_R, get (kws, :mass , zero (_R))),
43+ tryrationalize (_R, get (kws, :time , zero (_R))),
44+ tryrationalize (_R, get (kws, :current , zero (_R))),
45+ tryrationalize (_R, get (kws, :temperature , zero (_R))),
46+ tryrationalize (_R, get (kws, :luminosity , zero (_R))),
47+ tryrationalize (_R, get (kws, :amount , zero (_R))),
4748 )
49+ Dimensions {_R} (; kws... ) where {_R} = Dimensions (_R; kws... )
50+ Dimensions {_R} (args... ) where {_R} = Dimensions (Base. Fix1 (convert, _R).(args). .. )
4851end
4952
53+ const DIMENSION_NAMES = Base. fieldnames (Dimensions)
54+ const DIMENSION_SYNONYMS = (:𝐋 , :𝐌 , :𝐓 , :𝐈 , :𝚯 , :𝐉 , :𝐍 )
55+ const SYNONYM_MAPPING = NamedTuple (DIMENSION_NAMES .=> DIMENSION_SYNONYMS)
56+
5057"""
5158 Quantity{T}
5259
5360Physical quantity with value `value` of type `T` and dimensions `dimensions`.
54- The `valid` field is used to indicate whether the quantity is valid or not
55- (e.g., due to dimensional error). For example, the velocity of an object
56- with mass 1 kg and velocity 2 m/s is `Quantity(2, mass=1, length=1, time=-1)`.
57- You should access these fields with `ustrip(q)`, `dimensions(q)`, and `valid(q)`.
61+ For example, the velocity of an object with mass 1 kg and velocity
62+ 2 m/s is `Quantity(2, mass=1, length=1, time=-1)`.
63+ You should access these fields with `ustrip(q)`, and `dimensions(q)`.
5864You can access specific dimensions with `ulength(q)`, `umass(q)`, `utime(q)`,
5965`ucurrent(q)`, `utemperature(q)`, `uluminosity(q)`, and `uamount(q)`.
6066
@@ -65,15 +71,17 @@ including `*`, `+`, `-`, `/`, `^`, `sqrt`, and `cbrt`.
6571
6672- `value::T`: value of the quantity of some type `T`
6773- `dimensions::Dimensions`: dimensions of the quantity
68- - `valid::Bool`: whether the quantity is valid or not
6974"""
70- struct Quantity{T}
75+ struct Quantity{T, R }
7176 value:: T
72- dimensions:: Dimensions
73- valid:: Bool
77+ dimensions:: Dimensions{R}
78+
79+ Quantity (x; kws... ) = new {typeof(x), DEFAULT_DIM_TYPE} (x, Dimensions (; kws... ))
80+ Quantity (x, :: Type{_R} ; kws... ) where {_R} = new {typeof(x), _R} (x, Dimensions (_R; kws... ))
81+ Quantity (x, d:: Dimensions{_R} ) where {_R} = new {typeof(x), _R} (x, d)
82+ end
7483
75- Quantity (x; kws... ) = new {typeof(x)} (x, Dimensions (; kws... ), true )
76- Quantity (x, valid:: Bool ; kws... ) = new {typeof(x)} (x, Dimensions (; kws... ), valid)
77- Quantity (x, d:: Dimensions ) = new {typeof(x)} (x, d, true )
78- Quantity (x, d:: Dimensions , valid:: Bool ) = new {typeof(x)} (x, d, valid)
84+ struct DimensionError{Q1,Q2} <: Exception
85+ q1:: Q1
86+ q2:: Q2
7987end
0 commit comments