Reputation: 407
I come from Python. I have a linear algebra problem to treat in C++, and I chose to use Armadillo to do so, as it advertises itself as being MATLAB-like, thus SciPy-like.
I'm looking for a way to populate two matrices, one with the rows, one with the columns of a 2D-matrix of given shape (in Python, that would be numpy.indices).
For instance, if I have a 4 rows/3 columns matrix shape, what I want is to build a row matrix:
0 0 0
1 1 1
2 2 2
3 3 3
and a column matrix:
0 1 2
0 1 2
0 1 2
0 1 2
in order to do some calculations afterwards.
It is similar to C++ Armadillo Generate Indices uvec of a given vec or matrix without looping it but with a matrix instead of a 1D-vector.
Is there a way to do so without too much looping? I know about linspace to populate a vector, but I'd prefer not to loop over a a bunch of vectors to merge them in a matrix. I am just starting with Armadillo, and I am not really aware of its capabilities yet (basically, I just have matrices products and inversion to do).
Upvotes: 0
Views: 2237
Reputation: 154
While the answer given does generate the requested matrices the OP asked for a solution not using loops. This answer uses regspace and repmat and is perhaps conceptually simpler:
#include <iostream>
#include <armadillo>
using namespace std;
using namespace arma;
int main (int argc, char const* argv[])
{
ivec a_col = regspace<ivec>(0, 3);
imat A = repmat(a_col, 1, 3);
irowvec b_row = regspace<irowvec>(0,2);
imat B = repmat(b_row, 4, 1);
cout << A << endl;
cout << B << endl;
return 0;
}
I have to confess that I'm a little new to armadillo so I won't promise that this is fast or follows best practices, but I think it's probably closest to equivalent SciPy code.
Upvotes: 1
Reputation: 527
@Aubergine. The armadillo library is very useful for scientific computing and easy to pick up. I would encourage to get family with its documentation page armadillo documentation
Concerning your particular problem, here is a solution I am proposing:
#include<iostream>
#include<armadillo>
using namespace std;
using namespace arma;
int main(int argc, char **argv)
{
// Create two matrices A and B of shape 4x3 filled with zeros
imat A = zeros<imat>(4, 3);
imat B = zeros<imat>(4, 3);
// Fill each row
for(int i=0; i < 4; i++)
{
A.row(i) = i * ones<ivec>(3).t(); //
}
// Fill each column
for(int i=0; i < 3; i++)
{
B.col(i) = i * ones<ivec>(4);
}
cout << "A = \n" << A << endl;
cout << "B = \n" << B << endl;
return 0;
}
The compilation goes like this on my computers (Mac OSX and Ubuntu):
g++ -std=c++11 -O2 `pkg-config --cflags --libs armadillo` testArmadillo.cpp -o a.out
Then, we can run the executable simply by typing:
./a.out
and the output is as follows:
A =
0 0 0
1 1 1
2 2 2
3 3 3
B =
0 1 2
0 1 2
0 1 2
0 1 2
For more information about imat, ivec, see imat and ivec
Upvotes: 1