?? tmatrix.h
字號:
/********************************************************************************
CopyRight: You can use the Class freely as long as you keep this comment and the following :
Authour: Warren Wo ,HangZhou ZheJiang province;
Email: woyf@sina.com
QQ:124254045
*************************************************************************/
//---------------------------------------------------------------------------
#ifndef TMATRIX_H_
#define TMATRIX_H_
//container and iterator:
#include <vector>
#include <valarray>
#include <algorithm>
#include <functional>
//i/o operations:
#include <fstream.h>
//special classes:
#include <complex>
#include <numeric>
#pragma hdrstop
#define CERR(S) {cerr<<S<<endl; getch();throw;}
using namespace std;
//---------------------------------------------------------------------------
typedef complex<double> complex_double_type;
template<class type = complex_double_type> //defaul type: complex<double>
class matrix{
private:
//Matrix:
typedef type Cell; //cells
typedef vector<Cell> RowVector; //row vectors
typedef vector<Cell> ColVector; //column vectors
typedef vector<RowVector> Matrix_type; //matrix set up by row vectors
//Only used in some member functions such as CreatMatrix() , operator =()...
//to estimate if there are enough memories or if the rowCount or colCount
//is validate:
RowVector rVector;
ColVector cVector;
//"Mother" vectors whose elements are also vectors;:
Matrix_type Matrix;
int rowSize,rowCount; //Size of a row and row count:
//rowSize == colCount, colSize == rowCount
int& colSize; //column size
int& colCount; //the number of columns
int totalElem; //total number of element in the matrix
bool inline CreatMatrix(); //Creat Matrix frame
public:
//Constructors:
matrix():colSize(rowCount),colCount(rowSize){}
//matrix with dimension m*n
matrix( int RowCount , int ColCount );
//Initialize matrix by using unary dim array:
matrix(const type A[],const int& ArraySize,int RowCount , int ColCount);
//copy constructor:
matrix(const matrix<type>&);
//destructor:
~matrix(){ }
//"=" operator:
//Reminder: the type of the left and the right must be the same.For example:
//the following is legal: matrix<complex<int>> m1; matrix <complex<int>> m2; m1 = m2;
//while it's invalidate if "m1" turn to be "matrix<int>" type:
matrix<type>& operator = (const matrix<type>& M);
//uniary operators:
//"!" operator: the inverse of matrix:
matrix<complex_double_type> operator !();
//"~" operator: to turn a matrix:
matrix<type> operator~();
//"^" Operator: matrix pow:
matrix<type> operator ^(const int);
//Binary operators:
//+= operator:
matrix<type>& operator +=(const matrix<type>&);
//-= operator:
matrix<type>& operator -=(const matrix<type>&);
//*= operator:
matrix<type>& operator *=(const matrix<type>&);
matrix<type>& operator *=(const type&);
//"==" and "!=" operators:
bool operator ==(const matrix<type>&);
bool operator !=(const matrix<type>&);
//reference
const vector<type> operator[ ](const int&) const;
void adjust(const int&,const int&);
//Load Matrix from a file
void LoadFromFile(const char*filename,ios_base::openmode mode = ios_base::in);
//Set an element,a single row or column:
void SetCells( int rIndex, int cIndex,const Cell& cell);
void SetRows( int rIndex, vector<type>& RowVector);
void SetCols( int cIndex, vector<type>& ColVector);
//Save Matrix to a file
void SaveToFile
(const char* filename,ios_base::openmode mode = ios_base::out);
//Read a row/column indicated by the parament:
const RowVector ReadRows( int RowIndex) const;
const ColVector ReadCols( int ColIndex) const;
//Read a element mantained by the matrix:
const Cell ReadCells( int rIndex, int cIndex) const;
//Return row/column count:
const int inline RowCount() const;
const int inline ColCount() const;
//Swap rows/columns:
void SwapRows( int rowIndex1, int rowIndex2);
void SwapCols( int colIndex1, int colIndex2);
//Add a new row/column at the end:
void AddRow(const vector<type>& Vector);
void AddCol(const vector<type>& Vector);
//Resize the matrix:
void resize(const int RowCount, const int ColCount,const Cell& cell = 0 );
//Get associate matrix:
matrix<type>& associate();
//Apply function to rows/cols:
void ApplyRows(const int RowIndex,type fun(type&));
void ApplyCols(const int ColIndex,type fun(type&));
//Shirnk this matrix to indentity matrix which has the dims of the samller of the row count
//and column count:
void ShrinkToIdentityMatrix();
//convert matrix to complex double type:
matrix<complex_double_type> c_complex_double();
//convert matrix to double type:
matrix<double> c_double();
};
//#define DEBUG
//---------------------------------------------------------------------------
//**********************************************
// non-inline member functions definition:
//**********************************************
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//*******************************
//Private member functions:
//*******************************
//---------------------------------------------------------------------------
template<class type>bool
inline matrix<type>::CreatMatrix()
{
//creat failed if there are not enough memory:
if(rowSize > rVector.max_size() || colSize > cVector.max_size())
return 0;
else{
//creat subvectors in the matrix:
vector<type> rowVector(rowSize);
//creat mother vectors
Matrix.resize(rowCount);
//Link subvectors with the mother vector to creat the frame:
fill(Matrix.begin(),Matrix.end(),rowVector);
return true;
}
}
//---------------------------------------------------------------------------
//*******************************
//public member functions:
//*******************************
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//Constructors:
//---------------------------------------------------------------------------
template<class type>
matrix<type>:: matrix( int RowCount , int ColCount):
rowCount(RowCount),rowSize(ColCount),colSize(rowCount),colCount(rowSize)
{
//ensure row count and column count at least no less than 1;
rowCount =( rowCount>0 ) ? rowCount : 1;
rowSize = ( rowSize >0 ) ? rowSize : 1;
totalElem = rowCount * rowSize;
//Creat matrix frame:
if(!CreatMatrix())
throw;
}
//Constructor: to convert an unary array to matrix:
template<class type>
matrix<type>:: matrix(const type A[],const int& ArraySize,int RowCount,int ColCount):
rowCount(RowCount),rowSize(ColCount),colSize(rowCount),colCount(rowSize)
{
//ensure row count and column count at least no less than 1;
rowCount =( rowCount>0 ) ? rowCount : 1;
rowSize = ( rowSize >0 ) ? rowSize : 1;
totalElem = rowCount * rowSize;
//Creat matrix frame:
if(!CreatMatrix())
throw;
int u = 0;
for(int i=0;i<rowCount;i++){
for(int j =0;j<colCount && u < ArraySize;j++,u++)
Matrix[i][j] = A[u];
}
}
//Copy constructor:
template<class type>
matrix<type>:: matrix(const matrix<type>& M):colSize(rowCount),colCount(rowSize) //ini reference member:
{
Matrix.resize(M.RowCount());
for(int i = 0;i < M.RowCount() ;i++){
Matrix[i] = M.ReadRows(i);
}
rowCount = Matrix.size();
colCount = Matrix[0].size();
}
//---------------------------------------------------------------------------
//: "=" operator:
//---------------------------------------------------------------------------
template<class type> matrix<type>&
matrix<type>::operator = (const matrix<type>& M)
{
const int safeFactor = 10000; //keep rowCount or colCount less than 10000;
//self-assignment testing:
if(this == &M) return *this;
if(M.RowCount() > safeFactor){
CERR("Requiring too many rows or columns! Member function operator=()\
failed.Any key to quit.");
}
Matrix.resize(M.RowCount());
for(int i = 0;i < M.RowCount() ;i++){
Matrix[i] = M.ReadRows(i);
}
rowCount = Matrix.size();
colCount = Matrix[0].size();
return *this;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//Common member functions:
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
template<class type> void
matrix<type>::SetCells( int rIndex, int cIndex,const Cell& cell)
{
if( cIndex >= colCount || rIndex >= rowCount || rIndex < 0 || cIndex < 0){
CERR("No cell can be set!Any key to Quit.");
}
const int i = rIndex,j = cIndex;
Matrix[i][j] = cell;
}
//---------------------------------------------------------------------------
template<class type> const type
matrix<type>::ReadCells( int rIndex, int cIndex) const
{
if( cIndex >= colCount || rIndex >= rowCount || rIndex < 0 || cIndex < 0){
CERR("This cell doesn't exit!Any key to Quit.");
}
const int i = rIndex,j = cIndex;
return Matrix[i][j];
}
//---------------------------------------------------------------------------
template<class type>void
matrix<type>::LoadFromFile(const char* filename,ios_base::openmode mode)
{
//Open file to input:
ifstream matrixIn(filename,mode | ios::nocreate);
if(!matrixIn){
CERR("File don't exit!LoadFromFile() failed.Any key to Quit.");
}
istream_iterator<type,char> infstream(matrixIn),eof;
vector<type> rowVector(totalElem);
//temp vector that recieve all elements from input file:
vector<Cell> tempVect;
copy(infstream,eof,inserter(tempVect,tempVect.begin()));
//Copy temp vector to rowVector,and now it is safe even if the number of elements
//in the file is more than that of the matrix.By using block,it's also safe when
//the number of elemnets in the file is less than the matrix's size. The matrix
//will just get as many as it can mantain from the begining of the file to the
//NO. totalElem.
int block;
block = (totalElem > tempVect.size()) ? tempVect.size() : totalElem;
copy(tempVect.begin(),tempVect.begin() + block,rowVector.begin());
//Store cells to the Matrix:
vector<Cell>::iterator location = rowVector.begin();
for(int i = 0;i < rowCount ;i++){
//copy to matrix set up by row:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -