[system] / trunk / pg / lib / Units.pm Repository: Repository Listing bbplugincoursesdistsnplrochestersystemwww

View of /trunk/pg/lib/Units.pm

Revision 4671 - (download) (as text) (annotate)
Mon Nov 27 02:01:24 2006 UTC (13 years, 2 months ago) by gage
File size: 18238 byte(s)
```Make
Units::fundamental_units  and

Units::known_units  public hashes.
```

```    1
2
3 # This is the "exported" subroutine.  Use this to evaluate the units given in an answer.
4
5 sub evaluate_units {
6   &Units::evaluate_units;
7 }
8
9 # Methods for evaluating units in answers
10 package Units;
11
12 #require Exporter;
13 #@ISA = qw(Exporter);
14 #@EXPORT = qw(evaluate_units);
15
16
17 # compound units are entered such as m/sec^2 or kg*m/sec^2
18 # the format is unit[^power]*unit^[*power].../  unit^power*unit^power....
19 # there can be only one / in a unit.
20 # powers can be negative integers as well as positive integers.
21
22     # These subroutines return a unit hash.
23     # A unit hash has the entries
24     #      factor => number   number can be any real number
25     #      m      => power    power is a signed integer
26     #      kg     => power
27     #      s      => power
28     #      rad    => power
29     #      degC   => power
30     #      degF   => power
31     #      degK   => power
32     #      perhaps other fundamental units will added later as well.
33
34 # Unfortunately there will be no automatic conversion between the different
35 # temperature scales since we haven't allowed for affine conversions.
36
37 our %fundamental_units = ('factor' => 1,
38                      'm'      => 0,
39                      'kg'     => 0,
40                      's'      => 0,
41                      'rad'    => 0,
42                      'degC'   => 0,
43                      'degF'   => 0,
44                      'degK'   => 0,
45                      'mol'    => 0,  # moles, treated as a fundamental unit?
46                      'amp'    => 0,
47 );
48
49
50 # This hash contains all of the units which will be accepted.  These must
51 #be defined in terms of the
52 # fundamental units given above.  If the power of the fundamental unit is
53 #not included it is assumed to
54 # be zero.
55
56 our \$PI = 4*atan2(1,1);
57 #         9.80665 m/s^2  -- standard accelearationof gravity
58
59 our %known_units = ('m'  => {
60                            'factor'    => 1,
61                            'm'         => 1
62                           },
63                  'kg'  => {
64                            'factor'    => 1,
65                            'kg'        => 1
66                           },
67                  's'  => {
68                            'factor'    => 1,
69                            's'         => 1
70                           },
71                 'rad' => {
72                            'factor'    => 1,
73                            'rad'       => 1
74                           },
75                'degC' => {
76                            'factor'    => 1,
77                            'degC'      => 1
78                           },
79                'degF' => {
80                            'factor'    => 1,
81                            'degF'      => 1
82                           },
83                'degK' => {
84                            'factor'    => 1,
85                            'degK'      => 1
86                           },
87                'mol'  => {
88                            'factor'    =>1,
89                            'mol'       =>1
90                          },
91                 'amp'  => {
92                            'factor'    => 1,
93                            'amp'       => 1,
94                          },
95 # ANGLES
96 # deg  -- degrees
97 #
98                 'deg'  => {
99                            'factor'    => 0.0174532925,
100                            'rad'       => 1
101                           },
102 # TIME
103 # s     -- seconds
104 # ms    -- miliseconds
105 # min   -- minutes
106 # hr    -- hours
107 # day   -- days
108 # yr    -- years  -- 365 days in a year
109 #
110                   'ms'  => {
111                            'factor'    => 0.001,
112                            's'         => 1
113                           },
114                   'min'  => {
115                            'factor'    => 60,
116                            's'         => 1
117                           },
118                   'hr'  => {
119                            'factor'    => 3600,
120                            's'         => 1
121                           },
122                   'day'  => {
123                            'factor'    => 86400,
124                            's'         => 1
125                           },
126                   'yr'  => {
127                            'factor'    => 31557600,
128                            's'         => 1
129                           },
130
131 # LENGTHS
132 # m    -- meters
133 # cm   -- centimeters
134 # km   -- kilometers
135 # mm   -- millimeters
136 # micron -- micrometer
137 # um   -- micrometer
138 # nm   -- nanometer
139 # A    -- Angstrom
140 #
141                  'km'  => {
142                            'factor'    => 1000,
143                            'm'         => 1
144                           },
145                  'cm'  => {
146                            'factor'    => 0.01,
147                            'm'         => 1
148                           },
149                  'mm'  => {
150                            'factor'    => 0.001,
151                            'm'         => 1
152                           },
153              'micron'  => {
154                            'factor'    => 10**(-6),
155                            'm'         => 1
156                           },
157                  'um'  => {
158                            'factor'    => 10**(-6),
159                            'm'         => 1
160                           },
161                  'nm'  => {
162                            'factor'    => 10**(-9),
163                            'm'         => 1
164                           },
165                   'A'  => {
166                            'factor'    => 10**(-10),
167                            'm'         => 1
168                           },
169 # ENGLISH LENGTHS
170 # in    -- inch
171 # ft    -- feet
172 # mi    -- mile
173 # light-year
174 #
175                  'in'  => {
176                            'factor'    => 0.0254,
177                            'm'         => 1
178                           },
179                  'ft'  => {
180                            'factor'    => 0.3048,
181                            'm'         => 1
182                           },
183                  'mi'  => {
184                            'factor'    => 1609.344,
185                            'm'         => 1
186                           },
187          'light-year'  => {
188                            'factor'    => 9.46E15,
189                            'm'         => 1
190                           },
191 # VOLUME
192 # L   -- liter
193 # ml -- milliliters
194 # cc -- cubic centermeters
195 #
196                   'L'  => {
197                            'factor'    => 0.001,
198                            'm'         => 3
199                           },
200                  'cc'  => {
201                            'factor'    => 10**(-6),
202                            'm'         => 3,
203                           },
204                  'ml'  => {
205                            'factor'    => 10**(-6),
206                            'm'         => 3,
207                           },
208 # VELOCITY
209 # knots -- nautical miles per hour
210 #
211               'knots'  => {
212                            'factor'    =>  0.5144444444,
213                            'm'         => 1,
214                            's'         => -1
215                           },
216 # MASS
217 # g    -- grams
218 # kg   -- kilograms
219 #
220                   'g'  => {
221                            'factor'    => 0.001,
222                            'kg'         => 1
223                           },
224 # ENGLISH MASS
225 # slug -- slug
226 #
227                'slug'  => {
228                            'factor'    => 14.6,
229                            'kg'         => 1
230                           },
231 # FREQUENCY
232 # Hz    -- Hertz
233 # kHz   -- kilo Hertz
234 # MHz   -- mega Herta
235 #
236                  'Hz'  => {
237                            'factor'    => 2*\$PI,  #2pi
238                            's'         => -1,
239                            'rad'       => 1
240                           },
241                 'kHz'  => {
242                            'factor'    => 1000*2*\$PI,  #1000*2pi,
243                            's'         => -1,
244                            'rad'       => 1
245                           },
246                 'MHz'  => {
247                            'factor'    => (10**6)*2*\$PI,  #10^6 * 2pi,
248                            's'         => -1,
249                            'rad'       => 1
250                           },
251                 'rev'  => {
252                       'factor'   => 2*\$PI,
253                       'rad'      => 1
254                       },
255                 'cycles'  => {
256                       'factor'   => 2*\$PI,
257                       'rad'      => 1
258                       },
259
260 # COMPOUND UNITS
261 #
262 # FORCE
263 # N      -- Newton
264 # microN -- micro Newton
265 # uN     -- micro Newton
266 # dyne   -- dyne
267 # lb     -- pound
268 # ton    -- ton
269 #
270                  'N'  => {
271                            'factor'    => 1,
272                            'm'         => 1,
273                            'kg'        => 1,
274                            's'         => -2
275                           },
276             'microN'  => {
277                            'factor'    => 10**(-6),
278                            'm'         => 1,
279                            'kg'        => 1,
280                            's'         => -2
281                           },
282                  'uN'  => {
283                            'factor'    => 10**(-6),
284                            'm'         => 1,
285                            'kg'        => 1,
286                            's'         => -2
287                           },
288                'dyne'  => {
289                            'factor'    => 10**(-5),
290                            'm'         => 1,
291                            'kg'        => 1,
292                            's'         => -2
293                           },
294                  'lb'  => {
295                            'factor'    => 4.4482216152605,
296                            'm'         => 1,
297                            'kg'        => 1,
298                            's'         => -2
299                           },
300                 'ton'  => {
301                            'factor'    => 8900,
302                            'm'         => 1,
303                            'kg'        => 1,
304                            's'         => -2
305                           },
306 # ENERGY
307 # J      -- Joule
308 # kJ     -- kilo Joule
309 # erg    -- erg
310 # lbf    -- foot pound
311 # cal    -- calorie
312 # kcal   -- kilocalorie
313 # eV     -- electron volt
314 # kWh    -- kilo Watt hour
315 #
316                     'J'  => {
317                            'factor'    => 1,
318                            'm'         => 2,
319                            'kg'        => 1,
320                            's'         => -2
321                           },
322                  'kJ'  => {
323                            'factor'    => 1000,
324                            'm'         => 2,
325                            'kg'        => 1,
326                            's'         => -2
327                           },
328                 'erg'  => {
329                            'factor'    => 10**(-7),
330                            'm'         => 2,
331                            'kg'        => 1,
332                            's'         => -2
333                           },
334                 'lbf'  => {
335                            'factor'    => 1.35582,
336                            'm'         => 2,
337                            'kg'        => 1,
338                            's'         => -2
339                           },
340                 'cal'  => {
341                            'factor'    => 4.19,
342                            'm'         => 2,
343                            'kg'        => 1,
344                            's'         => -2
345                           },
346                'kcal'  => {
347                            'factor'    => 4190,
348                            'm'         => 2,
349                            'kg'        => 1,
350                            's'         => -2
351                           },
352                 'eV'  => {
353                            'factor'    => 1.60E-9,
354                            'm'         => 2,
355                            'kg'        => 1,
356                            's'         => -2
357                           },
358                 'kWh'  => {
359                            'factor'    => 3.6E6,
360                            'm'         => 2,
361                            'kg'        => 1,
362                            's'         => -2
363                           },
364 # POWER
365 # W      -- Watt
366 # kW     -- kilo Watt
367 # hp     -- horse power  746 W
368 #
369                  'W'  => {
370                            'factor'    => 1,
371                            'm'         => 2,
372                            'kg'        => 1,
373                            's'         => -3
374                           },
375                  'kW'  => {
376                            'factor'    => 1000,
377                            'm'         => 2,
378                            'kg'        => 1,
379                            's'         => -3
380                           },
381                 'hp'   => {
382                            'factor'    => 746,
383                            'm'         => 2,
384                            'kg'        => 1,
385                            's'         => -3
386                           },
387 # PRESSURE
388 # Pa     -- Pascal
389 # kPa    -- kilo Pascal
390 # atm    -- atmosphere
391                  'Pa'  => {
392                            'factor'    => 1,
393                            'm'         => -1,
394                            'kg'        => 1,
395                            's'         => -2
396                           },
397                 'kPa'  => {
398                            'factor'    => 1000,
399                            'm'         => -1,
400                            'kg'        => 1,
401                            's'         => -2
402                           },
403                 'atm'  => {
404                            'factor'    => 1.01E5,
405                            'm'         => -1,
406                            'kg'        => 1,
407                            's'         => -2
408                           },
409 # ELECTRICAL UNITS (incomplete)
410 # C      -- Coulomb
411 # V      -- volt
412 # mV     -- milivolt
413 # kV     -- kilovolt
414 # MV     -- megavolt
415 # F      -- Farad
416 # mF     -- miliFarad
417 # uF     -- microFarad
418 # ohm    -- ohm
419 # kohm   -- kilo-ohm
420                 'C'    => {
421                            'factor'    => 1,
422                            'amp'       => 1,
423                            's'         => 1,
424                          },
425                 'V'    => {
426                            'factor'    => 1,
427                            'J'         => 1,
428                            'C'         => -1,
429                          },
430                 'mV'   => {
431                            'factor'    => 0.001,
432                            'V'         => 1,
433                          },
434                 'kV'   => {
435                            'factor'    => 1000,
436                            'V'         => 1,
437                          },
438                 'MV'   => {
439                            'factor'    => 10**(6),
440                            'V'         => 1,
441                          },
442                 'F'    => {
443                            'factor'    => 1,
444                            'C'         => 1,
445                            'V'         => -1,
446                          },
447                 'mF'   => {
448                            'factor'    => 0.001,
449                            'F'         => 1,
450                          },
451                 'uF'   => {
452                            'factor'    => 10**(-6),
453                            'F'         => 1,
454                          },
455                 'ohm'  => {
456                            'factor'    => 1,
457                            'V'         => 1,
458                            'amp'       => -1,
459                          },
460                 'kohm' => {
461                            'factor'    => 1000,
462                            'ohm'       => 1,
463                          },
464 );
465
466
467
468 sub process_unit {
469
470   my \$string = shift;
471     die ("UNIT ERROR: No units were defined.") unless defined(\$string);  #
472   #split the string into numerator and denominator --- the separator is /
473     my (\$numerator,\$denominator) = split( m{/}, \$string );
474
475
476
477   \$denominator = "" unless defined(\$denominator);
478   my %numerator_hash = process_term(\$numerator);
479   my %denominator_hash =  process_term(\$denominator);
480
481
482     my %unit_hash = %fundamental_units;
483   my \$u;
484   foreach \$u (keys %unit_hash) {
485     if ( \$u eq 'factor' ) {
486       \$unit_hash{\$u} = \$numerator_hash{\$u}/\$denominator_hash{\$u};  # calculate the correction factor for the unit
487     } else {
488
489       \$unit_hash{\$u} = \$numerator_hash{\$u} - \$denominator_hash{\$u}; # calculate the power of the fundamental unit in the unit
490     }
491   }
492   # return a unit hash.
493   return(%unit_hash);
494 }
495
496 sub process_term {
497   my \$string = shift;
498   my %unit_hash = %fundamental_units;
499   if (\$string) {
500
501     #split the numerator or denominator into factors -- the separators are *
502
503       my @factors = split(/\*/, \$string);
504
505     my \$f;
506     foreach \$f (@factors) {
507       my %factor_hash = process_factor(\$f);
508
509       my \$u;
510       foreach \$u (keys %unit_hash) {
511         if ( \$u eq 'factor' ) {
512           \$unit_hash{\$u} = \$unit_hash{\$u} * \$factor_hash{\$u};  # calculate the correction factor for the unit
513         } else {
514
515           \$unit_hash{\$u} = \$unit_hash{\$u} + \$factor_hash{\$u}; # calculate the power of the fundamental unit in the unit
516         }
517       }
518     }
519   }
520   #returns a unit hash.
521   #print "process_term returns", %unit_hash, "\n";
522   return(%unit_hash);
523 }
524
525
526 sub process_factor {
527   my \$string = shift;
528   #split the factor into unit and powers
529
530     my (\$unit_name,\$power) = split(/\^/, \$string);
531   \$power = 1 unless defined(\$power);
532   my %unit_hash = %fundamental_units;
533
534   if ( defined( \$known_units{\$unit_name} )  ) {
535     my %unit_name_hash = %{\$known_units{\$unit_name}};   # \$reference_units contains all of the known units.
536     my \$u;
537     foreach \$u (keys %unit_hash) {
538       if ( \$u eq 'factor' ) {
539         \$unit_hash{\$u} = \$unit_name_hash{\$u}**\$power;  # calculate the correction factor for the unit
540       } else {
541         my \$fundamental_unit = \$unit_name_hash{\$u};
542         \$fundamental_unit = 0 unless defined(\$fundamental_unit); # a fundamental unit which doesn't appear in the unit need not be defined explicitly
543         \$unit_hash{\$u} = \$fundamental_unit*\$power; # calculate the power of the fundamental unit in the unit
544       }
545     }
546   } else {
547     die "UNIT ERROR Unrecognizable unit: |\$unit_name|";
548   }
549   %unit_hash;
550 }
551
552 # This is the "exported" subroutine.  Use this to evaluate the units given in an answer.
553 sub evaluate_units {
554   my \$unit = shift;
555   my %output =  eval(q{process_unit( \$unit)});
556   %output = %fundamental_units if \$@;  # this is what you get if there is an error.
557   \$output{'ERROR'}=\$@ if \$@;
558   %output;
559 }
560 #################
561
562 1;
```

 aubreyja at gmail dot com ViewVC Help Powered by ViewVC 1.0.9