About matrix subscripting index

D

d major

Hello, everyone.
I want to implement a Matrix class for numeric computing, just like
this:

class myMatrix{
public:
myMatrix(int m,int n);
...
private:
size_t row,col;
double **mat;
};

So, if I instantiate a matrix
myMatrix T;
how can I override this operator '[ ][ ]' s.t. T[j] can be used?
By the way, could you share your instance of matrix for me?
 
K

Kai-Uwe Bux

d said:
Hello, everyone.
I want to implement a Matrix class for numeric computing, just like
this:

class myMatrix{
public:
myMatrix(int m,int n);
...
private:
size_t row,col;
double **mat;
};

So, if I instantiate a matrix
myMatrix T;
how can I override this operator '[ ][ ]' s.t. T[j] can be used?


You make operator[] return a row-proxy type, which in turn has an operator[]
that returns a double& for the entry. See the FAQ for details.

Note: this is not entirely trivial (especially if you care about
const-correctness). You should consider using operator(row-index,col-index)
instead. This is also suggested in the FAQ, however, it is a somewhat
contested issue and the FAQ does not represent a consensus. In fact, most
matrix libraries out there implement both: access by (row,col) and access
by [row][col].

More fundamentatally: why do you roll your own matrix implementation? There
are good matrix libraries out there. Google is your friend.

By the way, could you share your instance of matrix for me?

Sure. One of my favorite 2x3 is:

2 3 4
1 0 3


Best

Kai-Uwe Bux
 
J

Jim Langston

d said:
Hello, everyone.
I want to implement a Matrix class for numeric computing, just like
this:

class myMatrix{
public:
myMatrix(int m,int n);
...
private:
size_t row,col;
double **mat;
};

So, if I instantiate a matrix
myMatrix T;
how can I override this operator '[ ][ ]' s.t. T[j] can be used?
By the way, could you share your instance of matrix for me?


[][] can't be overridden, but what you can do is override [] and have it
return a proxy unit where [] you override [] again.

This is one way to do it, but it is somewhat frowned upon and overriding ()
taking two parameters is suggested. Overriding () with two parameters
doesn't require a proxy object.
 
O

Obnoxious User

Hello, everyone.
I want to implement a Matrix class for numeric computing, just like
this:

class myMatrix{
public:
myMatrix(int m,int n);
...
private:
size_t row,col;
double **mat;
};

So, if I instantiate a matrix
myMatrix T;
how can I override this operator '[ ][ ]' s.t. T[j] can be used? By
the way, could you share your instance of matrix for me?


#include <iostream>

class myMatrix {
public:
myMatrix(int m,int n);
~myMatrix();
double * operator[](int index);
int rows();
int cols();
private:
int d_rows;
int d_cols;
double ** d_matrix;
};

double * myMatrix::eek:perator[](int index) {
return d_matrix[index];
}

int myMatrix::rows() {
return d_rows;
}

int myMatrix::cols() {
return d_cols;
}

myMatrix::~myMatrix() {
for(int i = 0; i < d_rows; ++i)
delete[] d_matrix;
delete[] d_matrix;
}

myMatrix::myMatrix(int m, int n) : d_rows(m), d_cols(n) {
d_matrix = new double* [d_rows];
for(int i = 0; i < d_rows; ++i)
d_matrix = new double [d_cols];
}

int main() {

myMatrix mtx(4,4);
for(int row = 0; row < mtx.rows(); ++row)
for(int idx = 0; idx < mtx.cols(); ++idx)
mtx[row][idx] = row + idx;

for(int row = 0; row < mtx.rows(); ++row) {
for(int idx = 0; idx < mtx.cols(); ++idx)
std::cout<<mtx[row][idx]<<",";
std::endl(std::cout);
}

return 0;
}
 
J

James Kanze

d major wrote:
I want to implement a Matrix class for numeric computing,
just like this:
class myMatrix{
public:
myMatrix(int m,int n);
...
private:
size_t row,col;
double **mat;
};
So, if I instantiate a matrix
myMatrix T;
how can I override this operator '[ ][ ]' s.t. T[j] can be used?

You make operator[] return a row-proxy type, which in turn has
an operator[] that returns a double& for the entry. See the
FAQ for details.
Note: this is not entirely trivial (especially if you care
about const-correctness).

Given that double* and double const* both have an overloaded [],
and can work as a proxy, it's hard to say that it's not trivial.
Expanding to three or more dimensions isn't entirely trivial, of
course, and nor is adding bounds checking, but neither are that
difficult either.
 
J

James Kanze

d major wrote:
I want to implement a Matrix class for numeric computing,
just like this:
class myMatrix{
public:
myMatrix(int m,int n);
...
private:
size_t row,col;
double **mat;
};
So, if I instantiate a matrix
myMatrix T;
how can I override this operator '[ ][ ]' s.t. T[j] can be used?
By the way, could you share your instance of matrix for me?

[][] can't be overridden, but what you can do is override []
and have it return a proxy unit where [] you override []
again.
This is one way to do it, but it is somewhat frowned upon and
overriding () taking two parameters is suggested.

Some people frown upon it, and others find it preferable. As
Uwe-Kai said, there isn't really a consensus about this.
Overriding () with two parameters doesn't require a proxy
object.

Which may make it slightly easier to implement. The choice,
however, should be based on your team's opinion as to which is
the better philosophy for the interface.
 
K

Kai-Uwe Bux

James said:
d major wrote:
I want to implement a Matrix class for numeric computing,
just like this:
class myMatrix{
public:
myMatrix(int m,int n);
...
private:
size_t row,col;
double **mat;
};
So, if I instantiate a matrix
myMatrix T;
how can I override this operator '[ ][ ]' s.t. T[j] can be used?

You make operator[] return a row-proxy type, which in turn has
an operator[] that returns a double& for the entry. See the
FAQ for details.
Note: this is not entirely trivial (especially if you care
about const-correctness).

Given that double* and double const* both have an overloaded [],
and can work as a proxy, it's hard to say that it's not trivial.
Expanding to three or more dimensions isn't entirely trivial, of
course, and nor is adding bounds checking, but neither are that
difficult either.


It didn't occur to me to use double * or double const * as row-proxys, and
upon reflection, I don't think it's a good idea. Expressions such as *M[4]
and M[5]+1 (where M is a myMatrix) should be rejected by the compiler.

Of course, none of this is rocket science. However, the main question
remains: why not just use a matrix library?


Best

Kai-Uwe Bux
 
J

James Kanze

Kai-Uwe Bux a écrit :
James Kanze wrote:
d major wrote:
I want to implement a Matrix class for numeric computing,
just like this:
class myMatrix{
public:
myMatrix(int m,int n);
...
private:
size_t row,col;
double **mat;
};
So, if I instantiate a matrix
myMatrix T;
how can I override this operator '[ ][ ]' s.t. T[j] can be used?
You make operator[] return a row-proxy type, which in turn has
an operator[] that returns a double& for the entry. See the
FAQ for details.
Note: this is not entirely trivial (especially if you care
about const-correctness).

Given that double* and double const* both have an overloaded [],
and can work as a proxy, it's hard to say that it's not trivial.
Expanding to three or more dimensions isn't entirely trivial, of
course, and nor is adding bounds checking, but neither are that
difficult either.

It didn't occur to me to use double * or double const * as
row-proxys, and upon reflection, I don't think it's a good
idea. Expressions such as *M[4] and M[5]+1 (where M is a
myMatrix) should be rejected by the compiler.

It depends on your goals. If the main goal is to get something
up and running quickly, in order to experiment with, then
double* is fine. If robustness is part of the goal, then no; at
the very least, you'd want to have assertion checks on the
bounds.
Of course, none of this is rocket science. However, the main
question remains: why not just use a matrix library?

Quite. Code that someone else has already written and debugged
always takes less time to develop. And in this case, you
shouldn't have too much problem finding code that is already
widely used, so (hopefully at least) any serious errors will
already have been discovered and corrected.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top