This problem is intrinsic to programming and will not disappear
We can only circumvent the problem by making the program invoke different functions when a different type of variable is passed
Vector Jacobi(Matrix P, Matrix Q, Vector b)
{
Vector v1, v2;
int i;
float d;
for (i = 0; i < 3; i = i + 1)
{ v1.x[i] = 0;
v2.x[i] = 1;
}
d = 0.1;
while ( d > 0.0001 )
{
v2 = P*v1 + Q*b;
d = distance(v1, v2);
v1 = v2;
}
return(v2);
}
|
P*v1 (= P.operator*(v1)) Q*b (= Q.operator*(b)) |
must be polymorphic
so that:
Vector sol, b; DenseMatrix P1, Q1; sol = Jacobi(P1, Q1, b); |
will invoke operator* in the DenseMatrix class and
Vector sol, b; SparseMatrix P1, Q1; sol = Jacobi(P1, Q1, b); |
will invoke operator* in the SparseMatrix class
class myOldClass ----> class myNewClass:myOldClass
{ {
virtual function1() virual function1()
} }
myOldClass X; myNewClass Y;
^ ^
\ /
\ /
\ /
\ /
\ /
myOldClass *ptr
ptr = &X; ptr = &Y;
ptr->function1(); ptr->function1();
// Calls function1() // Calls function1()
// in myOldClass // in myNewClass
|
|
Example:
class DenseMatrix -------------------->
{
public:
float A[3][3];
virtual Vector operator*(Vector &v)
{
Vector z;
int i, j;
for (i = 0; i < 3; i=i+1)
z.x[i] = 0;
for (i = 0; i < 3; i=i+1)
for (j = 0; j < 3; j=j+1)
z.x[i] = z.x[i]
+ A[i][j]*v.x[j];
return z;
}
};
|
class SparseMatrix : DenseMatrix
{
public:
int nnz;
float val[6];
int row[6];
int col[6];
virtual Vector operator*(Vector &v)
{
Vector z;
int k;
for (k = 0; k < 3; k = k + 1)
z.x[k] = 0;
for (k = 0; k < nnz; k = k + 1)
z.x[row[k]] = z.x[row[k]]
+ val[k]*v.x[col[k]];
return z;
}
};
|
Vector Jacobi(DenseMatrix &P, DenseMatrix &Q, Vector b)
{
Vector v1, v2;
int i;
float d;
for (i = 0; i < 3; i = i + 1)
{ v1.x[i] = 0;
v2.x[i] = 1;
}
d = 1.0;
while ( d > 0.0001 )
{
cout << v1.x[0] << "\t" << v1.x[1] << "\t" << v1.x[1] << "\n" ;
v2 = P*v1 + Q*b;
d = distance(v1, v2);
v1 = v2;
}
return(v2);
}
|
int main(int argc, char *argv[])
{
Vector sol, b;
DenseMatrix P1, Q1;
sol = Jacobi(P1, Q1, b); // Solves dense system
SparseMatrix P2, Q2;
sol = Jacobi(P2, Q2, b); // Solves sparse system
}
|
We must either (1) pass the parameter by reference or (2) use the C style pass address by value.
class Matrix
{
public:
virtual Vector operator*(Vector &v);
};
| |
class DenseMatrix:Matrix
{
public:
float A[3][3];
virtual Vector operator*(Vector &v)
{
Vector z;
int i, j;
for (i = 0; i < 3; i=i+1)
z.x[i] = 0;
for (i = 0; i < 3; i=i+1)
for (j = 0; j < 3; j=j+1)
z.x[i] = z.x[i]
+ A[i][j]*v.x[j];
return z;
}
};
|
class SparseMatrix:Matrix
{
public:
int nnz;
float val[6];
int row[6];
int col[6];
virtual Vector operator*(Vector &v)
{
Vector z;
int k;
for (k = 0; k < 3; k = k + 1)
z.x[k] = 0;
for (k = 0; k < nnz; k = k + 1)
z.x[row[k]] = z.x[row[k]]
+ val[k]*v.x[col[k]];
return z;
}
};
|
Vector Jacobi(Matrix & P, Matrix & Q, Vector b)
{
Vector v1, v2;
int i;
float d;
for (i = 0; i < 3; i = i + 1)
{ v1.x[i] = 0;
v2.x[i] = 1;
}
d = 1.0;
while ( d > 0.0001 )
{
cout << v1.x[0] << "\t" << v1.x[1] << "\t" << v1.x[1] << "\n" ;
v2 = P*v1 + Q*b;
d = distance(v1, v2);
v1 = v2;
}
return(v2);
}
|
int main(int argc, char *argv[])
{
Vector sol, b;
DenseMatrix P1, Q1;
sol = Jacobi(P1, Q1, b); // Solves dense system
SparseMatrix P2, Q2;
sol = Jacobi(P2, Q2, b); // Solves sparse system
}
|