[system] / trunk / pg / lib / Units.pm Repository:
ViewVC logotype

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

Parent Directory Parent Directory | Revision Log Revision Log


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