|
|
| |
Physics::Unit(3) |
User Contributed Perl Documentation |
Physics::Unit(3) |
Physics::Unit - Manipulate physics units and dimensions.
use Physics::Unit ':ALL'; # exports all util. function names
# Define your own unit named "ff"
$ff = new Physics::Unit('furlong / fortnight', 'ff');
print $ff->type, "\n"; # prints: Speed
# Convert to mph; this prints: One ff is 0.0003720... miles per hour
print "One ", $ff->name, " is ", $ff->convert('mph'), " miles per hour\n";
# Get canonical string representation
print $ff->expanded, "\n"; # prints: 0.0001663... m s^-1
# More intricate unit expression (using the newly defined unit 'ff'):
$gonzo = new Physics::Unit "13 square millimeters per ff";
print $gonzo->expanded, "\n"; # prints: 0.07816... m s
# Doing arithmetic maintains the types of units
$m = $ff->copy->times("5 kg");
print "This ", $m->type, " unit is ", $m->ToString, "\n";
# prints: This Momentum unit is 0.8315... m gm s^-1
See also the Synopsis section of Physics::Unit::Scalar for more
examples.
These modules provide classes for the representation of physical units and
quantities, as well as a large library of predefined Physics::Unit objects.
New units and quantities can be created with simple human-readable expressions
(for example, "cubic meters per second").
The resultant objects can then be manipulated arithmetically, with the
dimensionality correctly maintained.
Physics::Unit objects generally represent standard, named units,
like meter or electronvolt. Physics::Unit::Scalar and related
classes, on the other hand, are used to represent various quantities that
might occur as the result of a measurement or a specification, like
"5.7 meters" or "7.4 teraelectronvolts".
A Physics::Unit object has a list of names, a dimensionality, and
a magnitude. For example, the SI unit of force is the newton. In this
module, it can be referred to with any of the names newton,
nt, or newtons. It's dimensionality is that of a force: mass X
distance / time^2. It's magnitude is 1000, which expresses how large it is
in terms of the unprefixed base units gram, meter, and
second.
Units are created through the use of unit expressions, which allow
you to combine previously defined named units in new and interesting ways.
In the synopsis above, "furlong /
fortnight" is a unit expression.
Units that have the same dimensionality (for example, acres
and square kilometers) can be compared, and converted from one to the
other.
- Physics::Unit
- This page.
- Physics::Unit::Scalar
- Describes the Scalar class and all of the type-specific classes that
derive from Scalar.
- physics-unit
- Describes the command-line utility that is included with this module.
- Physics::Unit::UnitsByName
- Table of all of the units predefined in the unit library, alphabetically
by name.
- Physics::Unit::UnitsByType
- Tables listing all the units in the unit library, grouped by type.
- Physics::Unit::Implementation
- Describes some implementation details for the Unit module.
- Physics::Unit::Scalar::Implementation
- Implementation details for the Scalar module.
A Unit can have one or more names associated with it, or it can be unnamed
(anonymous). Named units are immutable. This ensures that expressions used to
derive other Units will remain consistent. The values of anonymous Unit
objects, however, can change.
Among named Units, there are three types: prefixes (for example,
"kilo", "mega", etc.), base units, and derived
units.
A prefix Unit is a special-case dimensionless Unit object that can
be used in expressions attached to other Unit names with no intervening
whitespace. For example, "kilogram" is a unit expression that uses
the prefix kilo. For more details about the use of prefixes, see
"Unit Expressions", below.
A base unit is one that defines a new base dimension. For example,
the Unit meter is a base unit; it defines the dimension for
Distance. The predefined unit library defines nine base units, for
each of nine fundamental quantities. See "InitBaseUnit()"
below for a list.
A derived Unit is one that is built up from other named Units,
using a unit expression. Most Units are derived Units.
The terms base dimension and derived dimension (or derived type)
are sometimes used. Distance is an example of a base dimension. It is
not derived from any other set of dimensional quantities. Speed,
however, is a derived dimension (or derived type), corresponding to
Distance / Time.
Unit names are not allowed to contain whitespace, or any of the characters ^, *,
/, (, or ). Case is not significant. Also, they may not begin with any
sequence of characters that could be interpreted as a decimal number.
Furthermore, the following reserved words are not allowed as unit names:
per, square, sq, cubic, squared, or
cubed. Other than that, pretty much anything goes.
Unit expressions allow you to create new Unit objects from the set of existing
named Units. Some examples of unit expressions are:
megaparsec / femtosecond
kg / feet^2 sec
square millimeter
kilogram meters per second squared
The operators allowed in unit expressions are, in order from high
to low precedence:
- prefix
- Any prefix that is attached to a Unit name is applied to that Unit
immediately (highest precedence). Note that if there is whitespace between
the prefix and the Unit name, this would be the space operator, which is
not the same (see below).
The unit library comes with a rather complete set of
predefined SI prefixes; see the UnitsByType page.
The prefixes are allowed before units, or by themselves. Thus,
these are equivalent:
(megameter)
(mega meter)
But note that when used in expressions, there can be subtle
differences, because the precedence of the prefix operation is higher
than the space operator. So "square
megameter" is a unit of area, but
"square mega meter" is a unit of
distance (equal to 10^12 meters).
- square, sq, or cubic
- Square or cube the next thing on the line
- squared or cubed
- Square or cube the previous thing on the line.
- "^" or "**"
- Exponentiation (must be to an integral power)
- whitespace
- Any amount of whitespace between units is considered a multiplication
- *, /, or per
- Multiplication or division
- parentheses
- Can be used to override the precedence of any of the operators.
For the most part, this precedence order lets you write unit
expressions in a natural way. For example, note that the space operator has
higher precedence than '*', '/', or 'per'. Thus
""meters/sec sec"" is a unit of
acceleration, but
""meters/sec*sec"" is not. The
latter is equivalent to just 'meters'.
This is the approximate grammar used by the parser.
expr : term
| term '/' expr
| term '*' expr
| term 'per' expr
term : factor
| term <whitespace> factor
factor : primary
| primary '**' integer
primary : number
| word
| '(' expr ')'
| 'square' primary
| 'sq' primary
| 'cubic' primary
| primary 'squared'
| primary 'cubed'
A rather complete set of units is pre-defined in the unit library, so it will
probably be rare that you'll need to define your own. See the UnitsByName or
UnitsByType page for a complete list.
A pound is a unit of force. I was very much tempted to make
it a unit of mass, since that is the way it is used in everyday speech, but
I just couldn't do it. The everyday pound, then, is named pound-mass,
lbm, lbms, or pounds-mass.
However, I couldn't bring myself to do the same thing to all the
other American units derived from a pound. Therefore, ounce,
ton, long-ton, and hundredweight are all units of
mass.
A few physical constants were defined as Unit objects. This list is very
restricted, however. I limited them to physical constants which really qualify
as universal, according to (as much as I know of) the laws of physics, and a
few constants which have been defined by international agreement. Thus, they
are:
- c - the speed of light
- G - the universal gravitational constant
- eq - elementary charge
- em - electron mass
- u - atomic mass unit
- g0 - standard gravity
- atm - standard atmosphere
- re - equatorial radius of the reference geoid
- rp - polar radius of the reference geoid
- h - Planck constant
- Na - Avogadro constant
A few unit names and abbreviations had to be changed in order to avoid name
conflicts. These are:
- Elementary charge - abbreviated eq instead of e
- Earth gravity - abbreviated g0 instead of g
- point - there are several definitions for this term. In our
library, we define it to be exactly 1/72 of an inch.
- minute is defined as a unit of time. For the unit of arc, use
arcminute. Same for second and arcsecond.
- pound - As described above, this is defined as a unit of force,
with synonyms pound-force, pounds-force,
pound-weight, and lbf. For the unit of mass, use
pound-mass, pounds-mass, or lbm.
- ounce - As a unit of mass, use ounce, ounce-force, or
ozf. For the unit of volume, use fluid-ounce, floz,
or fluidounce.
By default, this module exports nothing. You can request all of the functions to
be exported as follows:
use Physics::Unit ':ALL';
Or, you can just get specific ones. For example:
use Physics::Unit qw( GetUnit ListUnits );
- InitBaseUnit($type1, $nameList1,
$type2, $nameList2, ...)
- This function is used to define any number of new, fundamental,
independent dimensional quantities. Each such quantity is represented by a
Unit object, which must have at least one name. From these base units, all
the units in the system are derived.
The library is initialized to know about nine base quantities.
These quantities, and the base units which represent them, are:
- 1. Distance - meter
- 2. Mass - gram
- 3. Time - second
- 4. Temperature - kelvin
- 5. Current - ampere
- 6. Substance - mole
- 7. Luminosity - candela
- 8. Money - us-dollar
- 9. Data - bit
More base quantities can be added at run-time, by calling this
function. The arguments to this function are in pairs. Each pair consists of
a type name followed by a reference to an array. The array consists of a
list of names which can be used to reference the unit. For example:
InitBaseUnit('Beauty' => ['sonja', 'sonjas', 'yh']);
This defines a new basic physical type, called Beauty. This
also causes the creation of a single new Unit object, which has three names:
sonja, sonjas, and yh. The type Beauty is
refered to as a base type. The Unit sonja is refered to as the base
unit corresponding to the type Beauty.
After defining a new base Unit and type, you can then create other
Units derived from this Unit, and other types derived from this type.
- InitPrefix($name1, $number1,
$name2, $number2, ...)
- This function defines new prefixes. For example:
InitPrefix('gonzo' => 1e100, 'piccolo' => 1e-100);
From then on, you can use those prefixes to define new units,
as in:
$beautification_rate = new Physics::Unit('5 piccolosonjas / hour');
- InitUnit($nameList1, $unitDef1,
$nameList2, $unitDef2, ...)
- This function creates one or more new named Units. This is called at
compile time to initialize the module with all the predefined units. It
may also be called by users at runtime, to expand the unit system. For
example:
InitUnit( ['chris', 'cfm'] => '3 piccolosonjas' );
creates another Unit of type Beauty equal to 3e-100
sonjas.
Both this utility function and the
"new" class method can be used to
create new, named Unit objects. Units created with
"InitUnit" must have a name, however,
whereas "new" can be used to create
anonymous Unit objects.
In this function and in others, an argument that specifies a
Unit (a "unitDef") can be given either as Unit object, a
single Unit name, or a unit expression. So, for example, these are the
same:
InitUnit( ['mycron'], '3600 sec' );
InitUnit( ['mycron'], 'hour' );
InitUnit( ['mycron'], GetUnit('hour') );
No forward references are allowed.
- InitTypes($typeName1, $unit1,
$typeName2, $unit2, ...)
- Use this function to define derived types. For example:
InitTypes( 'Blooming' => 'sonja / year' );
defines a new type that for a rate of change of Beauty
with time.
This function associates a type name with a specific
dimensionality. The magnitude of the Unit is not used.
- GetUnit($unitDef)
- Returns a Unit object associated with the the argument passed in. The
argument can either be a Unit object (in which case it is simply
returned), a unit name (in which case the name is looked up and a
reference to the corresponding Unit is returns), or a unit expression (in
which case a new Unit object is created and a reference to it is
returned).
- ListUnits()
- Returns a list of all Unit names known, sorted alphabetically.
- ListTypes()
- Returns a list of all the quantity types known to the library, sorted
alphabetically.
- NumBases()
- Returns the number of base dimension units.
- GetTypeUnit($type)
- Returns the Unit object corresponding to a given type name, or
undef if the type is not recognized.
- DeleteNames(@names)
- DeleteNames($unit)
- Deletes the names indicated by the argument, which can either be a list of
names, a reference to array of names, or a Unit object. If the argument is
a Unit object, then all the names of that Unit are deleted.
This provides a mechanism to override specific definitions in
the default unit library. Use with this with caution. If existing Unit
objects had been constructed using these names, the
"def" value of those Units would be
rendered invalid when these names are removed.
- new Physics::Unit( $unit [,
$name1, $name2, ... ] )
- $u->new( [$name1,
$name2, ... ] )
- This method creates a new Unit object. The names are optional. If more
than one name is given, the first is the "primary name", which
means it is the one returned by the
"name()" method.
Unit names must be unique. See the UnitsByName page to see an
alphabetical list of all the pre-defined unit names.
If no names are given, then an anonymous Unit is created. Note
that another way of creating new anonymous Units is with the
"GetUnit()" function. Unlike
GetUnit(), however, the new method always creates a new
object.
Examples:
# Create a new, named unit:
$u = new Physics::Unit ('3 pi furlongs', 'gorkon');
- $u->type([$typeName])
- Get or set this Unit's type.
For example:
print GetUnit('rod')->type, "\n"; # 'Distance'
Usually it will not be necessary to set a Unit's type. The
type is normally determined uniquely from the dimensionality. However,
occasionally, more than one type can match a given Unit's
dimensionality.
For example, Torque and Energy have the same
dimensionality. In that case, all of the predefined, named Units are
explicitly designated to be one type or the other. For example, the Unit
newton is defined to have the type Energy. See the
UnitsByType page to see which Units are defined as Energy and
which as Torque.
If you create a new Unit object that has this dimensionality,
then it will be necessary to explicitly specify which type that Unit
object is.
When this method is called to set the Unit's type, only one
type string argument is allowed, and it must be a predefined type name
(see "InitTypes" above).
This method returns one of:
- "undef"
- no type was found to match the unit's dimensionality
- 'prefix'
- in the special case where the unit is a named prefix
- a type name
- the prototype unit for this type name matches the unit's
dimensionality
- an array of type names
- more than one type was found to match the unit's dimensionality
Some examples:
$u1 = new Physics::Unit('kg m^2/s^2');
$t = $u1->type; # ['Energy', 'Torque']
$u1->type('Energy'); # This establishes the type once and for all
$t = $u1->type; # 'Energy'
# Create a new copy of a predefined, typed unit:
$u3 = GetUnit('joule')->new;
$t = $u3->type; # 'Energy'
- $u->name()
- Returns the primary name of the Unit. If this Unit has no names, then
"undef".
- $u->abbr()
- Returns the shortest name of the Unit. If this Unit has no names,
"undef".
- $u->names()
- Returns a list of names that can be used to reference the Unit. Returns
the empty list if the Unit is unnamed.
- $u->def()
- Returns the string that was used to define this Unit. Note that if the
Unit has been manipulated with any of the arithmetic methods, then the
"def" method will return
"undef", since the definition string is
no longer a valid definition of the Unit.
- $u->expanded()
- Produces a string representation of the Unit, in terms of the base Units.
For example:
print GetUnit('calorie')->expanded, "\n"; # "4184 m^2 gm s^-2"
- $u->ToString()
- There are several ways to serialize a Unit object to a string. This method
is designed to give you what you usually want, and to always give
something meaningful.
If the object is named, this does the same as the
"name()" method above. Otherwise, if
the object's definition string is still valid, this does the same as the
"def()" method above. Otherwise, this
does the same thing as the
"expanded()" method.
- $u->factor([$newValue])
- Get or set the Unit's conversion factor (magnitude). If this is used to
set a Unit's factor, then the Unit object must be anonymous.
- $u->convert($unitDef)
- Returns the number which converts this Unit to another. The types of the
Units must match. For example:
print GetUnit('mile')->convert('foot'), "\n"; # 5280
- $u->times($unitDef)
- Multiply this object by the given Unit. This will, in general, change a
Unit's dimensionality, and hence its type.
- $u->recip()
- Replaced a Unit with its reciprocal. This will, in general, change a
Unit's dimensionality, and hence its type.
- $u->divide($unitDef)
- Divide this object by the given Unit. This will, in general, change a
Unit's dimensionality, and hence its type.
For example:
$u = new Physics::Unit('36 m^2');
$u->divide('3 meters'); # now '12 m'
$u->divide(3); # now '4 m'
$u->divide('.5 sec'); # now '8 m/s'
- $u->power($i)
- Raises a Unit to an integral power. This will, in general, change its
dimensionality, and hence its type.
- $u->add($unitDef)
- Add a Unit, which must be of the same type.
- $u->neg()
- Replace a Unit with its arithmetic negative.
- $u->subtract($unitDef)
- Subtract a Unit, which must be of the same type.
- $u->copy()
- This creates a copy of an existing Unit, without copying the names. So you
are free to modify the copy (while modification of named Units is
verboten). If the type of the existing Unit is well-defined, then it,
also, is copied.
This is the same as the new method, when new is called as an
object method with no names.
- $u->equal($unit)
- Physics::Unit->equal($unit1,
$unit2);
- This returns 1 if the two Unit objects have the same type and the same
magnitude.
Here are some other modules that might fit your needs better than this one:
- MooseX::Types::NumUnit
- Math::Units
- Math::Units::PhysicalValue
- Petrophysics::Unit
- Physics::Udunits2
Written by Chris Maloney <voldrani@gmail.com>
Special thanks for major contributions and encouragement from Joel
Berger. Thanks also to Ben Bullock, and initial help in formatting for
distribution from Gene Boggs <cpan@ology.net>.
Copyright 2002-2003 by Chris Maloney
This library is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
Visit the GSP FreeBSD Man Page Interface. Output converted with ManDoc. |