[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 3655 - (download) (as text) (annotate)
Mon Sep 26 04:11:25 2005 UTC (14 years, 4 months ago) by gage
File size: 18084 byte(s)
Changed the numerical values of lbf to make it more accurate (assuming that lbf is an abbreviation for ft-lbs which I doubt).

Also replaced the conversion factor for pounds with a more accurate figure.

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

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9