axiom-developer
[Top][All Lists]

## Re: [Axiom-developer] Unit package proposals and questions

 From: William Sit Subject: Re: [Axiom-developer] Unit package proposals and questions Date: Tue, 06 Sep 2005 07:35:56 -0400

```I have snipped without indication, a lot of the paragraphs that we agreed on.

C Y wrote:
>
> On Sunday 04 September 2005 01:22 am, William Sit wrote:
> > ------------ Basics of the Proposal: UnitSystem domain specifications

> > C Y wrote:
> > > I don't quite understand s:S
> > In the setDimUnit, 'setDimUnit' commands, an expression s:S is involved,
> > where S is a domain that usually contains symbols ("RetractableTo Symbol"
> > in Axiom jargon) and s:S means s is such an expression.
>
> OK.  So in words, s is some specific symbol defined in the domain S.

s does not have to be a symbol, it may be an expression involving several
symbols even though that maybe a bit "dangerous" and unusual. This allows the
user who knows what he is doing to use what is known as an aggregate variable.
Aggregate variables are used to simplify the number of variables in an equation
and often very useful to understanding the interdependencies of variables,
reducing the equation into a dimensionless form, or to a linear relationship
between two aggregate variables. However, not all aggregate variables are
dimensionless. The ideal gas law is such an (simple) example: PV/T = constant;
so PV/T is an aggregate variable. The ideal gas law can also be put into the
form PV = cT, where c is the constant. Using PV as an aggregate variable, it is
proportional to T (and how coincidental, of reduced dimension Force*Length again
and unit for example, liter-atm, and the constant c is not dimensionless.)

> I think I've got it - so there are three levels:
>
> a)  change properties within a single expression, don't change global settings
> b)  change global settings for one dimension, but not for other dimensions
> building off of this one
> c)  change global settings for ALL dimensions using this dimension - e.g. the
> default rendering for force would become kg*cm/s^2 if
> setUnitAll("Length","cm") were used.

That is right.

> So let's say I define some examples (sorry, I'm not up enough on Axiom syntax
> yet to use it for this) would this be roughly how things would work?:

Your example below is basically the correct scenario. The syntax and output need
some changes, given next. I added sequence numbers.

> a::Length
> b::Length
> c::Force

Since Length, Force, etc are not domains in my proposed setup, you cannot use
the coercion symbol ::. Assuming you started with SI, you would have to replace
the above three lines by:

->(1) ua:=setDim("Length",a)

a [m]

Note that the unit is output using a pair of brackets, to avoid confusing it
with a variable m, perhaps. Also, the type of ua is now SIUnitSystem(S), if the
type of a is S.

->(2) ub:= setDim("Length", b)

b [m]

->(3) uc:= setDim("Force",c)

c [kg-m/s^2]  or [N]

> (4) setDimUnit("Length","cm", a)

This would have the following output:

a [cm]

Note that no conversion factor is used, since the expression a is entered
afresh. The two identifiers a and ua are of different types. This suggests that
we should add a new signature:

setDimUnit:(Dimension, Unit, %) -> %

so that

-> (4)' ua:=setDimUnit("Length","cm",ua)

a m2cm [cm]

> (5) setUnit("Length","m")

This would set all declared expressions of dimension Length to use [m] as unit.
Whether this is done retroactively or not is a design issue. We can provide both

> (6) setUnit("Force"", "N")

Same, all expression of dimension Force use N as unit.

>
> -> (7) a
>                      a  cm                [Length]

No: The use of 'a' will only return 'a', not 'a' with a unit. To get the unit,
you have to use:

-> (7)' ua

Assuming the setUnit does not change expressions already declared when (5) is
run, then

a m2cm [cm]  (same as (4)') assuming (4)' is run instead of (4).

Assuming the setUnit changes expressions retroactively when (5) is run, then

a m2cm cm2m [m], or smarter: a [m] (again, if (4)' is run)

> -> (8)  b
>                      b  m                  [Length]

No: Same as (7): would return just b, without unit.

-> (8)' ub

b [m]

since (5) does not affect ub no matter what the design is.

> -> (9) c
>                      c  N                  [Force]

No: Same as (7), will return c without unit.

-> (9)' uc
c [N]

since (6) has no effect on uc.

> (10) setUnitAll("Length","km")

This will affect all dimensions involving Length as a component. Whether this
will apply to expressions retroactively or not is a design issue. We can provide
both options with an added parameter.

> -> (11) a
>                      a cm2km  km        [Length]  (or would this stay as cm?)

-> (11)' ua

The expression a was in [cm] or [m] depending on design (see (7)). Assuming you
meant ua instead of 'a' in (11), your output assumes that no retroactive update
in (5) but retroactive update in (10). There are four possibilities already.

> -> (12) b
>                      b m2km  km         [Length]

(12)' ub
b m2km [km]

Assume you meant (11)'. Your answer assumes the unit of b is retroactively
updated to [km] when (10) ran.
Otherwise, the Interpreter has no reason to call the unit system package.

> -> (13) c
>                      c m2km  kg km / s^2     [Force]  (with better formatting)

-> (13)' uc
c m2km [kg.km/s^2]

This also assumes the unit of c is retroactively updated in (10).

>
> (14) setUnitAll("Time", "millisecond")
>
> -> (15) c
>               c m2km s2ms^-2  kg km / ms^2     [Force]

-> (15)' uc
c m2km s2ms^(-2)  [kg.km/ms^2]

Assuming (13)' and the unit of c is retroactively updated in (14).

> > ---------- Implementation issues: Updating variables and their units
> >
> > Some updating questions are raised and solutions suggested in the Scenario
> > Example section above.
> >
> > > As for current variables, shouldn't they be updated automatically by
> > > the global update?
> >
> > That is the idea. That is, a 'setUnitAll(dim, u)' command will change all
> > output and input variables/expressions that are of dimension dim to use
> > unit u. In the scenario Example section, we discussed the issues and some
> > possible actions. The basic design question to decide is: should this
> > global command affect only newer variables/expressions or should this
> > retroactively set all existing variables/expressions? The basic
> > implementation question is: what data structures will support these
> > functionalities efficiently (bear in mind some trade offs between memory
> > and CPU time, as usual)? It seems the proposed state-vector can support the
> > implementation, whatever the decisions.
>
> I think I would vote for retroactively setting all non-derived unit using
> instances, with perhaps another command to make this change without updating
> previous instances.  (How about setUnit is retroactive and changeUnit is from
> this point forward?)

Trouble is, neither the word "change" nor "set" provides a definite meaning. So
I think it is better that setUnit or setUnitAll will change all instances
retroactively.  As I already warned, just like when the unit of a single
expression is changed (the setDimUnit, either version), the other alternative,
changing only future instances will give rise to mixed units and a subsequent
computation involving mixed units must be brought to a common unit system. What
would be the unit of the result? I suppose the only meaningful unit is to the
system's unit in the state vector. Thus, by making changes retroactively at the
time a setUnit or setUnitAll is run, we bring the system back to uniformity
earlier and hence subsequent computations are more efficient. Lazy evaluation
does not pay if there are lots of subsequent computations, requiring conversion
for each quantity involved, and with no place to hold the changes.

> Not quite - N is force.  That was a mistake on my part - I meant something
> like setUnits(g,N,inches).  The above should have (and does, in Maxima)
> return an error.
> In Maxima, I think this works as a global setting (retroactive) of all
> non-derived instances of a dimension to a new length - essentially the same
> as doing
>
> setUnit("Mass","g")
> setUnit("Force","N")
> setUnit("Length","Inches")
>
> but letting Axiom figure out that g is a unit of Mass, N is a unit of Force,
> and Inches is a unit of Length.

I see, you want to set the units for multiple dimensions in one statement. We
can do that easily by allowing:

setUnits: (List Dimension, List Unit) -> Null (or state-vector)

> > And, yes, users should know the dimension of the unit they are inputting.
> > One danger with something like 'setAll(u)',  which left out the dimension
> > for u, is that a simple typo say from 'setAll(cm^2)' to 'setAll(cm^3)'
> > would not be caught and play havoc in subsequent computations. Forcing the
> > user to give the intended dimension provides a better chance that these
> > errors will be caught.
>
> I agree - I would like to have a "strict" mode available which compels the
> user to do this.  I fear making it the ONLY alternative will lose us users
> though.

By "us" you meant "USA"? I always remind my students the probe crashed on Mars
was due to mixing up (or unaware of the mix up) units. I don't think user would
mind including the dimension when setting units. It does help prevent typos from
passing through.

> Yes, I think we might want to do something like that - it would allow (or
> would it?) the possibility of a UnitConversion category with domains for
> PhysicalUnits, ComputerUnits, EconomicUnits, etc.

That is the idea. However, there is some technical difficulty that I do not yet
know how to solve, but I think it is doable:

UnitConversion(dim:List String, unit:List String):Category == ...

Trick is to convert dim and unit into arguments for the constructor Union so we
can form

Dimension:=Union(dim)  -- right now, syntax error
Unit:=Union(unit)

There must be a function in Axiom to do that. I just don't know. Here Union is
expecting a tuple of domains. In Union("Mass", ...), the strings are magically
turned into domains.

> > As we don't know all the expert areas now in existence, nor do we know what
> > new derived dimension or unit we may need (especially in 30 years' time),
> > there is no way we can have such a universal toplevel hash table. We CAN
> > implement SI (all the default and acceptable dimensions and units) or even
> > more, but such a domain will need to be revised to allow newer dimensions
> > and units. The design proposed will allow this of course (any design in
> > fact), but I still subscribe to the older Axiom philosophy that we do not
> > modify existing libraries except for bugs, and extend existing libraries
> > through additional implementation. We should allow arbitrary UnitSystems
> > (as I also indicated in my last email, supermarket manager will need a
> > totally different, "non-scientific" unit system with dimensions like
> > "Coke", "DietCoke", etc.)
>
> I agree.  I'm really curious to see if something like this ever gets used in
> such an application :-).

As long as they are doing only number crunching, they won't need it. But if they
have to solve for the optimal re-stock inventory strategy to minimize cost or
maximize profits, they may need symbolic computation.

> > ---------- Implementation Issues: Setting up Dimension and Unit domains

> How about we allow the mapping to go through when it IS unique, and return an
> error or ask a question if it isn't (something like provide a list of
> options, and ask the user to select one)?  (Maxima has the ability to ask
> questions of the user if it needs to - it makes some problems MUCH easier to
> solve.)  This is helpful and friendly to the user while still being fully
> correct.

To a certain extent, that can be done. We discussed that already. However, Axiom
does not seem to have the ability to ask questions of the user as far as I know.
The graphics package allows mouse selection and controlling using the mouse, so
I suppose that is a form of asking user input. But the Interpreter interface
does not even support the mouse. (Anyone wants to pick up this challenge?)

> > However, the problem still
> > is: given some unit in reduced basic dimensions such as
> > (mass-length/time^2).length, say kg.m^2/s^2, we do not know if the
> > dimension should be Energy (either Work or Kinetic Energy or Potential
> > Energy) or Moment. Vectorizing some of these dimensions may help: Work is a
> > force vector times a length vector, and so is moment, but the two length
> > vectors have different directions with respect to the direction of the
> > forces.
>
> Woo boy.  That's going to be a challenge to report - direction of length
> vector as a factor in results.  Actually, that's an interesting question -
> two length vectors may have different components, but the same magnitude.
> Does the unit meter represent merely the magnitude, or the vector information
> as well?

The Length units are scalar units. Magnitudes are not necessarily length but
they are also scalars. Vectors are given by its scalar components. Directions
are given by unit vectors, usually in terms of directional cosines.
There are formulae in standard coordinate geometry texts to compute projections
of a vector in any direction (by using the dot product).

> How do we represent vector information if we want to preserve it
> through the process of reducing dimensions?  The Work vs. Moment example
> would seem to argue that vector information and Dimensions can't really be
> separated, but I don't really know if I'm interperting that right.

That is right. Well, like it or not, physicists use lots of vectors and a unit
system should really support vectors. This can be done componentwise, but the
system has to be aware of how to obtain derived units when vector calculus is
applied! With symbolic computation, we can talk about vector functions,
differentiation, integration, etc and all these computations change the units
and dimensions.

The proposal allows a UnitSystem to be parametrized by a set S, and this set S
can be a set of vectors or vector functions. So when coding say SI(S), for
arbitrary S, one has to do cases when S has Vector, etc. Hehe, may be you can
get a ph d for this project!

>
> > --------- User environment for Unit systems: Static vs Dynamic
>
> > Also a user can save the history of all inputs,
> > including all 'set' commands (and also ')set' commands) and put them in
> > axiom.input or a 'myunitmod.input' and read it in anytime. There is no
> > need, in this dynamic design, to modify ANY compiled domain in the
> > UnitSystem category. When a user wants to have modification compiled into a
> > modSI domain, he will have to edit the SI.spad.pamphlet and change it into
> > modSI.spad.pamphlet and compile it. However, I don't see the necessity.
> > 'SaveUnitSystem(<newUnitSystemName>) is difficult (but not impossible) to
> > implement and involves automatically editing say SI.spad.pamphlet to
> > modSI.spad.pamphlet and automatically compiling it. It is trivial for a
>
> Actually, that was more my idea - have the saveUnitSystem command pick out all
> the most recent inputs that set the UnitSystem environment, and save them to
> a file.  The trouble is to pick out such commands, which was why I thought it
> might be simpler just to diff the "current" environment from the "default"
> environment and autogenerate the minimum set of commands to get from a to b.

Well, the setUnit and setUnitAll commands can be tracked by the UnitSystem
domain, and hence all it takes is to report the state-vector at the end of the
session, or just to save the state-vector and reload it in the next session. Not
a big deal.

> > --------------- Name space issues
> >
> > > (I'm still
> > > plotting to allow the user to gobble up all the unit names in the
> > > default namespace at their option, and that will DEFINITELY need
> > > interpreter work.
> >
> > As you know, I am strongly against "gobbling up all the unit names in the
> > default namespace' even if it is 'at their option'.  If you are seriously
> > thinking about student use, you know the average students will exercise
> > their options without knowing or understanding what they are doing. There
> > is no way to consistently reserve SOME unit names in namespace, and not
> > others. Any code to implement this will have to know the reserved names a
> > priori and that means ALL the abbreviations in SI units at a minimum.
>
> Right.  Reserving some would be worse than none, because it would be
> inconsistent.
>
> > You  would have created a nightmare in using the interpreter by requiring
> > users  to avoid any SI unit abbreviations as user variables. No computer
> > language  ever has that many reserved words. Note: Axiom function names
> > are NOT  reserved, but constructor (which may be category, domain or
> > package) names and their abbreviations are.
>
> If we were talking about a normal computer language, I agree.  However, in
> normal scientific usage, proper definition and use of equations should NOT
> use SI abbreviations as variables.  Doing so creates far too much potential
> for misinterpreting said variables later on.

That is true, but we are talking about computing. In normal scientific use, most
symbolic derivations or equations do not use units. The symbols do carry units
occasionally, but equations never include units. An equation is always an
equality for values, and homogeneous in dimension (which is not stated
explicitly). So the chance of seeing something like m m (for m meter) is small.

> I grant that your proposed
> system has a far better chance than any I have ever seen or heard of of
> making this workable, by being able to separate out m the variable and m the
> unit in the output even if they look the same to the human eye - e.g.:
>
> (1)-> 3*setUnit("Length","m","m")
>
>                                           3m m
>                                                                      [Length]

This works, if you give the right syntax:

-> (1)'    3*setUnit("Length","m",m)

3m [m]

> If this can actually function, then I am for it because it would be a
> virtually ideal solution, and it is more general in case other, non-physical
> unit cases need that generality.

> > There is perhaps one way to use variables (instead of strings) for
> > dimensions and units, but they will be local to the domain (using domain
> > namespace, rather than user namespace) and they will not be assigned any
> > value. The advantage over strings is that they can be used to perform
> > arithmetic operations of multiplication and division as symbols. Then
> > general conversion factors can be computed by setting up a small number of
> > conversion rules and by solving an equation.
>
> I'm beginning to see how this might work - visually speaking though, it hinges
> on the robustness of Axiom's separating units and non-units in output.  I
> think Axiom might be able to do this in a way most other systems couldn't (at
> least not without a lot more work).

Yes, that is probably much harder than providing arithmetic on strings. Besides,
we only need to provide multiplication and division. But I think it is doable in
Axiom. These local variables are not really visible to the Interpreter user
directly. The user may still have to use setDimUnit, setUnit, etc. The
separation is via the Rep already and the output can turn them into strings. The
problem is they are still symbols and so still restricts the namespace of the
domain, but that is much better than user namespace because the author for the
domain can avoid any potential conflict. The danger is in future updates of the
code;  the person updating may not be careful enough to avoid the reserved names
(like adding some units that turn out to be one of the local variables). Strings
avoid the problem altogether.

> > ---------- Implementation Issue: Simplification of dimensions

> > Perhaps we can add a field to Rep that gives the reduced dimension as well?
> > or provide a function
> >
> >   reduce: Dimension->Dimension
> >
> > (which in any case, will be useful and necessary).
>
> Yes, I think so.  Is the concept of reduced dimension defined anywhere?

I am not a historian. This can't be a new concept, but may or may not have been
formalized. May be the book "Theory of Dimensions" had it.

> > Whether any such references will help us develop the rules to simplify
> > dimensions, I don't know. From what we have discussed, it seems any rule
> > will need some expert knowledge (in the example I gave, the expert
> > knowledge is simply what pressure is). So I believe the best solution may
> > be to "leave it to the users", and let them create their own names and
> > simplification rules.
>
> Sounds good. How about as good setups are created we merge them into Axiom?
> Perhaps Axiom will become the central repository for advanced unit
> interaction rules, as people build off of the (hopefully) sound foundation of
> Axiom?

That will be goal.

> Without doubt scientific units will be the most useful in the short term.
> Building scientific symbolic computing on top of Axiom is going to require,
> as near as I can tell, three things:
>
> a)  the concepts of Dimensions and Units (underway)

Good.

> b)  Significant Digits, Uncertainty in Measurement, and Error propagation
> (hard, both in itself and also since potential errors due to the numerical
> calculations of the computer must also be considered in order to be rigorous)

This is a totally different domain, involving interval arithmetic, for example.
I don't know what error analysis packages or numerical packages have been
implemented in Axiom. While they are important, I suspect most people are so
used to very high precision computations they ignore to the accuracy of the raw
data.

> c)  Domains of significance.  I don't know what else to call this, but as an
> illustration, we know that Newton's laws of motion break down near the speed
> of light.  Science generally gets on with life by neglecting Einstein type
> effects at velocities which are low compared to c, since any possible
> contribution due to those effects is washed out and below any significant
> level of measurement possible.  So, let's say we input the fully general
> equations into Axiom for motion, velocity, etc. since we like generality.
> However, for sufficiently small velocities (or more correctly, sufficiently
> imprecise) measurements, we want to use Newton's equations, even
> symbolically.  They should (and do) simplify in the limit, and we want Axiom
> to be able to understand or even figure out such things on request, since
> such information is very useful to practical work.  Plus, it would be an
> awesome way to build intuition on when things matter.  The problem is, there
> would need to be a definition given for sufficiently imprecise.  Either
> deduced from supplied measurement uncertainties (and it should deduce them if
> it can since the human probably can't be relied on for this) or supplied in
> purely symbolic situations.  I have no idea how  to express this idea in
> Axiom, if it can even be done, but it would provide an absolutely incredible
> and powerful tool for using the right  equation given the data.
>
> OK, enough pie in the sky talk :-)

That what I think it is! I guess such generality will only be useful to those
who work in the area of transition between Newtonian and Quantum (don't even
know if that make sense). Maybe you are dreaming of the grand unification theory
and implementing that in Axiom?

> Night all, and thanks William as always
> for your patient, helpful and amazingly powerful ideas and thoughts.  I hope
> mine aren't being too tiresome - I think I'm finally beginning to see the
> light, although I'm afraid we might have a bit more than three set* commands
> when we get done.  (Derived Dimension simplification rules in SI will require
> a few more commands, based on my Maxima experience, and that didn't have
> anywhere near the flexibility this will have.)

You are welcome. Yes, there will be way more functions specified in the
UnitSystem category. We have discussed the may functions, but there will be
support functions, which are not too hard to implement and can be added quite
naturally.

I look forward to seeing this becoming a reality. It has been quite an
interesting discussion.

William

```