Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

我寫了一個 c 矩陣的物件,讓你使用矩陣會更方便。

0 views
Skip to first unread message

客來思樂

unread,
May 11, 1997, 3:00:00 AM5/11/97
to

不知道目前有沒有人寫出矩陣的 應用?
因為我常要使用矩陣,所以自已寫了一個功能還可以的簡單矩陣。
以後只要加上這一個 class,就可以直接定義矩陣了。
以下是完整的 C++ 矩陣物件程式,免費的。

/***********************************************************************/
/* main() */
/* { double num[] = {1,2,-1,2,1,0,-1,1,2}; */
/* Matrix B,A(num,3,3); //定義 A 矩陣的方式 */
/* cin >> B; // 直接由鍵盤輸入 B 無陣的數值 */
/* B = A.tr(); // B 是 A 的轉至矩陣 */
/* B = ~A; // B 是 A 的反矩陣 */
/* cout << A << ~B; //在螢幕上顯示出 A 矩陣及 B 的反矩陣 */
/* Matrix C = A * B; //C 矩陣是 A 矩陣乘以 B 矩陣 */
/* cout << C; */
/* //也可以使用以下的用法,要更清楚可以直接參考程式或修改 */
/* C *= B; A = A * 0.2; C *= 1.5; C += 1.5; */
/* C += B; A = B + C; C -= A; C = A - B; */
/* return 0; */
/* } */
/* */
/* running..... */
/* [ 1, 2, -1] */
/* A = [ 2, 1, 0] */
/* [ -1, 1, 2] */
/* */
/* [ -0.222222, 0.555556, -0.111111] */
/* B = ~A = [ 0.444444, -0.111111, 0.222222] */
/* [ -0.333333, 0.333333, 0.333333] */
/* */
/* [1,0,0] */
/* C = [0,1,0] */
/* [0,0,1] */
/* */
/***********************************************************************/

#ifndef __MATRIX_H
#define __MATRIX_H
//The program design by Jei-Chang Wang at Chung Cheng University EE.
// COPYRIGHT @1997/5/11 Mother's Day.
enum Boolean{False,True};
enum MatrixType{Zero,Unit,AllOne,Error}; //Set initial matrix value
class Matrix
{ friend istream& operator>>(istream&, Matrix&);
friend ostream& operator<<(ostream&, Matrix&);
private:
int row,col; //The number of row and column
double *start; //Point to begin matrix address value
protected:
double* Value(){ return start; }
Boolean RowMul(int rows,double number);
Boolean RowDiv(int rows,double number);
void PrintOut(ostream& os);
void PrintOut(ostream& os,Matrix& Mat);
Matrix& Inverse();
public:
Matrix(){ row = col = 0;
start = null;
}
Matrix(int rows,int cols):row(rows),col(cols)
{ if(start)delete [] start;
start = new double[col*row];
}
Matrix(Matrix& Mat){ start = null;
*this = Mat;
}
Matrix(double* addr,int rows,int cols);
~Matrix(){ if(start)delete [] start;
}
int Row(){ return row; }
int Col(){ return col; }
double Value(int rows,int cols)
{ return *( start + (rows*col) + cols ); }
void Set(MatrixType MI);
Matrix& tr();
Boolean SwapCol(int One,int Two);
Boolean SwapRow(int One,int Two);
Boolean RowSubRow(int One,int Two);
Boolean RowSubRowBy(int One,int Two,double Mul);
Matrix& operator=(Matrix &Mat);
Matrix& operator~(){ return(this->Inverse()); }
Matrix& operator+(Matrix &Mat);
Matrix& operator+(double number);
Matrix& operator+=(Matrix &Mat);
Matrix& operator+=(double number);
Matrix& operator-(Matrix &Mat);
Matrix& operator-(double number);
Matrix& operator-=(Matrix &Mat);
Matrix& operator-=(double number);
Matrix& operator*(Matrix &Mat);
Matrix& operator*(double number);
Matrix& operator*=(Matrix &Mat);
Matrix& operator*=(double number);
};

// Constraction the matrix
Matrix::Matrix(double* addr,int rows,int cols):row(rows),col(cols)
{ start = new double[col*row];
double *point;
point = start;
for(int i=0;i < rows;i++)
for(int j=0;j< cols;j++)
*point++=*addr++;
}

// The Matrix which row by the number
// Example: Mij*Ej
// RowMul(2,1.5); -> The seconde row of the Matrix by 1.5
Boolean Matrix::RowMul(int rows,double number)
{ int i;
if(rows > row)return False;
for(i=0;i< col;i++)
*( start + (rows*col) + i ) *= number;
return True;
}

// The Matrix which row by the number
// Example: RowDiv(2,1.5); -> The seconde row of the Matrix divide 1.5
Boolean Matrix::RowDiv(int rows,double number)
{ int i;
if(rows > row)return False;
if(!number)return False;
for(i=0;i< col;i++)
*( start + (rows*col) + i ) /= number;
return True;
}

// Subduction both of two rows
// Example: RowOne = RowOne - RowTwo
Boolean Matrix::RowSubRow(int One,int Two)
{ int i;
if(One > row || Two > row)return False;
for(i=0;i< col;i++)
*(start + (One*col) + i) -= *(start + (Two*col) + i);
return True;
}

// a row by a number then subduction both of two rows
// Example: RowOne = RowOne - ( RowTwo * Mul )
Boolean Matrix::RowSubRowBy(int One,int Two,double Mul)
{ int i;
if(One > row || Two > row)return False;
for(i=0;i< col;i++)
*(start + (One*col) + i) -=
( *(start + (Two*col) + i) * Mul );
return True;
}

//Swap two columns
Boolean Matrix::SwapCol(int One,int Two)
{ double Temp;
int i;
if(One > col || Two > col)return False;
for(i=0;i< row;i++)
{ Temp = *( start + (i*col) + One );
*(start + (i*col) + One) = *(start + (i*col) + Two);
*(start + (i*col) + Two) = Temp;
}
return True;
}

//Swap two rows
Boolean Matrix::SwapRow(int One,int Two)
{ double Temp;
int i;
if(One > row || Two > row)return False;
for(i=0;i< col;i++)
{ Temp = *( start + (One*col) + i );
*(start + (One*col) + i) = *(start + (Two*col) + i);
*(start + (Two*col) + i) = Temp;
}
return True;
}

// Set initial matrix value
void Matrix::Set(MatrixType MI)
{ int i,j;
double *point;
point = start;
switch(MI){
case Zero:
for(i=0;i < row;i++)
for(j=0;j< col;j++)
*point++ = 0;
break;
case Unit:
for(i=0;i < row;i++)
for(j=0;j< col;j++)
*point++ = 0;
for(i=0;i < row;i++)
*( start + (i*row) + i ) = 1.0;
break;
case AllOne:
for(i=0;i < row;i++)
for(j=0;j< col;j++)
*point++ = 1.0;
break;
case Error:
if(start)delete [] start;
start = null;
col = row = 0;
break;
}
}

Matrix& Matrix::Inverse()
{ int i,j;
double Temp;
static Matrix UnitInv;
if( this->row != this->col ){UnitInv.Set(Error);
return UnitInv;}
Matrix Domi = *this;
UnitInv = *this;
UnitInv.Set(Unit);
for(j=0;j< Domi.row;j++)
{ //To search first row value is not zero.
//cout << *this << Domi << UnitInv; //test key
if(!Domi.Value(j,j)){
for(i=j+1;i< Domi.row; i++)
if(Domi.Value(i,j))break;
if( i >= Domi.row ) {UnitInv.Set(Error);
return UnitInv;}
Domi.SwapRow(i,j);
UnitInv.SwapRow(i,j);
}
//Normalize row
Temp = Domi.Value(j,j);
Domi.RowDiv(j,Temp);
UnitInv.RowDiv(j,Temp);
//cout << *this << Domi << UnitInv; //test key

//Normalize other row
for(i=0;i< Domi.row;i++)
if(i!=j){
Temp = Domi.Value(i,j);
if(!Temp)continue;
Domi.RowSubRowBy(i,j,Temp);
UnitInv.RowSubRowBy(i,j,Temp);
}
}
return UnitInv;
}

// print the matrix
void Matrix::PrintOut(ostream& os)
{ int i,j;
for(i=0;i<row;i++)
{ os << "[ " ;
for(j=0;j<col;j++)
{ if(j) os << ", ";
os << Value(i,j);
}
os << " ]" << endl ;
}
}

// print the matrix
void Matrix::PrintOut(ostream& os,Matrix& Mat)
{ int i,j;
for(i=0;i<Mat.row;i++)
{ os << "[ " ;
for(j=0;j<Mat.col;j++)
{ if(j) os << ", ";
os << Mat.Value(i,j);
}
os << " ]" << endl ;
}
}

Matrix& Matrix::operator=(Matrix &Mat)
{ int i,j;
double *point,*source;
//Check *this == Mat ?
if( this->start == Mat.start &&
this->col == Mat.col &&
this->row == Mat.row )return *this;
if(this->start)delete [] this->start;
this->start = new double[Mat.col * Mat.row];
this->col = Mat.col;
this->row = Mat.row;
point = this->start;
source = Mat.start;
for(i=0;i < Mat.row;i++)
for(j=0;j < Mat.col;j++)
*point++ = *source++;
return *this;
}

Matrix& Matrix::operator+=(Matrix &Mat)
{ *this = *this + Mat;
return *this;
}

Matrix& Matrix::operator-=(Matrix &Mat)
{ *this = *this - Mat;
return *this;
}

Matrix& Matrix::operator*=(Matrix &Mat)
{ *this = *this * Mat;
return *this;
}

Matrix& Matrix::operator+=(double number)
{ int i,j;
double *Point;
Point = this->start;
for(i=0;i< this->row;i++)
for(j=0;j< this->col;j++)
*Point++ += number;
return *this;
}

Matrix& Matrix::operator-=(double number)
{ int i,j;
double *Point;
Point = this->start;
for(i=0;i< this->row;i++)
for(j=0;j< this->col;j++)
*Point++ -= number;
return *this;
}

Matrix& Matrix::operator*=(double number)
{ int i;
for(i=0;i< this->row;i++)
this->RowMul(i,number);
return *this;
}

Matrix& Matrix::operator+(double number)
{ static Matrix Ans;
Ans = *this;
Ans += number;
return Ans;
}

Matrix& Matrix::operator-(double number)
{ static Matrix Ans;
Ans = *this;
Ans -= number;
return Ans;
}

Matrix& Matrix::operator*(double number)
{ static Matrix Ans;
Ans = *this;
Ans *= number;
return Ans;
}

Matrix& Matrix::operator+(Matrix &Mat)
{ int i,j;
double *PointAns,*PointA,*PointB;
static Matrix Ans(this->row,this->col);
if( this->col != Mat.col ||
this->row != Mat.row ){Ans.Set(Error);
return Ans; }
PointAns = Ans.start;
PointA = this->start;
PointB = Mat.start;
for(i=0;i<this->row;i++)
for(j=0;j<this->col;j++)
*PointAns++ = *PointA++ + *PointB++;
return Ans;
}

Matrix& Matrix::operator-(Matrix &Mat)
{ int i,j;
double *PointAns,*PointA,*PointB;
static Matrix Ans(this->row,this->col);
if( this->col != Mat.col ||
this->row != Mat.row ){Ans.Set(Error);
return Ans; }
PointAns = Ans.start;
PointA = this->start;
PointB = Mat.start;
for(i=0;i<this->row;i++)
for(j=0;j<this->col;j++)
*PointAns++ = *PointA++ - *PointB++;
return Ans;
}

Matrix& Matrix::operator*(Matrix &Mat)
{ int i,j,l;
double *PointAns,*PointA,*PointB,Sum;
static Matrix Ans(this->row,Mat.col);
if( this->col != Mat.row ){Ans.Set(Error);
return Ans;}
PointAns = Ans.start;
for(i=0;i<this->row;i++)
for(j=0;j<Mat.col;j++)
{ PointA = this->start + ( i * this->col );
PointB = Mat.start + j;
for(Sum = 0.0,l=0 ; l < this->col ;l++)
Sum += (*(PointA+l) * *(PointB+l*Mat.col));
*PointAns++ = Sum;
}
return Ans;
}

Matrix& Matrix::tr()
{ int i,j;
double *PointAns;
static Matrix Ans(this->col,this->row); //swap row & column
PointAns = Ans.start;
for(i=0;i<this->col;i++)
for(j=0;j<this->row;j++)
*PointAns++ = *(this->start + (j*col) + i);
return Ans;
}

istream& operator>>(istream& is, Matrix& Mat)
{ cout << "Let Am*n is matrix" << endl;
cout << "Input rows=";
is >> Mat.row;
cout << "Input columns=";
is >> Mat.col;
if(Mat.start)delete [] Mat.start;
Mat.start = new double[Mat.col * Mat.row];
double *point;
point = Mat.start;
for(int i=0;i < Mat.row;i++)
for(int j=0;j< Mat.col;j++)
{ cout << "A(" << i+1 << ',' << j+1 << ")=" ;
is >> *point++;
}
return is;
}
ostream& operator<<(ostream& os, Matrix& Mat)
{ os << endl;
Mat.PrintOut(os,Mat);
os << endl;
return os;
}
#endif

--
巫山本無老為雪而白 疆海原不鬱因風愁面
Ξ Origin: 中正大學寂寞芳心小站 <bbs.ccu.edu.tw> [FROM: 140.123.213.10]

0 new messages