units-system 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'modalsupport'
4
+
5
+ group :development do
6
+ gem "shoulda", ">= 0"
7
+ gem "rdoc", "~> 3.12"
8
+ gem "bundler", "~> 1"
9
+ gem "jeweler", "~> 1.8.3"
10
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,29 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ git (1.2.5)
5
+ jeweler (1.8.3)
6
+ bundler (~> 1.0)
7
+ git (>= 1.2.5)
8
+ rake
9
+ rdoc
10
+ json (1.6.6)
11
+ modalsupport (0.8.3)
12
+ rake (0.9.2.2)
13
+ rdoc (3.12)
14
+ json (~> 1.4)
15
+ shoulda (3.0.1)
16
+ shoulda-context (~> 1.0.0)
17
+ shoulda-matchers (~> 1.0.0)
18
+ shoulda-context (1.0.0)
19
+ shoulda-matchers (1.0.0)
20
+
21
+ PLATFORMS
22
+ ruby
23
+
24
+ DEPENDENCIES
25
+ bundler (~> 1)
26
+ jeweler (~> 1.8.3)
27
+ modalsupport
28
+ rdoc (~> 3.12)
29
+ shoulda
data/README.rdoc CHANGED
@@ -59,10 +59,10 @@ local variables.
59
59
  # Now let's convert som imperial units to SI:
60
60
  puts (100*mi/h).to_si # => 44.704*m/s
61
61
 
62
- # Note that in is a Ruby keyword, so to use inches you must use self.in:
62
+ # Note that +in+ is a Ruby keyword, so to use inches you must use +self.in+:
63
63
  puts (10*cm).to(self.in) # => 3.93700787401575*in
64
64
  # ...or use tha alternative nonstandard name +inch+
65
- puts (10*cm).to(self.inch) # => 3.93700787401575*inch
65
+ puts (10*cm).to(inch) # => 3.93700787401575*inch
66
66
 
67
67
  # Now let's use derived units, e.g. power units:
68
68
  x = 10*kW
data/Rakefile CHANGED
@@ -1,21 +1,27 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
2
12
  require 'rake'
3
13
 
4
- begin
5
- require 'jeweler'
6
- Jeweler::Tasks.new do |gem|
7
- gem.name = "units-system"
8
- gem.summary = %Q{Arithmetic with units of measure}
9
- gem.description = %Q{Experimental unit conversion & arithmetic for Ruby 1.9}
10
- gem.email = "jgoizueta@gmail.com"
11
- gem.homepage = "http://github.com/jgoizueta/units-system"
12
- gem.authors = ["Javier Goizueta"]
13
- gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
14
- end
15
- Jeweler::GemcutterTasks.new
16
- rescue LoadError
17
- puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ gem.name = "units-system"
17
+ gem.summary = %Q{Arithmetic with units of measure}
18
+ gem.description = %Q{Experimental unit conversion & arithmetic for Ruby 1.9}
19
+ gem.email = "jgoizueta@gmail.com"
20
+ gem.homepage = "http://github.com/jgoizueta/units-system"
21
+ gem.authors = ["Javier Goizueta"]
22
+ # dependencies defined in Gemfile
18
23
  end
24
+ Jeweler::RubygemsDotOrgTasks.new
19
25
 
20
26
  require 'rake/testtask'
21
27
  Rake::TestTask.new(:test) do |test|
@@ -24,24 +30,9 @@ Rake::TestTask.new(:test) do |test|
24
30
  test.verbose = true
25
31
  end
26
32
 
27
- begin
28
- require 'rcov/rcovtask'
29
- Rcov::RcovTask.new do |test|
30
- test.libs << 'test'
31
- test.pattern = 'test/**/test_*.rb'
32
- test.verbose = true
33
- end
34
- rescue LoadError
35
- task :rcov do
36
- abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
37
- end
38
- end
39
-
40
- task :test => :check_dependencies
41
-
42
33
  task :default => :test
43
34
 
44
- require 'rake/rdoctask'
35
+ require 'rdoc/task'
45
36
  Rake::RDocTask.new do |rdoc|
46
37
  version = File.exist?('VERSION') ? File.read('VERSION') : ""
47
38
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.5
1
+ 0.1.0
data/lib/units-system.rb CHANGED
@@ -1,561 +1,13 @@
1
1
  # encoding: utf-8
2
2
 
3
- # Ruby Units-System experiments.
3
+ require 'modalsupport'
4
+ require 'units/measure'
5
+ require 'units/prefixes'
6
+ require 'units/system'
7
+ require 'units/math'
4
8
 
5
9
  module Units
6
-
7
- class Measure
8
10
 
9
- def initialize(mag=1.0, units={})
10
- @magnitude = mag # rename to value?
11
- case units
12
- when Symbol
13
- uinfo = Units.unit(units)
14
- if uinfo
15
- if uinfo.dim
16
- @units = {uinfo.dim=>[units,1]}
17
- else
18
- @magnitude *= uinfo.factor
19
- @units = {}
20
- end
21
- else
22
- raise ArgumentError,"Invalid symbol for Measure definition: #{units.inspect} "
23
- end
24
- when Measure
25
- @magnitude *= units.magnitude
26
- @units = units.units
27
- else
28
- @units = units
29
- end
30
- end
31
-
32
- attr_reader :magnitude, :units
33
-
34
- # represent in text using Ruby notation
35
- def to_s
36
- return @magnitude.to_s if magnitude?
37
- u_descr = Units.units_descr(@units)
38
- "#{@magnitude}*#{u_descr}"
39
- end
40
-
41
- # more verbose description (not grammatically perfect)
42
- def describe
43
- return @magnitude.to_s if magnitude?
44
- u_descr = Units.units_descr(@units, true)
45
- "#{@magnitude} #{u_descr}"
46
- end
47
-
48
- # more natural concise text representation
49
- def abr
50
- self.to_s.gsub('**','^').tr('*',' ')
51
- end
52
-
53
- # decompose compound units
54
- def detailed_units(all_levels = false)
55
- mag = @magnitude
56
- prev_units = self.units
57
- units = {}
58
- loop do
59
- compound = false
60
- prev_units.each_pair do |dim, (unit,mul)|
61
- ud = Units.unit(unit)
62
- if ud.decomposition
63
- compound = true
64
- mag *= ud.decomposition.magnitude
65
- ud.decomposition.units.each_pair do |d, (u,m)|
66
- mag *= self.class.combine(units, d, u, m)
67
- end
68
- else
69
- mag *= self.class.combine(units, dim, unit, mul)
70
- end
71
- end
72
- if all_levels && compound
73
- prev_units = units
74
- units = {}
75
- else
76
- break
77
- end
78
- end
79
- Measure.new mag, units
80
- end
81
-
82
- # decompose to base units
83
- def base
84
- detailed_units true
85
- end
86
-
87
- def self.combine(units, dim, unit, mult)
88
- factor = 1
89
- if units[dim]
90
- u,m = units[dim]
91
- if u!=unit
92
- factor *= Units.conversion_factor(unit, u)**mult
93
- end
94
- units[dim] = [u, m+mult]
95
- else
96
- units[dim] = [unit, mult]
97
- end
98
- factor
99
- end
100
-
101
- def /(other)
102
- self * (other.kind_of?(Numeric) ? 1.0/other : other.inverse)
103
- end
104
-
105
- def inspect
106
- "Measure(#{@magnitude.inspect}, #{@units.inspect})"
107
- end
108
-
109
- def *(other)
110
- case other
111
- when Numeric
112
- mag = self.magnitude*other
113
- units = self.units
114
- else
115
- mag = self.magnitude*other.magnitude
116
- units = {}
117
- (self.units.keys | other.units.keys).each do |dim|
118
- other_u = other.units[dim] || [nil,0]
119
- this_u = self.units[dim] || [other_u.first,0]
120
- # mag *= Units.conversion_factor(this_u.first, other_u.first) if other_u.first
121
- mult = this_u.last+other_u.last
122
- mag *= Units.conversion_factor(other_u.first, this_u.first)**(other_u.last) if other_u.first
123
- units[dim] = [this_u.first, mult]
124
- end
125
- end
126
- units.reject!{|dim,(u,m)| m==0}
127
- Measure.new(mag, units)
128
- end
129
-
130
- def +(other)
131
- Measure.new self.magnitude+other.to(self.units).magnitude, self.units
132
- end
133
-
134
- def -(other)
135
- self + (-other)
136
- end
137
-
138
- def **(n)
139
- raise ArgumentError,"Only integer powers are allowed for magnitudes" unless n.kind_of?(Integer)
140
- units = @units.dup
141
- units.each_pair do |dim, (u, m)|
142
- units[dim] = [u, m*n]
143
- end
144
- Measure.new @magnitude, units
145
- end
146
-
147
- def inverse
148
- #Measure.new(1.0/@magnitude, @units.map_hash{|unit,mult| [unit, -mult]})
149
- units = {}
150
- @units.each_pair do |dim, (unit, mult)|
151
- units[dim] = [unit, -mult]
152
- end
153
- Measure.new(1.0/@magnitude, units)
154
- end
155
-
156
- def -@
157
- Measure.new(-@magnitude, units)
158
- end
159
-
160
- def in(other, mode=:absolute)
161
- other = Measure.new(1.0, other) unless other.kind_of?(Measure)
162
- other = other.base
163
- this = self.base
164
- dims = this.units.keys | other.units.keys
165
- mag = this.magnitude/other.magnitude
166
- dims.each do |dim|
167
- if !this.units[dim] || !other.units[dim] ||
168
- (this.units[dim].last != other.units[dim].last)
169
- raise "Inconsistent units #{Units.units_descr(this.units)} #{Units.units_descr(other.units)}"
170
- end
171
- this_u, mult = this.units[dim]
172
- other_u = other.units[dim].first
173
- mag *= Units.conversion_factor(this_u, other_u)**mult
174
- end
175
- if mode!=:relative && dims.size==1 && this.units[dims.first].last==1
176
- # consider "level" conversion for biased units (otherwise consider interval or difference values)
177
- mag += Units.conversion_bias(this.units[dims.first].first, other.units[dims.first].first)
178
- end
179
- mag
180
- end
181
-
182
- def to(units, mode=:absolute)
183
- units = units.u if units.kind_of?(Measure)
184
- Measure.new self.in(units, mode), units
185
- end
186
-
187
- def si_units
188
- units = {}
189
- @units.each_pair do |dim, (unit, mult)|
190
- si_unit = SI_UNITS[dim]
191
- if si_unit.kind_of?(Measure)
192
- si_unit.units.each_pair do |d, (u,m)|
193
- self.class.combine(units, d, u, m*mult)
194
- end
195
- else
196
- self.class.combine(units, dim, si_unit, mult)
197
- end
198
- end
199
- units
200
- end
201
-
202
- def to_si
203
- to(si_units)
204
- end
205
-
206
- def coerce(other)
207
- [Measure.new(other, {}), self]
208
- end
209
-
210
- def u # dimension? unit? only_units? strip_units? units_measure?
211
- Measure.new(1.0, self.units)
212
- end
213
-
214
- # dimension (quantity)
215
- def dimension
216
- q = nil
217
- u = self.base.si_units
218
- SI_UNITS.each_pair do |dim, unit|
219
- unit = Measure.new(1.0, unit) unless unit.kind_of?(Measure)
220
- if unit.base.si_units == u
221
- q = dim
222
- break
223
- end
224
- end
225
- q
226
- end
227
-
228
- def dimensionless?
229
- base.units.reject{|d,(u,m)| m==0}.empty?
230
- end
231
-
232
- # less strict dimensionless condition (e.g. an angle is not a pure magnitude in this sense)
233
- def magnitude?
234
- self.units.reject{|d,(u,m)| m==0}.empty?
235
- end
236
-
237
- end # Measure
238
-
239
- def Measure(*args)
240
- if args.size==1
241
- case args.first
242
- when Numeric
243
- m = args.first
244
- u = {}
245
- else
246
- m = 1.0
247
- u = args.first
248
- end
249
- args = [m,u]
250
- end
251
- Units::Measure.new(*args)
252
- end
253
- module_function :Measure
254
-
255
- PREFIXES = {
256
- :y=>[1E-24, 'yocto'],
257
- :z=>[1E-21, 'zepto'],
258
- :a=>[1E-18, 'atto'],
259
- :f=>[1E-15, 'femto'],
260
- :p=>[1E-12, 'pico'],
261
- :n=>[1E-09, 'nano'],
262
- :"\302\265"=>[1E-06, 'micro'], # ASCII alternative: u; define it?
263
- :m=>[1E-03, 'milli'],
264
- :c=>[1E-02, 'centi'],
265
- :d=>[1E-01, 'deci'],
266
- :da=>[1E1, 'deca'],
267
- :h=>[1E02, 'hecto'],
268
- :k=>[1E03, 'kilo'],
269
- :M=>[1E06, 'mega'],
270
- :G=>[1E09, 'giga'],
271
- :T=>[1E12, 'tera'],
272
- :P=>[1E15, 'peta'],
273
- :E=>[1E18, 'exa'],
274
- :Z=>[1E21, 'zetta'],
275
- :Y=>[1E24, 'yotta']
276
- }
277
-
278
- def self.prefix_factor(prefix)
279
- pd = PREFIXES[prefix.to_sym]
280
- pd && pd.first
281
- end
282
-
283
- def self.prefix_name(prefix)
284
- pd = PREFIXES[prefix.to_sym]
285
- pd && pd.last
286
- end
287
-
288
- def self.prefix_factor_and_name(prefix)
289
- PREFIXES[prefix]
290
- end
291
-
292
- # mathematical functions available to unit blocks are defined here
293
- module Math
294
- end
295
-
296
- # unit methods and constants are defined here to be injected in units blocks
297
- module System
298
-
299
- extend Math
300
-
301
- def self.define(unit)
302
- define_var unit
303
- PREFIXES.each do |prefix, (factor, name)|
304
- define_var "#{prefix}#{unit}".to_sym
305
- end
306
- end
307
-
308
- class <<self
309
- private
310
- def define_var(name)
311
- name_initial = name.to_s[0,1]
312
- if name_initial==name_initial.upcase && name_initial!=name_initial.downcase
313
- # we could define a method with the requested name, but it would
314
- # no be usable without qualification (System.X) or brackets (X())
315
- # so we define a constant. But this requires Ruby 1.9 to be useful;
316
- # otherwise the constant is not accesible without qualification in units blocks.
317
- System.const_set name, Units.Measure(name)
318
- end
319
- self.class_eval do
320
- define_method name do
321
- Units.Measure(name)
322
- end
323
- module_function name
324
- end
325
- end
326
- end
327
-
328
- end # Units::System
329
-
330
- def units(&blk)
331
- Units::System.class_eval(&blk)
332
- end
333
- alias :u :units
334
- module_function :units, :u
335
-
336
- UnitDefinition = Struct.new(:dim, :factor, :name, :decomposition, :bias)
337
-
338
- UNITS = {} # Hash.new{|h,k| h[k]=UnitDefinition.new()}
339
-
340
- # get unit definition
341
- def self.unit(unit_symbol)
342
- ud = UNITS[unit_symbol]
343
- if ud.nil?
344
- factor = 1.0
345
- if factor_name = PREFIXES[unit_symbol]
346
- ud = UnitDefinition.new(nil, *factor_name)
347
- else
348
- u = unit_symbol.to_s
349
- PREFIXES.each_pair do |prefix, (f,name)|
350
- prefix = prefix.to_s
351
- if u[0...prefix.length] == prefix
352
- factor = f
353
- ud = UNITS[u[prefix.length..-1].to_sym]
354
- if ud
355
- ud = ud.dup
356
- ud.name = "#{name}#{ud.name}"
357
- break
358
- end
359
- end
360
- end
361
- end
362
- ud.factor *= factor if ud
363
- ud.decomposition *= factor if ud && ud.decomposition
364
- end
365
- raise ArgumentError,"Invalid Units #{unit_symbol}" unless ud
366
- ud
367
- end
368
-
369
- # Define new units.
370
- # Define a base unit (with a factor for conversion to SI units)
371
- # Units.define :unit_symbol, 'unit-name', :quantity, si_units_per_this_unit
372
- # Define a unit in terms or another (valid for base or derived units)
373
- # Units.define :unit_symbol, 'unit-name', value, :in_units
374
- # Define a base unit as a measure-expression
375
- # Units.define :unit_symbol, 'unit_name', u{...}
376
- # Define a derived unit as a measure-expression
377
- # Units.define :unit_symbol, 'unit_name', :quantity, u{...}
378
- # For base dimensions the SI unit for a quantity must also be stablished with Unit.si_units;
379
- # for derived units, SI units are automatically taken to be the first define unit of the quantity
380
- # with unitary value in SI base units.
381
- def self.define(unit_symbol, name, *args)
382
- eqhivalence = nil
383
- si_unit = false
384
- bias = nil
385
- if args.first.kind_of?(Symbol)
386
- dim = args.shift
387
- if args.first.kind_of?(Numeric)
388
- # simple units
389
- factor = args.shift
390
- factor_units = args.shift
391
- if factor_units
392
- ud = unit(factor_units)
393
- if ud.dim != dim
394
- raise ArgumentError, "Inconsistent units #{factor_units} in definition of #{unit_symbol}"
395
- end
396
- # maybe it was not simple after all...
397
- equivalence = factor*ud.decomposition if ud.decomposition
398
- factor *= ud.factor
399
- end
400
- # si_unit = (factor==1.0) # to save si_units definitions # TODO: tolerance?
401
- else
402
- # compound unit
403
- equivalence = args.shift
404
- factor = equivalence.to_si.magnitude
405
- si_unit = (factor==1.0) # TODO: tolerance?
406
- if equivalence.units.empty?
407
- # dimensionless compound dimension... (special case for angular units)
408
- equivalence = nil
409
- end
410
- end
411
- elsif args.first.kind_of?(Numeric)
412
- # unit define in terms of other unit
413
- factor = args.shift
414
- factor_units = args.shift
415
- u = unit(factor_units)
416
- dim = u.dim
417
- equivalence = factor*u.decomposition if u.decomposition
418
- factor *= u.factor
419
- bias = args.shift
420
- else
421
- # unit defined from a measure expression; the dimension must be already known or defined
422
- # here (as as symbol preceding the expression).
423
- definition = args.shift
424
- dim = definition.dimension
425
- raise ArgumentError,"To define a new compound unit a dimension must be specified" unless dim
426
- equivalence = definition
427
- factor = definition.to_si.magnitude
428
- # si_unit = (factor==1.0) # to save si_units definitions # TODO: tolerance?
429
- end
430
- unit_def = UnitDefinition.new(dim, factor, name, equivalence, bias)
431
- if UNITS.has_key?(unit_symbol)
432
- raise "Redefinition of #{unit_symbol} as #{unit_def} (previously defined as #{UNITS[unit_symbol]})"
433
- end
434
- UNITS[unit_symbol] = unit_def
435
- System.define unit_symbol
436
- Units.si_units unit_def.dim, unit_symbol if si_unit && !SI_UNITS.has_key?(unit_def.dim)
437
- end
438
-
439
- SI_UNITS = {}
440
-
441
- def self.si_units(dim, unit)
442
- SI_UNITS[dim] = unit
443
- end
444
-
445
- def self.dimension(u)
446
- unit(u).dim
447
- end
448
-
449
- def self.conversion_factor(from, to)
450
- from_u = unit(from)
451
- to_u = unit(to)
452
- raise ArgumentError,"Inconsistent Units (#{from}, #{to})" if from_u.dim!=to_u.dim
453
- from_u.factor/to_u.factor
454
- end
455
-
456
- def self.conversion_bias(from, to)
457
- from_u = unit(from)
458
- to_u = unit(to)
459
- raise ArgumentError,"Inconsistent Units (#{from}, #{to})" if from_u.dim!=to_u.dim
460
- factor = from_u.factor/to_u.factor
461
- (from_u.bias||0)*factor - (to_u.bias||0)
462
- end
463
-
464
- # simple unit name
465
- def self.unit_name(u)
466
- uinfo = Units.unit(u)
467
- uinfo && uinfo.name
468
- end
469
-
470
- def self.unit_descr(u, long=false, mult=1)
471
- if long
472
- u = unit_name(u)
473
- if mult!=1
474
- case mult
475
- when 2
476
- "squared #{u}"
477
- when 3
478
- "cubed #{u}"
479
- else
480
- "#{u} to the #{mult} power"
481
- end
482
- else
483
- u
484
- end
485
- else
486
- if mult!=1
487
- "#{u}**#{mult}"
488
- else
489
- u.to_s
490
- end
491
- end
492
- end
493
-
494
- def self.units_descr(units, long=false)
495
- units = units.values.sort_by{|u,m| -m}
496
- pos_units = units.select{|u| u.last>0}
497
- neg_units = units.select{|u| u.last<0}
498
- times = long ? " " : "*"
499
- num = pos_units.map{|u,m| unit_descr(u,long,m)}.join(times)
500
- num = "(#{num})" if pos_units.size>1 && !neg_units.empty? && !long
501
- den = neg_units.map{|u,m| unit_descr(u,long,-m)}.join("*")
502
- den = "(#{den})" if neg_units.size>1 && !long
503
- if pos_units.empty?
504
- u_descr = "1/#{den}"
505
- elsif neg_units.empty?
506
- u_descr = num
507
- else
508
- connector = long ? " per " : "/"
509
- u_descr = "#{num}#{connector}#{den}"
510
- end
511
- u_descr
512
- end
513
-
514
- module Math
515
-
516
- [:sin, :cos, :tan].each do |fun|
517
- define_method fun do |x|
518
- x = Units.u{x.in(rad)} if x.kind_of?(Measure)
519
- ::Math.send(fun, x)
520
- end
521
- module_function fun
522
- end
523
-
524
- [:asin, :acos, :atan].each do |fun|
525
- define_method fun do |x|
526
- if x.kind_of?(Measure)
527
- raise ArgumentError,"Invalid dimensions for #{fun} argument" unless x.dimensionless?
528
- x = x.magnitude
529
- end
530
- Units.u{::Math.send(fun, x)*rad}
531
- end
532
- module_function fun
533
- end
534
-
535
- module_function
536
- def atan2(x,y)
537
- if x.kind_of?(Measure)
538
- if y.kind_of?(Measure)
539
- if x.base.to_si.units != y.base.to_si.units
540
- raise ArgumentError,"Inconsistent units for atan2 arguments #{x.u}, #{y.u}"
541
- end
542
- # or x = x.to_si.magnitude, y=y.to_si.magnitude
543
- y = y.in(x.units)
544
- x = x.magnitude
545
- else
546
- raise ArgumentError,"Invalid dimensions for atan2 argument #{x.u}" unless x.dimensionless?
547
- x = x.magnitude
548
- end
549
- elsif y.kind_of?(Measure)
550
- raise ArgumentError,"Invalid dimensions for atan2 argument #{y.u}" unless y.dimensionless?
551
- y = y.magnitude
552
- end
553
- Units.u{::Math.atan2(x,y)*rad}
554
- end
555
-
556
- end
557
-
558
-
559
11
  # This must be included in any module or class from which units expressions
560
12
  # are to be used in units or u blocks.
561
13
  # It is not needed in Ruby 1.9.1 due to they way constant loop-up is done in that version,
@@ -571,101 +23,9 @@ module Units
571
23
  end
572
24
  end
573
25
  end
574
-
575
- include UseBlocks
576
-
577
- # Units definitions
578
-
579
- # declare SI base units
580
- si_units :mass, :kg # m
581
- si_units :length, :m # l
582
- si_units :time, :s # t
583
- si_units :electric_current, :A # I
584
- si_units :temperature, :K # T
585
- si_units :luminous_intensity, :cd # Iv
586
- si_units :amount_of_substance, :mol # n
587
-
588
- # define base units
589
- define :g, 'gram', :mass, 1E-3
590
- define :m, 'meter', :length, 1.0
591
- define :s, 'second', :time, 1.0
592
- define :A, 'ampere', :electric_current, 1.0
593
- define :K, 'kelvin', :temperature, 1.0
594
- define :cd,'candela',:luminous_intensity, 1.0
595
- define :mol,'mole', :amount_of_substance, 1.0
596
-
597
- # declare derived quantities with no named units
598
- si_units :speed, u{m/s}
599
- si_units :acceleration, u{m/s**2}
600
- si_units :area, u{m**2}
601
- si_units :volume, u{m**3}
602
-
603
- # derived quantities with named units
604
- define :W, 'Watt', :power, u{kg*m**2/s**3} # J/s
605
- define :Hz, 'herz', :frequency, u{1/s}
606
- define :N, 'newton', :force, u{m*kg/s**2}
607
- define :Pa, 'pascal', :pressure, u{N/m**2}
608
- define :J, 'joule', :energy, u{N*m}
609
- define :C, 'coulomb', :electric_charge, u{s*A}
610
- define :V, 'volt', :voltage, u{W/A}
611
- define :F, 'farad', :electric_capacitance, u{C/V}
612
- define :Ω, 'ohm', :electric_resistance, u{V/A} # ohm: Ω omega: Ω
613
- define :S, 'siemens', :electric_condctance, u{1/Ω}
614
- define :Wb, 'weber', :magnetic_flux, u{J/A}
615
- define :T, 'tesla', :magnetic_field, u{N/(A*m)}
616
- define :H, 'henry', :inductance, u{Wb/A}
617
- define :rad, 'radian', :angle, u{m/m}
618
- define :sr, 'steradian', :solid_angle, u{m**2/m**2}
619
- define :lm, 'lumen', :luminous_flux, u{cd*sr}
620
- define :lx, 'lux', :illuminance, u{lm/m**2}
621
- define :Bq, 'bequerel', :radioactivity, u{1/s}
622
- define :Gy, 'gray', :absorbed_dose, u{J/kg}
623
- define :Sv, 'sievert', :equivalent_dose, u{J/kg}
624
- define :kat, 'katal', :catalytic_activity, u{mol/s}
625
-
626
- # Other units
627
-
628
- define :min, 'minute', 60, :s
629
- define :h, 'hour', 60, :min
630
- define :d, 'day', 24, :h
631
- define :mi, 'mile', 1.609344, :km
632
- define :in, 'inch', 2.54, :cm
633
- define :ft, 'foot', 0.3048, :m
634
- define :inch, 'inch', 1, :in # alternative to avoid having to use self.in (in is a Ruby keyword)
635
- define :lb, 'pound', 0.45359237, :kg
636
26
 
637
- define :°C, 'degree Celsius', 1, :K, +273.15
638
- define :°F, 'degree Fahrenheit', 5.0/9.0, :K, +459.67
639
- define :R, 'rankine', 5.0/9.0, :K
640
-
641
- define :l, 'litre', u{dm**3}
642
- define :L, 'litre', 1, :l
643
-
644
- define :°, 'degree', ::Math::PI/180.0, :rad
645
- define :′, 'arc-minute', ::Math::PI/180.0/60.0, :rad
646
- define :″, 'arc-second', ::Math::PI/180.0/3600.0, :rad
647
- # not so cool, but easier to type alternatives:
648
- define :deg, 'degree', 1, :°
649
- define :arcmin, 'arc-minute', 1, :′
650
- define :arcsec, 'arc-second', 1, :″
651
-
652
- define :g0, 'standard gravity', u{9.80665*m/s**2}
653
-
654
- define :bar, 'bar', 1E5, :Pa
655
- define :atm, 'atmosphere', 101325.0, :Pa
656
- define :mWC, 'meters of water column', u{1E3*kg*g0/m**2}
657
- define :Torr, 'torricelli', u{atm/760}
658
- define :mHg, 'mHg', u{13.5951E3*kg*g0/m**2}
659
-
660
- # define :kp, 'kilopond', :force, u{kg*g0} # or define pond?
661
- define :gf, 'gram-force', u{g*g0} # kilopond kp = kgf
662
- define :lbf, 'pound-force', u{lb*g0}
663
-
664
- define :dyn, 'dyne', 10, :µN # u{1*g*cm/s**2}
665
- define :galUS, 'U.S. liquid gallon', u{231*self.in**3}
666
- define :galUK, 'Imperial gallon', 4.546092, :l
667
- define :hp, 'horsepower', u{550*ft*lbf/s}
668
-
669
- define :psi, 'pounds-force per square inch', u{lbf/self.in**2}
27
+ include UseBlocks
670
28
 
671
29
  end # Units
30
+
31
+ require 'units/definitions'