operator[] in matrix class

C

check.checkta

Hi,

I'd like to implement a simple matrix class. I'd like to overload
operator [] so that it returns as a vector (either the stl vector or
some other Vector class of my own). The reason I want to do this is
because it enables me to apply some functions of a vector to a row of
of matrix, e.g., I have a function to compute the sum of vector:

double my_sum(vector<double> x)
{
int i, n=x.size();
double result = 0;
for(i=0; i<n; ++i) result += x;
return result;
}

I'd like to compute the sum of the second row of a matrix:

Matrix<double> a(3,5);
double sum2 = my_sum(a[1]);

A simple one would have three private members, the number of rows,
columns and a double pointer. If operator[] returns a pointer to row
i, then I can't call my_sum(a[1]). If I force operator[] to return a
vector<T> it won't compile. Please help.

Thanks a lot.

Below is a snippet of the template class:
=======================================
template <class T>
class Matrix {
private:
int r;
int c;
T **dp;
public:
inline T* operator[](const int i);
inline const T* operator[](const int i) const;
};

template <class T>
inline T* Matrix<T>::eek:perator[](const int i)
{
return dp;
}

template <class T>
inline const T* Matrix<T>::eek:perator[](const int i) const
{
return dp;
}
 
N

Noah Roberts

Hi,

I'd like to implement a simple matrix class. I'd like to overload
operator []

Bad idea unless you absolutely have to for compatibility reasons. Even
then it is ill-advised and there are ways around implementing in terms
of [].

If I force operator[] to return a
vector<T> it won't compile. Please help.

I can only assume, since you haven't provided the source that is
actually the problem, that you are trying to return a T* as a
vector<T>. That won't work; they are completely different and
unrelated types. You have to build and initialize your vector and
return it. Add that to the fact that your sum operator accepts its
parameter by value and you have a very inefficient implementation.

Look for an alternative.
 
K

Kai-Uwe Bux

Noah said:
Hi,

I'd like to implement a simple matrix class. I'd like to overload
operator []

Bad idea unless you absolutely have to for compatibility reasons. Even
then it is ill-advised and there are ways around implementing in terms
of [].

By and in itself, overloading operator[] for a matrix class so that it
returns a proxy for a row vector is not a bad idea. It is just a little
more complicated to implement. However, the interface has a lot to offer.
For instance, the matrix class I am using allows me to express an
elementary row operation as follows:

matrix A;
...
A += c * A[j];

I consider this way more expressive than, e.g.,

row_add( A, i, j, c );

where I always forget the correct order of arguments. Also,

swap( A, A[j] );

is very suggestive notation.

Of course, the point is not overloading the operator, a row() method,
accompanied by a col() method, will also do the trick. The important aspect
of this interface is that it allows one to operate on row and column
vectors of a given matrix not just on its coefficients.


To the OP: in order to make something like this work, you may consider
designing the matrix and vector class simultaneously. They are tightly
coupled classes since proxy objects representing a row / column have to
interact nicely with vector objects. This is non-trivial. You are probably
better off not rolling your own code. What about using one of the many
available matrix classes out there?


Best

Kai-Uwe Bux
 
P

persenaama

I'd like to implement a simple matrix class. I'd like to overload
operator [] so that it returns as a vector (either the stl vector or
some other Vector class of my own). The reason I want to do this is
because it enables me to apply some functions of a vector to a row of
of matrix, e.g., I have a function to compute the sum of vector:

Then keep the data as vector<T> to begin with, then you can return
"const vector<T>&", to avoid constructing a new object for the return
value.

It would be more efficient to store the rows and columns in a
continuous array and compute the offset to a specified row when
required.
double my_sum(vector<double> x)

Outch. You are creating a *new* vector each time this function is
called, this will be a turtle. I take it performance is not a design
criteria, nor is memory efficiency? In that case just do:

vector< vector<T> > d; // member data in your Matrix class

If you care about abovementioned qualities, you write:

T* dp;

And then pass Matrix .. example:

double my_sum(const Matrix& m, int row)
{
const double* p = m[row];
for ( ... )
...

Or whatever. Doesn't look so nice? Then you might consider what you
will be using this FOR and re-think the API. I was merely suggesting
based on the available input.. I wouldn't necessarily write anything
like that. :)
 
C

Chris Theis

Hi,

I'd like to implement a simple matrix class. I'd like to overload
operator [] so that it returns as a vector (either the stl vector or
some other Vector class of my own). The reason I want to do this is
because it enables me to apply some functions of a vector to a row of
of matrix, e.g., I have a function to compute the sum of vector:
[SNIP]

As already pointed out there is an exhaustive section about matrices and
operator overloading in the FAQ. However, I'd recommend to consider
something like the UBLAS lib (which is part of boost now), or Blitz++. There
you'll find the functionality that you're looking for and the code is
already well debugged and optimized.

Cheers
Chris
 
A

Amadeus W. M.

Hi,

I'd like to implement a simple matrix class. I'd like to overload
operator [] so that it returns as a vector (either the stl vector or
some other Vector class of my own). The reason I want to do this is
because it enables me to apply some functions of a vector to a row of
of matrix, e.g., I have a function to compute the sum of vector:

double my_sum(vector<double> x)
{
int i, n=x.size();
double result = 0;
for(i=0; i<n; ++i) result += x;
return result;
}


Do this:

template <class Iterator_type>
double my_sum(Iterator_type begin, Iterator_type end)
{
double result=0;
for(Iterator_type x=begin; x!=end; x++) result += *x;
return result;
}



Now, if you have an stl::vector<double> X (or even a list<double>)
and you want to compute its sum, then you do

double s=my_sum(X.begin(), X.end());

If, on the other hand, you have a double * X of size n, then you do

double s=my_sum(X, X+n);



With your implementation of Matrix, you should then say

double s=my_sum(a[1],a[1]+a.columns());

where Matrix::rows(), Matrix::columns() trivially return r and c
respectively.



I'd like to compute the sum of the second row of a matrix:

Matrix<double> a(3,5);
double sum2 = my_sum(a[1]);

A simple one would have three private members, the number of rows,
columns and a double pointer. If operator[] returns a pointer to row
i, then I can't call my_sum(a[1]). If I force operator[] to return a
vector<T> it won't compile. Please help.

Thanks a lot.

Below is a snippet of the template class:
=======================================
template <class T>
class Matrix {
private:
int r;
int c;
T **dp;
public:
inline T* operator[](const int i);
inline const T* operator[](const int i) const;
};

template <class T>
inline T* Matrix<T>::eek:perator[](const int i)
{
return dp;
}

template <class T>
inline const T* Matrix<T>::eek:perator[](const int i) const
{
return dp;
}
 
J

jimmy

Amadeus said:
Hi,

I'd like to implement a simple matrix class. I'd like to overload
operator [] so that it returns as a vector (either the stl vector or
some other Vector class of my own). The reason I want to do this is
because it enables me to apply some functions of a vector to a row of
of matrix, e.g., I have a function to compute the sum of vector:

double my_sum(vector<double> x)
{
int i, n=x.size();
double result = 0;
for(i=0; i<n; ++i) result += x;
return result;
}


Do this:

template <class Iterator_type>
double my_sum(Iterator_type begin, Iterator_type end)
{
double result=0;
for(Iterator_type x=begin; x!=end; x++) result += *x;
return result;
}
I do like this way.


Now, if you have an stl::vector<double> X (or even a list<double>)
and you want to compute its sum, then you do

double s=my_sum(X.begin(), X.end());

If, on the other hand, you have a double * X of size n, then you do

double s=my_sum(X, X+n);



With your implementation of Matrix, you should then say

double s=my_sum(a[1],a[1]+a.columns());

where Matrix::rows(), Matrix::columns() trivially return r and c
respectively.



I'd like to compute the sum of the second row of a matrix:

Matrix<double> a(3,5);
double sum2 = my_sum(a[1]);

A simple one would have three private members, the number of rows,
columns and a double pointer. If operator[] returns a pointer to row
i, then I can't call my_sum(a[1]). If I force operator[] to return a
vector<T> it won't compile. Please help.

Thanks a lot.

Below is a snippet of the template class:
=======================================
template <class T>
class Matrix {
private:
int r;
int c;
T **dp;
public:
inline T* operator[](const int i);
inline const T* operator[](const int i) const;
};

template <class T>
inline T* Matrix<T>::eek:perator[](const int i)
{
return dp;
}

template <class T>
inline const T* Matrix<T>::eek:perator[](const int i) const
{
return dp;
}
 

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,772
Messages
2,569,591
Members
45,102
Latest member
GregoryGri
Top