2

How do I apply level 1 blas on a boost::numeric::ublas matrix? For example I want to compute the maximum entry or the sum of all entries. Using norm_1 or norm_inf on a matrix gives no compiler error but returns (as it seems to me) arbitrary results. I am using boost 1.42

Andreas Mueller
  • 27,470
  • 8
  • 62
  • 74

2 Answers2

3

norm_inf on a matrix computes the matrix norm induced by the infinity-norm on the underlying vector space. This happens to be the maximum absolute row sum of the matrix.

If you look at hannes's example, the last row of the matrix (i=99, j=0...99) contains:

9900, 9901, 9902, ... , 9999

If you sum those entries, you get 994950, which is exactly what norm_inf produces.

Stephen Canon
  • 103,815
  • 19
  • 183
  • 269
  • That's good to know. Is that documented somewhere? I didn't find it. Do you know how to calculate the maximum of all the entries? Using your post it could be done with a reshape but that seems a bit weird. – Andreas Mueller Aug 29 '11 at 05:30
  • @Andreas: assuming that the matrix is laid out contiguously in memory (likely, but I don't know if uBLAS guarantees that or not -- someone else will have to weigh in on that point), one could presumably construct a vector object backed by the same storage and call `norm_inf` on that. Ugly, but I imagine it would work. – Stephen Canon Aug 29 '11 at 06:20
  • And no, I couldn't find any actual documentation of that, but it makes sense and matches the behavior. A cursory search didn't find much documentation of uBLAS at all, actually. – Stephen Canon Aug 29 '11 at 06:21
1

A minimal example looks like this:

    #include<iostream>
    #include<boost/numeric/ublas/matrix.hpp>
    using namespace boost::numeric::ublas;
    int main(){
            int l = 100;
            matrix<double> m(l,l);
            for (int i = 0; i < l; ++i) {
                    for (int j = 0; j < l; ++j) {
                            m(i,j)=i*l+j;
                    }
            }
            std::cout << norm_inf(m)<<std::endl;
            return 0;
    }

It should give 99, but yields 994950.

This is a one-liner that at least solves the given task:

    float infnorm = accumulate(m.data().begin(),m.data().end(),0,std::max<double>);
hannes
  • 966
  • 9
  • 13