Boost logo

Ublas :

From: Matthias Schabel (boost_at_[hidden])
Date: 2007-03-28 13:31:48


Dear Mr. Walker,

Thanks for your interest and support. I'm glad the library sounds
like it is meeting some of your needs already. I will try to answer
as many of your questions as I can easily address :

> I'm sure you've heard this before, but things haven't been going
> very well. We use Visual Studio 2005sp1 (with a hotfix) and gcc4 on
> Mac OS X.

I develop primarily with XCode 2.4/gcc 4.0.1, but everything should
work on VS as well...

> 1. Boost.Test
> quantity< SI::length > a, b;
> BOOST_CHECK_CLOSE( a, b, 0.1 ); // Fails to compile
>
> Visual Studio:
> C2676: binary '<=' : 'Length' does not define this operator or a
> conversion to a type acceptable to the predefined operator

This ought to work (untested) :

BOOST_CHECK_CLOSE(a,b,0.1*SI::meters);

You can't compare quantities and scalars... Another option is :

BOOST_CHECK_CLOSE(a.value(),b.value(),0.1)

although this is, of course, loses the unit information...

> 2. Boost.uBLAS (vector)
> // typedef double Type;
> // typedef quantity< SI::length > Type;
> ublas::vector< Type > v(3);
> v *= 2.0; // works
> v * 2.0; // works for double, not for quantity
>
> Visual Studio balks down in <boost/numeric/ublas/traits.hpp> line
> 44 (inside struct promote_traits).

This is a type deduction flaw in ublas - if ublas was updated to use
Boost.Typeof, this issue would presumably go away. Basically, they're
using operator+ to deduce the promoted type in this operation
(likely, though I don't know this for sure, so an integer ublas
vector times a double precision scalar will give a double precision
ublas vector)... The best solution for this is clearly to use
Boost.Typeof in ublas rather than the existing type deduction
machinery, at least for compilers that support it. Compilers that
don't work with Boost.Typeof will almost certainly not be able to
compile the proposed Boost.Units library anyway... The way we do it
in the units library is to have typeof helpers
(add_typeof_helper<T,U>, subtract_typeof_helper<T,U>, etc...) that
will do reasonable promotion for built in types and correctly handle
UDTs as well...

> 3. Boost.uBLAS (zero_vector)
> ublas::zero_vector< quantity< SI::length > > v(3); // Fails to compile
>
> Visual Studio balks down in <boost/numeric/ublas/vector.hpp> line
> 762 (zero_(0)). It looks like it's trying to construct a quantity<
> SI::length > with the protected constructor:
> C2248: 'boost::units::quantity<Unit>::quantity' : cannot access
> protected member declared in class 'boost::units::quantity<Unit>'

Right - the problem here is that we (purposely) prevent construction
of quantities from bare value types as allowing that is problematic
for code maintainability. Clearly, this is an issue of interfacing
ublas with quantities; we have not yet approached the Boost community
in general or the maintainers of ublas in particular with the
prospect of integration. If and when Boost Units is accepted, that
would be the logical first step - as some of the examples
demonstrate, things like boost::math::quaternion and, clearly,
boost::ublas will need changes. If you want to get this to work
quickly, I would do something like this :

In line 762 of ublas/vector.hpp (and anywhere else in ublas where you
have a constructor passing a value type), make this replacement :

zero_(0) -> construct_zero<T>()

where T is the ublas value type and construct_zero is a template
function returning the appropriate value :

template<class T>
inline T construct_zero()
{
        return T(0);
}

template<class T,class Unit>
inline T construct_zero< boost::units::quantity<Unit,T> >
{
        return boost::units::quantity<Unit,T>::from_value(construct_zero<T>());
}

I'm ccing this response to the ublas mailing list...there may be some
other suggestions on achieving interoperability. In reality, I think
ublas should default construct here rather than explicitly use zero -
that is, replacing zero_(0) with zero_() will also work with
quantities...and is much simpler.

Best Regards,

Matthias