Применение Boost UBLAS blas-1 к матрицам

Как применить blas уровня 1 к матрице boost::numeric::ublas? Например, я хочу вычислить максимальную запись или сумму всех записей. Использование norm_1 или norm_inf на матрице не дает ошибки компилятора, но возвращает (как мне кажется) произвольные результаты. Я использую буст 1.42


person Andreas Mueller    schedule 26.08.2011    source источник


Ответы (2)


norm_inf на матрице вычисляет норму матрицы, индуцированную бесконечностью -норма в базовом векторном пространстве. Это максимальная абсолютная сумма строк матрицы.

Если вы посмотрите на пример hannes, последняя строка матрицы (i=99, j=0...99) содержит:

9900, 9901, 9902, ... , 9999

Если вы суммируете эти записи, вы получите 994950, что и дает norm_inf.

person Stephen Canon    schedule 28.08.2011
comment
Это хорошо знать. Это где-то задокументировано? Я не нашел. Вы знаете, как рассчитать максимум всех записей? Используя ваш пост, это можно было бы сделать с изменением формы, но это кажется немного странным. - person Andreas Mueller; 29.08.2011
comment
@Andreas: предполагая, что матрица расположена в памяти непрерывно (вероятно, но я не знаю, гарантирует ли это uBLAS или нет - кто-то еще должен будет взвесить этот момент), предположительно можно было бы построить векторный объект, поддерживаемый тем же хранилищем и вызовите norm_inf на нем. Некрасиво, но я думаю, что это сработает. - person Stephen Canon; 29.08.2011
comment
И нет, я не смог найти никакой фактической документации об этом, но это имеет смысл и соответствует поведению. Беглый поиск вообще не нашел много документации по uBLAS. - person Stephen Canon; 29.08.2011

Минимальный пример выглядит так:

    #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;
    }

Это должно дать 99, но дает 994950.

Это однострочник, который как минимум решает поставленную задачу:

    float infnorm = accumulate(m.data().begin(),m.data().end(),0,std::max<double>);
person hannes    schedule 26.08.2011
comment
Я не верю, что однострочник действительно работает; спрашивающий хочет получить максимальную абсолютную запись. - person Stephen Canon; 29.08.2011