I have a method that takes a std::vector as one of its parameters. Is there a way I can initialize a matrix by assigning the std::vector to the matrix? Here's what I tried to do below. Does anyone know how i can achieve assigning the vector (or even a pointer of doubles) to the matrix? Thanks in advance. Mike
void Foo(std::vector v)
{
matrix<double> m(m, n, v);
// work with matrix...
}
Here is yet another example of how this can be done:
#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;
}
According to the boost matrix documentation, there are 3 constructors for the matrix class: empty, copy, and one taking two size_types for the number of rows and columns. Since boost doesn't define it (probably because there are many ways to do it and not every class is gong to define a conversion into every other class) you are going to need to define the conversion.
Here's an approach that I would use, but since there are multiple ways to do this and the question doesn't specify how you want this done you may find a different approach more applicable to your situation.
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()];
}
}
}
A couple of notes about your provided code: std::vector needs a templated argument and you are declaring m
as a matrix and an input argument to it's constructor.
A more convenient way is like this:
matrix<double> m(m*n);
std::copy(v.begin(), v.end(), m.data().begin());
Simple answer, but not very apparent from the Boost documentation.
You may just use std::vector<> as type of storage array template paramerter instead of default unbounded_array<> for your matrix. (It's mentioned in footnote 2 of documentation on matrix<> class.)
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...
}
More variants of initialization can be found in your boost source: boost/libs/numeric/ublas/doc/samples/assignment_examples.cpp, as pointed out here: assign multiple values to boost::numeric::ublas::vector in c++
Or here: uBLAS examples, example 3, which is mentioned by related question: ublas: Wrap ublas::vector as ublas::matrix_expression
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With