 # Boost :

From: Matthias Schabel (boost_at_[hidden])
Date: 2007-02-19 00:28:00

Hi Deane,

I know you're a smart guy, and I want to understand your view on this
stuff.
Here are a few definitions to simplify the discussion:

dimension - a set of rational powers of abstract measures (length,
time, mass...)
unit - a specific measure of a dimension (meters, hours, etc...)
quantity - a quantity of a unit (5.6 meters, 7 hours, etc...)

Let's consider the diffusion equation that you have mentioned on a
couple
of occasions, in 1D:

dU/dt = k d^2U/dx^2

Let's call the dimension associated with U D{U}, that with t D{t},
and that with
x D{x}. Then, for this to be dimensionally correct, the dimension of
k needs to
be :

D{k} = D{x}^2 / ( D{U} D{t} )

For heat conduction, U=temperature, t=time, x=distance, and k=thermal
diffusivity, but, as you point out, these could represent anything
you wanted.
Now, if you just wanted to perform dimensional analysis on this
equation to
determine, for example the correct dimension of k, it is a strictly
formal operation;
the next version will include runtime capability in the dimension<>
class to
allow operations like this:

const length_type x;
const temperature_type U;
const time_type t;

std::cout << pow<2>(x)/(U*t) << std::endl;

to get this output:

[L]^2 [T]^-1 [t]^-1

This is analogous to the computations done in the unit<> class, but
with no
associated unit system. However, if you actually want to compute a
numerical
value from this equation, you have to specify what unit you use to
measure
the various quantities. These units do not, of course, all have to
belong to any
specific unit system, but the value of the thermal diffusivity
constant, k, will
depend on the specific combination of units used. To be completely
concrete,
imagine that you have an experimental apparatus that consists of a
long, thin
metal bar that you are heating from one end, and you would like to
determine
the thermal diffusivity constant by regressing your measurements of the
temperature at some point along the bar as a function of time to the
theoretical
expression. To do this, you need a function that computes the
solution to this
equation as a function of t:

temperature
end_of_bar_temperature(time t,position x)
{
return some_function_depending_on_k(t,x);
}

However, the value of k depends on the units you use to measure times
and
temperatures, so, if you write this function to take any unit of
time, and output
any unit of temperature, within the function you need to compute the
value
of k for those particular units. To do that, you need to have a value
of k that
is defined for _some_ triple of length, time, and temperature units,
and you
need to decide how to choose what unit system you are going to use do
the
calculation (where unit system in this context means any triple of
length, time,
and temperature units - it could be SI or CGS, but could also be
furlongs,
hours, and Rankine if you wanted it to be). The point is that the
calculation
needs to be congruent with the unit system that the constant k is
defined in...

> But I don't want the user of the library to have to define a
> "system" of
> units just to use a function in the library. If there is, say, a
> function that takes a distance, a mass, and a time and does
> computations
> with them, the user should be able to feed into that function
> arbitrary
> units for each of the three without having to use the dimensions
> library
> to define a system first.

As far as I can see, there are only three options:

1) pure dimensional analysis, where you don't consider the units or any
numerical values, and just analyze dimensional correctness

2) choosing a particular unit system in which dimensional constants are
defined and computing in that system, with no unit conversions

3) accepting any combination of units with the correct dimensions, then
converting internally

> So the thing I didn't like in your version of my sample code is the
> need
> for a template parameter called "System".

I'm working with Steven Watanabe on a demo implementation of the library
that allows heterogeneous units from different systems to be mixed,
so each
dimension carries its own system information along with it. The main
problem
with this is that it these heterogeneous composite units make it
difficult to
define functions that are restricted at compile time to a specific
unit system.
With concept extensions to C++, it ought to be possible to mitigate
this issue,
but at the moment I don't see an easy way to get both features at the
same
time...

> I think in another post you yourself indicate how these
> defined-by-convention "systems" of units used by physicists cause some
> awkwardness, because a system might not define the units for
> momentum to
> be equal to the units of mass times the units of distance divided
> by the
> units of time, creating the need for extra conversions.

I don't understand what you're getting at here...

Matthias