Инициализация буст-матрицы с помощью std::vector или массива
У меня есть метод, который принимает std:: vector в качестве одного из своих параметров. Есть ли способ, которым я могу инициализировать матрицу, назначая матрицу std:: vector? Вот что я пытался сделать ниже. Кто-нибудь знает, как я могу добиться назначения вектора (или даже указатель двойников) на матрицу? Заранее спасибо. Майк
void Foo(std::vector v)
{
matrix<double> m(m, n, v);
// work with matrix...
}
3 ответа
В соответствии с документацией по расширенной матрице для класса матрицы существует 3 конструктора: пустой, копируемый и один, принимающий два типа size_ty для числа строк и столбцов. Так как boost не определяет его (вероятно, потому что есть много способов сделать это, и не каждый класс способен определить преобразование в любой другой класс), вам нужно будет определить преобразование.
Вот подход, который я бы использовал, но поскольку есть несколько способов сделать это, и вопрос не определяет, как вы хотите, чтобы это было сделано, вы можете найти другой подход, более подходящий для вашей ситуации.
void Foo(const std::vector<double> & v) {
size_t m = ... // you need to specify
size_t n = ... // you need to specify
if(v.size() < m * n) { // the vector size has to be bigger or equal than m * n
// handle this situation
}
matrix<double> mat(m, n);
for(size_t i=0; i<mat.size1(); i++) {
for(size_t j=0; j<mat.size2(); j++) {
mat(i,j) = v[i+j*mat.size1()];
}
}
}
Несколько замечаний по поводу предоставленного вами кода: std::vector нужен шаблонный аргумент, и вы объявляете m
в качестве матрицы и входного аргумента для его конструктора.
Вот еще один пример того, как это можно сделать:
#include <algorithm>
#include <vector>
#include <boost/numeric/ublas/storage.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>
namespace ublas = boost::numeric::ublas;
template <typename T, typename F=ublas::row_major>
ublas::matrix<T, F> makeMatrix(std::size_t m, std::size_t n, const std::vector<T> & v)
{
if(m*n!=v.size()) {
; // Handle this case
}
ublas::unbounded_array<T> storage(m*n);
std::copy(v.begin(), v.end(), storage.begin());
return ublas::matrix<T>(m, n, storage);
}
int main () {;
std::vector<double> vec {1, 2, 3, 4, 5, 6};
ublas::matrix<double> mm = makeMatrix(3,2,vec);
std::cout << mm << std::endl;
}
Более удобный способ такой:
matrix<double> m(m*n);
std::copy(v.begin(), v.end(), m.data().begin());
Простой ответ, но не очень очевидный из документации Boost.
Вы можете просто использовать std::vector<> как тип параметра шаблона массива хранения вместо unbounded_array<> по умолчанию для вашей матрицы. (Это упомянуто в сноске 2 документации по классу matrix<>.)
void Foo(const std::vector<double> &v, size_t n)
{
using namespace boost::numeric::ublas;
size_t m = v.size() / n;
matrix< double, row_major, std::vector<double> > M(m, n);
M.data() = v;
// work with matrix...
}
Дополнительные варианты инициализации можно найти в вашем источнике boost: https://svn.boost.org/svn/boost/trunk/libs/numeric/ublas/doc/samples/assignment_examples.cpp, как указано здесь: назначьте несколько значений для boost:: numeric:: ublas::vector в C++
Или здесь: примеры uBLAS, пример 3, который упоминается в связанном вопросе: ublas: Обернуть ublas::vector как ublas::matrix_expression