phys-units 0.9.2 → 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +16 -14
- data/lib/phys/units/errors.rb +1 -6
- data/lib/phys/units/jp.rb +169 -0
- data/lib/phys/units/load_units.rb +2 -3
- data/lib/phys/units/mixin.rb +6 -0
- data/lib/phys/units/parse.rb +4 -4
- data/lib/phys/units/parse.y +6 -6
- data/lib/phys/units/quantity.rb +119 -95
- data/lib/phys/units/quanty.rb +10 -0
- data/lib/phys/units/unit.rb +280 -83
- data/lib/phys/units/unit_class.rb +29 -11
- data/lib/phys/units/utils.rb +3 -2
- data/lib/phys/units/version.rb +1 -1
- data/misc/mkjpspec.rb +149 -0
- data/misc/mkunitspec.rb +60 -0
- data/misc/readme.jp.md +6 -0
- data/spec/{units_dat_spec.rb → all_units_spec.rb} +0 -0
- data/spec/jp_units_spec.rb +256 -0
- data/spec/quantity_spec.rb +51 -9
- data/spec/unit_spec.rb +2 -2
- metadata +11 -4
data/lib/phys/units/unit.rb
CHANGED
@@ -9,61 +9,110 @@
|
|
9
9
|
|
10
10
|
module Phys
|
11
11
|
|
12
|
+
# Phys::Unit is a class to represent Physical Unit of Measure.
|
13
|
+
# It must have:
|
14
|
+
# * *Factor* of the unit. Conversion factor to +dimension+,
|
15
|
+
# i.e., its base units.
|
16
|
+
# * *Dimension* of the unit.
|
17
|
+
# Dimension is a hash table with base units and dimension values.
|
18
|
+
# Example:
|
19
|
+
# Phys::Unit["N"].dimension #=> {"kg"=>1, "m"=>1, "s"=>-2}
|
20
|
+
#== Usage
|
21
|
+
# require "phys/units"
|
22
|
+
# Q = Phys::Quantity
|
23
|
+
# U = Phys::Unit
|
24
|
+
#
|
25
|
+
# U["miles"] / U["hr"] #=> #<Phys::Unit 0.44704,{"m"=>1, "s"=>-1}>
|
26
|
+
# U["hr"] + U["30 min"] #=> #<Phys::Unit 5400,{"s"=>1}>
|
27
|
+
# U["(m/s)"]**2 #=> #<Phys::Unit 1,{"m"=>2, "s"=>-2}>
|
28
|
+
#
|
29
|
+
# case Q[1,"miles/hr"]
|
30
|
+
# when U["m"]
|
31
|
+
# "length"
|
32
|
+
# when U["s"]
|
33
|
+
# "time"
|
34
|
+
# when U["m/s"]
|
35
|
+
# "velocity"
|
36
|
+
# else
|
37
|
+
# "other"
|
38
|
+
# end #=> "velocity"
|
12
39
|
class Unit
|
13
40
|
|
41
|
+
# @visibility private
|
14
42
|
LIST = {}
|
43
|
+
# @visibility private
|
15
44
|
PREFIX = {}
|
16
45
|
|
46
|
+
# @visibility private
|
17
47
|
def self.prefix_regex
|
18
48
|
@@prefix_regex
|
19
49
|
end
|
20
50
|
|
21
|
-
|
51
|
+
# Initialize a new unit.
|
52
|
+
# @overload initialize(factor,dimension=nil)
|
53
|
+
# @param [Numeric] factor Unit conversion factor.
|
54
|
+
# @param [Hash] dimension Dimension hash.
|
55
|
+
# @overload initialize(expr,name=nil)
|
56
|
+
# @param [String] expr Unit string to be parsed later.
|
57
|
+
# @param [String] name Name of this unit.
|
58
|
+
# @overload initialize(unit,name=nil)
|
59
|
+
# @param [Phys::Unit] unit Copy contents from the argument.
|
60
|
+
# @param [String] name Name of this unit.
|
61
|
+
# @raise [TypeError] if invalit arg types.
|
62
|
+
#
|
63
|
+
def initialize(arg,extr=nil)
|
22
64
|
case arg
|
23
65
|
when Numeric
|
24
66
|
arg = Rational(arg) if Integer===arg
|
25
67
|
@factor = arg
|
26
|
-
alloc_dim(
|
68
|
+
alloc_dim(extr)
|
27
69
|
when Phys::Unit
|
28
|
-
|
70
|
+
@factor = arg.factor
|
71
|
+
alloc_dim arg.dim
|
72
|
+
@name = extr
|
29
73
|
when String
|
30
|
-
@
|
31
|
-
|
32
|
-
@factor = expr.factor
|
33
|
-
@offset = expr.offset
|
34
|
-
alloc_dim expr.dim
|
35
|
-
else
|
36
|
-
@expr = expr
|
37
|
-
end
|
74
|
+
@expr = arg
|
75
|
+
@name = extr
|
38
76
|
else
|
39
77
|
raise TypeError,"invalid argument : #{arg.inspect}"
|
40
78
|
end
|
41
79
|
end
|
42
80
|
|
43
|
-
|
81
|
+
# Unit expression to be parsed.
|
82
|
+
# @return [String, NilClass]
|
83
|
+
attr_reader :expr
|
84
|
+
|
85
|
+
# @visibility private
|
86
|
+
attr_reader :offset
|
87
|
+
# @visibility private
|
88
|
+
attr_reader :name
|
44
89
|
|
45
|
-
|
90
|
+
# Dimension hash.
|
91
|
+
# @example
|
92
|
+
# Phys::Unit["N"].dimension #=> {"kg"=>1, "m"=>1, "s"=>-2}
|
93
|
+
# @return [Hash]
|
94
|
+
def dimension
|
46
95
|
use_dimension
|
47
96
|
@dim
|
48
97
|
end
|
49
|
-
alias dimension
|
98
|
+
alias dim dimension
|
50
99
|
|
100
|
+
# Conversion factor except the dimension-value.
|
101
|
+
# @return [Numeric]
|
51
102
|
def factor
|
52
103
|
use_dimension
|
53
104
|
@factor
|
54
105
|
end
|
55
106
|
|
107
|
+
# Dimension value. Returns PI number for pi dimension,
|
108
|
+
# otherwise returns one. see BaseUnit.
|
109
|
+
# @return [Numeric]
|
56
110
|
def dimension_value
|
57
111
|
1
|
58
112
|
end
|
59
113
|
|
60
|
-
|
61
|
-
|
62
|
-
@factor = x.factor
|
63
|
-
@offset = x.offset
|
64
|
-
alloc_dim x.dim
|
65
|
-
end
|
66
|
-
|
114
|
+
# (internal use)
|
115
|
+
# @visibility private
|
67
116
|
def alloc_dim(hash=nil)
|
68
117
|
case hash
|
69
118
|
when Hash
|
@@ -74,32 +123,40 @@ module Phys
|
|
74
123
|
@dim.default = 0
|
75
124
|
end
|
76
125
|
|
126
|
+
# (internal use)
|
127
|
+
# Parse @expr string if it has not been parsed yet.
|
128
|
+
# This function must be called before access to @dim or @factor.
|
129
|
+
# @return [nil]
|
130
|
+
# @raise [UnitError] if unit parse error.
|
131
|
+
# @visibility private
|
77
132
|
def use_dimension
|
78
133
|
return if @dim && @factor
|
79
134
|
if @expr && @dim.nil?
|
80
|
-
puts "unit='#{@name}', parsing '#{@expr}'..." if Unit.debug
|
135
|
+
#puts "unit='#{@name}', parsing '#{@expr}'..." if Unit.debug
|
81
136
|
unit = Unit.parse(@expr)
|
82
137
|
case unit
|
83
138
|
when Unit
|
84
139
|
@dim = unit.dim
|
85
140
|
@factor = unit.factor
|
86
141
|
if @dim.nil? || @factor.nil?
|
87
|
-
raise
|
142
|
+
raise UnitError,"parse error : #{unit.inspect}"
|
88
143
|
end
|
89
144
|
when Numeric
|
90
145
|
@factor = unit
|
91
146
|
alloc_dim
|
92
147
|
else
|
93
|
-
raise
|
148
|
+
raise UnitError,"parse error : #{self.inspect}"
|
94
149
|
end
|
95
150
|
else
|
96
|
-
raise
|
151
|
+
raise UnitError,"undefined unit?: #{self.inspect}"
|
97
152
|
end
|
98
153
|
end
|
99
154
|
|
155
|
+
# Inspect string.
|
156
|
+
# @return [String]
|
100
157
|
def inspect
|
101
158
|
a = [Utils.num_inspect(@factor), @dim.inspect]
|
102
|
-
a << "@name="+@name.inspect if @name
|
159
|
+
#a << "@name="+@name.inspect if @name
|
103
160
|
a << "@expr="+@expr.inspect if @expr
|
104
161
|
a << "@offset="+@offset.inspect if @offset
|
105
162
|
a << "@dimensionless=true" if @dimensionless
|
@@ -110,6 +167,8 @@ module Phys
|
|
110
167
|
"#<#{self.class} #{s}>"
|
111
168
|
end
|
112
169
|
|
170
|
+
# Make unit string from dimension.
|
171
|
+
# @return [String]
|
113
172
|
def unit_string
|
114
173
|
use_dimension
|
115
174
|
a = []
|
@@ -125,8 +184,8 @@ module Phys
|
|
125
184
|
end
|
126
185
|
alias string_form unit_string
|
127
186
|
|
128
|
-
#
|
129
|
-
|
187
|
+
# Conversion Factor to base unit.
|
188
|
+
# @return [Numeric]
|
130
189
|
def conversion_factor
|
131
190
|
use_dimension
|
132
191
|
f = @factor
|
@@ -141,39 +200,77 @@ module Phys
|
|
141
200
|
f
|
142
201
|
end
|
143
202
|
|
203
|
+
# Returns true if scalar unit.
|
204
|
+
# *Scalar* means the unit does not have any dimension
|
205
|
+
# including dimensionless-dimension, and its factor is one.
|
206
|
+
# @return [Boolean]
|
144
207
|
def scalar?
|
145
208
|
use_dimension
|
146
209
|
(@dim.nil? || @dim.empty?) && @factor==1
|
147
210
|
end
|
148
211
|
|
212
|
+
# (internal use)
|
213
|
+
# @visibility private
|
149
214
|
def dimensionless_deleted
|
150
215
|
use_dimension
|
151
216
|
hash = @dim.dup
|
152
217
|
hash.delete_if{|k,v| LIST[k].dimensionless?}
|
153
218
|
end
|
154
219
|
|
220
|
+
# (internal use)
|
155
221
|
def dimensionless?
|
156
222
|
use_dimension
|
157
223
|
@dim.each_key.all?{|k| LIST[k].dimensionless?}
|
158
224
|
end
|
159
225
|
|
160
|
-
|
161
|
-
|
226
|
+
# (internal use)
|
227
|
+
# @visibility private
|
228
|
+
def same_dimension?(unit)
|
229
|
+
dimensionless_deleted == unit.dimensionless_deleted
|
162
230
|
end
|
163
231
|
alias same_dim? same_dimension?
|
164
232
|
|
233
|
+
# (internal use)
|
234
|
+
# @visibility private
|
235
|
+
# @raise [UnitError] if not dimensionless.
|
165
236
|
def assert_dimensionless
|
166
237
|
if !dimensionless?
|
167
|
-
raise
|
238
|
+
raise UnitError,"Not dimensionless: #{self.inspect}"
|
168
239
|
end
|
169
240
|
end
|
170
241
|
|
171
|
-
|
172
|
-
|
173
|
-
|
242
|
+
# (internal use)
|
243
|
+
# @visibility private
|
244
|
+
# @raise [UnitError] if different dimensions.
|
245
|
+
def assert_same_dimension(unit)
|
246
|
+
if !same_dimension?(unit)
|
247
|
+
raise UnitError,"Different dimension: #{self.inspect} and #{unit.inspect}"
|
174
248
|
end
|
175
249
|
end
|
176
250
|
|
251
|
+
# Comformability of units. Returns true if unit conversion is allowed.
|
252
|
+
# @param [Object] x other object (unit or quantity or numeric or other)
|
253
|
+
# @return [Boolean]
|
254
|
+
def conformable?(x)
|
255
|
+
case x
|
256
|
+
when Unit
|
257
|
+
dimensionless_deleted == x.dimensionless_deleted
|
258
|
+
when Quantity
|
259
|
+
dimensionless_deleted == x.unit.dimensionless_deleted
|
260
|
+
when Numeric
|
261
|
+
dimensionless?
|
262
|
+
else
|
263
|
+
false
|
264
|
+
end
|
265
|
+
end
|
266
|
+
alias === conformable?
|
267
|
+
alias compatible? conformable?
|
268
|
+
alias conversion_allowed? conformable?
|
269
|
+
|
270
|
+
# Convert a quantity to this unit.
|
271
|
+
# @param [Phys::Quantity] quantity to be converted.
|
272
|
+
# @return [Phys::Quantity]
|
273
|
+
# @raise [UnitError] if unit conversion is failed.
|
177
274
|
def convert(quantity)
|
178
275
|
if Quantity===quantity
|
179
276
|
assert_same_dimension(quantity.unit)
|
@@ -184,55 +281,75 @@ module Phys
|
|
184
281
|
end
|
185
282
|
end
|
186
283
|
|
284
|
+
# Convert a quantity to this unit only in scale.
|
285
|
+
# @param [Phys::Quantity] quantity to be converted.
|
286
|
+
# @return [Phys::Quantity]
|
287
|
+
# @raise [UnitError] if unit conversion is failed.
|
187
288
|
def convert_scale(quantity)
|
188
289
|
convert(quantity)
|
189
290
|
end
|
190
291
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
x / conversion_factor
|
292
|
+
# Convert from a value in this unit to a value in base unit.
|
293
|
+
# @param [Numeric] value
|
294
|
+
# @return [Numeric]
|
295
|
+
def convert_value_to_base_unit(value)
|
296
|
+
value * conversion_factor
|
197
297
|
end
|
198
298
|
|
199
|
-
|
200
|
-
|
201
|
-
|
299
|
+
# Convert from a value in base unit to a value in this unit.
|
300
|
+
# @param [Numeric] value
|
301
|
+
# @return [Numeric]
|
302
|
+
def convert_value_from_base_unit(value)
|
303
|
+
value / conversion_factor
|
202
304
|
end
|
203
305
|
|
306
|
+
# Returns numeric value of this unit, i.e. conversion factor.
|
307
|
+
# Raises UnitError if not dimensionless.
|
308
|
+
# @return [Numeric]
|
309
|
+
# @raise [UnitError] if not dimensionless.
|
204
310
|
def to_numeric
|
205
311
|
assert_dimensionless
|
206
312
|
conversion_factor
|
207
313
|
end
|
208
314
|
alias to_num to_numeric
|
209
315
|
|
210
|
-
def convert_to_float(x)
|
211
|
-
convert_to_numeric(x).to_f
|
212
|
-
end
|
213
316
|
|
317
|
+
# Returns Base Unit excluding dimensionless-dimension.
|
318
|
+
# @return [Phys::Unit]
|
214
319
|
def base_unit
|
215
320
|
Unit.new(1,dimensionless_deleted)
|
216
321
|
end
|
217
322
|
|
218
|
-
|
323
|
+
#--
|
219
324
|
|
325
|
+
# Return true if this unit is operable.
|
326
|
+
# @return [Boolean]
|
220
327
|
def operable?
|
221
328
|
true
|
222
329
|
end
|
223
330
|
|
331
|
+
# Raise error if this unit is not operable.
|
332
|
+
# @return [nil]
|
333
|
+
# @visibility private
|
224
334
|
def check_operable
|
225
335
|
if !operable?
|
226
|
-
raise
|
336
|
+
raise UnitError,"non-operable for #{inspect}"
|
227
337
|
end
|
338
|
+
nil
|
228
339
|
end
|
229
340
|
|
230
|
-
|
231
|
-
|
232
|
-
|
341
|
+
# Raise error if this unit or argument is not operable.
|
342
|
+
# @return [nil]
|
343
|
+
# @visibility private
|
344
|
+
def check_operable2(unit)
|
345
|
+
if !(operable? && unit.operable?)
|
346
|
+
raise UnitError,"non-operable: #{inspect} and #{unit.inspect}"
|
233
347
|
end
|
348
|
+
nil
|
234
349
|
end
|
235
350
|
|
351
|
+
# (internal use)
|
352
|
+
# @visibility private
|
236
353
|
def dimension_binop(other)
|
237
354
|
x = self.dim
|
238
355
|
y = other.dim
|
@@ -241,7 +358,7 @@ module Phys
|
|
241
358
|
keys = x.keys | y.keys
|
242
359
|
dims = {}
|
243
360
|
dims.default = 0
|
244
|
-
keys.each do |k|
|
361
|
+
keys.each do |k|
|
245
362
|
v = yield( x[k]||0, y[k]||0 )
|
246
363
|
dims[k] = v if v!=0
|
247
364
|
end
|
@@ -254,6 +371,8 @@ module Phys
|
|
254
371
|
end
|
255
372
|
end
|
256
373
|
|
374
|
+
# (internal use)
|
375
|
+
# @visibility private
|
257
376
|
def dimension_uop
|
258
377
|
x = self.dim
|
259
378
|
if Hash===x
|
@@ -269,6 +388,11 @@ module Phys
|
|
269
388
|
end
|
270
389
|
end
|
271
390
|
|
391
|
+
# Addition of units.
|
392
|
+
# Both units must be operable and conversion-allowed.
|
393
|
+
# @param [Phys::Unit, Numeric] x other unit
|
394
|
+
# @return [Phys::Unit]
|
395
|
+
# @raise [Phys::UnitError] if unit conversion is failed.
|
272
396
|
def +(x)
|
273
397
|
x = Unit.cast(x)
|
274
398
|
check_operable2(x)
|
@@ -276,6 +400,11 @@ module Phys
|
|
276
400
|
Unit.new(@factor+x.factor,@dim.dup)
|
277
401
|
end
|
278
402
|
|
403
|
+
# Subtraction of units.
|
404
|
+
# Both units must be operable and conversion-allowed.
|
405
|
+
# @param [Phys::Unit, Numeric] x other unit
|
406
|
+
# @return [Phys::Unit]
|
407
|
+
# @raise [Phys::UnitError] if not conformable unit conversion is failed.
|
279
408
|
def -(x)
|
280
409
|
x = Unit.cast(x)
|
281
410
|
check_operable2(x)
|
@@ -283,16 +412,28 @@ module Phys
|
|
283
412
|
Unit.new(@factor-x.factor,@dim.dup)
|
284
413
|
end
|
285
414
|
|
415
|
+
# Unary minus.
|
416
|
+
# This unit must be operable.
|
417
|
+
# @return [Phys::Unit]
|
418
|
+
# @raise [Phys::UnitError] if not operable.
|
286
419
|
def -@
|
287
420
|
check_operable
|
288
421
|
use_dimension
|
289
422
|
Unit.new(-@factor,@dim.dup)
|
290
423
|
end
|
291
424
|
|
425
|
+
# Unary plus.
|
426
|
+
# Returns self.
|
427
|
+
# @return [Phys::Unit]
|
292
428
|
def +@
|
293
429
|
self
|
294
430
|
end
|
295
431
|
|
432
|
+
# Multiplication of units.
|
433
|
+
# Both units must be operable.
|
434
|
+
# @param [Phys::Unit, Numeric] x other unit
|
435
|
+
# @return [Phys::Unit]
|
436
|
+
# @raise [Phys::UnitError] if not operable.
|
296
437
|
def *(x)
|
297
438
|
x = Unit.cast(x)
|
298
439
|
if scalar?
|
@@ -306,10 +447,15 @@ module Phys
|
|
306
447
|
Unit.new(factor,dims)
|
307
448
|
end
|
308
449
|
|
450
|
+
# Division of units.
|
451
|
+
# Both units must be operable.
|
452
|
+
# @param [Phys::Unit, Numeric] x other unit
|
453
|
+
# @return [Phys::Unit]
|
454
|
+
# @raise [Phys::UnitError] if not operable.
|
309
455
|
def /(x)
|
310
456
|
x = Unit.cast(x)
|
311
457
|
if scalar?
|
312
|
-
return x.
|
458
|
+
return x.inverse
|
313
459
|
elsif x.scalar?
|
314
460
|
return self
|
315
461
|
end
|
@@ -319,10 +465,15 @@ module Phys
|
|
319
465
|
Unit.new(factor,dims)
|
320
466
|
end
|
321
467
|
|
468
|
+
# Rational division of units.
|
469
|
+
# Both units must be operable.
|
470
|
+
# @param [Phys::Unit, Numeric] x other unit
|
471
|
+
# @return [Phys::Unit]
|
472
|
+
# @raise [Phys::UnitError] if not operable.
|
322
473
|
def rdiv(x)
|
323
474
|
x = Unit.cast(x)
|
324
475
|
if scalar?
|
325
|
-
return x.
|
476
|
+
return x.inverse
|
326
477
|
elsif x.scalar?
|
327
478
|
return self
|
328
479
|
end
|
@@ -332,20 +483,32 @@ module Phys
|
|
332
483
|
Unit.new(factor,dims)
|
333
484
|
end
|
334
485
|
|
486
|
+
# @visibility private
|
335
487
|
def self.rdiv(x,y)
|
336
488
|
Unit.cast(x).rdiv(y)
|
337
489
|
end
|
338
490
|
|
339
|
-
|
491
|
+
# Inverse of units.
|
492
|
+
# This unit must be operable.
|
493
|
+
# @param [Phys::Unit, Numeric] unit
|
494
|
+
# @return [Phys::Unit]
|
495
|
+
# @raise [Phys::UnitError] if not operable.
|
496
|
+
def inverse
|
340
497
|
check_operable
|
341
498
|
dims = dimension_uop{|a| -a}
|
342
499
|
Unit.new(Rational(1,self.factor), dims)
|
343
500
|
end
|
344
501
|
|
345
|
-
|
346
|
-
|
502
|
+
# @visibility private
|
503
|
+
def self.inverse(x)
|
504
|
+
Unit.cast(x).inverse
|
347
505
|
end
|
348
506
|
|
507
|
+
# Exponentiation of units.
|
508
|
+
# This units must be operable.
|
509
|
+
# @param [Numeric] x numeric
|
510
|
+
# @return [Phys::Unit]
|
511
|
+
# @raise [Phys::UnitError] if not operable.
|
349
512
|
def **(x)
|
350
513
|
check_operable
|
351
514
|
m = Utils.as_numeric(x)
|
@@ -353,18 +516,31 @@ module Phys
|
|
353
516
|
Unit.new(@factor**m,dims)
|
354
517
|
end
|
355
518
|
|
519
|
+
# @visibility private
|
356
520
|
def self.func(fn, x)
|
357
521
|
fn = 'log' if fn == 'ln'
|
358
522
|
m = Unit.new(x).to_numeric
|
359
523
|
Unit.new( Math.send(fn,m) )
|
360
524
|
end
|
361
525
|
|
526
|
+
# Equality of units
|
527
|
+
# @param [Object] x other unit or object
|
528
|
+
# @return [Boolean]
|
362
529
|
def ==(x)
|
530
|
+
case x
|
531
|
+
when Numeric
|
532
|
+
x = Unit.cast(x)
|
533
|
+
when Unit
|
534
|
+
else
|
535
|
+
return false
|
536
|
+
end
|
363
537
|
use_dimension
|
364
|
-
@factor == x.factor && @dim == x.dim &&
|
538
|
+
@factor == x.factor && @dim == x.dim &&
|
365
539
|
offset == x.offset && dimension_value == x.dimension_value
|
366
540
|
end
|
367
541
|
|
542
|
+
# Coerce.
|
543
|
+
# @return [Array]
|
368
544
|
def coerce(x)
|
369
545
|
[Unit.find_unit(x), self]
|
370
546
|
end
|
@@ -372,27 +548,30 @@ module Phys
|
|
372
548
|
end # Unit
|
373
549
|
|
374
550
|
|
551
|
+
# BaseUnit is a class to represent units defined by "!" in unit.dat
|
552
|
+
# including SI units.
|
375
553
|
class BaseUnit < Unit
|
376
|
-
|
377
|
-
|
554
|
+
|
555
|
+
def self.define(name,expr,dimval=nil)
|
556
|
+
dimles = (expr == "!dimensionless")
|
557
|
+
LIST[name] = self.new(name,dimles,dimval)
|
558
|
+
end
|
559
|
+
|
560
|
+
def initialize(name,dimless=false,dimval=nil)
|
561
|
+
case name
|
378
562
|
when String
|
379
|
-
@name =
|
563
|
+
@name = name
|
380
564
|
@factor = 1
|
381
|
-
@dim = {
|
565
|
+
@dim = {name=>1}
|
382
566
|
@dim.default = 0
|
383
567
|
@dimensionless = dimless
|
384
|
-
@dimension_value =
|
568
|
+
@dimension_value = dimval || 1
|
385
569
|
else
|
386
570
|
raise ArgumentError "BaseUnit#initialize: arg must be string: #{s}"
|
387
571
|
end
|
388
572
|
end
|
389
573
|
|
390
|
-
|
391
|
-
super(x)
|
392
|
-
@dimensionless = x.dimensionless
|
393
|
-
@dimension_value = x.dimension_value
|
394
|
-
end
|
395
|
-
|
574
|
+
# @visibility private
|
396
575
|
def use_dimension
|
397
576
|
end
|
398
577
|
|
@@ -400,6 +579,7 @@ module Phys
|
|
400
579
|
@dimensionless
|
401
580
|
end
|
402
581
|
|
582
|
+
# @visibility private
|
403
583
|
def dimensionless_deleted
|
404
584
|
if @dimensionless
|
405
585
|
{}
|
@@ -408,42 +588,59 @@ module Phys
|
|
408
588
|
end
|
409
589
|
end
|
410
590
|
|
591
|
+
# Dimension value.
|
592
|
+
# Returns PI number for pi dimension, otherwise returns one.
|
593
|
+
# @return [Numeric]
|
594
|
+
# @example
|
595
|
+
# Phys::Unit["pi"].dimension_value #=> 3.141592653589793
|
411
596
|
attr_reader :dimension_value
|
412
597
|
end
|
413
598
|
|
414
599
|
|
600
|
+
# OffsetUnit is a class to represent units with offset value.
|
601
|
+
# Focused on Farenheight/Celsius temperature.
|
415
602
|
class OffsetUnit < Unit
|
416
603
|
|
417
604
|
def self.define(name,unit,offset=nil)
|
418
|
-
LIST[name] = self.new(name,
|
605
|
+
LIST[name] = self.new(unit,name,offset)
|
419
606
|
end
|
420
607
|
|
421
|
-
def initialize(name,
|
422
|
-
super(name,arg)
|
423
|
-
@offset = offset
|
608
|
+
def initialize(arg,name=nil,offset=nil)
|
424
609
|
if offset.nil?
|
425
610
|
raise ArgumentError,"offset is not supplied"
|
426
611
|
end
|
612
|
+
super(arg,name)
|
613
|
+
@offset = offset
|
427
614
|
end
|
428
615
|
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
def convert_value_from_base_unit(x)
|
434
|
-
(x - @offset) / conversion_factor
|
435
|
-
end
|
436
|
-
|
616
|
+
# Convert a quantity to this unit only in scale.
|
617
|
+
# @param [Phys::Quantity] quantity to be converted.
|
618
|
+
# @return [Phys::Quantity]
|
619
|
+
# @raise [UnitError] if unit conversion is failed.
|
437
620
|
def convert_scale(quantity)
|
438
621
|
if Quantity===quantity
|
439
|
-
assert_same_dimension(quantity.unit)
|
622
|
+
assert_same_dimension(quantity.unit)
|
440
623
|
v = quantity.value * quantity.unit.conversion_factor
|
441
624
|
v = v / self.conversion_factor
|
442
625
|
else
|
443
|
-
raise
|
626
|
+
raise UnitError,"not Quantitiy: #{quantity.inspect}"
|
444
627
|
end
|
445
628
|
end
|
446
629
|
|
630
|
+
# Convert from a value in this unit to a value in base unit.
|
631
|
+
# @param [Numeric] value
|
632
|
+
# @return [Numeric]
|
633
|
+
def convert_value_to_base_unit(value)
|
634
|
+
value * conversion_factor + @offset
|
635
|
+
end
|
636
|
+
|
637
|
+
# Convert from a value in base unit to a value in this unit.
|
638
|
+
# @param [Numeric] value
|
639
|
+
# @return [Numeric]
|
640
|
+
def convert_value_from_base_unit(value)
|
641
|
+
(value - @offset) / conversion_factor
|
642
|
+
end
|
643
|
+
|
447
644
|
def operable?
|
448
645
|
false
|
449
646
|
end
|