Map Eigen replicate Matrix - c++

I am trying to bring code from Matlab to C++. There is some information related to my case in the KDE Eigen Forums.
What I try to achieve is related to Matlab's meshgrid, for which the solution given over there is
X = RowVectorXd::LinSpaced(1,3,3).replicate(5,1);
Y = VectorXd::LinSpaced(10,14,5).replicate(1,3);
i.e., .replicate the vectors the amount of the other dimension. In my case I have two existing (n x 1) vectors and want to create a (n^2, 2) matrix which contains all combinations of vector elements, that is:
[1 3 6]^T and [7 8]^T ==> [1 7, 3 7, 6 7, 1 8, 3 8, 6 8]^T
where ^T just means transposed, lines are comma-separated. (In my case the vectors use floats, but that shouldn't matter).
The first column of the matrix [1 3 6 1 3 6]^T is easily created by Eigen's .replicate function. However, I struggle to create the second column [7 7 7 8 8 8]^T.
My idea was to use .replicate in the other dimension (obtaining a matrix) and then use a rowWise Eigen::Map to bring it to a linear (vector) view (as suggested in the docs), but I understand the arising compiler error such that Eigen::Map doesn't work with an Eigen::Replicate type.
#include <Eigen/Core>
using namespace Eigen;
int main()
{
MatrixXd reptest1(1, 5);
reptest1 << 1, 2, 3, 4, 5;
auto result2 = reptest1.replicate(2, 1); // cols, rows: 5, 2
auto result3 = Map<Matrix<double, 1, Dynamic, Eigen::RowMajor> >(result2); // this doesn't work
return 0;
}
VS2017 complains: error C2440: '<function-style-cast>': cannot convert from 'Eigen::Replicate<Derived,-1,-1>' to 'Eigen::Map<Eigen::Matrix<double,1,-1,1,1,-1>,0,Eigen::Stride<0,0>>'
GCC also complains. no matching function for call (can't copy&paste exact message as it is on another machine).
Am I doing this too complicated? Should using Map work?

Map can only work on matrices, not on expressions. So replace auto result2 by MatrixXd result2, and you're done. See common pitfalls.

Related

How to access multiple elements in c++ Eigen array?

I want to retrieve certain elements in an Eigen array and return them as a vector. I use the following code:
Eigen::ArrayXXi test;
test.resize(5,5);
test.setRandom();
Eigen::Matrix<int, 2, 3> inds;
inds<<0, 2, 3, 2, 3, 1;
auto res = test(inds.row(0), inds.row(1));
std::cout<<"test: \n"<<test <<std::endl;
std::cout<<"inds: \n"<<inds <<std::endl;
std::cout<<"res: \n"<<res <<std::endl;
The output is:
test:
730547559 -649503489 -48539462 893772102 -1038736613
-226810938 -353856438 276748203 291438716 -552146456
607950953 576018668 -290373134 466641602 -779039257
640895091 -477225175 28778235 -769652652 653214605
884005969 115899597 971155939 229713912 -737276042
inds:
0 2 3
2 3 1
res:
-48539462 893772102 -649503489
-290373134 466641602 576018668
28778235 -769652652 -477225175
The result is a matrix. I note that the diagonal of the matrix is the result I want. I could use res.diagonal() to retrieve the vector. However, I am still wondering if I can do the same thing in a more efficient way.
You can reshape the test Array to a column and then use the single-index access operator:
auto res = test.reshaped()(inds.row(0) + test.rows() * inds.row(1));
Generally, be careful when using auto with Eigen expressions (this case is fine, as long as test and inds are still valid when res is used).

Writing data into Eigen::Matrix row

I would like to write the (row-major ordered) data into a row of an Eigen::Matrix. I found a way, but to me it looks inefficient. Is there a faster/more concise way?
// 24 x 16 D Matrix
Eigen::Matrix<double, JOINT_NUM, 16> Mat;
// 4 x 4 D Matrix, stored in row major order to paste data correctly
Eigen::Matrix<double, 4, 4, Eigen::RowMajor> row0_rowMajor = row0;
// copy data from row major Matrix into first row of Mat
Mat.row(0) = Eigen::Map<Eigen::RowVectorXd>(row0_rowMajor.data(), row0_rowMajor.size());
Thanks!
Edit:
Here is a minimal working example, you can compile it with g++ -I/usr/include/eigen3 file.cpp and run with ./a.out:
#include <Eigen/Core>
#include <iostream>
int main(int argc, const char* argv[]) {
// 24 x 16 D Matrix
Eigen::Matrix<double, 2, 16> Mat_rowMajor;
Eigen::Matrix<double, 2, 16> Mat;
Mat.setZero();
Mat_rowMajor.setZero();
Eigen::Matrix4d row0;
row0 << 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15;
// 4 x 4 D Matrix, stored in row major order to paste data correctly
Eigen::Matrix<double, 4, 4, Eigen::RowMajor> row0_rowMajor = row0;
// copy data from row major Matrix into first row of Mat
Mat.row(0) = Eigen::Map<Eigen::RowVectorXd>(row0.data(), row0.size());
Mat_rowMajor.row(0) = Eigen::Map<Eigen::RowVectorXd>(row0_rowMajor.data(), row0_rowMajor.size());
std::cout << "row0:\n" << row0 << std::endl;
std::cout << "Matrix:\n" << Mat << std::endl;
std::cout << "Matrix Row-Major:\n" << Mat_rowMajor << std::endl;
return 1;
}
My aim is to get rid of the copying into the Eigen::Matrix<double, 4, 4, Eigen::RowMajor>, and work directly with row0, and remove the Eigen::Map... by just a simple copy if possible. It just makes the code much more readable, concise, and less prone to errors. Also, the copying is slow for larger matrices, which I'd like to avoid.
Eigen doesn't come with a vector-like view of a matrix, as far as I know. So the approach of using a Map is already pretty good. However, it is also very brittle.
Since your ultimate goal is to store into a row of a column-major matrix, vectorization is out of the question. That's why I don't think you can improve performance by doing something fancy. So you can go for something simple instead. Like this:
Eigen::Matrix<double, JOINT_NUM, 16> Mat;
const Eigen::Matrix4d row0 = ...;
auto out_row = Mat.row(0);
for(Eigen::Index i = 0; i < row0.rows(); ++i)
out_row.segment(i * row0.cols(), row0.cols()) = row0.row(i);
At least this makes it clear what is going on.
Side note: The reason why Eigen doesn't have a convenient view is likely that this keeps you stuck between a rock and a hard place when you want to support the general case:
Practically all methods should work on both block expressions and full matrices. In a block expression, the Map approach doesn't work because there is a gap between consecutive columns (in a column-major matrix).
So instead you would need a custom view type to translate indices. However, now you are translating from a 1D index to a 2D index, which requires a costly division on every access.
Other linear algebra packages like Numpy have the same issue. However, Numpy for example is more liberal in its memory allocations and would create a copy if it needs to. The only Eigen type that does copies if required, is Eigen::Ref and that comes with its own set of problems.
With Eigen 3.4 you can simply use the reshaped<>() mechanism:
Mat.row(0) = row0.reshaped<Eigen::RowMajor>();
Prior to Eigen 3.4, you can manually create a map (onto the data of Mat.row(0)), but you need to manually calculate some strides. E.g., if Mat is a column-major matrix, the index difference between two columns would be Mat.rows() (which would correspond to the "outer stride"), the difference between two rows would be 4*Mat.rows() (corresponding to the "inner stride"):
Eigen::Matrix4d::Map(Mat.row(0).data(), // address of first element
Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic> // stride object
(Mat.rows(), // column-stride/"outer stride"
4*Mat.rows()) // row-stride/"inner stride"
) = row0; // end of `Map()` and assignment of a 4x4 matrix `row0`
Alternatively, you could create a Map from a row-major 4x4 matrix, which would switch the meaning of inner and outer stride.
Overall, if you intend to store matrices in rows of Mat you should also consider making Mat itself row-major. In that case, each row of Mat would be stored in 16 consecutive bytes making the Map easier to create (and having memory locality is often advantageous anyway).

divide a ndarray by narray element-wise

I have this ndarray (not matrix):
mx = np.array([[10,25,33],[3,1,5],[50,50,52]])
[[10 25 33]
[ 3 1 5]
[50 50 52]]
and I want to get a ndarray of shares by dividing every element by the sum of the column. So the result of this operation:
[[10/63 25/76 33/90]
[ 3/63 1/76 5/90]
[50/63 50/76 52/90]]
I can do
np.true_divide(mx,mx.sum(axis=0))
Are ther some build-in functions to calculate shares or stuff like that?
The problem is related to how int behaves in division between python2 and python3. Should you start with float array it would work fine. There is also np.true_divide() that you mention in the comment.

Determine all square sub matrices of a given NxN matrix in C++

GIven an NxN square matrix, I would like to determine all possible square sub matrices by removing equal number of rows and columns.
In order to determine all possible 2x2 matrices I need to loop 4 times. Similarly for 3x3 matrices I need to loop 6 times and so on. Is there a way to generate code in C++ so that the code for the loops is generated dynamically? I have checked some answers related to code generation in C++, but most of them use python in it. I have no idea regarding python. So, is it possible to write code to generate code in C++?
If I get what you are saying, you mean you require M loops to choose M rows, and M loops for M columns for an M x M sub matrix, 1 <= M <= N
You don't need 2*M loops to do this. No need to dynamically generate code with an ever-increasing number of loops!
Essentially, you need to "combine" all possible combinations of i_{1}, i_{2}, ..., i_{M} and j_{1}, j_{2}, ..., j_{M} such that 1 <= i_{1} < i_{2} < ... < i_{M} <= N (and similarly for j)
If you have all possible combinations of all such i_{1}, ..., i_{M} you are essentially done.
Say for example you are working with a 10 x 10 matrix and you require 4 x 4 sub matrices.
Suppose you selected rows {1, 2, 3, 4} and columns {1, 2, 3, 4} initially. Next select column {1, 2, 3, 5}. Next {1, 2, 3, 6} and so on till {1, 2, 3, 10}. Next select {1, 2, 4, 5}, next {1, 2, 4, 6} and so on till you reach {7, 8, 9, 10}. This is one way you could generate all ("10 choose 4") combinations in a sequence.
Go ahead, write a function that generates this sequence and you are done. It can take as input M, N, current combination (as an array of M values) and return the next combination.
You need to call this sequence to select the next row and the next column.
I have put this a little loosely. If something is not clear I can edit to update my answer.
Edit:
I will be assuming loop index starts from 0 (the C++ way!). To elaborate the algorithm further, given one combination as input the next combination can be generated by treating the combination as a "counter" of sorts (except that no digit repeats).
Disclaimer : I have not run or tested the below snippet of code. But the idea is there for you to see. Also, I don't use C++ anymore. Bear with me for any mistakes.
// Requires M <= N as input, (N as in N x N matrix)
void nextCombination( int *currentCombination, int M, int N ) {
int *arr = currentCombination;
for( int i = M - 1; i >= 0; i-- ) {
if( arr[i] < N - M + i ) {
arr[i]++;
for( i = i + 1, i < M; i++ ) {
arr[i] = arr[i - 1] + 1;
}
break;
}
}
}
// Write code for Initialization: arr = [0, 1, 2, 3]
nextCombination( arr, 4, 10 );
// arr = [0, 1, 2, 4]
// You can check if the last combination has been reached by checking if arr[0] == N - M + 1. Please incorporate that into the function if you wish.
Edit:
Actually I want to check singularity of all possible sub matrices. My approach is to compute all submatrices and then find their determinants. How ever after computing the determinant of 2x2 matrices , I'll store them and use while computing determinants of 3x3 matrices. And so on. Can you suggest me a better approach. I have no space and time constraints. – vineel
A straight-forward approach using what you suggest is to index the determinants based on the the rows-columns combination that makes a sub matrix. At first store determinants for 1 x 1 sub matrices in a hash map (basically the entries themselves).
So the hash map would look like this for the 10 x 10 case
{
"0-0" : arr_{0, 0},
"0-1" : arr_{0, 1},
.
.
.
"1-0" : arr_{1, 0},
"1-1" : arr_{1, 1},
.
.
.
"9-9" : arr_{9, 9}
}
When M = 2, you can calculate determinant using the usual formula (the determinants for 1 x 1 sub matrices having been initialized) and then add to the hash map. The hash string for a 2 x 2 sub matrix would look something like 1:3-2:8 where the row indices in the original 10 x 10 matrix are 1,3 and the column indices are 2, 8. In general, for m x m sub matrix, the determinant can be determined by looking up all necessary (already) computed (m - 1) x (m - 1) determinants - this is a simple hash map lookup. Again, add the determinant to hash map once calculated.
Of course, you may need to slightly modify the nextCombination() function - it currently assumes row and column indices run from 0 to N - 1.
On another note, since all sub matrices are to be processed starting from 1 x 1, you don't need something like a nextCombination() function. Given a 2 x 2 matrix, you just need to select one more row and column to form a 3 x 3 matrix. So you need to select one row-index (that's not part of the row indices that make the 2 x 2 sub matrix) and similarly one column-index. But doing this for every 2 x 2 matrix will generate duplicate 3 x 3 matrices - you need to think of some way to eliminate duplicates. One way to avoid duplicates is by choosing only such row/column whose index is greater than the highest row/column index in the sub matrix.
Again I have loosely defined the idea. You can build upon it.

pointer to sub-row of Eigen MatrixXd that behaves like a VectorXd

I have an Eigen MatrixXd and need a pointer to some subsequent entries of some row. I would like to be able to use this pointer. I have something like this:
Eigen::MatrixXd* matrix = new MatrixXd(3, 3);
(*matrix) << 1, 2, 3,
4, 5, 6,
7, 8, 9;
Block<MatrixXd, 1, Dynamic, false, true> full_row = (*matrix).row(1);
// this gives me the full row. I am interested only in the row containing 5 6.
Block<MatrixXd> part_row = (*matrix).block(1, 1, 1, 2);
// this gives me the partial row that I want, but now i need two indices to
// access an element.
part_row(0, 1) = 3; // works
part_row(1) = 3; // gives compiler error
I would like to be able to directly access the partial row, without having to copy the values. This is really important, since it has to be done often and I cannot afford to copy vectors back and forth. (I believe I cannot expect the compiler to optimize out the copying, since the sizes of the matrices are generally unknown). Any help is greatly appreciated. Cheers!
You need to specify that your submatrix is a vector:
Block<MatrixXd,1,Dynamic> part_row(*matrix, 1, 1, 1, 2);