/* * surf - visualizing algebraic curves and algebraic surfaces * Copyright (C) 1996-1997 Friedrich-Alexander-Universitaet * Erlangen-Nuernberg * 1997-2000 Johannes Gutenberg-Universitaet Mainz * Authors: Stephan Endrass, Hans Huelf, Ruediger Oertel, * Kai Schneider, Ralf Schmitt, Johannes Beigel * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifndef MATRIX_H #define MATRIX_H #include #include "Thread.h" #include // #define DEBUG #include "debug.h" template class Matrix { private: Matrix(const Matrix &); void operator=(const Matrix &); public: Matrix(int newSize) : size(newSize), elems(new Type[newSize*newSize]) {} ~Matrix() { delete []elems; }; Type & getElement (int row, int column) { return elems[getIndex(row,column)]; }; const Type& getElement (int row, int column) const { return elems[getIndex(row, column)]; }; Type det() const; int getSize() const {return size; }; Type threadedDeterminant() const; protected: int size; Type *elems; inline int getIndex (int row, int col) const { assert(row >= 0 && col >= 0 && row& m) const; void getBestRow (int &row, int &zeros) const; void getBestColumn (int &col, int &zeros) const; static void *computeDeterminant(void *ptr); }; template void * Matrix::computeDeterminant(void *ptr) { Matrix *matrix = (Matrix *) ptr; Type *retval = new Type (matrix->det()); delete matrix; return retval; } // well, this function does not work. the problem is that the polynomials in // the matrix are not copied and the RefCounter class is not thread safe. // protecting RefCounter's release and retain with mutexes leads to poore // performance. This will be fixed. // - Ralf template Type Matrix::threadedDeterminant () const { if (size==1) return elems[0]; else if (size==2) return elems[0]*elems[3]-elems[1]*elems[2]; Type result; setNull(result); if (Thread::shouldStop()) { return result; } int bestRow; int bestRowZeros; int bestCol=-1; int bestColZeros=-1; getBestRow(bestRow, bestRowZeros); getBestColumn(bestCol, bestColZeros); TRACE(bestRow); TRACE(bestRowZeros); TRACE(bestCol); TRACE(bestColZeros); struct { pthread_t thread; bool nonzero; } threads [size]; memset (threads, 0, size*sizeof(threads[0])); void *subdeterminant; if (bestRowZeros > bestColZeros) { int col; for (col=0; col void Matrix::getBestRow (int &row, int &zeros) const { int minNonZero=getSize(); int bestRow=0; int r; for (r=0; r void Matrix::getBestColumn (int &col, int &zeros) const { int minNonZero=getSize(); int bestCol=0; int c; for (c=0; c ostream & operator << (ostream &os, const Matrix &m) { int size=m.getSize(); int i; int j; for (i=0; i void Matrix::deleteRowAndColumn (int row, int col, Matrix &m) const { BEGIN("deleteRowAndColumn"); int r; int c; assert(m.getSize()==getSize()-1); for (r=0; r Type Matrix::det() const { if (size==1) return elems[0]; else if (size==2) return elems[0]*elems[3]-elems[1]*elems[2]; // return threadedDeterminant(); Type result; setNull(result); if (Thread::shouldStop()) { return result; } Matrix m (size-1); #if 1 int bestRow; int bestRowZeros; int bestCol=-1; int bestColZeros=-1; getBestRow(bestRow, bestRowZeros); getBestColumn(bestCol, bestColZeros); TRACE(bestRow); TRACE(bestRowZeros); TRACE(bestCol); TRACE(bestColZeros); if (bestRowZeros > bestColZeros) { DMESS("enwickle nach Zeile"); int col; for (col=0; col