www.pudn.com > AdaBoost_weaklearner_1.rar > matrix.cpp


#include "matrix.h" 
#include  
#include  
#include  
#include  
 
#define AS_ZERO		0.0001 
 
Matrix::Matrix(int r, int c) 
{ 
	rows = r; 
	cols = c; 
	alloc(); 
 
	// initialize all elements to zero 
	toZero(); 
} 
 
// copy constructor // 
Matrix::Matrix(const Matrix& m) 
{ 
	rows = m.rows; 
	cols = m.cols; 
	alloc(); 
 
	for (int i = 0; i < rows; i++) 
		for (int j = 0; j < cols; j++) 
			element[i][j] = m.element[i][j]; 
} 
 
// destructor // 
Matrix::~Matrix(void) 
{ 
	release(); 
//	cout << "Matrix is: " << this << endl; 
//	cout << "destructor called" << endl; 
} 
 
// allocate memory on heap // 
void Matrix::alloc(void) 
{ 
	element = new T* [rows]; 
	for (int i = 0; i < rows; i++) 
		element[i] = new T [cols]; 
} 
 
// free heap memory // 
void Matrix::release(void) 
{ 
	for (int i = 0; i < rows; i++) 
	{ 
		delete [] element[i]; 
		element[i]=0; 
	} 
	delete [] element; 
	element=0; 
} 
 
void Matrix::toZero(void) 
{ 
	for (int i = 0; i < rows; i++) 
		for (int j = 0; j < cols; j++) 
			element[i][j] = 0; 
} 
 
void Matrix::zeros(int i, int j) 
{ 
	for (int ii = 0; ii < rows; ii++) 
		for (int jj = 0; jj < cols; jj++) 
			element[ii][jj] = 0; 
} 
 
void Matrix::toOne(void) 
{	 
	for (int i = 0; i < rows; i++) 
	for (int j = 0; j < cols; j++) 
	element[i][j] = 1; 
} 
 
void Matrix::ones(int i, int j, T val, int scaler) 
{ 
    for (int ii = 0; ii < i; ii++) 
		for (int jj = 0; jj < j; jj++) 
			element[ii][jj] = val / scaler; 
} 
 
void Matrix::print(void) const 
{ 
	cout << *this;									// w/ << overloaded // 
//	for (int i = 0; i < rows; i++) 
//	{ 
//		for (int j = 0; j < cols; j++) 
//			cout << element[i][j] << '\t'; 
//		cout << endl; 
//	} 
} 
 
void Matrix::set (int i, int j, T val) 
{ 
	//if(i>rows-1 || j>cols-1) 
	//	reptError("Matrix subscript out of bound, set(i,j) failed!"); 
	    i=i-1; 
    	element[i][j]=val; 
} 
 
void Matrix::setValue (int tt, T val) 
{ 
	tt=tt-1; 
	element[tt][0] = val; 
} 
 
// Get Value from matrix 
int Matrix::getValue(int j,double *val, Matrix& m) const 
{ 
	j=j-1; 
	(*val) = m.element[0][j]; 
	return (0); 
} 
 
// Get Value from matrix 
int Matrix::getValueSpecific(int i, int j,double *val, Matrix& m) const 
{  
	(*val) = m.element[i][j]; 
	return (0); 
} 
 
// overload subscript operator to access element[i][j] // 
T Matrix::operator () (int i, int j) const 
{ 
	if(i>rows-1 || j>cols-1) 
		reptError("Matrix subscript out of bound, () failed!"); 
	return element[i][j]; 
} 
 
// Take only part from the matrix 
void Matrix::partOfMatrix(int r, int c, Matrix& m) const 
{ 
   for (int i = 0; i < row(); i++) 
		for (int j = 0; j < col()-1; j++) 
			element[i][j] = m.element[i][j]; 
} 
 
void Matrix::partOfMatrixNext(int r, int c, int step, Matrix& m) const 
{ 
   int k=0; 
   int i = step - r; 
   for (i; i < step; i++){ 
	   for (int j = 0; j < col()-1; j++){ 
			element[k][j] = m.element[i][j]; 
	   } 
	   k++; 
   } 
} 
 
// Take only part from the matrix from end 
void Matrix::partOfMatrixFromEnd(int r_train,int step,int c,Matrix& m) const 
{ 
   int k=0; 
   int i=r_train - step; 
   for (i; i < r_train; i++){ 
	   for (int j = 0; j < col()-1; j++){ 
			element[k][j] = m.element[i][j]; 
	   } 
	   k++; 
   } 
} 
 
// This function return the matrix size 
void Matrix::matrixSize(int *i, int *j, Matrix& m) const 
{ 
   (*i) = m.rows; 
   (*j) = m.cols; 
} 
// scalar minus matrix 
void Matrix::ScalarMinusMatrix(double k, Matrix& m) const 
{ 
   	int r=rows; 
	int c=m.col(); 
	for (int i=0; i < r; i++) 
	    for (int j=0; j < c; j++) 
		    element[i][j] = k  - m.element[i][j]; 
} 
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 
// Take a specific part (coloum) from the matrix 
void Matrix::specificPartOfMatrix(Matrix& m,int r, int c) 
{ 
	//Matrix temp(r,r); 
	int j = c; 
	int k=0; 
	for (int i = 0; i < row(); i++) 
 
		element[i][k] = m.element[i][j]; 
} 
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 
// From matrix (Vector) to Array  
void Matrix::matrixToArray(double array[10], Matrix& m) const 
{ 
	int r=rows; 
	int c=cols;  
	for (int i = 0; i < r; i++) 
	   for (int j=0; j < c; j++) 
		    array[i]=m.element[i][j]; 
//	return array[10]; 
} 
 
// From matrix (Vector) to Array  
void Matrix::matrixToArrayold(double array[10], Matrix& m) const 
{ 
	int r=rows; 
	int c=m.col();  
	int i = 0; 
	for (int j=0; j < c; j++) 
		    array[j]=m.element[i][j]; 
//	return array[10]; 
} 
 
void Matrix::matrixExp(Matrix& m) const 
{ 
   double dVal; 
   int r=rows; 
   int c=m.col(); 
   for (int i = 0; i < r; i++){ 
	   for (int j = 0; j < c; j++){ 
			dVal = m.element[i][j]; 
		    //dValue = fabs(dVal); 
			element[i][j] = exp(dVal); 
	   } 
   } 
} 
 
void Matrix::matrixLog(Matrix& m) const 
{ 
   double dVal; 
   int r=rows; 
   int c=m.col(); 
   for (int i = 0; i < r; i++){ 
	   for (int j = 0; j < c; j++){ 
			dVal = m.element[i][j]; 
		    //dValue = fabs(dVal); 
			element[i][j] = log(dVal); 
	   } 
   } 
} 
 
void Matrix::matrixAbs(Matrix& m) const 
{ 
   double dVal; 
   //double dValue; 
   for (int i = 0; i < row(); i++){ 
	   for (int j = 0; j < col()-1; j++){ 
			dVal = m.element[i][j]; 
		    //dValue = fabs(dVal); 
			element[i][j] = fabs(dVal); 
	   } 
   } 
} 
 
int Matrix::matrixSumCol(double *sum,  Matrix& m) const 
{ 
	int r=rows; 
	int c=cols; 
    for (int i = 0; i < r; i++) 
		for (int j = 0; j < c-1; j++) 
			(*sum) += m.element[i][j]; 
		 
		return (0);		 
} 
 
int Matrix::matrixSumRow(double *sum,  Matrix& m) const 
{ 
	int r=rows; 
	int c=cols; 
	for (int j = 0; j < c; j++){ 
		for (int i = 0; i < r; i++){ 
		    	(*sum) += m.element[i][j]; 
		} 
	} 
		 
	return (0);		 
} 
 
// Compare between the current value and the perivues value 
int Matrix::matrixCompareAndSet(int *i_index, int c_train, Matrix& m) const 
{ 
	int r=rows; 
	int c=m.col(); 
	Matrix temp(r, c); 
	for (int i = 1; i < r; i++){ 
		for (int j = 0; j < c; j++){ 
            temp.element[i][j] = (m.element[i][j] - m.element[i-1][j]); 
			if ((temp.element[i][j] == 0) && (m.element[i][j] > 0)) 
			{ 
				*i_index=*i_index+1; 
				if (*i_index > (c_train -2)) 
				{ 
					*i_index=1; 
				} 
			} 
			else 
			{ 
			    *i_index=*i_index;			 
			} 
		} 
	} 
	return *i_index; 
	 
} 
 
// Compare between the current value and the perivues value 
int Matrix::matrixCompareAndSetfor_t(int k, int *t_index, int c_train, Matrix& m) const 
{ 
	//int r=rows; 
	int c=m.col(); 
	Matrix temp(k, c); 
	for (int i = 1; i < k; i++){ 
		for (int j = 0; j < c; j++){ 
            temp.element[i][j] = (m.element[i][j] - m.element[i-1][j]); 
			if ((temp.element[i][j] == 0) || (temp.element[i][j] == 1) && (m.element[i][j] > 0)) 
			{ 
				*t_index=*t_index-5; 
				if (*t_index > 130) 
				{ 
					*t_index=73; 
				} 
				if (*t_index < 70) 
				{ 
					*t_index=127; 
				} 
			} 
			else 
			{ 
			    *t_index=*t_index;			 
			} 
		} 
	} 
	return *t_index; 
	 
} 
 
// Find the max value of the matrix 
int Matrix::matrixMax(double *val, int *index, Matrix& m) const 
{ 
	int r=rows; 
	int c=m.col(); 
	Matrix temp(r, c); 
    int j,i; 
    for (i = 0; i < r; i++){ 
		for (j = 0; j < c-1; j++){ 
			if (m.element[i][j] > m.element[i][j+1]) 
			{ 
				temp.element[i][j] = m.element[i][j]; 
				m.element[i][j]=m.element[i][j+1]; 
				m.element[i][j+1]=temp.element[i][j]; 
				if (m.element[i][j+1] > (*val)) 
				{ 
                  (*val) = m.element[i][j+1]; 
				  (*index) = j; 
				} 
				//temp.element[i][j] = m.element[i][j]; 
			    //(*val) = m.element[i][j]; 
				//(*index) = j; 
			} 
		//	else  
		//	{ 
		//		temp.element[i][j] = m.element[i][j+1]; 
		//		(*val) = m.element[i][j]; 
		//		(*index) = j; 
		//	} 
		} 
	} 
	return (0);	 
} 
 
Matrix& Matrix::operator= (const Matrix& m) 
{ 
	if(rows != m.row() || cols != m.col()) 
		reptError("Matrix dimensions differ, assignment failed!"); 
 
	for (int i = 0; i < m.row(); i++) 
		for (int j = 0; j < m.col(); j++) 
			element[i][j] = m.element[i][j]; 
 
	return *this; 
} 
 
istream& operator>> (istream& is, Matrix& m) 
{ 
	for (int i=0; i < m.row(); i++) 
		for (int j=0; j < m.col(); j++) 
			is >> m.element[i][j]; 
 
	return is; 
} 
 
ostream& operator<< (ostream& os, const Matrix& m) 
{ 
	for (int i=0; i 1) 
	   c = c-1; 
	else 
	   c = c; 
	Matrix temp(r, c); 
 
	for (int i=0; i < r; i++) 
	{ 
		for (int j=0; j < c; j++) 
		{ 
			temp.element[i][j] = element[i][j] - m.element[i][j]; 
		} 
	} 
 
	return temp;  
 // if(rows != m.row() || cols != m.col()) 
 //		reptError("Matrix sizes mismatch, subtraction failed!"); 
    /* 
	Matrix temp(rows, cols); 
	temp = *this; 
	temp -= m; 
 
	return temp; 
	*/ 
} 
 
// compare the correct label matrix and scaler 
Matrix Matrix::operator> (const T& c) const 
{ 
	Matrix temp(rows, cols); 
	temp = *this; 
	temp >= c; 
 
	return temp; 
} 
 
// combined scalar multiplication and assignment operator // 
Matrix& Matrix::operator>= (const T& c) 
{ 
	for (int j = 0; j < cols; j++){ 
		for (int i = 0; i < rows; i++){ 
			if (element[i][j] > c) 
				element[i][j]=1; 
			else 
				element[i][j]=0; 
		} 
	} 
	 
	return *this; 
} 
 
// scale a matrix by a constant c // 
Matrix Matrix::operator* (const T& c) const 
{ 
	Matrix temp(rows, cols); 
	temp = *this; 
	temp *= c; 
 
	return temp; 
} 
 
// two matrix multiplication //  
Matrix Matrix::operator* (const Matrix& m) const 
{ 
//	if(cols != m.row()) 
//		reptError("Matrix dimensions error, multiplication failed!"); 
 
	int r=rows; 
	int c=m.col(); 
	Matrix temp(r, c); 
 
	for (int i=0; i < r; i++) 
	{ 
		for (int j=0; j < c; j++) 
		{ 
			for (int k=0; k < cols; k++) 
			{ 
				temp.element[i][j] += element[i][k] * m.element[k][j]; 
				if(fabs(temp.element[i][j])<=AS_ZERO) 
					temp.element[i][j]=0;			// round small # to zero 
			} 
		} 
	} 
 
	return temp; 
} 
 
void Matrix::scalarDivisonScalar(double scalar_1, double scalar_2, const Matrix& m) const 
{ 
	int r=rows;; 
	int c=m.col(); 
	for (int i=0; i < r; i++) 
		for (int j=0; j < c; j++) 
			 element[i][j] = scalar_1 / scalar_2; 
} 
 
 
 
void Matrix::matrixdDivisonScalar(double scalar, const Matrix& m) const 
{ 
	int r=rows; 
	int c=m.col(); 
//	Matrix temp(r, c); 
	for (int i=0; i < r; i++){ 
		for (int j=0; j < c; j++){ 
			 element[i][j] = m.element[i][j] / scalar; 
			//if(fabs(temp.element[i][j])<=AS_ZERO) 
			//	temp.element[i][j]=0;			// round small # to zero 
		} 
	} 
	 
//	return temp; 
} 
 
 
// divison matrix by scaler  
Matrix Matrix::operator / (const Matrix& m) const 
{ 
	//	if(cols != m.row()) 
	//		reptError("Matrix dimensions error, multiplication failed!"); 
	 
	int r=rows; 
	int c=m.col(); 
	Matrix temp(r, c); 
	 
	for (int i=0; i < r; i++) 
	{ 
		for (int j=0; j < c; j++) 
		{ 
			temp.element[i][j] = element[i][j] / m.element[i][j]; 
			if(fabs(temp.element[i][j])<=AS_ZERO) 
				temp.element[i][j]=0;			// round small # to zero 
		} 
	} 
	 
	return temp; 
} 
 
 
// set a matrix to an identity matrix // 
void Matrix::toUnit(void) 
{ 
	if (!isSquare()) 
		reptError("No identity matrix for a non-square matrix!"); 
 
	for (int i = 0; i < rows; i++) 
		for (int j = 0; j < cols; j++) 
			element[i][j]=(i==j) ? (T) 1 : (T) 0; 
} 
 
void Matrix::reptError (char* errorMsg) const 
{ 
	cerr << errorMsg << endl; 
	exit(1); 
} 
 
// compute the transpose matrix // 
void Matrix::matrixTranspose (int r, int c, const Matrix& m) const 
{ 
	for (int i = 0; i < r; i++) 
		for (int j = 0; j < c; j++) 
			element[j][i] = m.element[i][j]; 
} 
 
// compute the transpose matrix // 
Matrix Matrix::transpose (void) const 
{ 
	int r=rows; 
	int c=cols; 
	Matrix temp(c, r); 
 
	for (int i = 0; i < r; i++) 
		for (int j = 0; j < c; j++) 
	      temp.element[j][i] = element[i][j]; 
 
	return temp; 
} 
 
// copy the matrix 
void Matrix::copy (int tt, Matrix& m) const 
{	 
	int r=rows; 
	int i = 0; 
	int j = tt; 
	double val; 
	val = m.element[0][0]; 
	element[i][tt] = val; 
} 
// copy matrix to matrix 
void Matrix::copyMatrixToMatrix (Matrix& m) 
{	 
	int r=rows; 
	int c=cols; 
	for (int i = 0; i < r; i++) 
		for (int j = 0; j < c; j++) 
	      element[i][j] = m.element[i][j]; 
} 
 
void Matrix::copyToMatrix(int tt, Matrix& m) const 
{ 
	double val; 
	tt=tt-1; 
	//for (int i=0; i < tt; i++){ 
	   val = m.element[0][tt]; 
	   element[tt][0] = val; 
	//} 
} 
 
 
// minor() returns the minior of an element (r, c) // 
void Matrix::minor(int r, int c, Matrix& m) const 
{ 
	// precondition: a square matrix & the calling matrix with 
	// dimension >= 3 // 
 
	int k, l; 
	for(int i = 0; i < rows-1; i++) 
	{ 
		k=(i>=r) ? (i+1):i; 
		for(int j = 0; j < cols-1; j++) 
		{ 
			l=(j>=c) ? (j+1):j; 
			m.element[i][j]=element[k][l]; 
		} 
	} 
} 
 
// cofact() calculates the cofactor of an element at (r, c) // 
T Matrix::cofact(int r, int c) const 
{ 
	// precondition: a square matrix & the calling matrix with 
	// dimension >= 3 // 
 
	T cof; 
	Matrix temp(rows-1, cols-1); 
 
	minor(r, c, temp); 
//	cout << endl; 
//	temp.print(); 
	cof=(T) pow(-1, r+c)*temp.det(); 
 
	return cof; 
} 
 
// computes the adjoin matrix of a given matrix // 
void Matrix::adjoin(Matrix& m) const 
{ 
	int dim=rows;								// rows=cols 
 
	if (!isSquare()) 
		reptError("No adjoin matrix for a non-square matrix!"); 
	if(m.row() != rows || m.col() != cols) 
		reptError("Non square adjoin matrix defined!"); 
 
	for(int i = 0; i < dim; i++) 
		for(int j = 0; j < dim; j++) 
			m.element[i][j]=cofact(i, j); 
//	cout << endl; 
//	m.print(); 
	m=m.transpose(); 
//	cout << endl; 
//	m.print(); 
} 
 
// calculates the determinant of a matrix by first changing it 
// to a upper triangular matrix // 
T Matrix::det(void) const 
{ 
	if (!isSquare()) 
		reptError("No determinant for a non-square matrix!"); 
 
	T determinant=1; 
	Matrix temp(rows, cols); 
	temp=*this; 
//	cout << endl; 
//	temp.print(); 
 
	temp.toUpper(); 
//	cout << endl; 
//	temp.print(); 
	for (int i = 0; i < rows; i++) 
		determinant *= temp.element[i][i];				// m(n, n) could be 0 
 
	if(fabs(determinant)<=AS_ZERO)						// if too small, set to zero 
		determinant=0; 
 
	return determinant; 
} 
 
// covert to upper triangular matrix // 
void Matrix::toUpper(void) 
{ 
	// precondition: a square matrix // 
 
	int i, j, k, dim=rows; 
	for (j = 0; j < dim-1; j++) 
	{ 
		// check if the diagonal element is zero // 
		if(fabs(element[j][j])<=AS_ZERO) 
		{ 
			element[j][j]=0; 
			for(i = j+1; i < dim; i++) 
			{ 
				if(element[i][j] != 0) 
				{ 
					swapRow(i, j, dim); 
					break; 
				} 
			} 
			if(i>=dim)								// every element=0 // 
			{ 
				cout << "Cann't convert to upper triangular matrix, "; 
				cout << "Error in column No. j=" << j << endl; 
				reptError("Every element in column j is zero!"); 
			} 
		} 
 
		// convert to upper triangular matrix // 
		for (i = j+1; i < dim; i++) 
		{ 
			if(element[i][j]==0)	continue; 
			for(k = j+1; k < dim; k++) 
				element[i][k]=element[i][k]-element[j][k]*element[i][j]/element[j][j]; 
			element[i][j]=0; 
		} 
	} 
} 
 
// swap 2 lines, each has c columns // 
Matrix& Matrix::swapRow(int r1, int r2, int c) 
{ 
	T temp; 
	for (int j=0; j=9 && ch<=13))				// skip whitespace // 
		{ 
			is.get(); 
			continue; 
		} 
		if (ch=='#') 
		{ 
			is.ignore(1000,'\n');					// skip comment line // 
			continue; 
		} 
 
		for(j=0; j> element[i][j]; 
		i++; 
	} 
	is.close(); 
//	if(i != rows) 
//		reptError("File row# != rows!"); 
} 
 
void Matrix::writeFile (char* file_name) 
{ 
	ofstream fos; 
 
	fos.open(file_name, ios::out, filebuf::sh_none); 
	if(fos.fail()) 
	{ 
		cout << "File name = " << file_name << endl; 
		reptError("Open file to write failed!"); 
	} 
 
	fos << *this; 
//	for(int i=0; i