Boost logo

Boost :

From: Joerg Walter (jhr.walter_at_[hidden])
Date: 2002-07-01 23:22:59


----- Original Message -----
From: "Benedikt Weber" <weber_at_[hidden]>
Newsgroups: gmane.comp.lib.boost.devel
To: <boost_at_[hidden]>
Sent: Monday, July 01, 2002 5:26 PM
Subject: [boost] ublas type safety and bound check

> ublas is very flexible when combining matrices of different shapes.
However,
> some type safety would sometimes be useful. When initializing a triangular
> matrix by a full matrix, there is no compiler error. At runtime, the
> triangular matrix just takes what it needs, without giving a warning. With
> assignment it's the same problem. There are macros
NUMERICS_USE_FAST_COMMON
> and NUMERICS_BOUNDS_CHECK which I tried to undefine, to get a bound check,
> but I see no difference in the behaviour.
>
> #undef NUMERICS_USE_FAST_COMMON
> #undef NUMERICS_BOUNDS_CHECK
>
> const n= 3;
> numerics::matrix<double> A(n,n);
> for (int i= 0; i<n; ++i)
> for (int j= 0; j<n; ++j)
> A(i,j)= i+j;
>
> std::cout << "A" << std::endl;
> std::cout << A << std::endl;
>
> try {
> numerics::triangular_matrix<double> B= A; // undetected
> std::cout << "B= A" << std::endl;
> std::cout << B << std::endl;
> }
> catch (std::exception& e) {
> std::cout << e.what() << std::endl;
> }
> catch (...) {
> std::cout << "unknown exception" << std::endl;
> }
>
> A
> [3,3]((0,1,2),(1,2,3),(2,3,4))
> B= A
> [3,3]((0,0,0),(1,2,0),(2,3,4))
>
> Another example is assigning a larger to a smaller matrix. The problems
are
> the same ones as before.
>
> try {
> numerics::matrix<double> B(n-1,n-1);
> B.assign(A); // undetecetd
> std::cout << "B.assign(A)" << std::endl;
> std::cout << B << std::endl;
> }
> catch (std::exception& e) {
> std::cout << e.what() << std::endl;
> }
> catch (...) {
> std::cout << "unknown exception" << std::endl;
> }
>
> B.assign(A)
> [2,2]((0,1),(1,2))
>
>
> I am a little bit concerned, that you can do all these errors without
> getting warned! Is there something I missed or is just that way with
> expression templates? What are these macros good for?

The corresponding checks exist in the packed matrix evaluation:

#ifdef NUMERICS_BOUNDS_CHECK_EX
            {
                // Need the const member dispatched.
                const M &cm = m;
                typename E::const_iterator1 it1e (e ().begin1 ());
                typename E::const_iterator1 it1e_end (e ().end1 ());
                while (it1e != it1e_end) {
                    typename E::const_iterator2 it2e (it1e.begin ());
                    typename E::const_iterator2 it2e_end (it1e.end ());
                    while (it2e != it2e_end) {
                        // FIXME: we need a better floating point
comparison...
                        check (*it2e == cm (it2e.index1 (), it2e.index2 ()),
bad_index ());
                        ++ it2e;
                    }
                    ++ it1e;
                }
            }
#endif

but are currently disabled due to the usual problems with floating point
arithmetic when checking too strict. I'll discuss with Mathias, how to
install a customizable comparator.

Sorry for the inconvenience.

Regards

Joerg


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk