dvlper
dvlper

Reputation: 472

Eigen::MatrixXd.block assignment using a std::vector

Idea is to assign values from a std::vector to a block in Eigen::MatrixXd.

My question is, what is a good way to do?

 1 1 1        1   1   1
 1 1 1    to  1 102 123
 1 1 1        1   1   1

I tried converting the std::vector to an Eigen::Map, but with no success. I have a working code [following snippet], but it doesn't appeal much. Perhaps there is a simpler way?

    void do_work(Eigen::MatrixXd &m, const std::vector<double> &v,
                 const Index i, const Index j, 
                 const Index p, const Index q) {
      auto stop = j + q;
      for (Index start = j, idx = 0; start < stop; ++start, ++idx)
        m.block(i, start, p, 1) << v[idx];
    }

    Eigen::MatrixXd m(3, 3);
    m << 1, 1, 1, 1, 1, 1, 1, 1, 1;
    std::vector<double> v = {102, 123};
    Index change_row = 0;
    Index change_column_from = 1, change_column_to = v.size();
    do_work(m, v, change_row, change_column_from, 1, change_column_to);

Expected result would be to perform the operation in an efficient (and maybe more clean) way.

Upvotes: 2

Views: 805

Answers (1)

chtz
chtz

Reputation: 18807

To convert a std::vector<double> to an Eigen::Map write, e.g.

Eigen::Map<Eigen::VectorXd> map(v.data(), v.size());

for read-writable access, or the following, if you have read-only access to your vector:

Eigen::Map<const Eigen::VectorXd> map(v.data(), v.size());

This can be assigned to a block-expression, assuming the size of the block matches the size of the Map:

m.block(i,j, map.size(), 1) = map.transpose();
                               // transpose is actually optional here

Upvotes: 3

Related Questions