Hello experts,
I am working on a matrix class for practice. I just added a inverse and transpose function, and have some questions about the class ? I would appreciate someone to give me some suggestions.
1. In the inverse function, I have problem to do :
for(int i =0; ...) ... for the second time... so that I have to declare things like: int ii =0 , or iii =0 ...
does anyone know why ? since sometimes I don't have this problem...
2. For the + and - operator member function, I decide to return by value ... because in C= a+b
I do not want to change anything of a ! is this the best way to implement "+" and "-" ??? thanks.
3. in the inverse function, sometimes I have values like : 1.2e-15
so ... when we print it out, it looks bad ... what would be a better way to print out things ?
4. any suggestions to improve the matrix class ? many thanks.
--------------------------
----------
-----
// Matrix class ...
#ifndef _MatrixH_
#define _MatrixH_
#include <iostream>
#include <sstream>
#include <iomanip>
using namespace std;
//template <class T>
typedef double T;
class Matrix
{
public:
Matrix(size_t row =1 , size_t column=1):M(row),N(column)
, data(new T[M*N]){}
Matrix(const Matrix& B):M(B.M),N(B.N), data(new T[M*N])
{
for(int i=0; i<M*N; i++)
{
data[i]= B.data[i];
}
}
Matrix& operator=(const Matrix& B)
{
for(int i=0; i<M*N; i++)
{
data[i]= B.data[i];
}
return *this;
}
Matrix operator+(const Matrix& B)
{
int B_M = B.getRow();
int B_N = B.getColumn();
if(B_M != M || B_N!= N)
{
throw "Dimension do NOT match !" ;
}
Matrix C(M,N);
for(int i=0; i<M*N; i++)
{
C.data[i] = data[i] + B.data[i];
}
return C;
}
Matrix operator-(const Matrix& B)
{
int B_M = B.getRow();
int B_N = B.getColumn();
if(B_M != M || B_N!= N)
{
throw "Dimension do NOT match !" ;
}
Matrix C(M,N);
for(int i=0; i<M*N; i++)
{
C.data[i] = data[i]-B.data[i];
}
return C;
}
Matrix operator*(const Matrix& B)
{
int B_M = B.getRow();
int B_N = B.getColumn();
if( N!= B_M)
{
throw "Dimension for multiplication do NOT match !" ;
}
Matrix C(M,N);
/*------------------------
----------
----------
----------
-------
// Standard implemetion of matrix multiplication formula
for(int i=0; i<M; i++)
for(int j=0;j<B_N; j++)
{
C.data[i*N+j]= 0;
for(int k=0; k<N;k++)
C.data[i*N+j]+= data[i*N+k]* B.data[k*N+j];
}
//------------------------
----------
----------
----------
----- */
//------------------------
----------
----------
----------
-------
// An optimized way to speed up the multiplication calculation
for(int i=0, e=0; i<M; i++)
for(int j=0;j<B_N; j++, e++)
{
T val = data[i*N] * B.data[j];
for(int k=1, c = i * N+1, d = j + B_N; k<N;k++, c++, d += B_N)
val += data[c]* B.data[d];
C.data[e] = val;
}
//------------------------
----------
----------
-------
return C;
}
//------------------------
----------
----------
--------
// A way to read & write matrix element, using (i,j)
T operator()(size_t i, size_t j) const { return data[i * N + j]; }
T& operator()(size_t i, size_t j) { return data[i * N + j]; }
//------------------------
----------
----------
---------
//------------------------
----------
----------
--------
// Another way to read & write matrix elemnt, using[i][j]
T* operator[](size_t i) {return (data + (N*i));}
T const*const operator[](size_t i) const{return (data + (N*i));}
//------------------------
----------
----------
--------
Matrix transpose()
{
Matrix trans(N,M);
for(int j=0; j<N; j++)
for (int i=0; i<M; i++)
{
trans.data[j*M+i] = data[i*N+j];
}
return trans;
}
Matrix inverse()
{
if(M!=N) throw "Only Square Matrix can have inverse!";
Matrix SI(M,2*M);
for(int i=0; i<M;i++)
{
for(int j=0; j<2*M; j++)
{
if(j<M)
{
SI.data[i*2*M+j] = data[i*M+j];
}
else
{
SI.data[i*2*M+j] = 0;
}
if(j==i+M) SI.data[i*2*M+j] =1.0;
}
}
for(int ii=0; ii<M-1; ii++)
{
for(int kk=ii+1; kk < M; kk++)
{
for(int jj=2*M-1; jj>=ii; jj--)
{
SI.data[kk*2*M+jj] -= SI.data[ii*2*M+jj] *
(SI.data[kk*2*M+ii]/SI.dat
a[ii*2*M+i
i]);
}
}
}
//------------------------
----------
---
for(int iii=M-1; iii>0; iii--)
{
for(int kkk=iii-1; kkk >=0; kkk--)
{
for(int jjj=2*M-1; jjj>=iii; jjj--)
{
SI.data[kkk*2*M+jjj] -= SI.data[iii*2*M+jjj] *
(SI.data[kkk*2*M+iii]/SI.d
ata[iii*2*
M+iii]);
}
}
}
for(int iiii=0; iiii<M; iiii++)
{
for(int jjjj=2*M-1; jjjj >=0; jjjj--)
{
SI.data[iiii*2*M+jjjj] =SI.data[iiii*2*M+jjjj]/SI
.data[iiii
*2*M+iiii]
;
}
}
Matrix I(M,M);
for(int s = 0; s<M; s++)
for(int r=0; r<M; r++)
{
I.data[s*M+r] = SI.data[s*2*M+r+M];
}
return I;
//------------------------
---------
}
//------------------------
---------
// A standard print() function, printing things to standard IO
void print(ostream& ss)
{
for (int i = 0, c = 0; i < M; i++) {
for (int j = 0; j < N; j++,c++) {
ss << setw(20) << data[c] ;
}
ss << endl;
}
}
//------------------------
----------
----------
-
//------------------------
----------
-
// A general print() function for possible future non-standard IO
template<class Streamlike>
void printStream(Streamlike s)
{
for (int i = 0, c = 0; i < M; i++) {
for (int j = 0; j < N; j++,c++) {
s << setw(4) << data[c] ;
}
s << endl;
}
}
//------------------------
----------
--
~Matrix()
{
delete [] data;
}
protected:
int getRow() const {return M;}
int getColumn() const {return N;}
private:
int N, M;
T *data ;
};
#endif