@@ -14,7 +14,6 @@ This is done to allow for calculations where physical dimensions are not known a
14
14
15
15
- [ Performance] ( #performance )
16
16
- [ Usage] ( #usage )
17
- - [ Units] ( #units )
18
17
- [ Types] ( #types )
19
18
- [ Vectors] ( #vectors )
20
19
@@ -26,8 +25,8 @@ when the compiler cannot infer dimensions in a function:
26
25
``` julia
27
26
julia> using BenchmarkTools, DynamicQuantities; import Unitful
28
27
29
- julia> dyn_uni = Quantity ( 0.2 , mass = 1 , length = 0.5 , amount = 3 )
30
- 0.2 𝐋 ¹ᐟ² 𝐌 ¹ 𝐍 ³
28
+ julia> dyn_uni = 0.2 u " m^ 0.5 * kg * mol^3 "
29
+ 0.2 m ¹ᐟ² kg mol ³
31
30
32
31
julia> unitful = convert (Unitful. Quantity, dyn_uni)
33
32
0.2 kg m¹ᐟ² mol³
@@ -64,56 +63,71 @@ to units and the compiler can optimize away units from the code.
64
63
65
64
## Usage
66
65
67
- You can create a ` Quantity ` object with a value and keyword arguments for the powers of the physical dimensions
68
- ( ` mass ` , ` length ` , ` time ` , ` current ` , ` temperature ` , ` luminosity ` , ` amount ` ) :
66
+ You can create a ` Quantity ` object
67
+ by using the convenience macro ` u"..." ` :
69
68
70
69
``` julia
71
- julia> x = Quantity (0.3 , mass= 1 , length= 0.5 )
72
- 0.3 𝐋 ¹ᐟ² 𝐌 ¹
70
+ julia> x = 0.3 u " km/s"
71
+ 300.0 m s⁻¹
72
+
73
+ julia> y = 42 * u " kg"
74
+ 42.0 kg
75
+
76
+ julia> room_temp = 100 u " kPa"
77
+ 100000.0 m⁻¹ kg s⁻²
78
+ ```
79
+
80
+ This supports a wide range of SI base and derived units, with common
81
+ prefixes.
82
+
83
+ You can also construct values explicitly with the ` Quantity ` type,
84
+ with a value and keyword arguments for the powers of the physical dimensions
85
+ (` mass ` , ` length ` , ` time ` , ` current ` , ` temperature ` , ` luminosity ` , ` amount ` ):
73
86
74
- julia> y = Quantity (10.2 , mass= 2 , time= - 2 )
75
- 10.2 𝐌 ² 𝐓 ⁻²
87
+ ``` julia
88
+ julia> x = Quantity (300.0 , length= 1 , time= - 1 )
89
+ 300.0 m s⁻¹
76
90
```
77
91
78
- Elementary calculations with ` +, -, *, /, ^, sqrt, cbrt ` are supported:
92
+ Elementary calculations with ` +, -, *, /, ^, sqrt, cbrt, abs ` are supported:
79
93
80
94
``` julia
81
95
julia> x * y
82
- 3.0599999999999996 𝐋 ¹ᐟ² 𝐌 ³ 𝐓 ⁻²
96
+ 12600.0 m kg s⁻¹
83
97
84
98
julia> x / y
85
- 0.029411764705882353 𝐋 ¹ᐟ² 𝐌 ⁻¹ 𝐓 ²
99
+ 7.142857142857143 m kg⁻¹ s⁻¹
86
100
87
101
julia> x ^ 3
88
- 0.027 𝐋 ³ᐟ² 𝐌 ³
102
+ 2.7e7 m³ s⁻ ³
89
103
90
104
julia> x ^ - 1
91
- 3.3333333333333335 𝐋 ⁻¹ᐟ² 𝐌 ⁻¹
105
+ 0.0033333333333333335 m⁻¹ s
92
106
93
107
julia> sqrt (x)
94
- 0.5477225575051661 𝐋 ¹ᐟ⁴ 𝐌 ¹ᐟ²
108
+ 17.320508075688775 m¹ᐟ² s⁻ ¹ᐟ²
95
109
96
110
julia> x ^ 1.5
97
- 0.1643167672515498 𝐋 ³ᐟ⁴ 𝐌 ³ᐟ²
111
+ 5196.152422706632 m³ᐟ² s⁻ ³ᐟ²
98
112
```
99
113
100
- Each of these values has the same type, thus obviating the need for type inference at runtime.
114
+ Each of these values has the same type, which means we don't need to perform type inference at runtime.
101
115
102
116
Furthermore, we can do dimensional analysis by detecting ` DimensionError ` :
103
117
104
118
``` julia
105
119
julia> x + 3 * x
106
- 1.2 𝐋 ¹ᐟ² 𝐌 ¹
120
+ 1.2 m ¹ᐟ² kg
107
121
108
122
julia> x + y
109
- ERROR: DimensionError: 0.3 𝐋 ¹ᐟ² 𝐌 ¹ and 10.2 𝐌 ² 𝐓 ⁻² have different dimensions
123
+ ERROR: DimensionError: 0.3 m ¹ᐟ² kg and 10.2 kg² s ⁻² have incompatible dimensions
110
124
```
111
125
112
126
The dimensions of a ` Quantity ` can be accessed either with ` dimension(quantity) ` for the entire ` Dimensions ` object:
113
127
114
128
``` julia
115
129
julia> dimension (x)
116
- 𝐋 ¹ᐟ² 𝐌 ¹
130
+ m ¹ᐟ² kg
117
131
```
118
132
119
133
or with ` umass ` , ` ulength ` , etc., for the various dimensions:
@@ -133,26 +147,28 @@ julia> ustrip(x)
133
147
0.2
134
148
```
135
149
136
- ## Units
150
+ ### Unitful
151
+
152
+ DynamicQuantities works with quantities that are exclusively
153
+ represented by their SI base units. This gives us type stability
154
+ and greatly improves performance.
137
155
138
- DynamicQuantities works with quantities which store physical dimensions and a value,
139
- and does not directly provide a unit system.
140
156
However, performing calculations with physical dimensions
141
157
is actually equivalent to working with a standardized unit system.
142
158
Thus, you can use Unitful to parse units,
143
159
and then use the DynamicQuantities->Unitful extension for conversion:
144
160
145
161
``` julia
146
- julia> using Unitful: Unitful, @u_str
162
+ julia> using Unitful: Unitful, @u_str ; import DynamicQuantities
147
163
148
164
julia> x = 0.5 u " km/s"
149
165
0.5 km s⁻¹
150
166
151
167
julia> y = convert (DynamicQuantities. Quantity, x)
152
- 500.0 𝐋 ¹ 𝐓 ⁻¹
168
+ 500.0 m s ⁻¹
153
169
154
170
julia> y2 = y^ 2 * 0.3
155
- 75000.0 𝐋 ² 𝐓 ⁻²
171
+ 75000.0 m² s ⁻²
156
172
157
173
julia> x2 = convert (Unitful. Quantity, y2)
158
174
75000.0 m² s⁻²
@@ -163,24 +179,31 @@ true
163
179
164
180
## Types
165
181
166
- Both the ` Quantity ` 's values and dimensions are of arbitrary type.
182
+ Both a ` Quantity ` 's values and dimensions are of arbitrary type.
167
183
By default, dimensions are stored as a ` DynamicQuantities.FixedRational{Int32,C} `
168
184
object, which represents a rational number
169
185
with a fixed denominator ` C ` . This is much faster than ` Rational ` .
170
186
171
187
``` julia
172
- julia> typeof (Quantity ( 0.5 , mass = 1 ) )
188
+ julia> typeof (0.5 u " kg " )
173
189
Quantity{Float64, FixedRational{Int32, 25200 }
174
190
```
175
191
176
192
You can change the type of the value field by initializing with a value
177
- of the desired type.
193
+ explicitly of the desired type.
178
194
179
195
``` julia
180
196
julia> typeof (Quantity (Float16 (0.5 ), mass= 1 , length= 1 ))
181
197
Quantity{Float16, FixedRational{Int32, 25200 }}
182
198
```
183
199
200
+ or by conversion:
201
+
202
+ ``` julia
203
+ julia> typeof (convert (Quantity{Float16}, 0.5 u " m/s" ))
204
+ Quantity{Float16, DynamicQuantities. FixedRational{Int32, 25200 }}
205
+ ```
206
+
184
207
For many applications, `FixedRational{Int8,6}` will suffice,
185
208
and can be faster as it means the entire `Dimensions`
186
209
struct will fit into 64 bits.
@@ -213,23 +236,23 @@ There is not a separate class for vectors, but you can create units
213
236
like so:
214
237
215
238
``` julia
216
- julia> randn (5 ) .* Dimensions (mass = 2 / 5 , length = 2 )
217
- 5 - element Vector{Quantity{Float64, FixedRational{Int32, 25200 }}}:
218
- - 0.6450221578668845 𝐋 ² 𝐌 ²ᐟ⁵
219
- 0.4024829670050946 𝐋 ² 𝐌 ²ᐟ⁵
220
- 0.21478863605789672 𝐋 ² 𝐌 ²ᐟ⁵
221
- 0.0719774550969669 𝐋 ² 𝐌 ²ᐟ⁵
222
- - 1.4231241943420674 𝐋 ² 𝐌 ²ᐟ⁵
239
+ julia> randn (5 ) .* u " m/s "
240
+ 5 - element Vector{Quantity{Float64, DynamicQuantities . FixedRational{Int32, 25200 }}}:
241
+ 1.1762086954956399 m s⁻¹
242
+ 1.320811324040591 m s⁻¹
243
+ 0.6519033652437799 m s⁻¹
244
+ 0.7424822374423569 m s⁻¹
245
+ 0.33536928068133726 m s⁻¹
223
246
```
224
247
225
248
Because it is type stable, you can have mixed units in a vector too:
226
249
227
250
``` julia
228
251
julia> v = [Quantity (randn (), mass= rand (0 : 5 ), length= rand (0 : 5 )) for _= 1 : 5 ]
229
- 5 - element Vector{Quantity{Float64, FixedRational{Int32, 25200 }}}:
230
- 2.2054411324716865 𝐌 ³
231
- - 0.01603602425887379 𝐋 ⁴ 𝐌 ³
232
- 1.4388184352393647
233
- 2.382303019892503 𝐋 ² 𝐌 ¹
234
- 0.6071392594021706 𝐋 ⁴ 𝐌 ⁴
252
+ 5 - element Vector{Quantity{Float64, DynamicQuantities . FixedRational{Int32, 25200 }}}:
253
+ 0.4309293892461158 kg⁵
254
+ 1.415520139801276
255
+ 1.2179414706524276 m³ kg⁴
256
+ - 0.18804207255117408 m³ kg⁵
257
+ 0.52123911329638 m³ kg²
235
258
```
0 commit comments