
Andy Little <andy <at> servocomm.freeserve.co.uk> writes:
"Michael Fawcett" wrote
On 6/8/06, Andy Little wrote:
-----Original Message----- From: Michael Fawcett [mailto:michael.fawcett <at> gmail.com]
I dont think many people realise! I have discussed it in various replies but no one has asked me the direct question:
Neither of those libraries above will work with other than numeric types AFAIK. IOW where T is a type (simplifying and ignoring e.g floating point promotion etc), it must satisfy:
T result = T() + T(); T result = T() * T();
(among others)
If T is a physical quantity, the second requirement never can be true.
I totally agree - and this is a big problem with using any existing matrix libraries that I know of. *Except* - with your t3_quantity, your last statement above is not true. This *will* work: t3_quantity result = t3_quantity() * t3_quantity(); For anyone who scratches their head as to what t3_quantity would be good for, here's one answer! It can be used with existing linear algebra libraries with a minimum of effort. (It would still be good to use t3_quantity only when necessary, however, because of the run-time penalty.)
blas::vec3<float> a(1, 0, 0); blas::vec3<double> b(0, 1, 0); blas::vec3<double> result = cross_product(a, b); // returns vec3<double>!
template <typename LHS, typename RHS> typename boost::result_of_plus<LHS, RHS>::type operator +(const LHS &lhs, const RHS &rhs) { typename boost::result_of_plus<LHS, RHS>::type nrv(lhs); nrv += rhs; return nrv; }
In fact the type makeup of a matrix for 2d transforms ends up looking like
In my work I implemented something very similar to this - but only for vectors with elements of homogeneous dimensions (e.g., a length vector, a velocity vector). When I have a vector of mixed quantities (length, velocity, time, dimensionless - together in one vector), I end up going to something more like t3_quantity. (FYI, this occurs in the context of least-squares estimation of model parameters, where the parameters are of various dimensions.) the
following:
where N is a numeric, Q is a quantity and R is the reciprocal of the quantity or 1/Q
( N N R ) ( NN R ) ( QQ N )
The 3D transform version is similar except with the extra row and column of course.
The problem is that this is quite a heavy modification to ask of a numeric matrix library, especially when most users will be using it for numeric values.
Yes, unfortunately, that's true. It will make it very hard to integrate any dimensional analysis library with any existing matrix library.
The point of all this is that the price of strong type checking (ie using PQS rather than numerics) may be discarding all your current libraries, which are based on the assumption of numerics. That is quite a high price!.
Again, unfortunately true. (But not because of bad PQS implementation! AFAICS the situation would be the same with any strongly-typed dimensional analysis library.)
I dont know any solution to this problem( except to exit the strong type checking) but basically there it is.
You can exit the strong type checking, or you can pay the performance penalty for t3_quantity. In effect what I ended up doing was both - by putting a compile-time switch in my t3_quantity to turn off the dimensional analysis. Then I get the best of both worlds - I live with the performance penalty for the sake of the dimensions-checking (and enforced documentation of units) until my formulas are debugged, and then I get the benefit of the speed in my production code - all while using a matrix library that doesn't care about any of this. (And BTW, it did find several bugs in my computations by flagging dimensions problems!) -- Leland