Boost logo

Boost :

From: Andy Little (andy_at_[hidden])
Date: 2006-06-08 07:10:20


"Gerhard Wesp" wrote
> Sorry, I don't have the time to read the PQS documentation in-depth
> right now.
>
> Still, I'd like to make one suggestion.
>
> I think that handling of dimensional quantities and conversion factors
> are orthogonal concepts and should be separated.

They are in PQS. This is the distinction between abstract and concrete
quantities and units in the documentation. However in source code it is more
convenient to combine these elements in one type. This is the t1_quantity.
t1_quantity can be passed as a template parameter carrying all the dimension and
unit information with it. This is not possible with external constants or
doubles etc.

> I suggest that for maximum transparency the library should *exclusively*
> handle quantities expressed in SI units.

Unfortunately in everyday life non-si units crop up frequently.

> I'm aware that this "mildly forces" developers to adopt SI units. I
> consider this a Good Thing.

PQS tries to favour SI quantities over non SI ones. By using SI quantities
rather than non-SI ones, you will get faster and more accurate results for
example.

> Conversion factors between non-SI units and SI units should be constant
> dimensional quantities, e.g. (assuming constructors from double):
>
> const length foot = .3048 ; // Meter
> const power european_horse_power = 735.4987 ; // Watt
> const mass pound = 0.4535924; // Kilogram

In PQS the constants are encoded as template parameters as part of the type.
The unit defined in <boost/pqs/meta/unit.hpp> holds all the required
information.
Any mulltiplier is held as a rational. In the case of SI quantities the rational
evaluates to 1 and this means that the rational can be optimised out of the
calculation. Exponents are held as powers so multiplication of two si
Quantities only involves multiplying runtime values. Any multiplication of their
units is in fact addition of powers done at compile time. This makes for much
faster and more accurate calculations.

Consider the calculation 1 km * 1 millisecond.

The external units approach

1 * km * 1 * millisecond,
which expanding the constants would be

1 * 1000. * 1 * .001

In pqs the internal calculation at runtime is simply

1. * 1.

The type of the result encodes the calculation 1000 * .001 as plus<3,-3>::value
in the unit of the result.

In pqs the user doesnt have to remember or look up the 'magic constants' that
you describe below. This is an important point, because it means that quantities
and conversions are potentially more consistent and predictable across
applications.

> This way, one could e.g. construct dimensional quantities like this:
> const power deux_chevaux = 2 * european_horse_power;
>
> Non-SI quantities would have to stay "out of the system" in normal
> floating point variables:
>
> length altitude;
> double altitude_ft = altitude / foot;
>
> Ignoring dimensionality, this is the notation Mathematica chooses.
>
> I have done some engineering simulations, written a flight simulation
> framework and used one that uses US units (D6; see www.bihrle.com).

A goal of pqs is to be useable in that sort of situation. To be really effective
it will need a lot of supporting classes ( matrix, vector, quat) though.

>The
> D6 source code is riddled with magic constants. I've collected some
> conversion constants in units.h of cpp-lib, see
> http://gwesp.tx0.org/software/.

One function of pqs is to provide these constants for conversion in a consistent
way. It is of course possible to extract them from the headers without using the
rest of the library too.

regards
Andy Little


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