Passing 2D Dynamic Arrays to Functions?

F

fivelitermustang

I have two matrices allocated dynamically in both directions: matrix x and
matrix v.

I want to pass these matrices into a function by reference. What I have
written down isn't working... can somebody enlighten me on how I would
solve this?

Here is what my prototype and my function look like:

=====================================================

double distance(int k, int i, int& n, double *x[], double *v[]);


double distance(int k, int i, const int& n, double *x[], double *v[])
{
double w;
for (int j=0; j<n; j++)
{
w = w + pow((x[k][j] - v[j]), 2);
}
return w;
}

In addition, I have another question. Is it possible to call this function
by only using the first two parameters (i and k)?
"x" and "v" are the matrices that are being read in and they will always
be used. "n" is a set constant at the beginning of the program that isn't
changed. It would clean up the code if I could just say "distance(i, k)"
and the other three variables would automatically be used.

As it sits now, this is how the function would be called (given that I
could get that double pointer issue sorted out... LOL!)

double q = 0;
for (int i=0; i<C; i++)
{
for (int k=0; k<Nm; k++)
{
q = q + pow((u[k]),m)*distance(k, i, n, x, v);
}
}

Any help would be greatly appreciated. :)
 
J

John Harrison

fivelitermustang said:
I have two matrices allocated dynamically in both directions: matrix x and
matrix v.

I want to pass these matrices into a function by reference. What I have
written down isn't working... can somebody enlighten me on how I would
solve this?

Here is what my prototype and my function look like:

=====================================================

double distance(int k, int i, int& n, double *x[], double *v[]);


double distance(int k, int i, const int& n, double *x[], double *v[])
{
double w;
for (int j=0; j<n; j++)
{
w = w + pow((x[k][j] - v[j]), 2);
}
return w;
}


Ho hum. What does 'doesn't work' mean? Does it give a compile error, a run
time error, does it run to completion but not give the results you expect?
What are the results you expect?

Is this really the code you have? The obvious problem is that w is an
uninitialised variable.

How exactly are you allocating your arrays, and how exactly are you calling
the function? Both of these are potential issues.

Why did you choose 'double *x[]', instead of 'double **x', any particular
reason?

So many questions.
In addition, I have another question. Is it possible to call this function
by only using the first two parameters (i and k)?

Yes, if you write a class. Put x and v and n as members of the class and
distance as a method of the class. Since you're programming C++, and C++ is
all about classes, this might be a good oppotunity to get some practise with
them.
"x" and "v" are the matrices that are being read in and they will always
be used. "n" is a set constant at the beginning of the program that isn't
changed. It would clean up the code if I could just say "distance(i, k)"
and the other three variables would automatically be used.

john
 
D

Dave Townsend

Yuk! Your approach doesn't use any of the featurs of C++, you
are still thinking in C!

My suggestion would be to use the STL to generate your matrices. You
can have a general Matrix class, with the matrix represented internally as
variable of type vector of vectors.
I've seen this published somewhere, I can't remember where, but you can
probably
find it. As a taste, look at the code below. You can encapsulate things
quiet nicely
and include the various matrix operations, multiply, addition, negation
etc, as
overloaed operators, perhaps even provide meaning to / using the inverse
operation.
Throw exceptions if the matrices are incompatible or operation is undefined.

( take a look at Scott Myer's book Effective C++, I think he handles two
dimensional
subscripting very nicely using a proxy class, my approach below is a bit
hacked. )

#include <vector>
using namespace std;

class Matrix
{
public:
// create zero matrix
Matrix( int M, int N )
{
for (int m=0; m<M ; m++)
{
vector<double> row;

for (int n=0; n<N; n++)
{
row.push_back(0.0);
}
_matrix.push_back(row);
}
}

Matrix( const Matrix& m )
{
// copy constructor
}



public:
vector<double>& operator[]( int rowindex)
{
return _matrix[rowindex];
}

public:
Matrix operator*( const Matrix& m )
{
// check validity of multiplying these matrices
// throw execption / bomb out if necessary.
}
private:
vector< vector<double> > _matrix;
};


// test program to illustrate the [][] indexing of the matrix elements
int main(int argc, char* argv[])
{
Matrix m(3, 3 );
printf (" M[0][0]=%f\n", m[0][0]);
m[0][0]=1.0;
printf (" M[0][0]=%f\n", m[0][0]);
double foo = m[0][0];
printf (" M[0][0]=%f\n", m[0][0]);
return 0;
}

fivelitermustang said:
I have two matrices allocated dynamically in both directions: matrix x and
matrix v.

I want to pass these matrices into a function by reference. What I have
written down isn't working... can somebody enlighten me on how I would
solve this?

Here is what my prototype and my function look like:

=====================================================

double distance(int k, int i, int& n, double *x[], double *v[]);


double distance(int k, int i, const int& n, double *x[], double *v[])
{
double w;
for (int j=0; j<n; j++)
{
w = w + pow((x[k][j] - v[j]), 2);
}
return w;
}

In addition, I have another question. Is it possible to call this function
by only using the first two parameters (i and k)?
"x" and "v" are the matrices that are being read in and they will always
be used. "n" is a set constant at the beginning of the program that isn't
changed. It would clean up the code if I could just say "distance(i, k)"
and the other three variables would automatically be used.

As it sits now, this is how the function would be called (given that I
could get that double pointer issue sorted out... LOL!)

double q = 0;
for (int i=0; i<C; i++)
{
for (int k=0; k<Nm; k++)
{
q = q + pow((u[k]),m)*distance(k, i, n, x, v);
}
}

Any help would be greatly appreciated. :)
 
F

fivelitermustang

Ho hum. What does 'doesn't work' mean? Does it give a >>compile error, a
run
time error, does it run to completion but not give the >>results you expect?
What are the results you expect?

Is this really the code you have? The obvious problem is >>that w is an
uninitialised variable.

How exactly are you allocating your arrays, and how exactly >>are you
calling
the function? Both of these are potential issues.

Why did you choose 'double *x[]', instead of 'double **x', >>any particular
reason?
So many questions.

Well, I chose to use double *x[] because it seemed intuitive to me. How
would I go about initializing it using **x? And how would I pass a matrix
initialized like that by reference?

The entire program is written however it is all monolithic and it does
work properly. I just want to put some of these operations into functions
for clarity and easier coding.

The error that it gives me is a compile time error.
"Error : function call 'distance(int, int, const int, double **, double
**)' does not match
'std::distance<...>(T0, T0)'
'distance(int, int, int &, double **, double **)'
clustering.cpp line 157 q = q + pow((u[k]),m)*distance(k, i, n, x,
v);"
 
J

John Harrison

fivelitermustang said:
Ho hum. What does 'doesn't work' mean? Does it give a >>compile error, a run
time error, does it run to completion but not give the >>results you expect?
What are the results you expect?

Is this really the code you have? The obvious problem is >>that w is an
uninitialised variable.

How exactly are you allocating your arrays, and how exactly >>are you
calling
the function? Both of these are potential issues.

Why did you choose 'double *x[]', instead of 'double **x', >>any particular
reason?
So many questions.

Well, I chose to use double *x[] because it seemed intuitive to me. How
would I go about initializing it using **x? And how would I pass a matrix
initialized like that by reference?

The entire program is written however it is all monolithic and it does
work properly. I just want to put some of these operations into functions
for clarity and easier coding.

The error that it gives me is a compile time error.
"Error : function call 'distance(int, int, const int, double **, double
**)' does not match
'std::distance<...>(T0, T0)'
'distance(int, int, int &, double **, double **)'
clustering.cpp line 157 q = q + pow((u[k]),m)*distance(k, i, n, x,
v);"


OK well I can now see the other problem

Look at your prototype

double distance(int k, int i, int& n, double *x[], double *v[]);

and your function

double distance(int k, int i, const int& n, double *x[], double *v[])

There's an extra const in the function which isn't in the prototype.

Personally I would change both to plain int, there's not much point in const
int&, and you don't need int&.

And fix that uninitialised variable w.

john
 
F

fivelitermustang

Essentially I had "n" defined at the beginning of the program as a
constant. When I was calling the function it wasn't expecting "n" to be a
constant. I just changed both the definitions to contain const and that
did the trick...

Thanks a lot for the help.
 
J

John Harrison

fivelitermustang said:
Essentially I had "n" defined at the beginning of the program as a
constant. When I was calling the function it wasn't expecting "n" to be a
constant. I just changed both the definitions to contain const and that
did the trick...

Thanks a lot for the help.

Glad you worked it out. The essential point is that the prototype and the
actual function should have the same signature.

Just because n is a constant is no reason to use const int&, as I said a
plain int is better.

john
 

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,768
Messages
2,569,575
Members
45,054
Latest member
LucyCarper

Latest Threads

Top