Boost logo

Boost :

From: Matthias Schabel (boost_at_[hidden])
Date: 2003-12-11 11:29:01


>> nobody to make suggestions here, but I just thought that you and
>> Matthias
>> Schabel could team-up: He appears to be ahead in code, but behind in
>> docs; you appear to be behind in code but ahead in docs ... ;-)
>
> Hmm .. if your suggesting I document his code for him... no thanks ;-)

C'mon - it'll be easy...

> The MPL lists are impressive to a non MPL guru.... but.... The
> effect on
> compile time is not. I am all for MPL etc but
> limiting it to where it is absolutely necessary... seems prudent to me.
> However that is an implementation thing...

Since comparisons seem to be inevitable : my rationale for using MPL is
that it allows me to implement a fully extensible and flexible
architecture which makes no decisions of policy for the user. That is,
the SI units model is really not special as far as the library goes, so
a user can easily define their own model which may or may not represent
physical quantities at all and still gain all the benefits of
dimensional analysis. As far as I can see, your implementation has the
same deficiencies as the original one from Barton and Nackman's book
and SIUnits - namely the fixed dependence on an anointed set of base
units. If you follow previous threads on this topic here, a recurring
theme is the need to be able to define non-physical units and have them
propagate properly. If the programmer wants to make sure they don't
put a bushels_of_apples quantity where they actually want
bushels_of_pomegranates, my library makes it relatively easy to do and
has nothing to say about this being a "legitimate" thing to do.
Clearly, some people may want to consider measures of angle as a unit
and others may not. In my code you have the flexibility to do that.

> The major problem to me is the
> syntax:
> (Yanl2 "test_units.cpp",line 194)
> SI<double>::Temperature T = (273.+37.)*_kelvin;
> SI<double>::Pressure P = 1.01325e5*_pascals;
> SI<double>::Length r = 0.5e-6*_meters;

> So units are always required... make them part of the type:
> pq_velocity<double>::m_div_s v1(2);
> now with a shorter version , wrapping a double value_type:
> q_velocity::m_div_s v1(2);
> q_mass::e effectiveMass(1.05);
> q_velocity::m_div_s fast(10000);
> No calcs involved in the ctor and the code documents itself.

My problems with your syntax are as follows :

1) you are committing to using a particular unit system at the outset
and spreading that committment throughout your code. In my library, if
I want to write some code using SI units and want to be safe about it,
I can do this :

typedef SI<double> unit_system;

unit_system::Velocity v1(2.*_meters/_second);

If at some later time a future programmer needs to use the code but
with CGS units, all that needs to be done is to change the typedef.
The constructor will then make the conversion if necessary and the code
will remain correct with a single line change. I don't see how you
would accomplish something like this with your design. After you've
gone through and changed all the m_div_s to cm_div_s, you still need to
manually make a conversion in the constructor to account for the change
in unit system, which is obviously dangerous. Furthermore, while the
expressions like 2.*_meters/_second appear to involve calculations, if
you look at the underlying code you'll see that _meters and _second are
both DimensionedUnit types which have the trivial constructor { } and
require no runtime ops to perform the multiplication as it is all
strictly type computation. I don't believe that you honestly think
that my syntax is less self-documenting than yours.

2) How would you write a function in your model which correctly
computes the work for any combination of a force and a distance?
Here's my implementation, which will work correctly with any unit
model, existing or future :

template<class Y,class Model1,class Model2,class Model3>
DimensionedQuantity<Y,DimensionedUnit<Model3,energy_type> >
work(DimensionedQuantity<Y,DimensionedUnit<Model1,force_type> > F,
      DimensionedQuantity<Y,DimensionedUnit<Model2,length_type> > dx)
{
     return DimensionedQuantity<Y,DimensionedUnit<Model3,force_type>
>(F)*
              DimensionedQuantity<Y,DimensionedUnit<Model3,length_type> >(dx);
}

3) Your model does not allow for extensibility.

> Further differences with Yanl
> Dimensionless quantities are inbuilt types. If you make a separate
> dimensionless type with
> an operator value_type,( my original code did this) something
> somewhere will
> trap. I cant remember specific situations,
> but I think there are some where no conversions are considered.
> template
> ctors???

I don't understand what you're talking about at all. If a quantity is
dimensionless, there are no relevant conversions as it no longer
belongs to any particular unit system.

> Best way to avoid the problem is just never to construct a
> dimensionless
> type... its unneccessary

As I've stated in the past, if you want to be able to differentiate the
result of some type computation which results in a dimensionless value,
you need to have a distinct type. Since my dimensionless_type is
implicitly convertible to the underlying value type, it behaves like a
normal value if you don't care, but gives you the flexibility to
choose.

> Further.. angles...
> Again tried various things. My conclusion is they should be a separate
> type. They are useful on their own
> so shouldnt be dependent on pqs..
> (The S.I. policy of incorporatiing of radians into its base units
> is I
> think
> a red herring. However pqs-1-00-01 acknowledges the great debt to the
> SI

You're quite dismissive of an institution that has been working on the
question of units and their representation for 150 years. I think you
should read their documentation more carefully; it's quite clear that
radians are a part of the SI unit system, whether you think they should
be or not. Anyway, my system doesn't mandate their use. If you never
use _radians in your code, it doesn't appear and you incur no overhead.

> I will say though that the physical-quantities types is primarily
> about ease
> of use not performance.
> Its designed from a programmer-users point of view.. I hope.

Performance is the _entire_ point of this exercise. If you can't stick
to zero-overhead, a units system will never be adopted. The vast
majority of people working in modeling of physical systems have zero
excess CPU cycles to waste. If this weren't the case, it would be
vastly easier to implement a runtime unit class.

Matthias

------------------------------------------------------------------------
---------------------------
Matthias Schabel, Ph.D.
Utah Center for Advanced Imaging Research
729 Arapeen Drive
Salt Lake City, UT 84108
801-587-9413 (work)
801-585-3592 (fax)
801-706-5760 (cell)
801-484-0811 (home)
mschabel at ucair med utah edu


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