Boost logo

Ublas :

Subject: [ublas] Extending type_traits for use with Boost Units
From: Manoj Rajagopalan (rmanoj_at_[hidden])
Date: 2009-08-26 17:29:12


Hi UBLAS developers,

  I have begun using Boost Units which was introduced in boost v 1.36. I am
working on extending UBLAS to support physically dimensioned types and I have
provided a short example below.

   This can be achieved efficiently if a few extensions to UBLAS type_traits
are allowed and I was wondering if anyone would object to this. An example of
such an extension would be the introduction of "sqrt_type" as the type for
the square root operation. This would be the return type for
type_traits<T>::type_sqrt(). For arithmetic types like float and double the
template can be partially specialized so that sqrt_type is float or double
but for physically dimensioned types like quantity<length,double>, sqrt_type
can be set to quantity<length^(1/2), double>.

    I have already adapted most of vector_expression.hpp for use with these
dimensioned quantities with work-arounds for these extensions but this is
getting ugly and unwieldy.

   In the example below, norm_2() is called to calculate distance. This
requires the introduction of two new types: an intermediate, sum_of_squares
type (with physical dimensions of area in this case), and a result type of
sqrt_type (with physical dimensions of length).

   To get this to work I have to modify the vector_norm_2 function to define
quantity<area,double> as the intermediate sum-of-squares type and
type_traits<quantity<area,double> > must have a sqrt_type of
quantity<length,double>.

   With these simple extensions, the existing machinery of UBLAS can be used
with dimensioned quantities.

   So, to reiterate, is there any objection to the introduction of these new
traits and typedefs without breaking existing functionality?

Thanks,
Manoj Rajagopalan

CODE EXAMPLE:

using namespace boost::units;
typedef quantity<si::length, double> length_t;
typedef quantity<si::time, double> time_t;
typedef quantity<si::velocity, double> velocity_t;

using namespace boost::numeric::ublas;
vector<length_t> length_vec;
vector<time_t> time_vec;
vector<velocity_t> velocity_vec;

velocity_vec = element_div(length_vec, time_vec);

// Why we need sqrt_type
typedef quantity<si::dimensionless, double> scalar_t;
scalar_t distance = boost::numeric::ublas::norm_2(length_vec);