
Hi, I have been continuing with my physical-quantities library over the last year, http://www.servocomm.freeserve.co.uk/Cpp/physical_quantity/index.html and I am now seeking feedback as to whether it is worth putting this forward as a boost library proposal.... *Overview* The physical-quantity type-family provides methods for modeling physical-quantities in C++ programs. The advantages and extra functionality over inbuilt types used in the role include, compile time dimensional-analysis checking, automatic conversion between units and an increase in source code comprehensibility. The type family includes two types, firstly a type where the units are fixed at compile-time referred to in the text as a ct-quantity and secondly a type where the units can be run-time modified, referred to in the text as an rt-quantity. The ct-quantity has many similar features to an inbuilt-type: - concrete type with simple,consistent semantics close to those of inbuilt-types. - aims for speed and code size performance close to that of in-built types. - requires no special framework to use. *Application areas* The application areas are very wide, including scientific-engineering, CAD, 3D games programming among many others. *Future directions* 2D and 3D vector quantities, scene-graphs and scene-modelling, Graphics interface (eg OpenGL), splines and curve analysis, successive approaximation , piecewise differentiation and integration algorithms. finite element analysis, etc etc. Issues from the previous thread on the library and physical quantities in general http://aspn.activestate.com/ASPN/Mail/Message/boost/1926782 issue: Angles. current status: Angles are implemented.There are two types, irrational (ie radians) and rational fractions of revolution ie degrees minutes etc). radians are what you might call a 'weak type'. (Though this behaviour can be modified by a macro switch). They will implicitly decay to (say) double and can be implicitly cast to double. However they also allow implicit conversions to and from degrees etc. hence an implicit conversion from degrees to radians can occur if a function has a radians argument, but not a double argument. They are also useful for output of units. --------------------- issue: Differentiating different but dimensionally equivalent types. current status: This is implemented. --------------------- issue: Implicit conversions between units. current status: Implicit conversions are intrinsic. They are practical instinctive and useful. --------------------- issue: You should be using mpl. current status: Hopefully I will be able to get hold of the metaprogramming book soon, at which point I can decide whether there are advantages. --------------------- regards Andy Little

From: "Andy Little" <andy@servocomm.freeserve.co.uk>
I have been continuing with my physical-quantities library over the last year, http://www.servocomm.freeserve.co.uk/Cpp/physical_quantity/index.html and I am now seeking feedback as to whether it is worth putting this forward as a boost library proposal....
From the examples and code I've looked at, it looks well designed and easy to use. You've obviously put a lot of work into this, both with the library and documentation. I also did some tests, myself, seeing how it dealt with
I'd be interested in such a library in Boost. It's also actually on the C++ standards committee's "wishlist for C++0x" (http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2004/n1689.html): "a SI/Units library. ( e = m c2, and end to the mars lander crashes.)" I've been playing with a library like this, a year or so ago, too, but saw there were several proposals in that area, which worked similarily, and decided instead to focus on the Concept Traits library. I decided that I could then instead support other people's proposals in the area of quantity/units library. I've always seen this kind of library as a "fun" thing, :) as I'm interested in science, having "played with" electronics, physics, chemistry, etc. especially in my youth, and I'm sure such a library - of Boost standard (using modern C++), which this one seems to be - would be a great thing for scientists, and people interested in science, everywhere. I tried to test the library on Intel C++ 7.1 (electronics_example.cpp, picked at random) but got some errors which prevented the test, so I've tried it on g++ 3.2, instead, where it worked. Unless I haven't found it, you might want to include which compilers/versions it works for in the docs. If you're interested in the diagnostics from Intel C++, I can mail them to you. the computation of units, and that worked fine. Sorry I can't give more feefback at this time - it's busy at work with long days, these days. but I wanted to at least to chime in and say that, yes, I'd be interested in a such a library in Boost. What might help is to give an overview of other libraries that exist for this, and what makes PQS different. One place to look is the Boost Files section (I saw at least three such libraries there). I saw that Walter Brown's library is mentioned in the docs, though. I think you should go ahead with it, and if it comes to formal review, I'll make sure to do an in-depth study of it, preferably some time before the review. Regards, Terje

"Terje Slettebø" <tslettebo@broadpark.no> wrote in message news:00c901c4b8f9$50478b50$0300000a@pc...
From: "Andy Little" <andy@servocomm.freeserve.co.uk>
I have been continuing with my physical-quantities library over the last year, http://www.servocomm.freeserve.co.uk/Cpp/physical_quantity/index.html and I am now seeking feedback as to whether it is worth putting this forward as a boost library proposal....
I'd be interested in such a library in Boost. It's also actually on the C++ standards committee's "wishlist for C++0x" (http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2004/n1689.html):
"a SI/Units library. ( e = m c2, and end to the mars lander crashes.)"
Yes I did see that. FWIW the highest priorities IMO would be threads, networking and GUI , though in some cases I guess that this turns C++ from a language to an Operating system ala Java. (And by threads I mean major-language-upheaval-concept rather than low level widgets) Nevertheless if C++ doesnt deal with these I think its going to get left behind reasonably quickly. C++ certainly shouldnt be too proud to learn from Java. I do see optimism in the GUI area and in threads if the concept approach wins out. Anway the leap from my current reference impl to a boost version is probably a big enough leap to contemplate ;-)
I've been playing with a library like this, a year or so ago, too, but saw there were several proposals in that area, which worked similarily, and decided instead to focus on the Concept Traits library. I decided that I could then instead support other people's proposals in the area of quantity/units library.
I've always seen this kind of library as a "fun" thing, :) as I'm interested in science, having "played with" electronics, physics, chemistry, etc. especially in my youth, and I'm sure such a library - of Boost standard (using modern C++), which this one seems to be - would be a great thing for scientists, and people interested in science, everywhere.
The 'fun' thing is a key point of the library. Another useful feature is consistency in converting between units, as well as the fact that each type encodes a lot more information than a double, making it a C++ 'hub' for conversion to-from eg XML , or the same entity in other programming languages, data exchange , COM, CORBA etc. (Thats a theme I would like to pursue in other areas such as graphics too) I hope to get to get to grips with the serialisation library when the next boost distro comes out and try to implement some of this. The other aspect is simply that of modelling. It helps to visualise the entity you are modelling when the physical quantities are named. That is difficult to describe rationally but certainly helps me when I am coding. The fun aspect translates into much better understanding of what source code is actually doing.
I tried to test the library on Intel C++ 7.1 (electronics_example.cpp, picked at random) but got some errors which prevented the test, so I've tried it on g++ 3.2, instead, where it worked. Unless I haven't found it, you might want to include which compilers/versions it works for in the docs. If you're interested in the diagnostics from Intel C++, I can mail them to you.
Yes I would be very interested in that naturally, maybe a boost post would be most useful? It has only been tested on VC7.1 and gcc3.2.( As I understand it the base level for a boost proposal is two compilers) Its in the docs but will make it more prominent.. The docs need a lot of work in all areas....
From the examples and code I've looked at, it looks well designed and
to use. You've obviously put a lot of work into this, both with the
easy library
and documentation.
Yes and the more work I do on the project, the more I realise that I have only just touched the surface. That is one downside if I prepare a boost proposal.... I have the building blocks of the known universe in my hands. The last thing I really want is to be documenting them, much rather wielding them. (Ok.... IOW its a fascinating project to be working on whether it becomes part of boost or no ;-) ) I also did some tests, myself, seeing how it dealt with
the computation of units, and that worked fine. Sorry I can't give more feefback at this time - it's busy at work with long days, these days. but I wanted to at least to chime in and say that, yes, I'd be interested in a such a library in Boost.
Thanks for the time you have spent and the comments. It is much appreciated.
What might help is to give an overview of other libraries that exist for this, and what makes PQS different. One place to look is the Boost Files section (I saw at least three such libraries there).
This is a tricky area, as I have already spent considerable time criticising other units libraries. What I will say is that I have looked at many if not all the libraries on the file section and have learnt a lot from from all of them. eg Eric Ford,Matthias Schabel, Phil Richards,Michael Kennistons quantities library. (And BTW thanks too to Paul Bristow for the math constants definitions) I hope that one major difference is in the level of documentation and simply spending time on details, such as stream output. The other major area that I have tried to address is the 'user-interface' (Is there a less ghastly term for this ? ) . IOW I have tried to do this from a users perspective. I saw that Walter
Brown's library is mentioned in the docs, though.
I think that SIUnits has a mythical status (The other well known work is in the 'Barton-Nackman book, though I havent seen this) and has probably had influence in a lot of areas eg mpl and metaprogramming. At the time it was written it put huge demands on compilers, both requiring a reasonably conforming compiler and in compile-times due to the large amount of meta-programming involved. Things have improved making this type of library much more practical these days. If SIUnits was put forward I would be happy to step aside for it, but as I understand that is unlikely for various reasons.
I think you should go ahead with it, and if it comes to formal review,
I'll
make sure to do an in-depth study of it, preferably some time before the review.
Sounds like an offer I cant refuse. Thanks! regards Andy Little

From: "Andy Little" andy@servocomm.freeserve.co.uk
"Terje Slettebø" <tslettebo@broadpark.no> wrote in message
I've been playing with a library like this, a year or so ago, too, but saw there were several proposals in that area, which worked similarly, and decided instead to focus on the Concept Traits library. I decided that I could then instead support other people's proposals in the area of quantity/units library.
I've always seen this kind of library as a "fun" thing, :) as I'm interested in science, having "played with" electronics, physics, chemistry, etc. especially in my youth, and I'm sure such a library - of Boost standard (using modern C++), which this one seems to be - would be a great thing for scientists, and people interested in science, everywhere.
The 'fun' thing is a key point of the library. Another useful feature is consistency in converting between units, as well as the fact that each type encodes a lot more information than a double, making it a C++ 'hub' for conversion to-from eg XML , or the same entity in other programming languages, data exchange , COM, CORBA etc. (Thats a theme I would like to pursue in other areas such as graphics too) I hope to get to get to grips with the serialisation library when the next boost distro comes out and
Some of the issues I ran into, when playing with such a library, were: How to handle input/output, especially formatting the prefix and unit information. For example, one may write the same unit as: 1 MJ 1000 kJ 1000000 J 1 megajoule 10^6 J 10^6 kg·m^2·s^-2 10^6 kg·m^2/s^2 etc. In other words, it may be written in an infinite variety of forms. Moreover, the user may want the various forms in different contexts. Thus, I/O was one of the areas I found most complex to solve. The unit calculation itself is really a solved problem. :) (at least for the usual SI units). Because of this, it may be best to decouple the presentation from the unit calculation. One may provide some convenience output components, but it may be best if it's also possible for the user to provide the formatting in any way they want. For example if they want to show it using a GUI widget. So one may have functions to retrieve the components of the quantity, i.e. the numerical value, the unit (or unit components in the fundamental SI units) and their exponent, etc. If one provide convenience functions, then there's an issue of if one should provide names for both char and wchar_t, and how to deal with output of units that have no ASCII/Latin1 character, such as ohm. Looking at the docs, it seems that this issue has been considered, and that it's possible to provide custom output. Could you perhaps have shown how to output some of the formats above, given the quantity 1 MJ? I've mentioned SI, here. That should be an "alarm bell", because another issue to consider is if the library should be SI specific, or be able to handle units in general, including user-supplied ones. I remember this has been discussed in earlier discussions about quantity libraries, here, and one "obvious" candidate for non-physical units is money: You may have a numerical value, and its currency, and the possibility to convert between the various currencies. Your library is named "physical quantities library", and this points to it being more SI-specific; looking at the implementation, it seems the number of dimensions is hardcoded to 9. I'm not saying this is right or wrong, merely mentioning that - apart from the I/O issue - this was another major headache I had in the design of the library I worked on. The headache was this: It would be possible to accommodate for an arbitrary number of dimensions (for example using typelists or type vectors - see Dave Abraham and Aleksey Gurtovoy's article "A Deeper Look at Metafunctions" (http://www.artima.com/cppsource/metafunctions.html) for an example of this. I used a similar approach, but without the mpl::transform part, as my early version was Loki-based (I had a custom "transformer"). Had I done it today, I'd use MPL), but then one question is what the cost may be in terms of compilation time. Using type vectors rather than typelists might be faster, but necessarily; I tried to substitute mpl::vector for mpl::list in the Concept Traits library unit test, and watched the compilation time go through the roof... On the other hand, if one stick to a fixed number of dimensions, how many is enough? And what should they be? If we were to get a quantity library in Boost, I think it should be able to handle other quantities than the physical ones, as well (I didn't think of the money example in the previous post, so I couldn't think of a non-physical quantity example, but I was concerned about the library being SI-specific. As I said above, this might be ok, but should be something that should be explicitly addressed, perhaps in the FAQ). One sticky issue if you allow arbitrary units/dimensions, is that in SI, the only base unit with an exponent is "kg" (due to "historical accident), so 1000 kg isn't 1 kkg but 1 Mg. This has to be accommodated. Because of issues like this (particularly the compile time/flexibility concern), and seeing that there were several other approaches in existence for this, I was content to step aside, and watch them struggle with these issues, instead. :) Just something to chew on. :) It's probably nothing new, but I think these are issues that needs to be addressed for a library to be considered for Boost. try
to implement some of this.
I guess this addresses the I/O, also.
The other aspect is simply that of modelling. It helps to visualise the entity you are modelling when the physical quantities are named. That is difficult to describe rationally but certainly helps me when I am coding. The fun aspect translates into much better understanding of what source code is actually doing.
Absolutely. When I played with my library, it was rather fun to write, e.g. (to use the syntax in your library): length::m m=123; mass::kg kg=234; time::s s=10; std::cout << kg*m*m/(s*s); and get the output: 35.40186 kJ :) In other words, it told you what the named unit was, if it existed. The output was done by having some stream state decide the formatting. However, as mentioned, this was rather experimental: I ended up using a formatting string, for more or less maximum flexibility, i.e. "%v %p%u<n>", where <n> was a number from 0 and up. 1 would give the output in the base units ("kg·m^2·s^-2"); 2 would give the next "level" up ("N·m"), and 3 would give the level after that (if existed) "J". %v gives the numerical value (excluding the prefix value), "%p" gives the prefix - "k" here, and "%u" gave the unit, "J". I had "tons" of these format specifiers, so I could get "35.40186 kilojoule", etc., as well. To sidestep this "implicit"/stream-stored formatting, it might be better to use casting, as you use in the library, provided that you can then print the resulting quantity any way you want. Oh, and one other thing to consider: The handling of temperature. For example, will you be able to accommodate different temperature scales?: temperature::K t=283.15; std::cout << (temperature::C) t; // Prints "10 °C", or some such. Note that for Fahrenheit, it's not just an offset calculation, but also the degrees are different. Some of this stuff is what makes making a quantity library both challenging and fun. ;) (Like I said in the previous posting, you're talking with someone who have struggled with these issues, so I guess I have some idea of some of the thorny issues it may raise. ;) )
I tried to test the library on Intel C++ 7.1 (electronics_example.cpp, picked at random) but got some errors which prevented the test, so I've tried it on g++ 3.2, instead, where it worked. Unless I haven't found it, you might want to include which compilers/versions it works for in the docs. If you're interested in the diagnostics from Intel C++, I can mail them to you.
Yes I would be very interested in that naturally, maybe a boost post would be most useful?
There are many of the same kind, so sure: Several of each of these: electronics_example.cpp PQS-2-00-02\pqs/numeric/converter_exception.hpp(24): warning #811: exception specification for implicitly declared virtual function "boost::numeric::bad_numeric_conversion::~bad_numeric_conversion" is incompatible with that of overridden function "std::bad_cast::~bad_cast" class bad_numeric_conversion : public std::bad_cast ^ PQS-2-00-02\pqs/meta/rational_c.hpp(84): error: the type of partial specialization template parameter constant "N" depends on another template parameter IntegerType N, ^ PQS-2-00-02\pqs/ct_quantity/named_abstract_quantity/anonymous_abstract_quant ity/length_pwr.hpp(76): error: constant "N2" is not used in template argument list of class template "pqs::meta::binary_operation<pqs::length_pwr<N1, D1>, Op, pqs::meta::rational_c<RatValueType, N2, D2>, void>" int N2, ^ Then this: E:\PROGRAM\C++\PQS-2-00-02\pqs/ct_quantity/named_abstract_quantity/anonymous _abstract_quantity/length_pwr.hpp(66): error: class "boost::mpl::void_" has no member "numerator" base_type::numerator, ^ detected during: <long instantiation stack trace snipped> Then some smaller stuff: PQS-2-00-02\pqs/ct_quantity/ct_quantity.hpp(116): remark #424: extra ";" ignored }; ^ Several of these: PQS-2-00-02\pqs/ct_quantity/quantity_unit/si_prefix.hpp(65): warning #1334: the "template" keyword used for syntactic disambiguation may only be used within a template si_unit::prefix<si_unit::yotta>::template symbol<char>() ^ I'll send you the whole thing on mail, as well. Note that although Intel C++ is EDG-based, the Windows version (which I used) is a little "schizophrenic", as it tries to be "compatible" with MSVC, too, especially if you play with some of the (undocumented, for Intel C++) EDG switches, to try to make it more conformant. I used the following: --arg_dep_lookup --no_microsoft_bugs --no_guiding_decls However, even when not using any of these switches, it gives the above errors. As EDG (which Intel C++ uses) is considered one of the most conforming compilers there is, I think it makes sense to at least compile on an EDG compiler, too.
It has only been tested on VC7.1 and gcc3.2.( As I understand it the base level for a boost proposal is two compilers)
I haven't seen that explicitly, but my experience is that for more regular stuff, two compilers might be enough, for more tricky/advanced stuff, one should test on at least three. The Concept Traits library compiled and ran fine on Intel C++ 7.1 and MSVC 7.1, but bombed on g++ 3.2, so even if it works on two compilers, that's no guarantee for the third (even for the first two, having developed it on Intel C++, I had to tweak it a little to make it work on MSVC 7.1).
What might help is to give an overview of other libraries that exist for this, and what makes PQS different. One place to look is the Boost Files section (I saw at least three such libraries there).
This is a tricky area, as I have already spent considerable time criticising other units libraries.
Unless I've missed it, maybe this could have been included in a section in the docs, too? This gives other people an overview of how your library stands in comparison to these other proposals, maybe as well as the rationale for the choices. I realise this can be quite a lot of work (and as you said, you've done a lot of work in this area, already, although perhaps not documented it to a large degree), but as a library author, if you want to "sell" your library, I'm afraid you'll have to do this, too, just like salespeople need to be aware of the competition (if any), and be able to explain what makes their product better, to make a successful sale. :) Regards, Terje

"Terje Slettebø" wrote
"Andy Little" wrote
Some of the issues I ran into, when playing with such a library, were:
How to handle input/output, especially formatting the prefix and unit information. For example, one may write the same unit as:
1 MJ 1000 kJ 1000000 J 1 megajoule 10^6 J 10^6 kg·m^2·s^-2 10^6 kg·m^2/s^2 etc.
In other words, it may be written in an infinite variety of forms. Moreover, the user may want the various forms in different contexts.
Of the 7 above 5 are doable (approximately) with the current setup via casting : casting to different units changes the actual value of the quantity. here 'e' has a numeric value of 1., casting to kJ changes the numeric value to 1000. os.setf(std::ios_base::fixed,std::ios_base::floatfield); os.precision(0); energy::MJ e(1); os << e << '\n'; os << energy::kJ(e) << '\n'; os << energy::J(e) << '\n'; os.setf(std::ios_base::scientific); os << energy::J(e) << '\n'; os << anonymous_cast(energy::J(e)) << '\n'; gives: 1 MJ 1000 kJ 1000000 J 1e+006 J 1e+006 kg.m+2.s-2 ... ( BTW The difference between named-quantities and anonymous-quantities is significant. Otherwise one could not differentiate (say) energy and torque. The anonymous_cast function removes the named-quantity connotations: pqs::energy::J e(1); pqs::torque::N_m t(1); os << e << '\n'; os << t << '\n'; os << anonymous_cast(e) <<'\n'; os << anonymous_cast (t) <<'\n'; gives: 1 J 1 N.m 1 kg.m+2.s-2 1 kg.m+2.s-2 There are various rules for when and why anonymous quantities pop up in calcs. ) ... as far as the megajoule version is concerned I have attempted to try to stay reasonably close to the SI output scheme, which rules this out as valid output. http://physics.nist.gov/Pubs/SP811/contents.html
Thus, I/O was one of the areas I found most complex to solve. The unit calculation itself is really a solved problem. :) (at least for the usual SI units).
Yes It is the details of the thing that cause the headaches!
Because of this, it may be best to decouple the presentation from the unit calculation. One may provide some convenience output components, but it
may
be best if it's also possible for the user to provide the formatting in any way they want.
For example if they want to show it using a GUI widget. So one may have functions to retrieve the components of the quantity, i.e.
This is implemented though probably needs clarification (I am aware that the docs are currently rambling) Firstly #include the "pqs/pqs.hpp" header brings in "the kitchen sink" including the convenience debugging output. (sadly missed adding angles in this header in pqs-2-00-02, so the "kitchen sink" will be a bit bigger next version) However in the "pqs/types/ " dir are two versions of each quantity header. The one with the _out.hpp suffix brings in the debug output for that quantity. Output does decompose into value and units, but is rather long winded to describe here. There are also separate rules for the so-called incoherent quantities. the
numerical value, the unit (or unit components in the fundamental SI units) and their exponent, etc.
This sounds like a good scheme, but is not currently implemented except for the numeric_value()... todo
If one provide convenience functions, then there's an issue of if one should provide names for both char and wchar_t, and how to deal with output of units that have no ASCII/Latin1 character, such as ohm.
Looking at the docs, it seems that this issue has been considered, and
The main issue for me with wchar_t is quite what to make of it. ref the recent "need for Unicode" thread on this. However I will need to deal with it, currently there are some undefined functions intended to fill out this aspect. that
it's possible to provide custom output. Could you perhaps have shown how to output some of the formats above, given the quantity 1 MJ?
Yes I guess I could. The docs need a complete restart !
I've mentioned SI, here. That should be an "alarm bell", because another issue to consider is if the library should be SI specific, or be able to handle units in general, including user-supplied ones.
Its not SI specific, and it is possible to use other so-called anonymous-abstract-quantities ( so long as they conform to the AnonymousAbstractQuantityImplementation Concept), however by doing that you need to fill in a large amount of detail. For instance the default output cant be used as its entirely dependent on the unit system. There is no convenient user-interface etc, and you would need to set all this up, which starts to get pretty cumbersome. ( I use a database to generate the types/ headers) .. However the math functions and operational stuff etc will work ok. There is also still a small amount of stuff that is hard wired ( eg the exponent-base for units), and might be better done as a traits class of the unit
I remember this has been discussed in earlier discussions about quantity libraries, here, and one "obvious" candidate for non-physical units is money: You may have a numerical value, and its currency, and the possibility to convert between the various currencies.
Unfortunately the arts of alchemy have been lost .... Seriously one stumbling block is the sheer inconsistency. Currencies units cannot be relatively measured in any meaningul way, so conversions arent constant.
Your library is named "physical quantities library", and this points to it being more SI-specific; looking at the implementation, it seems the number of dimensions is hardcoded to 9. I'm not saying this is right or wrong, merely mentioning that - apart from the I/O issue - this was another major headache I had in the design of the library I worked on.
The headache was this: It would be possible to accommodate for an arbitrary number of dimensions (for example using typelists or type vectors - see Dave Abraham and Aleksey Gurtovoy's article "A Deeper Look at Metafunctions" (http://www.artima.com/cppsource/metafunctions.html) for an example of
Basically the library is built around the SI system yes (7 'base units') . The rationale is simply that in practise IMO that is the major application area for this library. It is targetted at engineering and education , which is a large market with a low profile, rather than high level physics which has a high profile but is not a high volume market. Where the last ounce of performance is required you will probably be using inbuilt types and probably as I understand it Fortran. However if you want RAD then this library may be very helpful and some very quick tests indicate that it doesnt perform too badly compared with eg doubles, if you have access to an optimising compiler. this.
I used a similar approach, but without the mpl::transform part, as my early version was Loki-based (I had a custom "transformer"). Had I done it today, I'd use MPL), but then one question is what the cost may be in terms of compilation time. Using type vectors rather than typelists might be faster, but necessarily; I tried to substitute mpl::vector for mpl::list in the Concept Traits library unit test, and watched the compilation time go through the roof...
There are a fair few issues here. One being simply that I don't know enough about mpl. However one issue is legibility, Its easier to comprehend and typesafe : typedef anonymous_abstract_quantity< length_pwr<1>, time_pwr<-2>, mass_pwr<1>, temperature_pwr<0>, // these can default... current_pwr<0>, substance_pwr<0>, intensity_pwr<0> > anonymous_abstract_quantity_type; than boost::mpl::vector< rat<1>, rat<-2> rat<1> rat<0>, rat<0>, rat<0>, rat<0>
anonymous_abstract_quantity_type;
However I am reasonably confident that an mpl::container could be fitted in to the library without much difficulty. Again anything will do as long as the requirements of the Concept currently called "AnonymousAbstractQuantityImplementation" (Ouch!) are met. Again more documentation required I guess. The other issue is my binary_operation type deduction scheme. If there is an alternative boost mechanism with this functionality I'll be happy to try it. BOOST_DECLTYPE may fit the bill... sfinae ?? Overall.... Potentially a lot of fun to be had here ;-)
On the other hand, if one stick to a fixed number of dimensions, how many is enough? And what should they be?
If we were to get a quantity library in Boost, I think it should be able to handle other quantities than the physical ones, as well (I didn't think of the money example in the previous post, so I couldn't think of a non-physical quantity example, but I was concerned about the library being SI-specific. As I said above, this might be ok, but should be something
Within a given physical-quantity-system there will be a fixed number of base-units Eg, It is possible to use eg {length, time, mass} as a complete system with the library. In fact I should get round to implementing this as it is relatively easy to do and would improve compile times significantly where the other base-units arent required. that
should be explicitly addressed, perhaps in the FAQ).
One sticky issue if you allow arbitrary units/dimensions, is that in SI,
Ok. Basically anything (any set of things) that conforms to the rules (Ok .. what are the rules? ;-) ) will fit. However, as you pointed out previously its the output etc thats tricky, once you move out of SI you will need to provide a lot of that functionality yourself, so the 'simple to use' aspect is lost. Its these details that take the time, not the actual dimensional-analysis part. the
only base unit with an exponent is "kg" (due to "historical accident), so 1000 kg isn't 1 kkg but 1 Mg. This has to be accommodated. Because of issues like this (particularly the compile time/flexibility concern), and seeing that there were several other approaches in existence for this, I was content to step aside, and watch them struggle with these issues, instead. :)
;-) see the prefix-offset and the extent in the OfQuantityComponents concept Algorithm is in "pqs/ct_quantity/types/components/adjusted_coherent_prefix.hpp" heres a snippet of the source ( 'of_type' is OfNamedQuantityComponents Concept): (BTW extent can be negative eg reciprocal-time --> -1) enum{ adjusted_numerator = (CoherentExponent::numerator / of_type::extent) + of_type::prefix_offset }; I have struggled with the 'Defining your own types' part of the docs...its still not very good. So a lot more work is required. On the compile-time/run-time issue...There are two types currently, a compile time type with fixed units and a runtime type where units can be modified. I think there will also be a need for a universal_quantity, which can hold any type at runtime. This would probably be the basis of something to pass around among applications, ... and prototypes are around on the web, but I've lost the reference
Just something to chew on. :) It's probably nothing new, but I think these are issues that needs to be addressed for a library to be considered for Boost.
Thanks for the in-depth stuff, support and the thoughts..
The 'fun' thing is a key point of the library. Another useful feature is consistency in converting between units, as well as the fact that each type encodes a lot more information than a double, making it a C++ 'hub' for conversion to-from eg XML , or the same entity in other programming languages, data exchange , COM, CORBA etc. (Thats a theme I would like to pursue in other areas such as graphics too) I hope to get to get to grips with the serialisation library when the next boost distro comes out and try to implement some of this.
I guess this addresses the I/O, also.
The other aspect is simply that of modelling. It helps to visualise the entity you are modelling when the physical quantities are named. That is difficult to describe rationally but certainly helps me when I am coding. The fun aspect translates into much better understanding of what source code is actually doing.
Absolutely. When I played with my library, it was rather fun to write, e.g. (to use the syntax in your library):
length::m m=123;
[snip] (explicit value_type ctor )... length::m m(123); mass::kg kg(234); time::s s(10);
std::cout << kg*m*m/(s*s);
and get the output:
35.40186 kJ
:)
PQs used to do that, however it'll now return an anonymous-quantity here, because dimensionally-equivalent types may be representing different quantities, so this would require casting the result to either torque or energy, else you will just get the 'anonymous-quantity' output in the above example. But it was .. a cool trick :-)
In other words, it told you what the named unit was, if it existed. The output was done by having some stream state decide the formatting.
However,
as mentioned, this was rather experimental: I ended up using a formatting string, for more or less maximum flexibility, i.e. "%v %p%u<n>", where <n> was a number from 0 and up. 1 would give the output in the base units ("kg·m^2·s^-2"); 2 would give the next "level" up ("N·m"), and 3 would give the level after that (if existed) "J". %v gives the numerical value (excluding the prefix value), "%p" gives the prefix - "k" here, and "%u" gave the unit, "J". I had "tons" of these format specifiers, so I could get "35.40186 kilojoule", etc., as well.
cool.... but complicated ...
To sidestep this "implicit"/stream-stored formatting, it might be better
use casting, as you use in the library, provided that you can then print
to the
resulting quantity any way you want.
Oh, and one other thing to consider: The handling of temperature. For example, will you be able to accommodate different temperature scales?:
temperature::K t=283.15;
std::cout << (temperature::C) t; // Prints "10 °C", or some such.
Note that for Fahrenheit, it's not just an offset calculation, but also
Well if you still have the code .... OTOH as I indicated previously .. The SI rules are pretty rigid, and there is also an argument for making one basic standard output 'signature' by which to identify a particular type for char stream anyway. I do like simplicity .. At the end of the day this is an important element of the physical-quantity type.Its pretty humble. #include the headers, declare them in your code and get on with the real app. They are just little building blocks... like std::string or inbuilts. the
degrees are different.
I would have to implement these as separate ("seamlessly integrated") types, theyre real oddities they are :-) ... todo
Some of this stuff is what makes making a quantity library both challenging and fun. ;)
(Like I said in the previous posting, you're talking with someone who have struggled with these issues, so I guess I have some idea of some of the thorny issues it may raise. ;) )
I tried to test the library on Intel C++ 7.1 (electronics_example.cpp, picked at random) but got some errors which prevented the test, so I've tried it on g++ 3.2, instead, where it worked. Unless I haven't found it, you might want to include which compilers/versions it works for in the docs. If you're interested in the diagnostics from Intel C++, I can mail
As you say its all those details ... like centigrade, kg, etc ;-) them
to
you.
Thanks ... received ..
Note that although Intel C++ is EDG-based, the Windows version (which I used) is a little "schizophrenic", as it tries to be "compatible" with MSVC, too, especially if you play with some of the (undocumented, for Intel C++) EDG switches, to try to make it more conformant. I used the following:
--arg_dep_lookup --no_microsoft_bugs --no_guiding_decls
However, even when not using any of these switches, it gives the above errors. As EDG (which Intel C++ uses) is considered one of the most conforming compilers there is, I think it makes sense to at least compile on an EDG compiler, too.
Thanks for testing this out.
It has only been tested on VC7.1 and gcc3.2.( As I understand it the base level for a boost proposal is two compilers)
I haven't seen that explicitly, but my experience is that for more regular stuff, two compilers might be enough, for more tricky/advanced stuff, one should test on at least three. The Concept Traits library compiled and ran fine on Intel C++ 7.1 and MSVC 7.1, but bombed on g++ 3.2, so even if it works on two compilers, that's no guarantee for the third (even for the first two, having developed it on Intel C++, I had to tweak it a little to make it work on MSVC 7.1).
What might help is to give an overview of other libraries that exist for this, and what makes PQS different. One place to look is the Boost Files section (I saw at least three such libraries there).
This is a tricky area, as I have already spent considerable time criticising other units libraries.
Unless I've missed it, maybe this could have been included in a section in the docs, too? This gives other people an overview of how your library stands in comparison to these other proposals, maybe as well as the rationale for the choices. I realise this can be quite a lot of work (and as you said, you've done a lot of work in this area, already, although
Fair comment.. I'll try to get it working perhaps
not documented it to a large degree), but as a library author, if you want to "sell" your library, I'm afraid you'll have to do this, too, just like salespeople need to be aware of the competition (if any), and be able to explain what makes their product better, to make a successful sale. :)
Ok Thanks for the time you have spent on this. What I take from this overall is that the docs need a major redo. (And some historical background/ refs). As it stands I think the docs are often saying the same thing in 3 places... none of which is the right place. Perhaps I need a bit more of a top down approach for a change. regards Andy Little

From: "Andy Little" <andy@servocomm.freeserve.co.uk>
"Terje Slettebø" wrote
"Andy Little" wrote
Some of the issues I ran into, when playing with such a library, were:
How to handle input/output, especially formatting the prefix and unit information. For example, one may write the same unit as:
1 MJ 1000 kJ 1000000 J 1 megajoule 10^6 J 10^6 kg·m^2·s^-2 10^6 kg·m^2/s^2 etc.
In other words, it may be written in an infinite variety of forms. Moreover, the user may want the various forms in different contexts.
Of the 7 above 5 are doable (approximately) with the current setup via casting : casting to different units changes the actual value of the quantity. here 'e' has a numeric value of 1., casting to kJ changes the numeric value to 1000.
os.setf(std::ios_base::fixed,std::ios_base::floatfield); os.precision(0); energy::MJ e(1); os << e << '\n'; os << energy::kJ(e) << '\n'; os << energy::J(e) << '\n'; os.setf(std::ios_base::scientific); os << energy::J(e) << '\n'; os << anonymous_cast(energy::J(e)) << '\n';
gives:
1 MJ 1000 kJ 1000000 J 1e+006 J 1e+006 kg.m+2.s-2
That's great. :)
( BTW The difference between named-quantities and anonymous-quantities is significant. Otherwise one could not differentiate (say) energy and torque. The anonymous_cast function removes the named-quantity connotations:
pqs::energy::J e(1); pqs::torque::N_m t(1);
os << e << '\n'; os << t << '\n'; os << anonymous_cast(e) <<'\n'; os << anonymous_cast (t) <<'\n';
gives:
1 J 1 N.m 1 kg.m+2.s-2 1 kg.m+2.s-2
Yes, it's good that you can differentiate between various units having the same base units. It's similar with scalar values, which may be e.g. radians or steradians, but without any base units.
Looking at the docs, it seems that this issue has been considered, and that it's possible to provide custom output. Could you perhaps have shown how to output some of the formats above, given the quantity 1 MJ?
Yes I guess I could. The docs need a complete restart !
I've mentioned SI, here. That should be an "alarm bell", because another issue to consider is if the library should be SI specific, or be able to handle units in general, including user-supplied ones.
Its not SI specific, and it is possible to use other so-called anonymous-abstract-quantities ( so long as they conform to the AnonymousAbstractQuantityImplementation Concept), however by doing that you need to fill in a large amount of detail.
Well, as long as it's possible to write your own custom formatting, that's what is important. If you provide accessors for numerical value, unit name (possibly also base units), in some way, then that is catered for.
If we were to get a quantity library in Boost, I think it should be able to handle other quantities than the physical ones, as well (I didn't think of the money example in the previous post, so I couldn't think of a non-physical quantity example, but I was concerned about the library being SI-specific. As I said above, this might be ok, but should be something that should be explicitly addressed, perhaps in the FAQ).
Ok. Basically anything (any set of things) that conforms to the rules (Ok .. what are the rules? ;-) ) will fit. However, as you pointed out previously its the output etc thats tricky, once you move out of SI you will need to provide a lot of that functionality yourself, so the 'simple to use' aspect is lost. Its these details that take the time, not the actual dimensional-analysis part.
Well, making the "simple things simple, and the hard things possible", seems like a good design. :)
Absolutely. When I played with my library, it was rather fun to write, e.g. (to use the syntax in your library):
length::m m=123;
[snip]
(explicit value_type ctor )...
length::m m(123); mass::kg kg(234); time::s s(10);
std::cout << kg*m*m/(s*s);
and get the output:
35.40186 kJ
:)
PQs used to do that, however it'll now return an anonymous-quantity here, because dimensionally-equivalent types may be representing different quantities, so this would require casting the result to either torque or energy, else you will just get the 'anonymous-quantity' output in the above example. But it was .. a cool trick :-)
In other words, it told you what the named unit was, if it existed. The output was done by having some stream state decide the formatting. However, as mentioned, this was rather experimental: I ended up using a
Yes, good point. formatting
string, for more or less maximum flexibility, i.e. "%v %p%u<n>", where <n> was a number from 0 and up. 1 would give the output in the base units ("kg·m^2·s^-2"); 2 would give the next "level" up ("N·m"), and 3 would give the level after that (if existed) "J". %v gives the numerical value (excluding the prefix value), "%p" gives the prefix - "k" here, and "%u" gave the unit, "J". I had "tons" of these format specifiers, so I could get "35.40186 kilojoule", etc., as well.
cool.... but complicated ...
To sidestep this "implicit"/stream-stored formatting, it might be better to use casting, as you use in the library, provided that you can then print the resulting quantity any way you want.
Well if you still have the code ....
It was written using Spirit to parse the formatting string and fill it in, but unfortunately, I don't have it around, anymore. However, with a little knowledge of Spirit, it shouldn't be that hard to make it again. In any case, if the quantity objects provides accessors for its various properties, then such a formatter is really orthogonal to PQS, and people may write their own. Regards, Terje

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Andy Little Sent: Friday, October 22, 2004 6:09 AM To: boost@lists.boost.org Subject: [boost] pqs - physical quantities library
Hi,
I have been continuing with my physical-quantities library over the last year, http://www.servocomm.freeserve.co.uk/Cpp/physical_quantity/index.html and I am now seeking feedback as to whether it is worth putting this forward as a boost library proposal....
I've looked over your library a little. Overall, I like it. Having started one a few years ago, I understand how much work has gone into it. I have some feedback: * I would appreciate a little more depth in the glossary. The definitions are very much about the mechanics. A "coherent-quantity" is a concrete-quantity with an incoherent-multiplier of 1. Does that mean a kilometer is incoherent since its incoherent-multiplier must be different than the meter? Or is it coherent because it is part of the SI system, but feet, miles, etc. are incoherent? Looking through the code I believe the latter to be true, but the documentation doesn't succinctly explain that. In following links regarding coherent and incoherent quantities it felt like circular definitions. * Unless I missed it, I think you need to add a term to your nomenclature. What's between an abstract and a concrete quantity? length::m is an abstract-quantity with quantity-unit but no value thus it's neither abstract nor concrete. I would guess that this kind of quantity will probably be discussed a bit. * I believe the system is too SI-centric, resulting in this point and the two following. I would like to see the library move away from the SI units taking 7 of 9 prime-unit slots. I can envision a number of applications that could benefit from a quantities library but aren't based heavily on SI units. For example, if I'm modeling the business side of a networking company, my units could include computers, megabytes, and dollars. So there would be a lot of tracking of dimensions I don't care about and currently not enough available dimensions currently to track what I do care about. * The coherent prime-dimension-unit should be selectable. I don't want any precision issues beyond those that are strictly required. I'd prefer to see a system where I can specify a "coherency-set", e.g. S.I., Imperial, etc. Each coherency-set should be completely encapsulated from other sets. If I need conversions from one set to another, I can specialize a conversion template class for the two sets. * I'm a little leery of the structure of of_length, etc. It's not extensible to adding new unit types. To bring up a system I mentioned once before in a different thread, how would I add length::cubit without mucking around in the library files themselves? * of_quantity seems a little limiting regarding conversion issues. If my underlying value type is a UDT (such as an arbitrary precision type), I would like to have conversion numbers be objects of that UDT to maximize precision. * What's the plan for non-ICE pow()? A compile-time solution is clearly not an option. For completeness, it would be nice to see an example of how to deal with the situations where quantity information is lost. Thanks, Noah

"Noah Stein" <noah@acm.org> wrote
-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Andy Little Sent: Friday, October 22, 2004 6:09 AM To: boost@lists.boost.org Subject: [boost] pqs - physical quantities library
Hi,
I have been continuing with my physical-quantities library over the last year, http://www.servocomm.freeserve.co.uk/Cpp/physical_quantity/index.html and I am now seeking feedback as to whether it is worth putting this forward as a boost library proposal....
I've looked over your library a little. Overall, I like it. Having started one a few years ago, I understand how much work has gone into it. I have some feedback:
* I would appreciate a little more depth in the glossary. The definitions are very much about the mechanics.
I opted to just say what the things are, rather than to try to describe the 'metaphysics'. That is surprisingly hard to do IMO. What is and what isnt a physical-quantity?. However I accept the point. I have found documenting the work extremely difficult. A complete overhaul is required.
A "coherent-quantity" is a concrete-quantity with an incoherent-multiplier of 1. Does that mean a kilometer is incoherent since its incoherent-multiplier must be different than the meter?
No. The incoherent-multiplier is a conversion factor required to scale an incoherent quantity to a coherent quantity. length::km is a coherent-quantity. Therefore: The incoherent-multiplier of length::km is also 1. Note However that there is another constant in the quantity-unit, the 'coherent exponent'. In length::m the coherent exponent is 0, while in length::km the coherent-exponent is 3. The coherent-exponent is closely related to the si-prefixes eg cm -->-2, um --> -6 , km --> 3 etc In a multiplication on two coherent-quantities ( as opposed to incoherent-quantities, ie those where the incoherent-multiplier is != 1) as defined above, the coherent exponents are added at compile time, rather than runtime, thus making multiplication/division more efficient. IOW this works similarly to hand calculations. However incoherent-quantities (non SI quantities eg kgf, in, etc) must be converted to coherent-quantities first(N, cm) in some cases, making calculations less efficient. Examples of incoherent-quantities are length::mi, length::in, length::ft etc. IOW 'coherent-quantities' are those in practise referred to in the SI system as coherent units. Overall there are 3 parts to the quantity-unit. A typical declaration looks like so: quantity_unit< coherent_exponent<Numerator, Denominator>, incoherent_multiplier<MultiplicationConstant * 1000000>, quantity_unit_tag<ID>
the last part is required for corner cases eg: It is used to differentiate quantities for output purposes. For example in the following pressure::mmH20, and pressure::kgf_div_m2 are actually the same unit, (both 'incoherent-quantities' here) ,but note that output is diffferent. std::cout << pqs::pressure::mmH20(1) <<'\n'; std::cout << pqs::pressure::kgf_div_m2(1) <<'\n'; // to show they are in fact the same underlying unit std::cout << pqs::pressure::mmH20(1) / pqs::pressure::kgf_div_m2(1) << '\n'; // as opposed to std::cout << pqs::pressure::kgf_div_m2(1) / pqs::pressure::bar(1) <<'\n'; output : 1 mmH20 // note different output of two types 1 kgf.m-2 1 // dividing one by the other shows these are same unit 9.80665e-5 //otoh division of different units
Or is it coherent because it is part of the SI system, but feet, miles, etc. are incoherent? Looking through the code I believe the latter to be true, but the documentation doesn't succinctly explain that.
In following links regarding coherent and incoherent quantities it felt
Ok the latter analysis is correct :-), but requires clearer documentation on my part obviously. like
circular definitions.
Yes the docs need a restart. Criticism totally accepted :-)
* Unless I missed it, I think you need to add a term to your nomenclature. What's between an abstract and a concrete quantity? length::m is an abstract-quantity with quantity-unit but no value thus it's neither
abstract
nor concrete. I would guess that this kind of quantity will probably be discussed a bit.
* I believe the system is too SI-centric, resulting in this point and the two following. I would like to see the library move away from the SI units taking 7 of 9 prime-unit slots. I can envision a number of applications that could benefit from a quantities library but aren't based heavily on SI units. For example, if I'm modeling the business side of a networking company, my units could include computers, megabytes, and dollars. So
Not exactly... abstract-quantities have no numeric-value. They are useful only for dimensional-analysis. To perform any calculation on concrete-quantities the units are required. Without units the numeric-value is meaningless. IOW "I will arrive in 12". means nothing. "I will arrive in 12 minutes" does. there
would be a lot of tracking of dimensions I don't care about and currently not enough available dimensions currently to track what I do care about.
See the attached file "main.cpp". See also the AnonymousAbstractQuantityImplementation Concept. Anything conforming can be substituted, eg the anon_q1 struct in the above file. OTOH could be 700 dimensions if your compiler can handle it. Of course you will need to provide output and so on, however calcs work ok.
* The coherent prime-dimension-unit should be selectable. I don't want any precision issues beyond those that are strictly required. I'd prefer to see a system where I can specify a "coherency-set", e.g. S.I., Imperial, etc. Each coherency-set should be completely encapsulated from other sets. If I need conversions from one set to another, I can specialize a conversion template class for the two sets.
OK. Except that the SI is arguably The coherent set. There are no widely used others. The major purpose of the SI system has been to tie together disparate partially complete systems.
* I'm a little leery of the structure of of_length, etc. It's not extensible to adding new unit types. To bring up a system I mentioned once before in a different thread, how would I add length::cubit without mucking around in the library files themselves?
The current plan wiith these is that you Do just add in custom member typedefs within the of_length_<Value_type> struct. There are two versions of each. Obviously the one templated on the Value_type must be a struct, but the default Value_type version could be a namespace. However I found it considerably more convenient to make it a ' forwarding' class of the other: struct length : length_<of_quantity::default_value_type>{}; This can be extended: struct my_length : length { typedef some_type cubit; }; etc. OTOH it may be more convenient to create your own and add only those required, or use the ct_quantity raw. It is merely a convenience. In fact it might be better to put the actual containers in the background eg: namespace hidden{ struct length {...}; } typedef hidden::length length ; etc. Obviously it would be easy to replace the typedef with your own custom version. In fact I could do this pretty simply I guess. In fact Should do this.... next version :-)
* of_quantity seems a little limiting regarding conversion issues. If my underlying value type is a UDT (such as an arbitrary precision type), I would like to have conversion numbers be objects of that UDT to maximize precision.
The SI lays down conversion factors to 6 decimal places. + exponent Some things are limited by compile time constant issues. eg the incoherent-multiplier fits into a long. (eg the long template param of incoherent-multiplier == Constant * 1,000,000.) However extending this to arbitrary precision is possible perhaps, though I havent looked into it. Bearing in mind compile time as an issue too, however it may be possible using a different quantity_unit class. Personally though I have little interest in this, and generally use coherent-quantities which have 0 conversion error by design, so will leave that to others to implement.
* What's the plan for non-ICE pow()? A compile-time solution is clearly not an option. For completeness, it would be nice to see an example of how to deal with the situations where quantity information is lost.
Because multiplication of two quantities result in a particular Type the power-to-exponent has to be available at compile time for the current setup. (however powers can be rational eg pow<-1,2>(t) etc. ) When its not you will need to use a run-time type, eg with all the dimension information available and modifiable at runtime. This would certainly be a useful addition, eg a 'universal-quantity' and I may get round to implementing that. The compile time quantities certainly give good background and its merely a question of transferring (some) compile-time calcs to run-time. The current types would also be extremely useful here because they encapsulated the data in a concise way eg: universal_quantity x = length::m(1); x *= time::s (2); x = 1 ; //dimensionless if ( x.dimension_powers() == dimension_powers<of_length>() ){ length::m len = x; } //etc The data for the compile time types could also be reused. One way to look at the types in the"pqs/ct_quantity/types/ " headers is as a database of information. This has already beeen done to some extent in the rt_quantity, which has modifiable units and 'maps' the various units for output (see "pqs/examples/mapped_rt_quantity.cpp" and "pqs/rt_quantity/rt_units_map.hpp"), but the dimensions are fixed. However the rt_quantity has already proved useful. Hmm... maybe it would be fun to implement that. It might end up being the most useful type of all :-) regards Andy Little begin 666 main.cpp M+R\@($-O<'ER:6=H=" H0RD@06YD>2!,:71T;&4L(%=H:71E($QI9VAT($1E M=FEC92 R,# S+@T*+R\@(&%N9'E <V5R=F]C;VUM+F9R965S97)V92YC;RYU M:PT*+R\@(%!E<FUI<W-I;VX@=&\@8V]P>2P@=7-E+"!M;V1I9GDL('-E;&P@ M86YD(&1I<W1R:6)U=&4@=&AI<R!S;V9T=V%R90T*+R\@(&ES(&=R86YT960@ M<')O=FED960@=&AI<R!C;W!Y<FEG:'0@;F]T:6-E(&%P<&5A<G,@:6X@86QL M(&-O<&EE<RX-"B\O("!4:&ES('-O9G1W87)E(&ES('!R;W9I9&5D(")A<R!I M<R(@=VET:&]U="!E>'!R97-S(&]R(&EM<&QI960@=V%R<F%N='DL#0HO+R @ M86YD('=I=&@@;F\@8VQA:6T@87,@=&\@:71S('-U:71A8FEL:71Y(&9O<B!A M;GD@<'5R<&]S92X-"B-I;F-L=61E(")P<7,O<'%S+FAP<"(-"@T*;F%M97-P M86-E('!Q<WL-"@T*(" @("\O(&-U<W1O;2!A;F]N>6UP;W5S7V%B<W1R86-T M+7%U86YT:71Y#0H@(" @+R\@8V]N9F]R;6EN9R!T;R!T:&4@06YO;GEM;W5S M06)S=')A8W11=6%N=&ET>4EM<&QE;65N=&%T:6]N($-O;F-E<'0-"B @(" O M+R!R97%U:7)E<R!A;'-O(&)I;F%R>5]O<&5R871I;VX@=&\@8F4@<W!E8VEA M;&ES960@87,@8F5L;W<-"B @("!T96UP;&%T93P-"B @(" @(" @='EP96YA M;64@1FER<W14>7!E+ T*(" @(" @("!T>7!E;F%M92!396-O;F14>7!E+ T* M(" @(" @("!T>7!E;F%M92!4:&ER9%1Y<&4-"B @(" ^#0H@(" @<W1R=6-T M(&%N;VY?<3%[#0H@(" @(" @('1Y<&5D968@1FER<W14>7!E(" @(" @(" @ M(&9I<G-T7W1Y<&4[#0H@(" @(" @('1Y<&5D968@4V5C;VYD5'EP92 @(" @ M(" @('-E8V]N9%]T>7!E(#L-"B @(" @(" @='EP961E9B!4:&ER9%1Y<&4@ M(" @(" @(" @=&AI<F1?='EP93L-"@T*#0H@(" @(" @('1Y<&5D968@86YO M;E]Q,2 @='EP93L-"B @(" @(" @96YU;7L@:7-?9&EM96YS:6]N;&5S<R - M"B @(" @(" @/2 @("!F:7)S=%]T>7!E.CII<U]Z97)O#0H@(" @(" @("8F M("!S96-O;F1?='EP93HZ:7-?>F5R;PT*(" @(" @(" F)B @=&AI<F1?='EP M93HZ:7-?>F5R;WT@.PT*(" @('T[#0I]+R]P<7,-"@T*;F%M97-P86-E('!Q M<WL-"FYA;65S<&%C92!M971A>PT*#0H@(" @+R]&;VQL;W=I;6<@(')E<75I M<F5D(&9O<B!A;F]N7W$Q('1O(&-O;F9O<FT@#0H@(" @+R\@=&\@=&AE($-O M;7!I;&5T:6UE0FEN87)Y3W!E<F%T:6)L92!#;VYC97!T#0H@(" @+R\@86YD M($-O;7!I;&5T:6UE(%5N87)Y3W!E<F%T:6)L92!#;VYC97!T#0H@(" @('1E M;7!L871E(#P@#0H@(" @(" @('1Y<&5N86UE($9I<G-T5'EP92P-"B @(" @ M(" @='EP96YA;64@4V5C;VYD5'EP92P-"B @(" @(" @='EP96YA;64@5&AI M<F14>7!E+ T*(" @(" @("!I;G0@3BP-"B @(" @(" @:6YT($0-"B @(" ^ M#0H@(" @<W1R=6-T(&)I;F%R>5]O<&5R871I;VX\#0H@(" @(" @('1Y<&5N M86UE('!Q<SHZ86YO;E]Q,3P-"B @(" @(" @(" @($9I<G-T5'EP92P-"B @ M(" @(" @(" @(%-E8V]N9%1Y<&4L#0H@(" @(" @(" @("!4:&ER9%1Y<&4- M"B @(" @(" @/BP-"B @(" @(" @<'%S.CIT;U]P;W=E<BP-"B @(" @(" @ M<'%S.CIM971A.CIR871I;VYA;%]C/&EN="P@3BQ$/@T*(" @(#Y[#0H@(" @ M(" @('1Y<&5D968@='EP96YA;64@<'%S.CIM971A.CIR871I;VYA;%]C/&EN M="P@3BQ$/CHZ='EP92!R870[#0H@(" @(" @("!T>7!E9&5F('!Q<SHZ86YO M;E]Q,3P-"B @(" @(" @(" @('1Y<&5N86UE(&)I;F%R>5]O<&5R871I;VX\ M1FER<W14>7!E+'-T9#HZ;75L=&EP;&EE<RQR870^.CIR97-U;'1?='EP92P- M"B @(" @(" @(" @('1Y<&5N86UE(&)I;F%R>5]O<&5R871I;VX\4V5C;VYD M5'EP92QS=&0Z.FUU;'1I<&QI97,L<F%T/CHZ<F5S=6QT7W1Y<&4L#0H@(" @ M(" @(" @("!T>7!E;F%M92!B:6YA<GE?;W!E<F%T:6]N/%1H:7)D5'EP92QS M=&0Z.FUU;'1I<&QI97,L<F%T/CHZ<F5S=6QT7W1Y<&4-"B @(" @(" @/B!R M97-U;'1?='EP93L-"B @("!].PT*(" @(" @(" -"B @(" @=&5M<&QA=&4@ M/" -"B @(" @(" @='EP96YA;64@1FER<W14>7!E02P-"B @(" @(" @='EP M96YA;64@4V5C;VYD5'EP94$L#0H@(" @(" @('1Y<&5N86UE(%1H:7)D5'EP M94$L#0H@(" @(" @('1E;7!L871E(#QT>7!E;F%M93X@8VQA<W,@3W L#0H@ M(" @(" @('1Y<&5N86UE($9I<G-T5'EP94(L#0H@(" @(" @('1Y<&5N86UE M(%-E8V]N9%1Y<&5"+ T*(" @(" @("!T>7!E;F%M92!4:&ER9%1Y<&5"#0H@ M(" ^(" @(" @(" -"B @("!S=')U8W0@8FEN87)Y7V]P97)A=&EO;CP-"B @ M(" @(" @='EP96YA;64@<'%S.CIA;F]N7W$Q/ T*(" @(" @(" @(" @1FER M<W14>7!E02P-"B @(" @(" @(" @(%-E8V]N9%1Y<&5!+ T*(" @(" @(" @ M(" @5&AI<F14>7!E00T*(" @(" @(" ^+ T*(" @(" @("!/<"P-"B @(" @ M(" @='EP96YA;64@<'%S.CIA;F]N7W$Q/ T*(" @(" @(" @(" @1FER<W14 M>7!E0BP-"B @(" @(" @(" @(%-E8V]N9%1Y<&5"+ T*(" @(" @(" @(" @ M5&AI<F14>7!E0@T*(" @(" @(" ^+ T*(" @(" @("!T>7!E;F%M92!B;V]S M=#HZ96YA8FQE7VEF/ T*(" @(" @(" @(" @8F]O<W0Z.FUP;#HZ86YD7SP- M"B @(" @(" @(" @(" @("!P<7,Z.FUE=&$Z.F1E=&%I;#HZ:7-?=F%L:61? M8FEN87)Y7VQO9U]T<F%N<V9O<FT\#0H@(" @(" @(" @(" @(" @(" @($9I M<G-T5'EP94$L3W L1FER<W14>7!E0@T*(" @(" @(" @(" @(" @(#XL#0H@ M(" @(" @(" @(" @(" @<'%S.CIM971A.CID971A:6PZ.FES7W9A;&ED7V)I M;F%R>5]L;V=?=')A;G-F;W)M/ T*(" @(" @(" @(" @(" @(" @("!396-O M;F14>7!E02Q/<"Q396-O;F14>7!E0@T*(" @(" @(" @(" @(" @(#XL#0H@ M(" @(" @(" @(" @(" @<'%S.CIM971A.CID971A:6PZ.FES7W9A;&ED7V)I M;F%R>5]L;V=?=')A;G-F;W)M/ T*(" @(" @(" @(" @(" @(" @("!4:&ER M9%1Y<&5!+$]P+%1H:7)D5'EP94(-"B @(" @(" @(" @(" @(" ^+ T*(" @ M(" @(" @(" @(" @(&)O;W-T.CIM<&PZ.FYO=%\\#0H@(" @(" @(" @(" @ M(" @(" @('!Q<SHZ:7-?<&]W7V]P97)A=&]R/$]P/@T*(" @(" @(" @(" @ M(" @(#X-"B @(" @(" @(" @(#X-"B @(" @(" @/CHZ='EP90T*(" @(" @ M(" @(" @(" @( T*(" @/GL-"B @(" @(" @='EP961E9B!P<7,Z.F%N;VY? M<3$\#0H@(" @(" @(" @("!T>7!E;F%M92!P<7,Z.FUE=&$Z.F)I;F%R>5]L M;V=?=')A;G-F;W)M/$9I<G-T5'EP94$L3W L1FER<W14>7!E0CXZ.G)E<W5L M=%]T>7!E+ T*(" @(" @(" @(" @='EP96YA;64@<'%S.CIM971A.CIB:6YA M<GE?;&]G7W1R86YS9F]R;3Q396-O;F14>7!E02Q/<"Q396-O;F14>7!E0CXZ M.G)E<W5L=%]T>7!E+ T*(" @(" @(" @(" @='EP96YA;64@<'%S.CIM971A M.CIB:6YA<GE?;&]G7W1R86YS9F]R;3Q4:&ER9%1Y<&5!+$]P+%1H:7)D5'EP M94(^.CIR97-U;'1?='EP90T*(" @(" @(" ^(')E<W5L=%]T>7!E.PT*(" @ M(" @(" @(" @#0H@("!].PT*#0H@(" @=&5M<&QA=&4\#0H@(" @(" @('1Y M<&5N86UE($9I<G-T5'EP92 L#0H@(" @(" @('1Y<&5N86UE(%-E8V]N9%1Y M<&4L#0H@(" @(" @('1Y<&5N86UE(%1H:7)D5'EP90T*(" @(#X-"B @("!S M=')U8W0@=6YA<GE?;W!E<F%T:6]N/ T*(" @(" @("!P<7,Z.G)E8VEP<F]C M86PL#0H@(" @(" @('1Y<&5N86UE('!Q<SHZ86YO;E]Q,3P-"B @(" @(" @ M(" @($9I<G-T5'EP92P-"B @(" @(" @(" @(%-E8V]N9%1Y<&4L#0H@(" @ M(" @(" @("!4:&ER9%1Y<&4-"B @(" @(" @/@T*(" @(#Y[#0H@(" @(" @ M('1Y<&5D968@='EP96YA;64@<'%S.CIA;F]N7W$Q/ T*(" @(" @(" @(" @ M='EP96YA;64@=6YA<GE?;W!E<F%T:6]N/'-T9#HZ;F5G871E+$9I<G-T5'EP M93XZ.G)E<W5L=%]T>7!E+ T*(" @(" @(" @(" @='EP96YA;64@=6YA<GE? M;W!E<F%T:6]N/'-T9#HZ;F5G871E+%-E8V]N9%1Y<&4^.CIR97-U;'1?='EP M92P-"B @(" @(" @(" @('1Y<&5N86UE('5N87)Y7V]P97)A=&EO;CQS=&0Z M.FYE9V%T92Q4:&ER9%1Y<&4^.CIR97-U;'1?='EP90T*(" @(" @/B!R97-U M;'1?='EP93L-"B @('T[#0H-"GTO+VUE=&$-"GTO+W!Q<PT*"@II;G0@;6%I M;B@I"GL*(" @('1Y<&5D968@<'%S.CIC=%]Q=6%N=&ET>3P*(" @(" @("!P M<7,Z.FYA;65D7V%B<W1R86-T7W%U86YT:71Y/ H@(" @(" @(" @("!P<7,Z M.F%N;VY?<3$\"B @(" @(" @(" @(" @("!P<7,Z.FUE=&$Z.G)A=&EO;F%L M7V,\:6YT+#$^+ H@(" @(" @(" @(" @(" @<'%S.CIM971A.CIR871I;VYA M;%]C/&EN="PP/BP*(" @(" @(" @(" @(" @('!Q<SHZ;65T83HZ<F%T:6]N M86Q?8SQI;G0L,#X*(" @(" @(" @(" @/BP*(" @(" @(" @(" @<'%S.CIN M86UE9%]Q=6%N=&ET>5]T86<\,#X*(" @(" @(" ^+ H@(" @(" @('!Q<SHZ M<75A;G1I='E?=6YI=#P*(" @(" @(" @(" @<'%S.CIC;VAE<F5N=%]E>'!O M;F5N=#PP/BP*(" @(" @(" @(" @<'%S.CII;F-O:&5R96YT7VUU;'1I<&QI M97(\,3 P,# P,#X*(" @(" @(" ^+ H@(" @(" @(&1O=6)L92 *(" @(#X@ M("!T97-T7W1Y<&4Q.PH*(" @('1Y<&5D968@<'%S.CIC=%]Q=6%N=&ET>3P* M(" @(" @("!P<7,Z.FYA;65D7V%B<W1R86-T7W%U86YT:71Y/ H@(" @(" @ M(" @("!P<7,Z.F%N;VY?<3$\"B @(" @(" @(" @(" @("!P<7,Z.FUE=&$Z M.G)A=&EO;F%L7V,\:6YT+# ^+ H@(" @(" @(" @(" @(" @<'%S.CIM971A M.CIR871I;VYA;%]C/&EN="PQ/BP*(" @(" @(" @(" @(" @('!Q<SHZ;65T M83HZ<F%T:6]N86Q?8SQI;G0L,#X*(" @(" @(" @(" @/BP*(" @(" @(" @ M(" @<'%S.CIN86UE9%]Q=6%N=&ET>5]T86<\,#X*(" @(" @(" ^+ H@(" @ M(" @('!Q<SHZ<75A;G1I='E?=6YI=#P*(" @(" @(" @(" @<'%S.CIC;VAE M<F5N=%]E>'!O;F5N=#PP/BP*(" @(" @(" @(" @<'%S.CII;F-O:&5R96YT M7VUU;'1I<&QI97(\,3 P,# P,#X*(" @(" @(" ^+ H@(" @(" @(&EN=" * M(" @(#X@("!T97-T7W1Y<&4R.PH*"B @("!T97-T7W1Y<&4Q('0Q*#$I.PH@ M(" @=&5S=%]T>7!E,B!T,B@R*3L*(" @('!Q<SHZ;65T83HZ8FEN87)Y7V]P M97)A=&EO;CP*(" @(" @("!T97-T7W1Y<&4Q+ H@(" @(" @('-T9#HZ;75L M=&EP;&EE<RP*(" @(" @("!T97-T7W1Y<&4R"B @(" ^.CIR97-U;'1?='EP M92!T,6UU;'0R(#T@=#$@*B!T,CL*"B @("!S=&0Z.F-O=70@/#P@(G0Q("H@ M=#(@;G5M97)I8U]V86QU92 ]("(@/#P@=#%M=6QT,BYN=6UE<FEC7W9A;'5E M*"D@/#PG7&XG.PH@(" @<W1D.CIC;W5T(#P\("!T>7!E:60H=#%M=6QT,BDN M;F%M92@I(#P\("=<;B<["B @("!P<7,Z.FUE=&$Z.F)I;F%R>5]O<&5R871I M;VX\"B @(" @(" @=&5S=%]T>7!E,2P*(" @(" @("!S=&0Z.F1I=FED97,L M"B @(" @(" @=&5S=%]T>7!E,@H@(" @/CHZ<F5S=6QT7W1Y<&4@=#%D:79T M,B ]('0Q("\@=#(["B @("!S=&0Z.F-O=70@/#P@(G0Q("\@=#(@;G5M97)I M8U]V86QU92 ]("(@/#P@=#%D:79T,BYN=6UE<FEC7W9A;'5E*"D@/#PG7&XG M.PH@(" @<W1D.CIC;W5T(#P\('1Y<&5I9"AT,61I=G0R*2YN86UE*"D@/#PG M7&XG.PH*(" @("!P<7,Z.FUE=&$Z.F)I;F%R>5]O<&5R871I;VX\"B @(" @ M(" @=&5S=%]T>7!E,2P*(" @(" @("!S=&0Z.F1I=FED97,L"B @(" @(" @ M=&5S=%]T>7!E,0H@(" @/CHZ<F5S=6QT7W1Y<&4@=#%D:79T,2 ]('0Q("\@ M=#$["B @("!S=&0Z.F-O=70@/#P@(G0Q("\@=#$@;G5M97)I8U]V86QU92 ] M("(@/#P@=#%D:79T,2 \/"=<;B<["B @("!S=&0Z.F-O=70@/#P@='EP96ED M*'0Q9&EV=#$I+FYA;64H*2 \/"=<;B<["B @(" *(" @( H@(" @<'%S.CIM M971A.CIB:6YA<GE?;W!E<F%T:6]N/ H@(" @(" @('1E<W1?='EP93$L"B @ M(" @(" @<W1D.CIP;'5S+ H@(" @(" @('1E<W1?='EP93$*(" @(#XZ.G)E M<W5L=%]T>7!E('0Q<&QT,2 ]('0Q("L@=#$["@H@(" @<W1D.CIC;W5T(#P\ M(")T,2 K('0Q(&YU;65R:6-?=F%L=64@/2 B(#P\('0Q<&QT,2YN=6UE<FEC M7W9A;'5E*"D@/#PG7&XG.PH@(" @<W1D.CIC;W5T(#P\('1Y<&5I9"AT,7!L M=#$I+FYA;64H*2 \/"=<;B<["@H*(" @('!Q<SHZ;65T83HZ8FEN87)Y7V]P M97)A=&EO;CP*(" @(" @("!T97-T7W1Y<&4R+ H@(" @(" @('-T9#HZ;6EN M=7,L"B @(" @(" @=&5S=%]T>7!E,@H@(" @/CHZ<F5S=6QT7W1Y<&4@=#)M M:6YU<W0R(#T@=#(@+2!T,CL*(" @('-T9#HZ8V]U=" \/" B=#(@+2!T,B!N M=6UE<FEC7W9A;'5E(#T@(B \/"!T,FUI;G5S=#(N;G5M97)I8U]V86QU92@I M(#P\)UQN)SL*(" @('-T9#HZ8V]U=" \/"!T>7!E:60H=#)M:6YU<W0R*2YN M86UE*"D@/#PG7&XG.PH*(" @("!P<7,Z.FUE=&$Z.F)I;F%R>5]O<&5R871I M;VX\"B @(" @(" @=&5S=%]T>7!E,BP*(" @(" @("!P<7,Z.G1O7W!O=V5R M+ H@(" @(" @('!Q<SHZ;65T83HZ<F%T:6]N86Q?8SQI;G0L,BPQ/@H@(" @ M/CHZ<F5S=6QT7W1Y<&4@=#)P;W<R(#T@<'%S.CIP;W<\,CXH=#(I.PH@(" @ M<W1D.CIC;W5T(#P\(")P;W%S/#(^*'0R*2!N=6UE<FEC7W9A;'5E(#T@(B \ M/"!T,G!O=S(N;G5M97)I8U]V86QU92@I(#P\)UQN)SL*(" @('-T9#HZ8V]U M=" \/"!T>7!E:60H=#)P;W<R*2YN86UE*"D@/#PG7&XG.PH@("\O("!S=&0Z ?.F-O=70@/#P@=#)P;W<R(#P\)UQN)SL*(" @( I]"@`` ` end

Hi again, Thanks to everyone who has returned comments on the pqs library. My current instinct is not to put it forward as a boost proposal at this time. Having worked on the library for some time I have found it an interesting project., however the recurrent theme from the feedback is that the documentation needs to be much clearer. I also think I need to demonstrate application areas. IOW are physical quantities a practical proposition? Compile time dimensional analysis is a great example for showing of C++ at its best. However I do often ask myself the question as to whether this is 'showing off ' for academic interest rather than practicality. IOW once one starts to use a physical-quantity type, one soon finds that it becomes impossible to 'mesh' the type with other libraries. Examples here are std::complex and matrices. In both cases it requires a reimplementation to account for the different return types. Another issue is that the physical quantity type is restricted to compile-time. A runtime type is certainly possible though it would be considerably larger as it would need to carry the dimension and unit information along with it at run time. IOW a collection of types representing physical-quantities does not seem to be complete without being based in a much larger framework, with a lot more utilities. Perhaps this is an example of taking strong type checking too far, and may be the reason that a physical quantities library will not become a practical proposition. Whatever.. the library is certainly a facinating curiosity at least, and my curiosity as to where it will lead is not diminished. Here for example are a couple of types representing homogeneous vectors and transformation matrices for 2D transforms. Note that operations such as concatenation, determinant, cofactor and inverse all work satisfactorily within the strong type checking: PQ == the physical-quantity parameter type ( eg length::m) K/PQ == the 'reciprocal' of the type ( eg reciprocal_length::div_m } N == numeric type ( eg double) rc_matrix<PQ>( // 2D transformation matrix laid out in row/column format //using a tuple of tuples N, N, K/PQ, N, N, K/PQ, PQ, PQ, N ); row_vector<PQ>( // 2D vertex in homogeneous coordinates implicit //conversion to/from x,y vertex<PQ>. N, N, K/PQ ); regards Andy Little

| -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Andy Little | Sent: 05 November 2004 13:51 | To: boost@lists.boost.org | Subject: [boost] Re: pqs - physical quantities library | | Thanks to everyone who has returned comments on the pqs library. | My current instinct is not to put it forward as a boost | proposal at this time. I'm sure I am not the only lurker watching work on this VERY complex (and, sadly, very, very MESSY) issue. I want to thank Andy for his significant efforts, but to agree that none of his ambitious proposals on physical quantities and units are fully worked out yet. It is unclear to me if this is because of the intrinsic muddle of the units in use - even for pure SI, temperature in Celcuis and weight in kg are 'irregular' :-( And as for 'Imperial' </eyeroll> ... as we call it from the 'FatherLand', and are still so widely used in our favorite ex-colony, long after we went metric ;-). Or it is the language itself that can't handle it? But this remains an important problem: meanwhile there are very many programming mistakes made every day which are less spectacular than Martian Lander Prangs, but collectively much more important. So I hope it won't be removed from the Boost wish-list, and that work on it will continue, especially to mesh at compile-time with containers, including matrices. Paul Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539 561830 +44 7714 330204 mailto: pbristow@hetp.u-net.com

"Paul A Bristow" <pbristow@hetp.u-net.com> wrote
| -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Andy Little | Sent: 05 November 2004 13:51 | To: boost@lists.boost.org | Subject: [boost] Re: pqs - physical quantities library | | Thanks to everyone who has returned comments on the pqs library. | My current instinct is not to put it forward as a boost | proposal at this time.
I want to thank Andy for his significant efforts,
Thanks for the comments. regards Andy Little
participants (4)
-
Andy Little
-
Noah Stein
-
Paul A Bristow
-
Terje Slettebø