Interest in strict unit style typing for physics/science calculations

Is there any interest in a library that performs strict type checking on values with unit quantities? The intent is to prevent operation and assigment of unlike types. For example, if A is in meters/second, and B is in seconds: -A * B results in a value with "meters" units -A / B results in a value with "meters/seconds^2" -A = B results in an exception due to a mismatch The code I have so far supports arbitrary unit types via tokens, which have to be defined for a project. Some example code looks like (with several notation options): typedef UnitValue<float> uFloat; UnitType unit_m( 1 ); //define meters type UnitType unit_s( 2 ); //define seconds type uFloat time( unit_s ); time = unit_s( 3.0f ); //3 seconds uFloat speed( unit_m / unit_s ); speed = 15 * speed.Type(); //set speed of 15m/s uFloat accel( unit_m / unit_s / unit_s ); accel = speed / time; //results in 5m/s^2 accel = speed; //throws exception, m/s != m/s^2 time = accel; //throws exception, s != m/s^2 The library has a price for performance compared to native value operations. However, part of the requirements will be a flag (a #define ) that turns off the unit processing for the code, which effectively removes the classes (replaces the UnitValue simply with typedefs of the stored type). -- edA-qa mort-ora-y Idea Architect http://disemia.com/

"edA-qa mort-ora-y" <eda-qa@disemia.com> wrote
Is there any interest in a library that performs strict type checking on values with unit quantities? The intent is to prevent operation and assigment of unlike types.
Could take a look here: http://www.servocomm.freeserve.co.uk/Cpp/physical_quantity/index.html
The library has a price for performance compared to native value operations. However, part of the requirements will be a flag (a #define ) that turns off the unit processing for the code, which effectively removes the classes (replaces the UnitValue simply with typedefs of the stored type).
This is doable in my library at the above link. (However problems would start to arise if you need prefixed or incoherent units.) regards Andy Little

Andy Little wrote:
Could take a look here: http://www.servocomm.freeserve.co.uk/Cpp/physical_quantity/index.html
A few questions about your library: -How does one represent non-whole dimensions (such as m^1/2)? -How do I add new dimensions (different types)? -Will it work with non-fundamental/user-defined types, such as complex? -Is it possible to automatically determine the type of a calculation? That is, I want to declare q as the type of whatever a * b / c is? It seems like a really functional library, accomplishing its task at compile time (what I had hoped for in my code). Though it seems extremely bulky and takes a while to compile.
This is doable in my library at the above link. (However problems would start to arise if you need prefixed or incoherent
By doable, what do you mean? It is vitally important to my project that all this typing is turned off to allow the compiler to get a high-level of optimization. -- edA-qa mort-ora-y Idea Architect http://disemia.com/

"edA-qa" <edA-qa@disemia.com> wrote
A few questions about your library: -How does one represent non-whole dimensions (such as m^1/2)?
Firstly do note that this is an experimental library and as such things are changing from pqs-1-01-04- the version you have This affects the way new types are declared. The info here relates to pqs-1-01-04. (I hope to get the new version out within the month. but it is not entirely backward compatible.) Note too that the documentation on the site is newer and better than that included in the zip. So its worth looking at that in preference. for the particular case of m^1/2. You could declare it like this: typedef ct_quantity< double, abstract_identity< // name changing in pqs-2-00-01 abstract_pq< // name changing in pqs-200-01 length_pwr<1,2> //means dimension of length^1/2 > >, quantity_unit<> > meters_pwr0pt5; // whatever typedef name you require hence : int main() { meters_pwr0pt5 x(100); // ready to use. q_length::m len = x * x; len = power<2>(x); // as above x = power<1,2>(len); // means to power 1/2 } As it happens the length^1/2 is the easiest because many parameters default. The full blown template looks like this in pqs-1-01-04 typedef ct_quantity< double, // whatever value_type abstract_identity< abstract_pq< length_pwr<2,1>, // the exp of dimension of each base unit time_pwr<-3,1>, mass_pwr<1,1>, temperature_pwr<0,1>, current_pwr<-2,1>, substance_pwr<0,1>, intensity_pwr<0,1> >, auxiliary_tag<0> // can have different quantities of same dimension >, quantity_unit< coherent_exponent<3>, // eg 3 for km incoherent_multiplier<0> // 0 for coherent-quantity in pqs-1-01-04 BUT // for pqs 2-00-01 the incoherent multiplier template parameter mechanism // is changing too // pqs 2-00-01 adds another tag here too > > my_resistance; However as you appreciate declaring things this way is a daunting task, and there are better ways, which leads neatly to your next question...
-How do I add new dimensions (different types)?
I need to write the proper docs for this AND things are changing in the new version. So rather than explain this here I better get on with that part of the docs. I havent been happy with the the way things are handled as regards defining new types but have improved matters radically in pqs-2-00-01.
-Will it work with non-fundamental/user-defined types, such as complex?
Yes. For complex check in "pqs/complex/q_complex.hpp". Some examples and tests in "examples/complex_example.cpp". It only does the basic operations though, merely because of time reasons. Another thing to do. There is also some support of boost::numeric::interval. Example in "examples/interval_pq.cpp". I am working to make value_types yet more generic in the next version too.
-Is it possible to automatically determine the type of a calculation? That is, I want to declare q as the type of whatever a * b / c is?
Yes look here: http://www.servocomm.freeserve.co.uk/Cpp/physical_quantity/binary_operation.... which explains this. (binary_operation can be nested for more complex calcs) Note however that only anonymous-quantities can be declared (simply)this way, And as to what they are, again I need to write this up, but basically they are useful for temporaries in calculations
It seems like a really functional library, accomplishing its task at compile time (what I had hoped for in my code). Though it seems extremely bulky and takes a while to compile.
On the compile time issue. I agree absolutely, Its a pain. Compile times can be reduced somewhat by only including the headers from pqs/types for the particular quantities you want. (use the q_xxx_out.hpp versions if you require stream output.) On the bulkiness of the library. I am trying to address the issue with some success in pqs-2-00-01. Unfortunately there is a potentially infinite number of physical quantities. Much of the bulk is due to this.
This is doable in my library at the above link. (However problems would start to arise if you need prefixed or
incoherent
By doable, what do you mean? It is vitally important to my project that all this typing is turned off to allow the compiler to get a high-level of optimization.
Its doable If you dont require unit conversions, that is all lengths in meters, times in seconds etcetera. without prefixes. In that case merely create a header with a facsimile of the particular containers required. replacing the ct-quantity decl with a (say) double. e.g for length: namespace pqs{ struct q_length{ typedef double m; }; struct q_times{ typedef double s; }; etc } and you have the desired effect: q_length::m // is now just a double Of course if you do unit conversions from (say) meters to millimetres, you will get invalid results with this approach. Again this is doable by using a hybrid approach and doing all the conversions manually, but things do start to get ugly. However if you have an optimising compiler then I hope that (this and )the next version of pqs will give quite good results while leaving the checks in place. There is a lot of room for optimisation, but at this stage I am concentrating on the basics. And Yes I need to get on with the Docs too ! regards Andy Little
participants (3)
-
Andy Little
-
edA-qa
-
edA-qa mort-ora-y