Boost logo

Boost :

From: Terje Slettebø (tslettebo_at_[hidden])
Date: 2003-04-27 12:37:17


>From: <renej_at_[hidden]>

> >>From: <renej_at_[hidden]>
> >
> > There's another question. If we add angle as a dimension, then what
> > kind of angle is it? There are several kinds of angles, such as radians
> > (plane angle) and steradians (solid angle). If both were represented by
> > the same angle dimension, then it probably wouldn't make much sense to
> > add radians and steradians (and what would be the resulting quantity?),
> > yet, the library would allow it.
>
> in our implementation (plane) angle is sufficient, so we don't bother
> with solid angle for the moment. However, I think it should have it's
> own dimension since steradian != radian^2 (although m^2/m^2 = (m/m)^2 ;-)
>
> but I think a unit library would reach a much broader audience if it
allows
> to choose what dimensions are handled and how. For my application field
> it is necessary to incorporate everything related to robotics (time,
> length, angle, charge, mass), but temp, luminious intensity, amount of
> substance not really. I think it would be nice to be able to select only
> those you need in a unit lib and add your own "dimensions" if needed

That would typically also make it more complicated to implement, than a
library with a fixed set of dimensions, and fixed rules for their
interaction.

About a year ago, I experimented some with a very general SI unit library
implementation, as part of the ACCU mentored-developers SI units project
(http://homepage.ntlworld.com/mark.easterbrook/mentored/) (hence my
interested in this thread, besides general interest in science. :) ).

At the time, I had quite recently read "Modern C++ Design", and thought
about making a library where the units are stored in typelists. :) That
would allow any number of units, and any units.

The issue is defining the rules for operations on the units, though. Also,
the following two units would be considered different (to use MPL, for
illustration):

mpl::list<kg<1>,m<1>,s<-2> > // kg * m / s^2 (newton)
mpl::list<m<1>,kg<1>,s<-2> >

simply because they are different types.

I used derivation between the elements in the typelist, and Loki's
DerivedToFront, to provide ordering, to make them equal. Then I had some
hairy metaprogramming routines which took two typelists, and computed a new
one, by adding or subtracting exponents of corresponding types in the two
lists. Note that in this case, the two lists may contain different numbers
and kinds of elements. Unless a policy is used to specify all dimensions for
all units. The latter would mean that you have to rewrite all the unit
definitions, if you add or change dimensions, though.

The reason this was done - rather than the more simple approach of using a
vector of integers (like the mentioned quantity<> template in my earlier
posting), fixed in length, which may then be easily manipulated - was to
provide flexibility with regard to the number and kinds of dimensions.

However, I then realised that all this metaprogramming complexity would
probably have quite a price, for more elaborate computations. It could
increase the compilation time, for a flexibility that might not be used.

Even with this flexibility, it still used the same rules for all units, so
it still wouldn't cope with e.g. currency conversions, as it would happily
multiply two USD's and give a USD^2. :)

If you instead just use a vector of integers, you get all the SI dimensions,
except that angle will be dimensionless. The question is whether it's worth
complicating a library, and possibly increase the compilation time quite a
bit, just to be able to treat something like angle as a separate dimension.

Even if angle is added as a dimension, to an implementation using an integer
vector, it still wouldn't accommodate any other dimensions added later,
without rewriting the library and unit definitions.

Regards,

Terje


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