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 #includeusing 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; i maxLength) { 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