Joni
Joni

Reputation: 375

Parentheses followed by parentheses

I am trying to understand what a piece of C++ code is doing, but know nothing about C.

I have a loop like this:

(_A[0])=eigenMatrix::Zero(_n, _n);

for(i=0; i<_n; i++){
    for(j=0; j<=i; j++) (_A[0])(j,i)=(_A[0])(i,j)=value[i*n+j];
}

A is a vector of eigenMatrix type: vector <#eigenMatrix> _A;

I think the first line is defining (_A[0]) as a zero n*n matrix, but I can't work out what the (_A[0])(j,i) part is doing, and can't find any reference to this kind of ()() phrase in c++.

Upvotes: 0

Views: 712

Answers (3)

s.bandara
s.bandara

Reputation: 5664

Operator Overloading

In C++ you can respecify the meaning of various operators. For a Matrix class, it does make sense to define a meaning for parentheses:

double & Matrix::operator()(int row, int col) {
    return data[row][col];
}

would result in a Matrix object _A[0] from which elements can be obtained as in _A[0](2, 2).

lvalue Assignment

An interesting detail in your example is the assignment to an lvalue -- you can see _A[0](j,i) is on the left-hand side. Such an assignment is possible because we return a reference (double &) to the inner representation data.

If you open the header file that provides you with eigenMatrix (or rather its base class), you will find a declaration of a reference (&) returned by some Matrix::operator() method.

Why bother?

It provides convenient access to matrix elements while at the same time providing more control than simply exposing the inner data directly. For example you could imagine checks like

double & Matrix::operator()(int row, int col) {
    assert((row >= 0) && (row < n_row) && (col >=0 ) && (col < n_col));
    return data[row][col];
}

Upvotes: 3

Fantastic Mr Fox
Fantastic Mr Fox

Reputation: 33864

Lets break down this code.

so lets assume that this line:

(_A[0])=eigenMatrix::Zero(_n, _n);

is actually

A = eigen::Matrix::Zero(_n, _n);

I am making this assumption because

  1. Only element 0 of _A is ever accessed.
  2. I think maybe you are using the eigen Library.

The next part is then a little easier.

for(i=0; i<_n; i++){ // Loop from 0 to `_n` which is the size of the Zero Matrix. 
    for(j=0; j<=i; j++) // Loop from 0 to i, this means you are only accessing the
                        // lower left side of the matrix. 

                        i=0 -> [j=0, ... No Access
                        i=1 -> [j=0, j=1, ... No Access
                        i=_n -> [j=0, j=1, ... j=_n

         (A)(j,i) = (A)(i,j) = value[i*n+j]; 

The first part is redundant, you are assigning to yourself.

The second part ( = value[...]) is assigning the currently looked at matrix element to the same element but in a 2D array stored as a 1D vector called value. }

Upvotes: 0

Karol Czaradzki
Karol Czaradzki

Reputation: 389

I am not sure why () are used around _A[0].
_A[0](i,j) probably just returns a reference to value in i-th row and j-th column or another way around.

Here you can see how this operator is used:

int main()
{
  MatrixXd m(2,2);
  m(0,0) = 3;
  m(1,0) = 2.5;
  m(0,1) = -1;
  m(1,1) = m(1,0) + m(0,1);
}

and just to make everythign clear that's how you declare such an object.

class Matrix
{
private:
float value[4][4];

public:
float& operator()(int i, int j)
{
    return value[i][j];
}
};

Upvotes: 0

Related Questions