Boost logo

Ublas :

From: Darin DeForest (darin_at_[hidden])
Date: 2005-08-11 18:03:23

I have some issues with triangular matrices.

First issue seems that the triangle matrix allocates too much memory. Right now I non-square triangular matrices, where size1() != size2();

size is being computed by this method:

        size_type triangular_size (size_type size1, size_type size2) {
            size_type size = (std::max) (size1, size2);
            // Guard against size_type overflow - simplified
            BOOST_UBLAS_CHECK (size == 0 || size / 2 < (std::numeric_limits<size_type>::max) () / size /* +1/2 */, bad_size ());
            return ((size + 1) * size) / 2;

so for a 2x5 triangle matrix, this will take 6*5/2 = 15 elements. This is more than a regular 2x5 matrix which should be 10 elements large.

Another issue is with assignment, I have

matrix<float> m( M, N);
triangular_matrix<float, lower> lower (M, N);

// fill m with some values

lower = m;

In method:

    // Packed (proxy) row major case
    template<template <class T1, class T2> class F, class R, class M, class E>
    // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
    void matrix_assign (M &m, const matrix_expression<E> &e, packed_proxy_tag, row_major_tag) {

I get an error from this test failing:

        if (! disable_type_check<bool>::value)
            BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());

when I proceed the above assignment statement with

disable_type_check<bool>::value = true;

then the assignment works without an exception being generated, and some hand verification shows that the assignment worked.

The question is that the check seems useful, after all it is in the code. However I don't like surrounding assignment statements with check-off or check-on. The other option is to disable the BOOST_UBLAS_TYPE_CHECK define.

So given that, what is the best choice that I can make?

The last issue is a problem with indexing into the triangular matrix, because in some cases an exception can be raised as the following triangular_matrix method illustrates:

        reference operator () (size_type i, size_type j) {
            BOOST_UBLAS_CHECK (i < size1_, bad_index ());
            BOOST_UBLAS_CHECK (j < size2_, bad_index ());
            if (triangular_type::other (i, j))
                return data () [triangular_type::element (layout_type (), i, size1_, j, size2_)];
            else {
                bad_index ().raise ();
                // arbitary return value
                return const_cast<reference>(zero_);

In this case, I would expect the rest of the matrix to have some default value, like zero. This makes the caller if using this api to be aware that this matrix has a different accessing strategy.
Also I would point out that this would also make it work similar to unit_vector, where that only contains one value for a specified index, and all of it's other indexes have zero.

Right I consider this to be a documentation defect, since the documentation doesn't indicate that this exception would be raised.