DMelt:Units/2 Measurements with Units

From HandWiki
Member

Measurements with units

Before we considered how to perform conversion between different units. Now we will consider calculations with units. This part is based on the JScience project.

First, let us check the available units:

First, let us import International units and their derivatives:

from javax.measure.unit.SI import *
dir()

You will see the available units:

['AMPERE', 'ATTO', 'BECQUEREL', 'BIT', 'CANDELA', 'CELSIUS', 'CENTI', 
'CENTIMETER', 'CENTIMETRE', 'COULOMB', 'CUBIC_METRE', 'DECI', 'DEKA',
 'EXA', 'Editor', 'FARAD', 'FEMTO', 'GIGA', 'GRAM', 'GRAY', 'HECTO', 
 'HENRY', 'HERTZ', 'JOULE', 'KATAL', 'KELVIN', 'KILO', 'KILOGRAM', 
 'KILOMETER', 'KILOMETRE', 'LUMEN', 'LUX', 'MEGA', 'METER', 'METERS_PER_SECOND', 
 'METERS_PER_SQUARE_SECOND', 'METRE', 'METRES_PER_SECOND', 'METRES_PER_SQUARE_SECOND', 
 'METRE_PER_SECOND', 'METRE_PER_SQUARE_SECOND', 'MICRO', 'MILLI', 'MILLIMETER',
 'MILLIMETRE', 'MOLE', 'NANO', 'NEWTON', 'OHM', 'PASCAL', 'PETA', 'PICO', 
 'RADIAN', 'SECOND', 'SIEMENS', 'SIEVERT', 'SQUARE_METRE', 'STERADIAN', 'TERA', 
 'TESLA', 'VOLT', 'WATT', 'WEBER', 'YOCTO', 'YOTTA',  'ZEPTO', 'ZETTA',

Similarly, one can import non-international units:

from javax.measure.unit.NonSI import *
dir()

which shows

['ANGSTROM', 'ARE', 'ASTRONOMICAL_UNIT', 'ATMOSPHERE', 'ATOM', 
 'ATOMIC_MASS', 'BAR', 'BYTE', 'C', 'CENTIRADIAN', 'COMPUTER_POINT', 
 'CUBIC_INCH', 'CURIE', 'ClassPath', 'DAY', 'DAY_SIDEREAL', 'DECIBEL', 
 'DEGREE_ANGLE', 'DYNE', 'E', 'ELECTRON_MASS', 'ELECTRON_VOLT', 'ERG', 
 'FAHRENHEIT', 'FARADAY', 'FOOT', 'FOOT_SURVEY_US', 'FRANKLIN', 'G',
 'GALLON_DRY_US', 'GALLON_LIQUID_US', 'GALLON_UK', 'GAUSS', 'GILBERT', 
 'GRADE', 'HECTARE', 'HORSEPOWER', 'HOUR', 'INCH', 'INCH_OF_MERCURY',
 'KILOGRAM_FORCE', 'KILOMETERS_PER_HOUR', 'KILOMETRES_PER_HOUR', 'KNOT', 
 'LAMBERT', 'LIGHT_YEAR', 'LITER', 'LITRE', 'MACH', 'MAXWELL', 'METRIC_TON',
 'MILE', 'MILES_PER_HOUR', 'MILLIMETER_OF_MERCURY', 'MINUTE', 'MINUTE_ANGLE',
 'MONTH', 'NAUTICAL_MILE', 'OCTET', 'OUNCE', 'OUNCE_LIQUID_UK', 'OUNCE_LIQUID_US', 
 'PARSEC', 'PERCENT', 'PIXEL', 'POINT', 'POISE', 'POUND', 'POUND_FORCE', 'RAD', 
 'RANKINE', 'REM', 'REVOLUTION', 'ROENTGEN', 'RUTHERFORD', 'SECOND_ANGLE', 'SPHERE',
 'STOKE', 'TON_UK', 'TON_US', 'UserMacrosDir', 'WEEK', 'YARD', 'YEAR', 
 'YEAR_CALENDAR', 'YEAR_SIDEREAL',

Let is define the mass in pounds:

>> from  org.jscience.physics.amount import *
>> from javax.measure.unit.NonSI import *
>>>from javax.measure.unit.SI import *
>> m0=Amount.valueOf(100, POUND)    # define mass in pounds
>> m1=Amount.valueOf(100, KILOGRAM) # in kg
>> print m0, m1
Output: 100 lb  100 kg


Arithmetics with measures using units

You can do the standard math with measures using different units.

In this small example we defined two masses in different units and then divided by 3, multiplied by 5 and added another mass in kilograms. When we print it, we convert the answer to kilograms.

from  org.jscience.physics.amount import Amount
from javax.measure.unit.NonSI import *
from javax.measure.unit.SI import *
m0=Amount.valueOf(100, POUND)    # define mass in pounds
m1=Amount.valueOf(100, KILOGRAM) # in kg
m= m0.divide(2).times(5).plus(m1)

from java.lang.System import * # we use Java system output in UTF-8
out.println( m.to(KILOGRAM))

The answer in kg is:

(213.39809249999996 ± 2.8E-14) kg

The last "± 2.8E-14" does nor mean much since we defined the values without errors. We can do now manipulation assuming that each value has measurement uncertainty ("error").

from  org.jscience.physics.amount import Amount
from javax.measure.unit.NonSI import *
from javax.measure.unit.SI import *
m0=Amount.valueOf(100, 5, POUND)    # define mass with error in pounds 100 +- 5
m1=Amount.valueOf(100, 2, KILOGRAM) # in kg with error, 100 +-2 kg
m= m0.divide(2).times(5).plus(m1)
from java.lang.System import *
out.println( m.toString());

Now the output has a meaningful error:

(4.7E2 ± 17.) lb

Look at the class API for the "Amount" objects here: org.jscience.physics.amount.Amount org.jscience.physics.amount.Amount or in the summary org.jscience.physics.amount.package-summary org.jscience.physics.amount.package-summary.

Let's build a small example. Let's calculate the speed of a free falling object:

from org.jscience.physics.amount import Amount
from org.jscience.physics.amount import Constants
from javax.measure.unit.SI import *
 
TIME=Amount.valueOf(100,SECOND)
v=TIME.times(Constants.g) # t*gravitation constant
print  v



Which will show the output:

(980.6649999999997 ± 1.7E-13) m/s

Note that "Constants.g" is the gravitational constant which is

(9.8066499999999976 ± 8.9E-16) m/s²

{{ambox | type = notice | style = background-color:#AFEEEE; | text = important> You are not full member and have a limited access to this section. One can unlock this part after becoming [[https://datamelt.org/members/selock%7C a full member</javadoc>.

}}

Values with units using VisAd

The Java package VisAd VisAd contains powerful classes visad.Real visad.Real and visad.Data visad.Data to perform calculations with units and errors.

If your quantities are physical and have associated Units, then you might prefer to create a VisAD MathType that explicitly defines the metadata characteristics of your quantities. A MathType is used to define the kind of mathematical object that the Data object approximates. Every Data object in VisAD must have a MathType. In the previous examples, a default MathType with the name "Generic" was implicitly used for our Real objects.

In the simplest form for dealing with Units, the constructor for a MathType which defines Real values is:

RealType(String name, Unit u, Set s)

which allows you to assign a unique name to this MathType, a Unit for this, and define a default Set. In practice, the Set is seldom used and should just be passed as null in most cases. Here is an example using Java codding:

import visad.*;
Real t1,t2,sum;
RealType k = new RealType("kelvin",SI.kelvin,null);
t2 = new Real(k,273.);
t1 = new Real(k,255.);
sum = (Real) t1.add(t2);
System.out.println("sum = "+sum+" "+sum.getUnit());

When you run this example, you get: sum = 528.0 K In this example, we use an SI Unit (ampere, candela, kelvin, kilogram, meter, second, mole, radian, steradian). Note that we constructed two variables with the same MathType, that is the same name, Unit, and Set.

This example shows how to define values with errors and how to perform mathematical transformation while propagating errors (independently) using Jython/Python:

from visad import SI,Data,Real,RealType

def printReal(x):
   print x.toString(), "+-", (x.getError()).getErrorValue()

a=Real(10,2) # 10 +- 2 (error)
b=Real(30,5) # 30 +- 5 (error)

c=a.add(b,Data.NEAREST_NEIGHBOR, Data.INDEPENDENT)
print "a+b=", printReal(c)

c=a.divide(b,Data.NEAREST_NEIGHBOR, Data.INDEPENDENT)
print "a+b=", printReal(c)

a=Real(0.9,0.1) # 10 +- 2 (error)
c=a.cos(Data.NEAREST_NEIGHBOR, Data.INDEPENDENT)
print "acos(a)=", printReal(c)

a=Real(0.9,0.1) # 10 +- 2 (error)
c=a.pow(c,Data.NEAREST_NEIGHBOR, Data.INDEPENDENT)
print "a^4=", printReal(c)

print "use units:"
k=RealType("kelvin",SI.kelvin)
t2=Real(k,273.);
t1= Real(k,255.);
xsum =t1.add(t2);
print "sum = ",xsum," ",xsum.getUnit()