Boost logo

Boost :

From: Geoff Leyland (gley001_at_[hidden])
Date: 2003-11-04 16:23:03


Sorry to arrive in this discussion so late - I've tried to read all the
discussion up till now, but I may have missed some.

A long time ago I also implemented a dimensions and units library that
was principally for run-time checking.
This isn't useful for much of the code, as dimension checking at
run-time has quite an overhead, it was to deal with outputting and
particularly inputting quantities with dimensions and units.

Like what Mattias suggested, the concepts of "dimension" (M, L, T,
luminance...) were separate from units (feet, metres...) and a
dimensioned quantity. I wrote a small parser (at the time in ANTLR)
that could read in a dimensions and units definition file, and could
also read in a quantities with units. The units definition file went
something like

dimension length;
m = 1 * length;
cm = m / 100;
inch = cm * 2.54;

and so on, so you could effectively choose the unit that was the base
unit of each dimension.

I then started to work on a compile time dimension library, the
ultimate goal being that you could do something like

run_time_dimensioned_quantity<double> rt_torque;
cin >> rt_torque; // the input from cin might be in Nm, N*m, ft*lbf,
kg * m^2 / s^2
                                                        // torque is marked as a value with a dimension of mass * length
^2 * time ^-2
                                                        // OR torque might have the wrong dimensions and be, say m/s
compile_time_dimensioned_quantity<double, 1, 2, -2> ct_torque;
ct_torque = rt_torque; // will throw an exception of rt_torque
doesn't have the right dimensions

(the names of the objects were less wordy than what I've used above,
and I can't remember how I defined the compile time dimensions - this
was long before mpl - around the time that blitz first appeared)

I was working with fluid properties at the time, and the dispatch
possibilities of compile time dimensions appealed, ie instead of

gas steam;
double P = 101.4, T = 200.0; // what are the units???
steam.set_PT(P, T);

to set the fluid state based on the P, T point, you could go

gas steam;
compile_time_pressure P = 101.4 * kPa;
compile_time_temperature T = 200.0 * degC;
steam.set_state(P, T);

and ultimately, some kind of dynamic dispatch would be really cool:

gas steam;
run_time_dimensioned_value a, b;
cout << "What's the first thermodynamic variable?"; // user types "22
inHg"
cin >> a;
cout << "What's the second thermodynamic variable?"; // user types "500
F"
cin >> b;
steam.set_state(a, b);

Unfortunately, progress was arrested by more pressing needs (finishing
the damn PhD).

The code is pretty old, and contains strange "optimisations" that I
needed to get the compiler of the time to eat it, so I don't know if
its much use. I did use the run-time part for quite a long time in my
last job, so it does work (or did, with an old version of Metrowerks)

If anyone wants to have a look at the code I'd be more than happy do
dig it out and send it to them (I don't have a server I can easily put
it on at the moment). I'm not sure that it would be much use, given
its age, and that I'm not sure when I'll find time to work on it, but I
do think that having an integrated run-time (ie i/o) and compile time
units and dimension checking system would be great.

On another note, it seems to me that uncertainty propagation is a
completely separate issue from dimensions and units (though a no less
interesting one). I can't think of many cases though where you're not
going to end up needing monte-carlo simulation or importance sampling
for anything but very restrictive assumptions.

cheers,
goof


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk