Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Calculating with Units

177 views
Skip to first unread message

Nikolaus Rath

unread,
Dec 1, 2008, 7:02:03 AM12/1/08
to
Hello,

Until now, I have always defined my units manually in terms of
the 4 base units Kilogram, Meter, Coulomb and Second:

Newton = Kg Meter / Second^2;
Joule = Newton Meter;
Henry = Weber / Ampere;
Weber = Volt Second;
etc.

This allows me to evaluate expressions like

B = (\[Mu] Ii)/(2 \[Pi] r);

B /. { r -> 20 Meter, \[Mu] -> 4 \[Pi] * 10^-7 Henry/Meter,
Ii -> 2 Ampere}

% / Tesla

and directly see if the units in the final result are correct.

But since all these units (and many more) are already defined in the
Mathematica Units package, I was wondering if there isn't a way to use
that package in the same way. Unfortunately, it doesn't seem to
simplify the units, i.e. when I enter

(Ampere Henry)/(Meter Meter) // Simplify // SI

I get the same expression back. What I would like to get is either
"Tesla" or "Kilo Gram / (Coulomb Second)". Is there a way to
accomplish this?


Best,

-Nikolaus

--
=C2=BBIt is not worth an intelligent man's time to be in the majority.
By definition, there are already enough people to do that.=C2=AB
-J.H. Hardy

PGP fingerprint: 5B93 61F8 4EA2 E279 ABF6 02CF A9AD B7F8 AE4E 425C

David Park

unread,
Dec 2, 2008, 12:29:38 AM12/2/08
to
The Unit6`ExtendUnits1 package from my web site ($30) has a BaseSI command
that does the conversion you want.

Needs["Units6`ExtendUnits6`"]

B = (\[Mu] Ii)/(2 \[Pi] r);

B /. {r -> 20 Meter, \[Mu] -> 4 \[Pi]*10^-7 Henry/Meter,
Ii -> 2 Ampere};
%/Tesla
% // BaseSI
(Ampere Henry)/(50000000 Meter^2 Tesla)
1/50000000

(Ampere Henry)/(Meter Meter) // BaseSI
% // ToUnit[Tesla]
Kilogram/(Ampere Second^2)
1. Tesla

The package has many other features.
1) It is easier to convert units as a postfix operation.
2) It has a PrefixForm for automatically picking correct unit prefixes if
desired.
3) You can parse a unit into compatible descending units such as Hour,
Minute, Second.
4) You can simultaneously convert to a set of equivalent units.
5) It has simpler temperature conversions.
6) It has general decibel conversions.
7) You can install your own units or synonyms for units. For example GeV for
Giga ElectronVolt or mph for Mile/Hour.
8) You can deunitize unit expressions to any compatible set of input and
output units for numerical work.
9) You can use reduced units where certain physical constants are set to 1.
Examples would be geometric units in relativity and gravitation or atomic
units in atomic physics.


David Park
djm...@comcast.net
http://home.comcast.net/~djmpark

Bill Rowe

unread,
Dec 2, 2008, 12:31:26 AM12/2/08
to
On 12/1/08 at 7:02 AM, Niko...@rath.org (Nikolaus Rath) wrote:

>Until now, I have always defined my units manually in terms of the 4
>base units Kilogram, Meter, Coulomb and Second:

>Newton = Kg Meter / Second^2; Joule = Newton Meter; Henry = Weber /
>Ampere; Weber = Volt Second; etc.

>This allows me to evaluate expressions like

>B = (\[Mu] Ii)/(2 \[Pi] r);

>B /. { r -> 20 Meter, \[Mu] -> 4 \[Pi] * 10^-7 Henry/Meter,
>Ii -> 2 Ampere}

>% / Tesla

>and directly see if the units in the final result are correct.

>But since all these units (and many more) are already defined in the
>Mathematica Units package, I was wondering if there isn't a way to
>use that package in the same way. Unfortunately, it doesn't seem to
>simplify the units, i.e. when I enter

>(Ampere Henry)/(Meter Meter) // Simplify // SI

>I get the same expression back. What I would like to get is either
>"Tesla" or "Kilo Gram / (Coulomb Second)". Is there a way to
>accomplish this?

There is a rule in the Units`Private` context that will do much
of what you want. That is $ToFundamental. It can be accessed as follows:

In[5]:= (Ampere Henry)/(Meter Meter) //. Units`Private`$ToFundamental

Out[5]= Kilogram/(Ampere Second^2)

This isn't quite what you asked for mainly because Coulomb is a
derived unit in the SI system. However, I've found using this
enables me to more easily check the results of a computation and
verify the units are correct.

John Jowett

unread,
Dec 4, 2008, 7:16:38 AM12/4/08
to
I've mentioned my Accelerator`ContantsUnits` package before on this
group but it is now available for download from

http://jowett.home.cern.ch/jowett/Mathematica/Accelerator/ConstantsUnits.ht=
ml

Among many other things, it implements what Bill Rowe suggests below
in a function ToFundamentalSI[ ] but goes further in simplifying
expressions like Sqrt[Meter^2/Second^2] without applying PowerExpand
to other symbols in the expression.

If you download the package please let me know and give feedback.
Documentation is not ideal but there are numerous examples in the
package-defining notebook.

John Jowett

On Dec 2, 6:31 am, Bill Rowe <readn...@sbcglobal.net> wrote:


> On 12/1/08 at 7:02 AM, Nikol...@rath.org (Nikolaus Rath) wrote:
>
>
>
>
>
> >Until now, I have always defined my units manually in terms of the 4
> >base units Kilogram, Meter, Coulomb and Second:

> >Newton = Kg Meter / Second^2; Joule = Newton Meter; Henry = Weber =


/
> >Ampere; Weber = Volt Second; etc.
> >This allows me to evaluate expressions like
> >B = (\[Mu] Ii)/(2 \[Pi] r);
> >B /. { r -> 20 Meter, \[Mu] -> 4 \[Pi] * 10^-7 Henry/Meter,
> >Ii -> 2 Ampere}
> >% / Tesla
> >and directly see if the units in the final result are correct.
> >But since all these units (and many more) are already defined in the
> >Mathematica Units package, I was wondering if there isn't a way to
> >use that package in the same way. Unfortunately, it doesn't seem to
> >simplify the units, i.e. when I enter
> >(Ampere Henry)/(Meter Meter) // Simplify // SI
> >I get the same expression back. What I would like to get is either
> >"Tesla" or "Kilo Gram / (Coulomb Second)". Is there a way to
> >accomplish this?
>
> There is a rule in the Units`Private` context that will do much
> of what you want. That is $ToFundamental. It can be accessed as follows:
>
> In[5]:= (Ampere Henry)/(Meter Meter) //. Units`Private`$ToFundamental
>
> Out[5]= Kilogram/(Ampere Second^2)
>
> This isn't quite what you asked for mainly because Coulomb is a
> derived unit in the SI system. However, I've found using this
> enables me to more easily check the results of a computation and

> verify the units are correct.- Hide quoted text -
>
> - Show quoted text -


Daniel Lichtblau

unread,
Dec 4, 2008, 7:17:44 AM12/4/08
to
Nikolaus Rath wrote:
> Hello,

>
> Until now, I have always defined my units manually in terms of
> the 4 base units Kilogram, Meter, Coulomb and Second:
>
> Newton = Kg Meter / Second^2;
> Joule = Newton Meter;
> Henry = Weber / Ampere;

> Weber = Volt Second;
> etc.
>
> This allows me to evaluate expressions like
>
> B = (\[Mu] Ii)/(2 \[Pi] r);
>
> B /. { r -> 20 Meter, \[Mu] -> 4 \[Pi] * 10^-7 Henry/Meter,
> Ii -> 2 Ampere}
>
> % / Tesla
>
> and directly see if the units in the final result are correct.
>
> But since all these units (and many more) are already defined in the
> Mathematica Units package, I was wondering if there isn't a way to use
> that package in the same way. Unfortunately, it doesn't seem to
> simplify the units, i.e. when I enter
>
> (Ampere Henry)/(Meter Meter) // Simplify // SI
>
> I get the same expression back. What I would like to get is either
> "Tesla" or "Kilo Gram / (Coulomb Second)". Is there a way to
> accomplish this?
>
>
> Best,
>
>
> -Nikolaus
> [...]

My first reply, in private email, was to the effect that GroebnerBasis
and PolynomialReduce could be used. This was correct, but after further
prodding I realized it needs considerable elaboration.

In looking over some slides from a 2007 talk I realized I had more or
less done this once before, and the fact that a similar question has
appeared on MathGroup suggest that it is not a completely obscure thing
to want. It might be almost completely obscure (ACO), but all the same
I'm using this as an excuse to post a response.

We start with a list of units and a generating set of defining
relations. I also use some one and two letter abbreviations for brevity.

units = {Farads, Ohms, Pascals, Watts, Webers, Teslas, Henries,
Newtons, Joules, Volts, Amperes, Coulombs, Seconds,
Kilograms, Meters};
{f, o, p, wa, we, t, h, n, j, v, a, c, s, k, m} = units;

relations = {f - (c^2*s^2)/(k*m^2), o - (k*m^2)/(c^2*s),
p - k/(m*s^2), -((k*m^2)/s^3) + wa, -((k*m^2)/(c*s)) + we,
-(k/(c*s)) + t, h - (k*m^2)/c^2, n - (k*m)/s^2,
j - (k*m^2)/s^2, -((k*m^2)/(c*s^2)) + v, a - c/s};

Put each over a common denominator and extract the numerator. This gives
polynomial (rather than rational function) relations. This will be
important because Groebnerbasis and PolynomialReduce behave best when
handling legitimate polynomial input.

polyrelations = Numerator[Together[relations]]

Here is a problem. We want to sensibly handle denominators. That is
solved by creating the reciprocal variables and corresponding relations.

recipunits = Map[recip, units];
reciprels = Map[#*recip[#] - 1 &, units];
allrelations = Join[Numerator[Together[relations]], reciprels];
allvars = Flatten[Transpose[{recipunits, units}]];

Since the question involves representing units monomials in terms of a
core set of charge, time, mass, and length (a typical scenario), we
ordered those last. Also we ordered their corresponding reciprocals
after other variables.

With all this we can compute a Groebner basis, using the ordered
variables to define the (lexicographic) term order.

There is a catch here. The input defines what is called a toric ideal.
GroebnerBasis has reasonably fast special case code for that. It also
has code that attempts to recognize such input. But that recognition
code is a bit simple and fails in this example. And the general case
code is quite slow in this case (several minutes thus far, and still no
joy). So we resort to an explicit invocation of the special case code.

gbt = GroebnerBasis`ToricGroebnerBasis[allrelations, allvars];

Now we look at the given example. I've pluralized the units to
correspond with my version.

B = (\[Mu]*Ii)/(2*Pi*r);

B2 = B /.
{r->20*Meters, \[Mu]->(4*Pi*(Henries/Meters))/10^7, Ii->2*Amperes}

Out[29]= (Amperes*Henries)/(50000000*Meters^2)

We want to show that B2/Teslas is dimensionless, that is, it is a
numerical constant. We start by converting to an explicit polynomial.
This is done by a replacement rule that changes units with negative
exponents into their reciprocals, with corresponding positive exponents.
We then use PolynomialReduce with respect to gbt (keeping the same
variable ordering as from computing gbt). Finally we convert explicit
reciprocal variables to units with negative exponents.

Last[PolynomialReduce[
B2/Teslas /. (z_)^(n_Integer) /; n < 0 :> recip[z]^(-n),
gbt, allvars]] /. recip[z_] -> 1/z

Out[33]//InputForm= 1/50000000

This did give a constant, as we wanted.

To see what are the "fundamental" units of B2, we could simply do

In[36]:= InputForm[ Last[PolynomialReduce[
B2 /. (z_)^(n_Integer) /; n < 0 :> recip[z]^(-n),
gbt, allvars]] /. recip[z_] -> 1/z]
Out[36]//InputForm= Kilograms/(50000000*Coulombs*Seconds)

This, and other methods, can can be used to rewrite units monomials in
terms of equivalent ones that minimize total degree, or minimize the
maximal degree of numerator vs denominator, or minimize the number of
units that appears (possibly making the degree large in this scenario).
The starting point for all methods of which I am aware is to augment
with reciprocal variables and relations.

Daniel Lichtblau
Wolfram Research

Artur

unread,
Dec 5, 2008, 5:32:04 AM12/5/08
to
In:
FactorInteger[22! + 1, 2]
Out:
{{11983, 1}, {93799610095769647, 1}}
In:
PrimeQ[11983]
Out:
False

11983=23*521

I don't know that was aim of Mathematica creators was giving two maximal
divisors in option FactorInteger[x,2] ???

Best wishes
Artur

Szabolcs Horvát

unread,
Dec 5, 2008, 7:05:08 AM12/5/08
to
Artur wrote:
> In:
> FactorInteger[22! + 1, 2]
> Out:
> {{11983, 1}, {93799610095769647, 1}}
> In:
> PrimeQ[11983]
> Out:
> False
>
> 11983=23*521

I don't see why you think that this is a bug. You asked for only two
factors instead of full factorization.

Also, this has been said several times before, yet you take no heed: do
NOT reply to and old message when you intend to start a new discussion.
This masks the subject of the old thread, and is very annoying for
those of us who use threaded newsreaders.

John Jowett

unread,
Dec 6, 2008, 6:17:51 AM12/6/08
to
Hello again,
I think it is might be worth while to show how the original question
can be answered very simply with the use of two packages that have
been included in Mathematica since the very earliest versions. In the
following I have just cut and pasted from a notebook; the formulas
look nicer in StandardForm of course.

In[59]:= Needs["Units`"]

In[61]:= Needs["PhysicalConstants`"]

B = (mu0 Ii)/(2 \[Pi] r);

In[75]:= B /.{r -> 20. Meter, Ii -> 2 Ampere,
mu0 -> VacuumPermeability}

Out[75]= (2.*10^-8 Second Volt)/Meter^2

In[76]:= Convert[%, Tesla]

Out[76]= 2.*10^-8 Tesla

The reason I originally wrote the package mentioned in my previous
post (many years ago now) was to combine the two standard packages
with the Notation package and add a few more functions that make the
combination much more useful.

One thing I did was to introduce conventionally used symbols like c or
\mu_0 that would only evaluate under the action of N[], rather like Pi
and E, and unlike symbols such as SpeedOfLight that have assigned
values in the PhysicalConstants` package. That's because you often
don't want general formulas involving them to be partly converted to
numerical values
(E== m c^2 rather than
E == (89875517873681764 m Meter^2)/Second^2 ).

So this example can be worked as

In[34]:= Needs["Accelerator`ConstantsUnits`"]

In[45]:= ?Subscript[\[Mu], 0]

Subscript[\[Mu], 0] or mu0 is a symbol for the permeability of the \
vacuum; it evaluates numerically with N[ ].

In[56]:= B = (Subscript[\[Mu], 0] Ii)/(2 \[Pi] r);

In[57]:= B /.{r -> 20 Meter, Ii -> 2 Ampere} // N

Out[57]= (2.*10^-8 Ampere Henry)/Meter^2

In[58]:= Convert[%, Tesla]

Out[58]= 2.*10^-8 Tesla

There is also a system of registration of the dimensionality of
symbols which allows you to check whether formulas are dimensionally
correct without even plugging in numerical values as follows. I'm
throwing in Statampere and Furlong just to demonstrate that, thanks to
Convert[] and ToFundamentalSI[] you can evaluate expressions using any
old mix of units.


In[111]:= Clear[B, Ii, r];
IntroduceSymbol[B, "is the magnetic field.", Tesla];
IntroduceSymbol[Ii, "is the current in the wire.", Statampere];
IntroduceSymbol[r, "is the distance from the wire.", Furlong];

In[115]:=
DimensionCheck[B/((Subscript[\[Mu], 0] Ii)/(2 \[Pi] r))] //
N // ToFundamentalSI

Out[115]= 2.20918*10^20

In[98]:= DimensionCheck[B/((Subscript[\[Mu], 0] Ii)/(2 \[Pi] r))] //
N // ToFundamentalSI

Out[98]= 7.36901*10^10

The fact that this is a dimensionless number (the value is
meaningless) confirms that the argument of DimensionCheck[] is
dimensionless in SI units.

This refers everything to SI units. I think Daniel Lichtblau's method
might allow you to work in other systems with varying numbers of basic
dimensions.

John Jowett


On Dec 4, 1:17 pm, Daniel Lichtblau <d...@wolfram.com> wrote:
> Nikolaus Rath wrote:
>
> > Hello,
> >
> > Until now, I have always defined my units manually in terms of
> > the 4 base units Kilogram, Meter, Coulomb and Second:
> >
> > Newton = Kg Meter / Second^2;
> > Joule = Newton Meter;
> > Henry = Weber / Ampere;
> > Weber = Volt Second;
> > etc.
> >
> > This allows me to evaluate expressions like
> >
> > B = (\[Mu] Ii)/(2 \[Pi] r);
> >
> > B /. { r -> 20 Meter, \[Mu] -> 4 \[Pi] * 10^-7 Henry/Meter,
> > Ii -> 2 Ampere}
> >
> > % / Tesla
> >
> > and directly see if the units in the final result are correct.
> >
> > But since all these units (and many more) are already defined in the

> > Mathematica Units package, I was wondering if there isn't a way to u=

0 new messages