Boost logo

Boost :

From: Matthias Schabel (boost_at_[hidden])
Date: 2007-02-13 14:59:34


> Well, I should say in our case it didn't. You end up with several
> large
> functions with long lists of case statements and then separately,
> somewhere, a list of conversion factors. In this case we are talking
> about a static unit converter somewhere, and correct me if I'm
> wrong but
> I think they are in several different tables...not just tables for
> each
> dimension you will be doing conversions in but in different "systems".

At the risk of repeating myself, I would just like to point out that
this library
is primarily intended as a dimensional analysis library to ensure
correctness,
not a general purpose runtime unit conversion library. That being
said, I
have attempted to make the conversion architecture as flexible as
possible;
by appropriately specializing

template<class System1,class Dim1,
                 class System2,class Dim2,
                 class Y>
class conversion_helper< quantity<unit<System1,Dim1>,Y>,
                                                 quantity<unit<System2,Dim2>,Y> >

you should be able to get just about any unit conversion behavior you
want.
Default behavior is to only allow explicit unit conversions, but
implicit
conversion can be optionally enabled. I happen to implement conversions
for SI and CGS units using forward and backward tables, which entails
defining a conversion factor from SI->CGS and a conversion factor from
CGS->SI for each fundamental unit, but nothing in the library mandates
this design choice. You can roll your own to do just about anything...

> there are of course only a few dimensions we do this in. I have a
> hard
> time seeing a situation in which this isn't the way you would want
> to go
> about it.

Imagine I want to compute the electrostatic force between two charged
particles;
the equation for this depends on the unit system you are using. In
SI, the expression
is

F = (1/4 pi epsilon_0) q1 q2 / r12^2

in electrostatic units, this is

F = q1 q2 / r12^2

Imagine I want to write a function that computes this for a
computationally intensive
multi-body simulation where the function is called millions or
billions of times. With
mcs::units, you can just do this:

quantity<si::force>
electrostatic_force(const quantity<si::charge>& q1,
                                  const quantity<si::charge>& q2,
                                  const quantity<si::length>& r12)
{
        static const double k_C = 1.0/(4.0*pi*si::constants::epsilon_0);

        return k_C*q1*q2/(r12*r12);
}

quantity<esu::force>
electrostatic_force(const quantity<esu::charge>& q1,
                                  const quantity<esu::charge>& q2,
                                  const quantity<esu::length>& r12)
{
        return q1*q2/(r12*r12);
}

Note that there is no runtime overhead, and, more importantly, we can
select the
appropriate equation at compile-time. In this case, this is not just
a semantic advantage;
doing the calculation in SI units incurs an additional multiply for
each function invocation.
With runtime units, you would have to check the unit system each time
the function was
called - bad for simulation work.

Cheers,

Matthias


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