phys-units 0.9.4 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f0ec7810800a733cda3aa7f753bf10d11b76891d
4
- data.tar.gz: b2c93b618d876183ea89ebfab9e6f353a6160746
3
+ metadata.gz: 08a3f10419f3f682ae605f4cc4995f0d99605354
4
+ data.tar.gz: d947bfc917e8484eeb87fc178f315b1e0982331c
5
5
  SHA512:
6
- metadata.gz: b0b1ea5529d3017813abe2c056b8eda47db00f47dd3cf0405fd0551182f551bdd95493352ea0ff8ecce1091e5269a593411c09d1caa705514d9c39520e8d54b5
7
- data.tar.gz: 7d4bdf5a200c37d8d9cd7b0416bbaa7812a988905b358ea93e88dd635f056226305a6c57bbae0bfe27c48ef7ed9080a64ca91a28fcabc9b66675b4ab082443fd
6
+ metadata.gz: ef99074dc223bb887a79162e0928181eda392b87a1fae825c8a09691aca17083417125a9dee1548058b917f41344742ac7366f3dd1cc867cb37bff3a9eab9d86
7
+ data.tar.gz: e8a23b4054cee7acfd274d274272ddda9cb2975efc316083030afffeb52c1debf1d86ec51b076231054d7bab85b17e813e9ce762dbb79ae055b91725c548ac10
data/README.md CHANGED
@@ -18,6 +18,10 @@ Or install from source tree:
18
18
 
19
19
  $ ruby setup.rb
20
20
 
21
+ Load Phys-Units library in your Ruby script:
22
+
23
+ require 'phys/units'
24
+
21
25
  ## Overview
22
26
 
23
27
  ### Phys::Quantity
@@ -25,15 +29,16 @@ is the primary class of Phys-Units library, intended to be manipulated by users.
25
29
  This class represents Physical Quantities with a Unit of measurement.
26
30
  It contains *Value* and *Unit*.
27
31
 
28
- * *Value*
29
- must be a class instance having arithmetic methods,
32
+ * *Value* of the quantity is given as the first parameter of
33
+ Quantity constructor (alias is `Quantity[]`).
34
+ It must be a class instance having arithmetic methods,
30
35
  but it is not necessary to be a Numeric.
31
36
  This is a duck typing way.
32
37
 
33
38
  Phys::Quantity[2.5,"miles"].value #=> 2.5
34
39
 
35
- * *Unit*
36
- is an instance of Phys::Unit class obtained by parsing *expr* string.
40
+ * *Unit* is an instance of Phys::Unit class.
41
+ It is created from the second argument of Quantity constructor.
37
42
 
38
43
  Phys::Quantity[2.5,"miles"].unit #=> #<Phys::Unit 1609.344,{"m"=>1},@expr="5280 ft">
39
44
 
@@ -62,7 +67,7 @@ It has *Factor* and *Dimension*:
62
67
  Q[123,'mile'] / Q[2,'hr'] #=> Phys::Quantity[61,'mile/hr']
63
68
  Q[61,'miles/hr'].want('m/s') #=> Phys::Quantity[27.26944,'m/s']
64
69
  Q[1.0,'are'] == Q[10,'m']**2 #=> true
65
- Q[70,'tempF'] + Q[10,'tempC'] #=> Phys::Quantity[88,'tempF']
70
+ Q[70,'tempF'] + Q[10,'degC'] #=> Phys::Quantity[88,'tempF']
66
71
  Q[20,'tempC'].want('tempF') #=> Phys::Quantity[68,'tempF']
67
72
  Math.cos(Q[60,'degree'].to_f) #=> 0.5
68
73
 
@@ -84,7 +89,7 @@ It has *Factor* and *Dimension*:
84
89
  Phys-Units library is differentiated from many other units libraries for Ruby,
85
90
  by the following features:
86
91
 
87
- * Compatible with GNU Units except nonlinear units.
92
+ * Compatible with GNU Units except currency and nonlinear units.
88
93
  * Provides 2331 units, 85 prefixes, including UTF-8 unit names.
89
94
  * Defines Units by reading GNU Units text data
90
95
  (see [load_units.rb](https://github.com/masa16/phys-units/blob/master/lib/phys/units/load_units.rb)),
@@ -127,6 +132,8 @@ Caution: The use of Mix-in may cause conflicts with other library.
127
132
  ## Platforms tested
128
133
 
129
134
  * ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-linux]
135
+ * ruby 1.9.3p392 (2013-02-22 revision 39386) [x86_64-linux]
136
+ * ruby 1.8.7 (2012-10-12 patchlevel 371) [x86_64-linux]
130
137
 
131
138
  ## Copying License
132
139
 
@@ -677,7 +677,7 @@ Racc_debug_parser = false
677
677
 
678
678
  module_eval(<<'.,.,', 'parse.y', 23)
679
679
  def _reduce_2(val, _values, result)
680
- result = Unit.inverse(val[1])
680
+ result = Unit.cast(val[1]).inverse
681
681
  result
682
682
  end
683
683
  .,.,
@@ -21,7 +21,7 @@ class Parse
21
21
  rule
22
22
 
23
23
  target: expr
24
- | DIV list { result = Unit.inverse(val[1]) }
24
+ | DIV list { result = Unit.cast(val[1]).inverse }
25
25
  ;
26
26
 
27
27
  expr: list
@@ -18,16 +18,17 @@ module Phys
18
18
  # intended to be manipulated by users.
19
19
  # This class represents Physical Quantities with a Unit of measurement.
20
20
  # It contains *Value* and *Unit*.
21
- # * *Value* of the quantity
22
- # must be an instance having arithmetic methods,
21
+ # * *Value* of the quantity is given as the first parameter of
22
+ # Quantity constructor (alias is +Quantity[]+).
23
+ # It must be a class instance having arithmetic methods,
23
24
  # but it is not necessary to be a Numeric.
24
25
  # This is a duck typing way.
25
26
  # Phys::Quantity[2.5,"miles"].value #=> 2.5
26
27
  # Phys::Quantity[NArray.float(5).indgen,"miles"].want("m").value
27
28
  # #=> NArray.float(5):
28
29
  # [ 0.0, 1609.34, 3218.69, 4828.03, 6437.38 ]
29
- # * *Unit*
30
- # is an instance of Phys::Unit class obtained by parsing *expr* string.
30
+ # * *Unit* is an instance of Phys::Unit class.
31
+ # It is created from the second argument of Quantity constructor.
31
32
  # see document of Phys::Unit.
32
33
  # Phys::Quantity[2.5,"miles"].unit #=> #<Phys::Unit 1609.344,{"m"=>1},@expr="5280 ft">
33
34
  #
@@ -39,7 +40,7 @@ module Phys
39
40
  # Q[123,'mile'] / Q[2,'hr'] #=> Phys::Quantity[61,'mile/hr']
40
41
  # Q[61,'miles/hr'].want('m/s') #=> Phys::Quantity[27.26944,'m/s']
41
42
  # Q[1.0,'are'] == Q[10,'m']**2 #=> true
42
- # Q[70,'tempF'] + Q[10,'tempC'] #=> Phys::Quantity[88,'tempF']
43
+ # Q[70,'tempF'] + Q[10,'degC'] #=> Phys::Quantity[88,'tempF']
43
44
  # Q[20,'tempC'].want('tempF') #=> Phys::Quantity[68,'tempF']
44
45
  # Math.cos(Q[60,'degree'].to_f) #=> 0.5
45
46
  #
@@ -51,31 +52,29 @@ module Phys
51
52
 
52
53
  class << self
53
54
  # Alias to Phys::Quantity.new.
54
- # @param [Object] value Value of quantity.
55
- # @param [String,Symbol] expr Unit string to be parsed later.
56
- # @overload initialize(value,unit)
57
- # @param [Object] value Value of quantity.
58
- # @param [Phys::Unit] unit This unit is copyed if exists.
59
- # @overload initialize(value)
60
- # @param [Object] value Value of dimensionless quantity.
55
+ # @param [Object] value Value of quantity.
56
+ # @param [String,Symbol,Phys::Unit] unit
57
+ # * If +unit+ String or Symbol, it is regarded as a unit expression (to be parsed later).
58
+ # * If +unit+ is Phys::Unit, it is used as the unit of new quantity.
59
+ # * If +unit+ is not provided, the quantity is regarded as dimensionless.
61
60
  # @return [Phys::Quantity]
62
61
  # @raise [TypeError] if invalid arg types.
63
62
  # @raise [Phys::UnitError] if unit conversion is failed.
64
- def [](value,expr=nil)
65
- self.new(value,expr)
63
+ def [](value,unit=nil)
64
+ self.new(value,unit)
66
65
  end
67
66
  end
68
67
 
69
68
  # Initialize a new quantity.
70
69
  # @overload initialize(value,expr,unit=nil)
71
70
  # @param [Object] value Value of quantity.
72
- # @param [String,Symbol] expr Unit string to be parsed later.
73
- # @param [Phys::Unit] unit This unit is copyed if exists.
71
+ # @param [String,Symbol] expr Unit expression.
72
+ # @param [Phys::Unit] unit If exists, this parameter is used as the unit of new quantity.
74
73
  # @overload initialize(value,unit)
75
74
  # @param [Object] value Value of quantity.
76
- # @param [Phys::Unit] unit This unit is copyed if exists.
75
+ # @param [Phys::Unit] unit This parameter is used as the unit of new quantity.
77
76
  # @overload initialize(value)
78
- # @param [Object] value Value of dimensionless quantity.
77
+ # @param [Object] value Value of a dimensionless quantity.
79
78
  # @raise [TypeError] if invalid arg types.
80
79
  # @raise [Phys::UnitError] if unit conversion is failed.
81
80
  #
@@ -291,8 +290,8 @@ module Phys
291
290
  @value > @unit.convert(other)
292
291
  end
293
292
 
294
- # Closeness. Returns +true+ if difference between +self+ and +other+ is
295
- # smaller than +epsilon+ times sum of their absolute values.
293
+ # Closeness. Returns +true+ if
294
+ # (self-other).abs <= (self.abs+other.abs) * epsilon
296
295
  # Before the comparison, it converts +other+ to the unit of +self+.
297
296
  # @param [Phys::Quantity] other
298
297
  # @param [Numeric] epsilon
@@ -301,7 +300,7 @@ module Phys
301
300
  def close_to(other,epsilon=Float::EPSILON)
302
301
  other_value = @unit.convert(other)
303
302
  abs_sum = @value.abs+other_value.abs
304
- abs_sum==0 || (@value-other_value).abs/abs_sum <= epsilon
303
+ (@value-other_value).abs <= abs_sum*epsilon
305
304
  end
306
305
 
307
306
  # Exponentiation.
@@ -365,6 +364,9 @@ module Phys
365
364
  # If the +other+ param is *not* Phys::Quantity,
366
365
  # +other+ is regarded as a dimensionless value.
367
366
  # The values and units are divided respectively.
367
+ # Note that the method of the value's class is used.
368
+ # @example
369
+ # Phys::Quantity[3,:m]/2 #=> Phys::Quantity[1,"m"]
368
370
  # @param [Object] other
369
371
  # @return [Phys::Quantity] a quantity
370
372
  # @raise [Phys::UnitError] if unit is not operable.
@@ -555,7 +557,7 @@ module Phys
555
557
  self.class.to_s+"["+Unit::Utils.num_inspect(@value)+expr+"]"+sufx
556
558
  end
557
559
 
558
- # Comformability of quantity. Returns true if unit conversion between +self+ and +x+ is possible.
560
+ # Conformability of quantity. Returns true if unit conversion between +self+ and +x+ is possible.
559
561
  # @param [Object] x other object (Unit or Quantity or Numeric or something else)
560
562
  # @return [Boolean]
561
563
  def ===(x)
@@ -43,12 +43,13 @@ module Phys
43
43
  #
44
44
  class Unit
45
45
 
46
- # @visibility private
46
+ # Hash table of registered units.
47
47
  LIST = {}
48
- # @visibility private
48
+ # Hash table of registered prefixes.
49
49
  PREFIX = {}
50
50
 
51
- # @visibility private
51
+ # Regex for registered prefixes.
52
+ # @return [Regexp]
52
53
  def self.prefix_regex
53
54
  @@prefix_regex
54
55
  end
@@ -58,11 +59,12 @@ module Phys
58
59
  # @param [Numeric] factor Unit scale factor.
59
60
  # @param [Hash] dimension Dimension hash.
60
61
  # @overload initialize(expr,name=nil)
61
- # @param [String] expr Unit string to be parsed later.
62
- # @param [String] name Name of this unit.
62
+ # @param [String] expr Expression of the unit. It is parsed lazily, i.e.,
63
+ # parsed not when this instance is created, but when @factor and @dim is used.
64
+ # @param [String] name Name of the unit.
63
65
  # @overload initialize(unit,name=nil)
64
- # @param [Phys::Unit] unit Copy contents from the argument.
65
- # @param [String] name Name of this unit.
66
+ # @param [Phys::Unit] unit Its contents is used for new unit.
67
+ # @param [String] name Name of the unit.
66
68
  # @raise [TypeError] if invalid arg types.
67
69
  #
68
70
  def initialize(a1,a2=nil)
@@ -83,7 +85,7 @@ module Phys
83
85
  end
84
86
  end
85
87
 
86
- # Unit expression to be parsed.
88
+ # Expression of the unit.
87
89
  # @return [String, NilClass]
88
90
  attr_reader :expr
89
91
 
@@ -199,6 +201,12 @@ module Phys
199
201
  end
200
202
  alias string_form unit_string
201
203
 
204
+ # Returns self name or unit_string
205
+ # @return [String]
206
+ def to_s
207
+ @name || unit_string
208
+ end
209
+
202
210
  # Conversion Factor to base unit, including dimension-value.
203
211
  # @return [Numeric]
204
212
  # @example
@@ -221,7 +229,7 @@ module Phys
221
229
  end
222
230
 
223
231
  # Returns true if scalar unit.
224
- # *Scalar* means the unit does not have any dimension
232
+ # *Scalar* means this unit does not have any dimension
225
233
  # including dimensionless-units, and its factor is one.
226
234
  # @return [Boolean]
227
235
  def scalar?
@@ -306,7 +314,13 @@ module Phys
306
314
  # @return [Phys::Quantity]
307
315
  # @raise [UnitError] if unit conversion is failed.
308
316
  def convert_scale(quantity)
309
- convert(quantity)
317
+ if Quantity===quantity
318
+ assert_same_dimension(quantity.unit)
319
+ v = quantity.value * quantity.unit.conversion_factor
320
+ v = v / self.conversion_factor
321
+ else
322
+ quantity / to_numeric
323
+ end
310
324
  end
311
325
 
312
326
  # Convert from a value in this unit to a value in base unit.
@@ -459,7 +473,7 @@ module Phys
459
473
  if scalar?
460
474
  return x
461
475
  elsif x.scalar?
462
- return self
476
+ return self.dup
463
477
  end
464
478
  check_operable2(x)
465
479
  dims = dimension_binop(x){|a,b| a+b}
@@ -477,7 +491,7 @@ module Phys
477
491
  if scalar?
478
492
  return x.inverse
479
493
  elsif x.scalar?
480
- return self
494
+ return self.dup
481
495
  end
482
496
  check_operable2(x)
483
497
  dims = dimension_binop(x){|a,b| a-b}
@@ -496,11 +510,6 @@ module Phys
496
510
  Unit.new(Rational(1,self.factor), dims)
497
511
  end
498
512
 
499
- # @visibility private
500
- def self.inverse(x)
501
- Unit.cast(x).inverse
502
- end
503
-
504
513
  # Exponentiation of units.
505
514
  # This units must be operable.
506
515
  # @param [Numeric] x numeric
@@ -515,8 +524,11 @@ module Phys
515
524
 
516
525
  # @visibility private
517
526
  def self.func(fn, x)
518
- fn = 'log' if fn == 'ln'
519
527
  m = Unit.new(x).to_numeric
528
+ if fn == 'log2' && RUBY_VERSION<'1.9.0'
529
+ return Unit.new( Math.log(m)/Math.log(2) )
530
+ end
531
+ fn = 'log' if fn == 'ln'
520
532
  Unit.new( Math.send(fn,m) )
521
533
  end
522
534
 
@@ -547,7 +559,7 @@ module Phys
547
559
 
548
560
  # BaseUnit is a class to represent units defined by "!"
549
561
  # in the data form of GNU units.
550
- # It includes SI units and dimensinless units such as radian.
562
+ # It includes SI units and dimensionless units such as radian.
551
563
  class BaseUnit < Unit
552
564
 
553
565
  def self.define(name,expr,dimval=nil)
@@ -601,7 +613,19 @@ module Phys
601
613
 
602
614
 
603
615
  # OffsetUnit is a class to represent units with offset value.
604
- # Allows Farenheight/Celsius temperature.
616
+ # Allows Fahrenheit/Celsius temperature.
617
+ # Unit operations are not allowed.
618
+ # @example
619
+ # require 'phys/units'
620
+ #
621
+ # Phys::Quantity[20,:tempC].want(:tempF) #=> Phys::Quantity[68,'tempF']
622
+ # Phys::Quantity[3,:tempC] + Phys::Quantity[10,:degF] #=> Phys::Quantity[(77/9),"tempC"]
623
+ # Phys::Quantity[3,:tempC] * Phys::Quantity[3,:m] #=> UnitError
624
+ # Phys::Quantity[3,:tempC] ** 2 #=> UnitError
625
+ #
626
+ # # Next examples currently work, but I suggest the use of degC and degF.
627
+ # Phys::Quantity[3,:tempC] + Phys::Quantity[10,:tempF] #=> Phys::Quantity[(77/9),"tempC"]
628
+ # Phys::Quantity[3,:tempC] * 2 #=> Phys::Quantity[6,"tempC"]
605
629
  class OffsetUnit < Unit
606
630
 
607
631
  def self.define(name,unit,offset=nil)
@@ -616,20 +640,6 @@ module Phys
616
640
  @offset = offset
617
641
  end
618
642
 
619
- # Convert a quantity to this unit only in scale.
620
- # @param [Phys::Quantity] quantity to be converted.
621
- # @return [Phys::Quantity]
622
- # @raise [UnitError] if unit conversion is failed.
623
- def convert_scale(quantity)
624
- if Quantity===quantity
625
- assert_same_dimension(quantity.unit)
626
- v = quantity.value * quantity.unit.conversion_factor
627
- v = v / self.conversion_factor
628
- else
629
- raise UnitError,"not Quantity: #{quantity.inspect}"
630
- end
631
- end
632
-
633
643
  # Convert from a value in this unit to a value in base unit.
634
644
  # @param [Numeric] value
635
645
  # @return [Numeric]
@@ -644,6 +654,7 @@ module Phys
644
654
  (value - @offset) / conversion_factor
645
655
  end
646
656
 
657
+ # Returns false
647
658
  def operable?
648
659
  false
649
660
  end
@@ -18,9 +18,11 @@ module Phys
18
18
  false
19
19
  end
20
20
 
21
- # Define a new Unit. Expression is not parsed at the time of this method.
22
- # @param [String,Symbol] name Name of this unit.
23
- # @param [String] expr Expression.
21
+ # Define a new Unit. Expression is parsed lazily, i.e., parsed
22
+ # not when this method is called, but when @factor and @dim is used.
23
+ # Note that the result of unit calculation depends on the timing of unit definition.
24
+ # @param [String,Symbol] name Name of the unit.
25
+ # @param [String] expr Expression of the unit.
24
26
  def define(name,expr)
25
27
  case name
26
28
  when String
@@ -49,8 +51,9 @@ module Phys
49
51
 
50
52
 
51
53
  # Force the argument to be Phys::Unit.
52
- # @param [Phys::Unit,Numeric]
54
+ # @param [Object] x
53
55
  # @return [Phys::Unit]
56
+ # @raise [TypeError] if invalid type for units.
54
57
  def cast(x)
55
58
  case x
56
59
  when Unit
@@ -14,6 +14,8 @@ module Phys
14
14
  # Defines method with unit name.
15
15
  # *Caution*: Variable names may conflict with unit names.
16
16
  # @example
17
+ # require 'phys/units'
18
+ #
17
19
  # Phys::UnitsMixin.module_eval do
18
20
  # puts 123.4*km
19
21
  # puts (23*mile/hr).want(m/s)
@@ -60,6 +62,8 @@ module Phys
60
62
  # ActiveSupport-like mix-in.
61
63
  # *Caution*: This kind of global change will cause unexpected problems.
62
64
  # @example
65
+ # require 'phys/units'
66
+ #
63
67
  # class Numeric
64
68
  # include Phys::UnitsNumericMixin
65
69
  # end
@@ -1,5 +1,5 @@
1
1
  module Phys
2
2
  class Unit
3
- VERSION = "0.9.4"
3
+ VERSION = "0.9.5"
4
4
  end
5
5
  end
data/lib/phys/units.rb CHANGED
@@ -1,3 +1,6 @@
1
+ if RUBY_VERSION<'1.9.0'
2
+ require "rational"
3
+ end
1
4
  require "phys/units/version"
2
5
  require "phys/units/errors.rb"
3
6
  require "phys/units/unit_class.rb"
@@ -0,0 +1,7 @@
1
+ # http://www.tokyo-dome.co.jp/dome/facilities/
2
+ tokyodome_area 46755 m^2
3
+ tokyodome_volume 1240000 m^3
4
+
5
+ # http://www.tokyo-skytree.jp/archive/spec/
6
+ skytree_height 634 m
7
+ skytree skytree_height
data/misc/mkunitspec.rb CHANGED
@@ -8,6 +8,7 @@ def close_values(a,b)
8
8
  end
9
9
 
10
10
  puts <<EOL
11
+ # -*- coding: utf-8 -*-
11
12
  $LOAD_PATH.unshift File.dirname(__FILE__)
12
13
  require "helper"
13
14
 
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  $LOAD_PATH.unshift File.dirname(__FILE__)
2
3
  require "helper"
3
4
 
@@ -126,10 +126,10 @@ describe "Phys::Quantity" do
126
126
  end
127
127
 
128
128
  context "Temperature" do
129
- describe Q[1,"tempC"] - Q[1,"tempC"] do
129
+ describe Q[1,"tempC"] - Q[1,"degC"] do
130
130
  it {should == Q[0,"tempC"]}
131
131
  end
132
- describe Q[50,"tempF"] + Q[10,"tempC"] do
132
+ describe Q[50,"tempF"] + Q[10,"degC"] do
133
133
  it {should == Q[68,"tempF"]}
134
134
  end
135
135
  describe Q[0,"tempC"].want("tempF") do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phys-units
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.4
4
+ version: 0.9.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masahiro TANAKA
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-05 00:00:00.000000000 Z
11
+ date: 2013-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -65,6 +65,7 @@ files:
65
65
  - lib/phys/units/units_mixin.rb
66
66
  - lib/phys/units/utils.rb
67
67
  - lib/phys/units/version.rb
68
+ - misc/misc_units.dat
68
69
  - misc/mkjpspec.rb
69
70
  - misc/mkunitspec.rb
70
71
  - misc/readme.jp.md