www.pudn.com > Image_segment.rar > Matrix.h


//Copyright (c) 2004-2005, Baris Sumengen 
//All rights reserved. 
// 
// CIMPL Matrix Performance Library 
// 
//Redistribution and use in source and binary 
//forms, with or without modification, are 
//permitted provided that the following 
//conditions are met: 
// 
//    * No commercial use is allowed.  
//    This software can only be used 
//    for non-commercial purposes. This  
//    distribution is mainly intended for 
//    academic research and teaching. 
//    * Redistributions of source code must 
//    retain the above copyright notice, this 
//    list of conditions and the following 
//    disclaimer. 
//    * Redistributions of binary form must 
//    mention the above copyright notice, this 
//    list of conditions and the following 
//    disclaimer in a clearly visible part  
//    in associated product manual,  
//    readme, and web site of the redistributed  
//    software. 
//    * Redistributions in binary form must 
//    reproduce the above copyright notice, 
//    this list of conditions and the 
//    following disclaimer in the 
//    documentation and/or other materials 
//    provided with the distribution. 
//    * The name of Baris Sumengen may not be 
//    used to endorse or promote products 
//    derived from this software without 
//    specific prior written permission. 
// 
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT 
//HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
//EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
//NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
//MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
//PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
//CONTRIBUTORS BE LIABLE FOR ANY 
//DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
//EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
//(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
//OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
//DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
//HOWEVER CAUSED AND ON ANY THEORY OF 
//LIABILITY, WHETHER IN CONTRACT, STRICT 
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
//OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
//OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
//POSSIBILITY OF SUCH DAMAGE. 
 
 
 
#pragma once 
#ifndef MATRIX_H 
#define MATRIX_H 
 
 
 
#include  
 
using std::cout; 
using std::cerr; 
using std::endl; 
using std::ostream; 
using std::right; 
using std::fixed; 
 
#include  
 
using std::setw; 
 
#include  
#include  
#include  
 
#include  
 
using std::string; 
 
#include  
 
using std::ostringstream; 
 
#include  
 
#include  
using std::numeric_limits; 
 
 
using namespace std; 
 
 
#include "cimpl.h" 
 
 
namespace CIMPL 
{ 
 
 
// forward declaration 
//template< class T > class Array; 
template< class T > class Matrix; 
template< class T > class SubMatrix; 
template< class T > class Vector; 
 
/// \brief 2-D Matrix class. 
template< class T > 
class Matrix  
{ 
 
	//friend class Array; 
	friend class Vector; 
	friend class SubMatrix; 
 
 
protected: 
	T *data; 
	int ndims;  // always 2 
	int length; // xDim*yDim 
	int xDim; 
	int yDim; 
	Cleaner *clean;   // Reference counting Garbage collector. 
 
	Vector *columns; 
	 
public: 
	Matrix(); 
	Matrix(const int rows, const int columns); 
	Matrix(const int rows, const int columns, T init); 
	 
	Matrix(string str); 
 
	Matrix(Matrix &m); // copy constructor 
 
	~Matrix(); 
	 
	void Clean(); 
 
	/// Make sure enough memory is already allocated. 
	/// Memory is from now on handled by the matrix... Don't free it manually. 
	void Set(const int rows, const int columns, T *_data);  
 
	const T* DataPtr(); 
	T* Data(); 
 
	Matrix Clone() const; 
	 
	void SwitchColumns(int i, int j); 
 
	/// \brief reorganizes data array such that matrix elements are  
	/// ordered in column major ordering. Calling this function will  
	/// allocate new memory with correct ordering of elements and old memory is freed. 
	/// 
	/// If you created external (manual) pointers to matrix data, you might experience  
	/// memory/pointer errors after the data is rearranged. 
	void SyncData2Columns(); 
	 
//	SubMatrix Slice(int row1, int row2, int col1, int col2); 
//	SubMatrix Slice(string str1, string str2); 
 
	Matrix Slice(int row1, int row2, int col1, int col2); 
	Matrix Slice(string str1, string str2); 
 
	Vector Slice(string str); 
 
 
	const int Columns() const; 
	const int Rows() const; 
	const int XDim() const; 
	const int YDim() const; 
	const int* Dims() const; 
	const int Length() const; 
	const int Numel() const; 
	const int NDims() const; 
	void Init(const T init); 
 
	Matrix&  Rand(const double max); 
	static Matrix Rand(const int rows, const int cols, const double max); 
 
	void ReadFromMatrix(const Matrix& m); 
	void ReadFromMatrix(const Matrix& m, const int rowStart, const int colStart); 
 
	static Matrix Cat(int dimension, Matrix& m1, Matrix& m2); 
	static Matrix Cat(int dimension, Matrix& m1, Vector& m2); 
	static Matrix Cat(int dimension, Vector& m1, Matrix& m2); 
	static Matrix Cat(int dimension, Vector& m1, Vector& m2); 
 
	static Matrix Ones(int side); 
	static Matrix Ones(int rows, int cols); 
	static Matrix Zeros(int side); 
	static Matrix Zeros(int rows, int cols); 
 
 
	static bool IsSquare(Matrix& m); 
	static bool IsM2MCompatible(Matrix& m1, Matrix& m2); 
	static Matrix MMultiply(Matrix& m1, Matrix& m2); 
	static Matrix MMultiply(Matrix& m1, Vector& m2); 
	static Matrix MMultiply(Vector& m1, Matrix& m2); 
 
	static Matrix Transpose(Matrix& m); 
	Matrix& Transpose(); 
 
	//static Matrix Hermitian(Matrix& m); 
	//Matrix& Hermitian(); 
 
	static bool IsCompatible(Matrix& m1, Matrix& m2); 
	 
	// Boolean Operations... 
	static Matrix And(Matrix& m1, Matrix& m2); 
	static Matrix Or(Matrix& m1, Matrix& m2); 
	static Matrix Lt(Matrix& m1, Matrix& m2); 
	static Matrix Gt(Matrix& m1, Matrix& m2); 
	static Matrix Le(Matrix& m1, Matrix& m2); 
	static Matrix Ge(Matrix& m1, Matrix& m2); 
	static Matrix Eq(Matrix& m1, Matrix& m2); 
	static Matrix Ne(Matrix& m1, Matrix& m2); 
 
	// Boolean Operations with value type... 
	static Matrix And(Matrix& m, T v); 
	static Matrix Or(Matrix& m, T v); 
	static Matrix Lt(Matrix& m, T v); 
	static Matrix Gt(Matrix& m, T v); 
	static Matrix Le(Matrix& m, T v); 
	static Matrix Ge(Matrix& m, T v); 
	static Matrix Eq(Matrix& m, T v); 
	static Matrix Ne(Matrix& m, T v); 
 
 
// Add matrix to another matrix 
	static Matrix Add(Matrix& m1, Matrix& m2); 
	static Matrix Subtract(Matrix& m1, Matrix& m2); 
	static Matrix Multiply(Matrix& m1, Matrix& m2); 
	static Matrix Divide(Matrix& m1, Matrix& m2); 
 
// Add value to another matrix 
	static Matrix Add(Matrix& m1, T v2); 
	static Matrix Subtract(Matrix& m1, T v2); 
	static Matrix Subtract(T v2, Matrix& m1); 
	static Matrix Multiply(Matrix& m1, T v2); 
	static Matrix Divide(Matrix& m1, T v2); 
	static Matrix Divide(T v2, Matrix& m1); 
 
 
// Add matrix to "this" matrix 
	Matrix& Add(Matrix& m); 
	Matrix& Subtract(Matrix& m); 
	Matrix& Multiply(Matrix& m); 
	Matrix& Divide(Matrix& m); 
 
// Add value to "this" matrix 
	Matrix& Add(T v); 
	Matrix& Subtract(T v); 
	Matrix& Multiply(T v); 
	Matrix& Divide(T v); 
 
 
//OPERATORS 
	//Matrix& operator= (T init); 
	Matrix& operator= (Matrix& m); 
	//Matrix& operator= (Array& m); 
	Matrix& operator= (Vector& m); 
	Matrix& operator= (SubMatrix& m); 
 
	Matrix& operator= (string str); 
 
	Matrix operator+ (); 
	Matrix operator- (); 
	Matrix operator! (); 
	 
	friend Matrix operator, (Matrix& m1, Matrix& m2) 
	{ 
		return Matrix::Cat(2, m1, m2); 
	} 
	 
	friend Matrix operator, (Matrix& m1, Vector& m2) 
	{ 
		return Matrix::Cat(2, m1, m2); 
	} 
 
	friend Matrix operator, (Vector& m1, Matrix& m2) 
	{ 
		return Matrix::Cat(2, m1, m2); 
	} 
 
 
 
	// Transpose 
	Matrix operator~ (); 
 
	friend ostream& operator<< (ostream& output, Matrix& m) 
	{ 
		int bufferWidth = 80; 
		int lm = m.Rows(); 
		int rowNoWidth = (int)log10((double)(lm-1))+2; 
		int infoWidth = 3+rowNoWidth+2; 
 
		int maxLength  = 1; 
		for(int i=0; imaxLength) 
			{ 
				maxLength = l; 
			} 
		} 
 
		int columnWidth = maxLength+3; 
		int columnMax = (bufferWidth-infoWidth)/columnWidth; 
		 
		output << typeid(m).name() << " of size " << m.Rows() << "x" << m.Columns() << endl; 
		output << "=======================" << endl; 
		if(m.Columns() <= columnMax) 
		{ 
			for(int i=0;i 0) 
			{ 
				output << endl; 
				output << "----------------------" << endl; 
				output << "Columns " << groups*columnMax+1 << " through " << groups*columnMax+leftover-1+1 << endl; 
				output << "----------------------" << endl; 
				for(int i=0;i& operator[] (const int i); 
	 
	/// \brief returns a new Matrix using the slice rectangle. 
	//Matrix operator() (const int row1, const int row2, const int col1, const int col2); 
	SubMatrix operator() (const int row1, const int row2, const int col1, const int col2); 
 
	/// \brief returns a new Matrix using the slice rectangle. 
	//Matrix operator() (string str1, string str2); 
	SubMatrix operator() (string str1, string str2); 
	Vector operator() (string str); 
 
	/// Matrix to Matrix multiplication 
	friend Matrix operator& (Matrix& m1, Matrix& m2) 
	{ 
		return Matrix::MMultiply(m1, m2); 
	} 
	 
	/// Matrix to column Vector multiplication 
	friend Matrix operator& (Matrix& m1, Vector& m2) 
	{ 
		return Matrix::MMultiply(m1, m2); 
	} 
 
	/// Row Vector to Matrix multiplication 
	friend Matrix operator& (Vector& m1, Matrix& m2) 
	{ 
		return Matrix::MMultiply(m1, m2); 
	} 
 
 
	// Boolean operations 
	friend Matrix operator&& (Matrix& m1, Matrix& m2) 
	{ 
		return Matrix::And(m1, m2); 
	} 
 
	friend Matrix operator|| (Matrix& m1, Matrix& m2) 
	{ 
		return Matrix::Or(m1, m2); 
	} 
 
	friend Matrix operator< (Matrix& m1, Matrix& m2) 
	{ 
		return Matrix::Lt(m1, m2); 
	} 
 
	friend Matrix operator> (Matrix& m1, Matrix& m2) 
	{ 
		return Matrix::Gt(m1, m2); 
	} 
 
	friend Matrix operator<= (Matrix& m1, Matrix& m2) 
	{ 
		return Matrix::Le(m1, m2); 
	} 
 
	friend Matrix operator>= (Matrix& m1, Matrix& m2) 
	{ 
		return Matrix::Ge(m1, m2); 
	} 
 
	friend Matrix operator== (Matrix& m1, Matrix& m2) 
	{ 
		return Matrix::Eq(m1, m2); 
	} 
 
	friend Matrix operator!= (Matrix& m1, Matrix& m2) 
	{ 
		return Matrix::Ne(m1, m2); 
	} 
 
 
	// Boolean operations with value type 
	friend Matrix operator&& (Matrix& m, T v) 
	{ 
		return Matrix::And(m, v); 
	} 
	friend Matrix operator&& (T v, Matrix& m) 
	{ 
		return Matrix::And(m, v); 
	} 
 
	friend Matrix operator|| (Matrix& m, T v) 
	{ 
		return Matrix::Or(m, v); 
	} 
	friend Matrix operator|| (T v, Matrix& m) 
	{ 
		return Matrix::Or(m, v); 
	} 
 
	friend Matrix operator< (Matrix& m, T v) 
	{ 
		return Matrix::Lt(m, v); 
	} 
	friend Matrix operator< (T v, Matrix& m) 
	{ 
		return Matrix::Gt(m, v); 
	} 
 
	friend Matrix operator> (Matrix& m, T v) 
	{ 
		return Matrix::Gt(m, v); 
	} 
	friend Matrix operator> (T v, Matrix& m) 
	{ 
		return Matrix::Lt(m, v); 
	} 
 
	friend Matrix operator<= (Matrix& m, T v) 
	{ 
		return Matrix::Le(m, v); 
	} 
	friend Matrix operator<= (T v, Matrix& m) 
	{ 
		return Matrix::Ge(m, v); 
	} 
 
	friend Matrix operator>= (Matrix& m, T v) 
	{ 
		return Matrix::Ge(m, v); 
	} 
	friend Matrix operator>= (T v, Matrix& m) 
	{ 
		return Matrix::Le(m, v); 
	} 
 
	friend Matrix operator== (Matrix& m, T v) 
	{ 
		return Matrix::Eq(m, v); 
	} 
	friend Matrix operator== (T v, Matrix& m) 
	{ 
		return Matrix::Eq(m, v); 
	} 
 
	friend Matrix operator!= (Matrix& m, T v) 
	{ 
		return Matrix::Ne(m, v); 
	} 
	friend Matrix operator!= (T v, Matrix& m) 
	{ 
		return Matrix::Ne(m, v); 
	} 
 
 
 
 
 
 
 
 
// Add matrix to another matrix 
	friend Matrix operator+ (Matrix& m1, Matrix& m2) 
	{ 
		return Matrix::Add(m1, m2); 
	} 
 
	friend Matrix operator- (Matrix& m1, Matrix& m2) 
	{ 
		return Matrix::Subtract(m1, m2); 
	} 
 
	friend Matrix operator* (Matrix& m1, Matrix& m2) 
	{ 
		return Matrix::Multiply(m1, m2); 
	} 
 
	friend Matrix operator/ (Matrix& m1, Matrix& m2) 
	{ 
		return Matrix::Divide(m1, m2); 
	} 
 
 
// Add value to another matrix 
	friend Matrix operator+ (Matrix& m, T v) 
	{ 
		return Matrix::Add(m, v); 
	} 
 
	friend Matrix operator+ (T v, Matrix& m) 
	{ 
		return Matrix::Add(m, v); 
	} 
 
	friend Matrix operator- (Matrix& m, T v) 
	{ 
		return Matrix::Subtract(m, v); 
	} 
 
	friend Matrix operator- (T v, Matrix& m) 
	{ 
		return Matrix::Subtract(v, m); 
	} 
 
	friend Matrix operator* (Matrix& m, T v) 
	{ 
		return Matrix::Multiply(m, v); 
	} 
 
	friend Matrix operator* (T v, Matrix& m) 
	{ 
		return Matrix::Multiply(m, v); 
	} 
 
	friend Matrix operator/ (Matrix& m, T v) 
	{ 
		return Matrix::Divide(m, v); 
	} 
 
	friend Matrix operator/ (T v, Matrix& m) 
	{ 
		return Matrix::Divide(v, m); 
	} 
 
 
 
 
// Add inline 
	Matrix& operator+= (Matrix& m); 
	Matrix& operator-= (Matrix& m); 
	Matrix& operator*= (Matrix& m); 
	Matrix& operator/= (Matrix& m); 
 
	Matrix& operator+= (T v); 
	Matrix& operator-= (T v); 
	Matrix& operator*= (T v); 
	Matrix& operator/= (T v); 
 
	 
// TYPE CONVERSIONS 
	//Matrix(Array &m); 
	Matrix(Vector &m); 
	Matrix(SubMatrix &m); 
 
 
}; 
 
#include "./Matrix.inl" 
 
 
 
}; //namespace 
 
 
#endif