Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* * * * * * * * * * * * * * * * * * * * * **
- * Mathematical matrix function library *
- * by Shuffle *
- * version 0.7 (2013-03-18) *
- * * * * * * * * * * * * * * * * * * * * * */
- #include <iostream>
- #include <cstdlib>
- #include <cmath>
- using namespace std;
- ///Class definition
- class Matrix{
- public:
- Matrix(int,int,bool,bool,int);
- ~Matrix();
- //Basic and diagnostical
- int getHeight() const;
- int getWidth() const;
- float getItem(int,int) const;
- void setItem(float,int,int);
- void setMathematical(bool);
- bool getMathematical() const;
- void applyProcessOnAll(float (*)(float));
- void applyProcessOnItem(float (*)(float), int, int);
- //Mathematical
- float getDeterminant() const;
- Matrix getSubDeterminants() const;
- bool isSquareMatrix() const;
- Matrix getTransposed() const;
- Matrix getInverse() const;
- Matrix flipHorizontal() const;
- Matrix flipVertical() const;
- Matrix flipDiagonal() const;
- //Debug
- void setDebug(bool);
- void fillWithRandomData(int); //by Gergő
- void fillTestData();
- void drawMatrix() const;
- void debugSpacing() const;
- private:
- int rows; //number of matrix rows
- int cols; //number of matrix columns
- float **MatrixData; //contains matrix data
- int isMathematical; //if indexing begins with 0 or 1 (only in get/setItem methods)
- bool debug; //level 1 debug
- bool debugRecurse; //level 2 debug > set in constructor!
- int debugLevel;
- };
- ///Constructor & destructor
- Matrix::Matrix(int height, int width, bool isMath = true, bool dbg = false, int debugLvl = 0){
- if (height < 1 || width < 1 ){
- std::cout << "#(!!!)Zero or 1x1 size matrix! Exiting..." << "\r\n";
- throw 2;
- }
- #define MATRIX_DEBUG if(debug)
- setDebug(dbg);
- debugLevel = debugLvl;
- MATRIX_DEBUG debugSpacing();
- MATRIX_DEBUG std::cout << "#Creating matrix..." << "\r\n";
- rows = height;
- cols = width;
- setMathematical(isMath);
- MatrixData = new float*[rows];
- for (int i = 0;i <= rows-1; i++){
- MatrixData[i] = new float[cols];
- }
- debugRecurse = false;
- }
- Matrix::~Matrix(){
- }
- ///Debugging methotds
- void Matrix::setDebug(bool dbg){
- debug = dbg;
- }
- void Matrix::debugSpacing() const{
- for(int i=0; i < debugLevel;i++)
- cout << "\t";
- }
- void Matrix::drawMatrix() const{
- MATRIX_DEBUG debugSpacing();
- cout << "***\t";
- for(int z = 1; z <= cols;z++)
- cout << "[" << z << "]\t";
- cout << "\r\n";
- for(int i = 0; i <= rows-1;i++){
- MATRIX_DEBUG debugSpacing();
- cout << "[" << i+1 << "]\t";
- for(int j = 0; j <= cols-1;j++){
- cout << MatrixData[i][j] << "\t";
- }
- cout << "\r\n";
- }
- }
- void Matrix::fillWithRandomData(int interval){
- srand(time(NULL));
- for(int i = 0; i <= rows-1;i++)
- for(int j = 0; j <= cols-1;j++)
- MatrixData[i][j]=floor(((float)rand()/(float)RAND_MAX)*interval);
- }
- void Matrix::fillTestData(){
- #define M MatrixData
- M[0][0] = 1;M[0][1] = 4;M[0][2] = -0;
- M[1][0] = 2;M[1][1] = 5;M[1][2] = 1;
- M[2][0] = 3;M[2][1] = 6;M[2][2] = 0;
- #undef M
- }
- ///Basic and diagnostical methods
- int Matrix::getWidth() const{
- return rows;
- }
- int Matrix::getHeight() const{
- return cols;
- }
- float Matrix::getItem(int row, int col) const{
- return MatrixData[row-isMathematical][col-isMathematical];
- }
- void Matrix::setItem(float ertek, int row, int col){
- MatrixData[row-isMathematical][col-isMathematical] = ertek;
- }
- void Matrix::setMathematical(bool isMath){
- if (isMath){
- MATRIX_DEBUG debugSpacing();
- MATRIX_DEBUG std::cout << "#Indexing matrix set to mathematical!" << "\r\n";
- isMathematical = 1;
- }else{
- MATRIX_DEBUG debugSpacing();
- MATRIX_DEBUG std::cout << "#Indexing matrix set to C style!" << "\r\n";
- isMathematical = 0;
- }
- }
- bool Matrix::getMathematical() const{
- return isMathematical ? true : false;
- }
- void Matrix::applyProcessOnAll(float (*proc)(float)){
- //use: object.applyProcessOnAll(*function);
- MATRIX_DEBUG debugSpacing();
- MATRIX_DEBUG std::cout << " #Processing matrix...";
- for(int i = 0; i <= rows-1;i++)
- for(int j = 0; j <= cols-1;j++)
- MatrixData[i][j]=proc(MatrixData[i][j]);
- MATRIX_DEBUG std::cout << "done!" << "\r\n";
- }
- void Matrix::applyProcessOnItem(float (*proc)(float), int row, int col){
- //use: object.applyProcessOnAll(*function,row,column);
- MATRIX_DEBUG debugSpacing();
- MATRIX_DEBUG std::cout << "#Processing item [" << row << "][" << col << "]";
- MatrixData[row-1][col-1]=proc(MatrixData[row-1][col-1]);
- MATRIX_DEBUG std::cout << "done!" << "\r\n";
- }
- ///Mathematical methods
- bool Matrix::isSquareMatrix() const{
- if (rows == cols)
- return true;
- else
- return false;
- }
- Matrix Matrix::getTransposed() const {
- Matrix I = Matrix(cols,rows,false,debug,debugLevel+1);
- for(int i = 0; i <= rows-1;i++)
- for(int j = 0; j <= cols-1;j++)
- I.setItem(MatrixData[i][j],j,i);
- return I;
- }
- Matrix Matrix::flipHorizontal() const{ //!ezt használjuk determináns számításhoz
- Matrix I = Matrix(rows,cols,false,debug,debugLevel+1);
- for(int i = 0; i <= rows-1;i++)
- for(int j = 0; j <= cols-1;j++)
- I.setItem(MatrixData[i][j],rows-1-i,j);
- return I;
- }
- Matrix Matrix::flipVertical() const{
- Matrix I = Matrix(rows,cols,false,debug,debugLevel+1);
- for(int i = 0; i <= rows-1;i++)
- for(int j = 0; j <= cols-1;j++)
- I.setItem(MatrixData[i][j],i,cols-1-j);
- return I;
- }
- Matrix Matrix::flipDiagonal() const{
- Matrix I = Matrix(rows,cols,false,debug,debugLevel+1);
- for(int i = 0; i <= rows-1;i++)
- for(int j = 0; j <= cols-1;j++)
- I.setItem(MatrixData[i][j],rows-1-i,cols-1-j);
- return I;
- }
- float Matrix::getDeterminant() const{
- if (isSquareMatrix()){
- MATRIX_DEBUG debugSpacing();
- MATRIX_DEBUG cout << "#Counting determinant...\r\n";
- //!csúnya, át kell írni - önmagáról másolat
- Matrix tempMatrix = Matrix(rows,cols,false,debugRecurse,debugLevel+1);
- for(int v = 0; v <= rows-1;v++)
- for(int z = 0; z <= cols-1;z++)
- tempMatrix.setItem(MatrixData[v][z],v,z);
- //!
- float tDeterminant = 0,subResult;
- int overHead, item, phaseFlip = 1;
- if (cols > 2){
- for(int phase=0;phase<=1;phase++){ //!átlók megfordítása (2X fut le)
- for(int i=0;i<=cols-1;i++){
- subResult = 1; //!szorzat 0-zása
- for(int j=0;j<=cols-1;j++){
- item = i + j; //!oldalra léptetést valósítja meg
- if (item > cols -1)
- overHead = cols; //!overhead: ha esetleg túlfolynánk a mátrixon, akkor visszaugrasztja a mutatót bal oldalra (mintha maga mellé lenne másolva)
- else
- overHead = 0;
- subResult *= tempMatrix.getItem(j,item-overHead); //!részedmény szorzása az átlóban lévő elemek részeredményével
- }
- tDeterminant += phaseFlip * subResult;
- }
- //!fázis megfordítása
- phaseFlip = -1;
- tempMatrix = tempMatrix.flipHorizontal();
- }
- MATRIX_DEBUG debugSpacing();
- MATRIX_DEBUG cout << "#Done! Determinant: " << tDeterminant << "\r\n";
- return tDeterminant;
- }else if(cols == 2){
- //!2x2-es mátrix számítása fixen
- subResult = tempMatrix.getItem(0,0);
- subResult *= tempMatrix.getItem(1,1);
- tDeterminant = subResult;
- subResult = tempMatrix.getItem(0,1);
- subResult *= tempMatrix.getItem(1,0);
- tDeterminant -= subResult;
- MATRIX_DEBUG debugSpacing();
- MATRIX_DEBUG cout << "#Done! Determinant: " << tDeterminant << "\r\n";
- return tDeterminant;
- }else if(cols == 1){
- tDeterminant = tempMatrix.getItem(0,0);
- MATRIX_DEBUG debugSpacing();
- MATRIX_DEBUG cout << "#Done! Determinant: " << tDeterminant << "\r\n";
- return tDeterminant;
- }
- }else{
- MATRIX_DEBUG debugSpacing();
- MATRIX_DEBUG cout << "#(!!!)Not a SquareMatrix! ";
- return 0;
- }
- }
- Matrix Matrix::getSubDeterminants() const{
- MATRIX_DEBUG debugSpacing();
- MATRIX_DEBUG cout << "#Counting subdeterminants...\r\n";
- Matrix sDeterminants(rows, cols, false, debugRecurse,debugLevel+1);
- for(int i = 0; i <= rows-1;i++){
- for(int j = 0; j <= cols-1;j++){ //!minden egyes elemre al-determináns számolása
- //!új mátrix létrehozása egyel kevesebb oszloppal és sorral
- Matrix subMatrix(rows-1, cols-1, false, debugRecurse,debugLevel+1);
- //!részmátrix elemeinek bemásolása
- MATRIX_DEBUG cout << "\r\n#Number: " << MatrixData[i][j] <<"\r\n";
- int backStep1 = 0;
- int backStep2 = 0;
- for(int k = 0; k <= rows-1;k++){
- if (i==k){
- backStep1 = 1;
- MATRIX_DEBUG cout << "#>>Skipping k: " << k << "\r\n";
- continue;
- }
- for(int l = 0; l <= cols-1;l++){
- if (j==l){
- backStep2 = 1;
- MATRIX_DEBUG cout << "#>>Skipping l: " << k << "\r\n";
- continue;
- }
- MATRIX_DEBUG cout << "#>>Reading item index: (" << k << "," << l << ") value: " << MatrixData[k][l] <<"\r\n";
- subMatrix.setItem(MatrixData[k][l],k-backStep1,l-backStep2);
- MATRIX_DEBUG cout << "# >>Setting to position: (" << k-backStep1 << "," << l-backStep2 << ")\r\n";
- }
- backStep2 = 0;
- }
- MATRIX_DEBUG subMatrix.drawMatrix();
- MATRIX_DEBUG cout << "#Subdeterminant: " << subMatrix.getDeterminant() <<"\r\n";
- sDeterminants.setItem(subMatrix.getDeterminant(),i,j);
- }
- MATRIX_DEBUG debugSpacing();
- MATRIX_DEBUG cout << "#Done!\r\n";
- }
- sDeterminants.drawMatrix();
- return sDeterminants;
- }
- Matrix Matrix::getInverse() const{
- MATRIX_DEBUG debugSpacing();
- MATRIX_DEBUG cout << "#Counting inverse...\r\n";
- //!csúnya, át kell írni - önmagáról másolat
- Matrix tempMatrix = Matrix(rows,cols,false,debugRecurse,debugLevel+1);
- for(int v = 0; v <= rows-1;v++)
- for(int z = 0; z <= cols-1;z++)
- tempMatrix.setItem(MatrixData[v][z],v,z);
- //!
- float mDeterm = tempMatrix.getDeterminant(); //!1.lépés: determinánsok számítása
- if (mDeterm != 0){ //!(nem 0 a determináns?)
- Matrix sDeterm = tempMatrix.getSubDeterminants(); //!2.lépés: al-determinánsok számítása
- sDeterm = sDeterm.getTransposed(); //!3.lépés: al-determinánsok transzponálása
- int sign = 1; //!4.lépés: előjelek fordítása sakktábla szerűen és leosztás a determinánssal
- for(int i = 0; i <= rows-1;i++){
- for(int j = 0; j <= cols-1;j++){
- sDeterm.setItem((sDeterm.getItem(i,j)*sign)/mDeterm,i,j);
- sign = sign * (-1);
- }
- }
- MATRIX_DEBUG debugSpacing();
- MATRIX_DEBUG cout << "#Done!\r\n";
- return sDeterm;
- }else{
- MATRIX_DEBUG debugSpacing();
- MATRIX_DEBUG cout << "#ERROR! Determinant is zero (0)! \r\n";
- throw 1;
- }
- }
- ///Processor sample
- float addOne(float num){ //test
- return num+1;
- }
- ///Debug function
- void boolCout(bool x){
- if (x)
- std::cout << "true";
- else
- std::cout << "false";
- }
- ///Entrance
- int main(void){
- Matrix A = Matrix(3,3,true,true);
- A.fillWithRandomData(4);
- A.fillTestData();
- //A.drawMatrix();
- A.getDeterminant();
- //Matrix B = A.getSubDeterminants();
- //A.applyProcessOnAll(*addOne);
- A = A.getInverse();
- cout << "\r\n";
- A.drawMatrix();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement