Search code examples
c++armadillo

C++ Armadillo: arrays of indices from 2D-matrix


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).


Solution

  • @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