|
Boost : |
From: Andy Little (andy_at_[hidden])
Date: 2003-10-18 06:13:21
"Paul A. Bristow" <boost_at_[hidden]> wrote in message
news:AHEJIHEOOOBMJPAGPLIPAEDLEHAA.boost_at_hetp.u-net.com...
> | -----Original Message-----
> | From: boost-bounces_at_[hidden]
> | [mailto:boost-bounces_at_[hidden]]On Behalf Of Andy Little
> | Sent: Friday, October 17, 2003 3:48 AM
> | To: boost_at_[hidden]
> | Subject: [boost] Re: Physical Quantities revisited
> |
> | Unit conversion is a real problem now!
>
> Absolutely - and we need better tools to deal with them, but also to avoid
> serious mistakes in calculation which led, for the most spectacular
example, to
> the Mars Lander to be a Mars Crasher instead.
Have I missed something...? My code does this:
http://www.servocomm.freeserve.co.uk/Cpp/physical_quantity/index.html
The current discussion about
> Dimensional Analysis is primarily directed at this aspect, with emphasis
on
> near-zero run-time cost, something especially important to you embedders.
In the package the hard work involved in calculating a scaling is done once
only at first call:
line 289
http://www.servocomm.freeserve.co.uk/Cpp/physical_quantity/inc/PhysicalQuantityClassTemplate.h
note: source may change 18 10 03
The 'scale' variable is static, hence only computed on first call.
(non optimising VC 7 finds whether it has done the calc by flipping a bit
and checking it on entry.
Would be interesting to know what gcc does with it...?)
If you wanted to avoid that start up cost you could use a mesh
rather than a star mechanism for scaling and supply explicit constants for
scaling between each unit within a dimension and possibly each combination
which then runs to a large number
Add a unit and you will need to supply all the links. Possible and more
accurate but less convenient.
( On the other hand there may be a better solution to this ... within
current standard :-) )
Scaling between units at run time involves multiplication by a floating
point constant, where both units are the same this resolves to 1.0 .
For simplicity and bearing in mind that this is a demo, I have not added
specialisations for when both units are the same.( may do so this week to
check that there are no problems and stall this issue )
With that specialisation and if you limited yourself to one type of unit
then this package would be as efficient and accurate as other user defined
arith classes.
You will only pay for what you use.
>
> It is obviously essential that any units system works with any dimensional
> analysis system, something we haven't cracked yet.
My code is one solution. its cracked :-)
The examples discussed using a separate class, lists etc for the dimensions
may be useful If they help the user .
But its usually better to start off by doing it the hard way, especially if
you are not too sure what you are dealing with :-)
> Watch this space.
Meanwhile
> have fun with your package.
Ok.. Sadly though I suspect that you may pass reasonably close to where I
already am in some respects. You do seem to have dismissed my code quite
fast
There may be good reasons but it would be interesting to clarify what they
are ?
Firstly you have identified units conversion, which you agree is quite
important.
My code makes a reasonable go at this.
regards
Andy Little
andy_at_[hidden]
------------------
Included here some thoughts that came up on the DA topic...
1)
Dimensional analysis is of very limited functionality in computing terms,
unless applied to a physical quantity.
2)
Without units a physical quantity has no meaning... Units are intrinsic
to say, " I am travelling at 10", is without meaning.. hence this is
downright dangerous:
length myLength(10); // what is this entity ?
whereas to say "I am travelling at 10 metres per second", is meaningful.
pq_length::m myLength(10) ; // Ok well defined (using 'm' or
'metres' for readability could be argued )
The unit of a quantity is brief but practically defines the entity.
metres informs us we are dealing with a length and its units
metres per second informs us we are dealing with a velocity and so on.
Some PQ packages appear to tag the units onto the dimension..
The units are tightly associated with a dimension and need to be considered
as a whole .
C++ templates provide a good non-hierarchical binding mechanism.
3)
A gallon of petrol is an entity, with various properties one of which is its
volume.
Tip in a gallon of water and you have a mess but it has a volume of 2
gallons.
The volume may change as a function of temperature ... but it will still be
a volume
No need to "tag", use a class and add your pq as a member. add the material
as another member ... or what you will
4)
a dimensionless quantity is redundant so the following is fine in my book
(using the syntax I have used in my Physical Quantities demo
where this is achieved by specialising a dimensionless quantity. see:
line 64
http://www.servocomm.freeserve.co.uk/Cpp/physical_quantity/inc/PhysicalQuantityClassTemplate.h
note: source may change 18 10 03
pq_velocity::m_per_s v1(10);
pq_velocity::miles_per_hour v2(10);
float ratio = v1/v2; // ok internally applies scaling
//and returns a dimensionless quantity
//which is implicitly converted to
an inbuilt type.
In other words the C++ inbuilt types are equivalent to dimensionless
quantities.
5) Fractional dimensions
Could we have a real life example of this ?
6) logs
An example calc would help here too.
One I can think of is voltage across a diode, where voltage is a logarithmic
function of current.
Mathematicians help required .. Is the log function on something that has
dimensions or does it resolve to a dimensionless number?
If its dimensionless then it is no great problem... then need another
example :-)
----------------------------------------
Purpose of a Physical Quantities library.. Compile time messages at
developer level.
Having used the above mentioned demo it certainly shows that physical
quantities and dimensional analysis
are very good for showing the power of C++, however what is lacking and
possibly why , though there are many
libraries about, they tend to fade away when applied in a real situation, is
because of the error reporting provided by the compiler.
( Which is all this is about really... to spot DA errors)
Because of the high level of abstraction involved in template programming,
there would seem to me to be a lot of use for
some means of compile time error reporting that can be added by the
developer, way beyond CPP.
For instance I would much rather know that " the dimensional analysis at
line xxx is invalid"
than that "there is no conversion to.. or whatever the compiler delivers.
In my library for example it would be nice to be able to warn the user
about loss of accuracy when doing a conversion from say metres to feet, in a
similar way that most compilers do on inbuilt type conversions.
One way to achieve this relatively painlessly is by allowing the developer
to provide error output in an empty function whose sole purpose is to
trap the mistake, when the compiler sees function called in user code.The
example is too simplistic (generic constructors would do the job in my demo)
but hopefully demonstrates the idea:
e.g.
pq_mass::kg convert_to_Kilograms( pq_length::m const& len)
{
#compile-time-error "no conversion of a length to a mass"
}
pq_length::feet convert_to_feet( pq_length::m const& len)
{
#compile-time-warning "conversion of metres to feet, may lose floating
point accuracy in conversion"
... // ok user warned.. do the conv
return m;
}
Without this or something the package is interesting but rather confusing.
DA errors just get jumbled into the general error message scheme, hence this
could be user, library developer bug or anything. I think this is why PQ
libraries dont get used much... they dont do what they do very neatly
naturally this type of thing would be generally useful for developers
outside this context, perhaps boost has something on these lines?
Andy Little
andy_at_[hidden]
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk