9

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...
}
1
  • 1
    A matrix is a two dimensional structure, a vector is a one dimensional structure. How do you plan to determine the correct dimensions for the matrix by inspecting the vector? Commented Nov 13, 2011 at 4:12

4 Answers 4

6

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;
}
Sign up to request clarification or add additional context in comments.

Comments

4

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.

Comments

4

A more convenient way is like this:

matrix<double> m(m*n);
std::copy(v.begin(), v.end(), m.data().begin());

Comments

2

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.