Boost logo

Ublas :

Subject: [ublas] Floating point exceptions and unexpected call to sqrt with sparse integer vectors
From: Mark Johnson (mj1_at_[hidden])
Date: 2009-08-10 15:48:12


Thanks Jesse for your answer to my previous question.

A lot of my work involves statistics of sparse vectors of positive
integers, so it seems ublas sparse vectors and matrices are going to be
very useful for me.

However, I find that sparse vectors of integers produce strange floating
point exceptions (they work great with floats and doubles). When I use
gdb to trace these exceptions I find unexplained calls to sqrt(), even
though my program doesn't involve sqrt() at all. I'd appreciate any advice!

Here's a simple program that demonstrates the problem; I use
feenableexcept() to trap floating point exceptions.

    #include <boost/numeric/ublas/io.hpp>
    #include <boost/numeric/ublas/vector.hpp>
    #include <boost/numeric/ublas/vector_expression.hpp>
    #include <boost/numeric/ublas/vector_proxy.hpp>
    #include <boost/numeric/ublas/vector_sparse.hpp>

    #include <iostream>

    // _GNU_SOURCE must be defined and fenv.h included to
    // trap floating-point exceptions (fpes).
    //
    #define _GNU_SOURCE 1
    #include <fenv.h>

    namespace ublas = boost::numeric::ublas;

    int main(int argc, char** argv) {

       // trap floating point exceptions
       feenableexcept(FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW);

       ublas::mapped_vector<int> v = ublas::unit_vector<int>(2, 1);
       std::cout << "v = " << v << std::endl;
    }

When I compile and run this program I get a floating point exception,
which is curious as there's no floating point math in the program at all.

    [mj_at_lugha tmp]$ g++ -g -O0 ublas-int.cc -o ublas-int
    [mj_at_lugha tmp]$ ./ublas-int
    Floating point exception

Gdb shows that the exception is generated in a call to sqrt(-2147483648)

    [mj_at_lugha tmp]$ gdb ublas-int
    ...(gdb) run
    Starting program: /home/mj/tmp/ublas-int

    Program received signal SIGFPE, Arithmetic exception.
    0x0000000000405468 in std::sqrt<int> (__x=-2147483648) at
    /usr/lib/gcc/x86_64-redhat-linux/4.4.0/../../../../include/c++/4.4.0/cmath:439
    439 { return __builtin_sqrt(__x); }
    Missing separate debuginfos, use: debuginfo-install
    glibc-2.10.1-2.x86_64 libgcc-4.4.0-4.x86_64 libstdc++-4.4.0-4.x86_64
    (gdb) bt
    #0 0x0000000000405468 in std::sqrt<int> (__x=-2147483648) at
    /usr/lib/gcc/x86_64-redhat-linux/4.4.0/../../../../include/c++/4.4.0/cmath:439
    #1 0x0000000000401ac0 in (anonymous
    namespace)::boost_numeric_ublas_sqrt<int> (t=@0x7fffffffdd98) at
    /usr/include/boost/numeric/ublas/traits.hpp:32
    #2 0x0000000000404759 in
    boost::numeric::ublas::scalar_traits<int>::type_sqrt
    (t=@0x7fffffffdd98) at /usr/include/boost/numeric/ublas/traits.hpp:107
    #3 0x0000000000403fbe in
    boost::numeric::ublas::detail::expression_type_check<boost::numeric::ublas::mapped_vector<int,
    boost::numeric::ublas::map_std<unsigned long, int,
    std::allocator<std::pair<unsigned long const, int> > > >,
    boost::numeric::ublas::vector<int,
    boost::numeric::ublas::unbounded_array<int, std::allocator<int> > >
> (e1=@0x7fffffffdee0, e2=@0x7fffffffde00) at
    /usr/include/boost/numeric/ublas/detail/vector_assign.hpp:42
    #4 0x0000000000403466 in
    boost::numeric::ublas::vector_assign<boost::numeric::ublas::scalar_assign,
    boost::numeric::ublas::mapped_vector<int,
    boost::numeric::ublas::map_std<unsigned long, int,
    std::allocator<std::pair<unsigned long const, int> > > >,
    boost::numeric::ublas::unit_vector<int, std::allocator<int> > >
    (v=@0x7fffffffdee0, e=@0x7fffffffdf20) at
    /usr/include/boost/numeric/ublas/detail/vector_assign.hpp:369
    #5 0x0000000000402e5c in
    boost::numeric::ublas::vector_assign<boost::numeric::ublas::scalar_assign,
    boost::numeric::ublas::mapped_vector<int,
    boost::numeric::ublas::map_std<unsigned long, int,
    std::allocator<std::pair<unsigned long const, int> > > >,
    boost::numeric::ublas::unit_vector<int, std::allocator<int> > >
    (v=@0x7fffffffdee0, e=@0x7fffffffdf20) at
    /usr/include/boost/numeric/ublas/detail/vector_assign.hpp:448
    #6 0x0000000000402a19 in boost::numeric::ublas::mapped_vector<int,
    boost::numeric::ublas::map_std<unsigned long, int,
    std::allocator<std::pair<unsigned long const, int> > >
>::mapped_vector<boost::numeric::ublas::unit_vector<int,
    std::allocator<int> > > (this=0x7fffffffdee0, ae=@0x7fffffffdf20,
    non_zeros=0) at /usr/include/boost/numeric/ublas/vector_sparse.hpp:312
    #7 0x0000000000401a16 in main (argc=1, argv=0x7fffffffe028) at
    ublas-int.cc:22
    (gdb)

Any ideas as to what's happening? I must admit I don't understand why
the program is calling sqrt()!

Thanks in advance,

Mark