用Stl矩阵初始化Boost矩阵

时间:2018-07-13 09:38:27

标签: c++ c++11 matrix boost

是否有更好的(简短/替代)方法?

#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>
using namespace boost::numeric::ublas;
int main () {
    int size = 2;
    matrix<double> a(size, size, 1);
    std::vector<std::vector<double>> s(size,std::vector<double>(size, 2));
    matrix<double> c(size, size);
    for (int i = 0; i < size; ++i) 
        for (int j = 0; j < size; ++j) 
            c(i, j) = s[i][j];
    std::cout << a << std::endl << std::endl;
    std::cout << c << std::endl << std::endl;
    std::cout << prod (a, c) << std::endl << std::endl;
}

我认为像matrix<double> c(s);之类的东西会更好。我尝试了(有趣的是,如果我注释掉最后三行,它将进行编译)。

#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>

#include <vector>

using std::copy;

using namespace boost::numeric::ublas;

int main () {
    int size = 2;
    matrix<double> a(size, size, 1);

    std::vector<std::vector<double>> s(size,std::vector<double>(size, 3));
    vector<double, std::vector<std::vector<double>> > c(s);

    std::cout << a << std::endl << std::endl;
    std::cout << c << std::endl << std::endl;
    std::cout << prod (a, c) << std::endl << std::endl;
}

但得到:

c++ -g -Wall -O3 -std=gnu++11 -I boost_1_67_0   -c -o main.o main.cpp
In file included from main.cpp:1:
In file included from boost_1_67_0/boost/numeric/ublas/matrix.hpp:18:
boost_1_67_0/boost/numeric/ublas/vector.hpp:223:18: error: no viable conversion from returned value of type 'const std::__1::__vector_base<std::__1::vector<double, std::__1::allocator<double> >, std::__1::allocator<std::__1::vector<double, std::__1::allocator<double> > > >::value_type' (aka 'const std::__1::vector<double, std::__1::allocator<double> >') to function return type 'const boost::numeric::ublas::type_traits<double>::value_type' (aka 'const double')
                 return data () [i];
                        ^~~~~~~~~~~
boost_1_67_0/boost/numeric/ublas/io.hpp:58:18: note: in instantiation of member function 'boost::numeric::ublas::vector<double, std::__1::vector<std::__1::vector<double, std::__1::allocator<double> >, std::__1::allocator<std::__1::vector<double, std::__1::allocator<double> > > > >::operator()' requested here
            s << v () (0);
                 ^
main.cpp:18:15: note: in instantiation of function template specialization 'boost::numeric::ublas::operator<<<char, std::__1::char_traits<char>, boost::numeric::ublas::vector<double, std::__1::vector<std::__1::vector<double, std::__1::allocator<double> >, std::__1::allocator<std::__1::vector<double, std::__1::allocator<double> > > > > >' requested here
    std::cout << c << std::endl << std::endl;
              ^
In file included from main.cpp:1:
In file included from boost_1_67_0/boost/numeric/ublas/matrix.hpp:18:
In file included from boost_1_67_0/boost/numeric/ublas/vector.hpp:22:
boost_1_67_0/boost/numeric/ublas/vector_expression.hpp:74:20: error: no matching function for call to object of type 'const boost::numeric::ublas::vector_reference<const boost::numeric::ublas::vector<double, std::__1::vector<std::__1::vector<double, std::__1::allocator<double> >, std::__1::allocator<std::__1::vector<double, std::__1::allocator<double> > > > > >::referred_type' (aka 'const boost::numeric::ublas::vector<double, std::__1::vector<std::__1::vector<double, std::__1::allocator<double> >, std::__1::allocator<std::__1::vector<double, std::__1::allocator<double> > > > >')
            return expression () (i);
                   ^~~~~~~~~~~~~
boost_1_67_0/boost/numeric/ublas/functional.hpp:833:37: note: in instantiation of member function 'boost::numeric::ublas::vector_reference<const boost::numeric::ublas::vector<double, std::__1::vector<std::__1::vector<double, std::__1::allocator<double> >, std::__1::allocator<std::__1::vector<double, std::__1::allocator<double> > > > > >::operator()' requested here
                t += e1 () (i, j) * e2 () (j);
                                    ^
boost_1_67_0/boost/numeric/ublas/matrix_expression.hpp:4013:34: note: in instantiation of function template specialization 'boost::numeric::ublas::matrix_vector_prod1<boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >, boost::numeric::ublas::vector<double, std::__1::vector<std::__1::vector<double, std::__1::allocator<double> >, std::__1::allocator<std::__1::vector<double, std::__1::allocator<double> > > > >, double>::apply<boost::numeric::ublas::matrix_reference<const boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > > >, boost::numeric::ublas::vector_reference<const boost::numeric::ublas::vector<double, std::__1::vector<std::__1::vector<double, std::__1::allocator<double> >, std::__1::allocator<std::__1::vector<double, std::__1::allocator<double> > > > > > >' requested here
            return functor_type::apply (e1_, e2_, i);
                                 ^
boost_1_67_0/boost/numeric/ublas/io.hpp:58:18: note: in instantiation of member function 'boost::numeric::ublas::matrix_vector_binary1<boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >, boost::numeric::ublas::vector<double, std::__1::vector<std::__1::vector<double, std::__1::allocator<double> >, std::__1::allocator<std::__1::vector<double, std::__1::allocator<double> > > > >, boost::numeric::ublas::matrix_vector_prod1<boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >, boost::numeric::ublas::vector<double, std::__1::vector<std::__1::vector<double, std::__1::allocator<double> >, std::__1::allocator<std::__1::vector<double, std::__1::allocator<double> > > > >, double> >::operator()' requested here
            s << v () (0);
                 ^
main.cpp:19:15: note: in instantiation of function template specialization 'boost::numeric::ublas::operator<<<char, std::__1::char_traits<char>, boost::numeric::ublas::matrix_vector_binary1<boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >, boost::numeric::ublas::vector<double, std::__1::vector<std::__1::vector<double, std::__1::allocator<double> >, std::__1::allocator<std::__1::vector<double, std::__1::allocator<double> > > > >, boost::numeric::ublas::matrix_vector_prod1<boost::numeric::ublas::matrix<double, boost::numeric::ublas::basic_row_major<unsigned long, long>, boost::numeric::ublas::unbounded_array<double, std::__1::allocator<double> > >, boost::numeric::ublas::vector<double, std::__1::vector<std::__1::vector<double, std::__1::allocator<double> >, std::__1::allocator<std::__1::vector<double, std::__1::allocator<double> > > > >, double> > >' requested here
    std::cout << prod (a, c) << std::endl << std::endl;
              ^
boost_1_67_0/boost/numeric/ublas/vector.hpp:230:17: note: candidate function not viable: 'this' argument has type 'const boost::numeric::ublas::vector_reference<const boost::numeric::ublas::vector<double, std::__1::vector<std::__1::vector<double, std::__1::allocator<double> >, std::__1::allocator<std::__1::vector<double, std::__1::allocator<double> > > > > >::referred_type' (aka 'const boost::numeric::ublas::vector<double, std::__1::vector<std::__1::vector<double, std::__1::allocator<double> >, std::__1::allocator<std::__1::vector<double, std::__1::allocator<double> > > > >'), but method is not marked const
             reference operator () (size_type i) {
                       ^
2 errors generated.
make: *** [main.o] Error 1
[Finished in 1.1s with exit code 2]
[shell_cmd: make]

2 个答案:

答案 0 :(得分:1)

您需要flatten std::vector<std::vector<double>>,然后才能复制到boost::ublas::matrix

std::copy(flatten(s.begin(), s.end()), flatten(s.end()), c.begin1()); 
// or c.begin2() if s is column major

答案 1 :(得分:1)

实际上,如果没有展平范围,则可以“流”到矩阵:

auto out = c.begin2();
for (auto& v : s)
    out = boost::copy(v, out);

Live On Coliru

#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/range/algorithm/copy.hpp>

using namespace boost::numeric::ublas;

int main() {
    int size = 2;
    matrix<double> a(size, size, 1);

    std::vector<std::vector<double> > s(size, std::vector<double>(size, 2));

    matrix<double> c(size, size);
    auto out = c.begin2();
    for (auto& v : s)
        out = boost::copy(v, out);

    std::cout << a << std::endl << std::endl;
    std::cout << c << std::endl << std::endl;

    std::cout << prod(a, c) << std::endl << std::endl;
}

打印

[2,2]((1,1),(1,1))

[2,2]((2,2),(2,2))

[2,2]((4,4),(4,4))