TMatrix.cpp

Go to the documentation of this file.
00001 
00002 #include <iomanip>
00003 
00004 template <class TRing>
00005 inline void TMatrix<TRing>::init( )
00006 {
00007         assert (rows_m>=0);
00008         assert (cols_m>=0);
00009 
00010         data            = NULL;
00011 
00012         size_t size = rows_m;
00013         size*=cols_m;
00014 
00015         if ( (size) > 0 )
00016         {
00017                 data            = new TNum[ size ];
00018                 assert( data!=NULL );
00019         }
00020         
00021         pcolumn = NULL;
00022         
00023         if (rows_m>0)
00024                 pcolumn = new TNum*[rows_m];
00025 
00026         for (unsigned int i=0; i<this->rows_m; i++)
00027                 pcolumn[i] = &data[ getDataPos(i,0)];
00028 }
00029 
00030 
00031 //---------------------------------------construction /destruction------------------------------------------------------
00035 template <class TRing>
00036 TMatrix<TRing>::TMatrix(unsigned int _zeilen, unsigned  int _spalten,  
00037                         const TRing* _ring,     std::string _name  ):   rows_m(_zeilen), 
00038                                                                         cols_m(_spalten), 
00039                                                                         ring(_ring), 
00040                                                                         name(_name)
00041 {
00042         
00043         init();
00044         // ab hier ist es anders.
00045         fillZero();
00046 }
00047 
00048 template <class TRing>
00049 TMatrix<TRing>::TMatrix(unsigned int _zeilen, unsigned  int _spalten,  
00050                         const TRing* _ring, TVector<TRing> & vec,std::string _name  ):  rows_m(_zeilen), 
00051                                                                                         cols_m(_spalten), 
00052                                                                                         ring(_ring), 
00053                                                                                         name(_name)
00054 {
00055         init();
00056 
00057         size_t size = rows_m;
00058         size*=cols_m;
00059         // ab hier ist es anders.
00060         assert(size==vec.getSize() )    ;
00061 
00062         for ( size_t i=0; i<getSize(); i++ )
00063                         data[i] = vec.getVal(i);
00064 
00065 }
00066 
00067 
00068 
00074 
00078 template <class TRing>
00079 template <class TemplateMatrix>
00080 TMatrix<TRing>::TMatrix(const TemplateMatrix &mat, const TRing* _ring):
00081                                                                         rows_m( mat.getRowNum() ), 
00082                                                                         cols_m( mat.getColNum() ), 
00083                                                                         ring( _ring), 
00084                                                                         name( mat.getName() )
00085                                                                         
00086 {
00087         init();
00088         
00089         
00090         // ab hier ist es anders.
00091         for (unsigned int row=0; row<rows_m; row++)
00092         {
00093                 for (unsigned int col=0; col<cols_m; col++)
00094                 {
00095                         data[ getDataPos(row,col) ] = ring->Convert( mat.getVal(row,col) );
00096                 }
00097         }
00098 }
00099 
00100 /*
00101 template <class TRing> template <class _istream>
00102 TNum Convert(int entry)
00103 {
00104         if ( ring )
00105 
00106                 ring->Convert();
00107         else
00108                 return TNum(entry);
00109 }*/
00110 
00111 
00112 template <class TRing> template <class _istream>
00113 void TMatrix<TRing>::createFromStream(_istream & _dataStream)
00114 {
00115         #ifdef DEBUG
00116                 std::cerr << " TMatrix::createFromStream(): " << std::endl << std::endl; 
00117         #endif
00118 
00119         std::string matrixStr = extractNextBracedData( _dataStream );
00120 
00121         std::stringstream matrixStream(matrixStr);
00122 
00123         //matrixStream << ;
00124 
00125         rows_m = countSubGroups( matrixStream );
00126 
00127         std::cerr << "rows_m"<<rows_m << std::endl;
00128         
00129 
00130         extractChar(matrixStream, '{');
00131 
00132         std::string matrixRow = extractNextBracedData( matrixStream );
00133 
00134         std::stringstream smatrixRow(matrixRow);
00135         
00136 
00137         cols_m = countElements(smatrixRow);
00138 
00139         std::cerr << "cols_m" << cols_m << std::endl;
00140         
00141         // ab hier ist es gleich
00142 
00143         init();
00144 
00145         // ab hier ist es anders
00146 
00147         int elemNr = 0;
00148 
00149         matrixStream.clear();
00150         matrixStream.seekg(0);
00151         
00152         extractChar(matrixStream, '{');
00153         
00154         std::cerr << "matrixStream" << matrixStream.str() << std::endl;
00155 
00156         for (unsigned int row=0;  row<rows_m ;  row++)
00157         {
00158                 matrixRow   = extractNextBracedData(matrixStream);
00159 
00160                 std::cerr << "matrixRow" << matrixRow << std::endl;     
00161                 std::stringstream       smatrixRow2(matrixRow) ;
00162 
00163 
00164                 extractChar(smatrixRow2, '{');
00165 
00166                 for (unsigned int col=0;  col<cols_m ;  col++)
00167                 {
00168                         int currEntry = 0;
00169                         smatrixRow2 >> currEntry;
00170                 
00171                         data[ elemNr ] = ring->Convert(currEntry);
00172                         elemNr++;
00173 
00174                         if (col !=cols_m-1 ) 
00175                                 extractChar( smatrixRow2, ',' );
00176                         else extractChar( smatrixRow2, '}' );
00177                 }
00178                 if (row !=rows_m-1 ) 
00179                                 extractChar( matrixStream, ',' );
00180                 else extractChar( matrixStream, '}' );
00181         }
00182         std::cerr << "matrix initialization OK" << std::endl;
00183 }
00184 
00185 
00186 
00189 template <class TRing> 
00190 TMatrix<TRing>::TMatrix(string matrixStr,  const TRing* _ring, std::string _name)   :  ring(_ring),  name(_name)
00191 {
00192         std::stringstream  matrixStream;
00193 
00194         matrixStream << matrixStr;
00195 
00196         createFromStream( matrixStream );
00197 }
00198 
00201 template <class TRing>
00202  template <class _istream>
00203 TMatrix<TRing>::TMatrix(  const TRing* _ring, _istream& dataStream, std::string _name)  :       ring( _ring ), 
00204                                                                                                 name( _name )
00205 {
00206         createFromStream(dataStream);
00207 }
00208 
00209 
00210 template <class TRing>
00211   TMatrix<TRing>::TMatrix(const TMatrix<TRing>& mat):   rows_m ( mat.rows_m  ) ,
00212                                                         cols_m ( mat.cols_m ) ,
00213                                                         ring (mat.ring) 
00214                                                         
00215 {
00216 
00217                 // hier kann man es auch gleich gestalten wie oben!
00218                 init();
00219 
00220                 for ( size_t i=0; i<(size_t)rows_m*cols_m; i++ )
00221                         data[i] = mat.data[i];          
00222 }
00223 
00224 
00225 
00226 template <class TRing>
00227 TMatrix<TRing>::~TMatrix()
00228 {
00229         if ( data!=NULL )
00230                 delete[] data;
00231 
00232         if ( pcolumn!=NULL )
00233                 delete[] pcolumn;
00234 };
00235 
00236 
00237 //---------------------------------------safety------------------------------------------------------
00238 
00239 template <class TRing> 
00240 size_t  TMatrix<TRing>::getSize() const 
00241 {       
00242         size_t size =rows_m;
00243         size *=cols_m;
00244         return size;
00245 };
00246 
00247 template <class TRing> 
00248 TVector<TRing>*         TMatrix<TRing>::convertToVector  () const
00249 {
00250         TVector<TRing>* matrixAsVector = new TVector<TRing>(getSize(),ring,name);
00251         
00252         for ( size_t i=0; i<getSize(); i++ )
00253                         matrixAsVector->setVal(i,data[i] );
00254 
00255         return matrixAsVector;
00256 }
00257 
00258 
00259 template <class TRing> 
00260 void  TMatrix<TRing>::checkBounds(unsigned int row, unsigned int col) const
00261 {
00262         if ( row>=rows_m  || col>=cols_m)
00263                         {
00264                                 std::cerr << "TMatrix: bound error !"           << std::endl;
00265                                 std::cerr << "row " << row << " rows_m " << rows_m      << std::endl;
00266                                 std::cerr << "col " << col << " cols_m " << cols_m      << std::endl;   
00267                                 exit(0);
00268                         }
00269 }
00270 
00271 
00272 //---------------------------------------init------------------------------------------------------
00273 
00274 
00276 template <class TRing>
00277 void TMatrix<TRing>::fillZero()
00278 {               
00279         // http://de.wikibooks.org/wiki/C%2B%2B-Programmierung:_Standard_Template_Library
00280 
00281         //std::fill(data, data+rows_m*cols_m, TNum::Zero);
00282 
00283         
00284         for (size_t pos=0; pos< rows_m*cols_m; pos++)
00285         {
00286                 data[ pos ] = TNum::Zero;
00287         }
00288         //memset(data ,0x00, rows_m*cols_m*sizeof(TNum) );
00289 }
00290 
00295 template <class TRing>
00296 void TMatrix<TRing>::randomInit(long * _pRandomSeed )
00297 {
00298         for (size_t pos=0; pos< rows_m*cols_m; pos++)
00299         {
00300                 data[ pos ] = ring->ConvertScalar( random(_pRandomSeed, ring->getCharacteristic()-1)   );
00301         }
00302 }
00303 
00304 
00305 
00306 
00307 //------------------------------------data access ----------------------------------------------------------------------
00308 
00309 template <class TRing>
00310 inline void TMatrix<TRing>::setVal(const unsigned int row, const unsigned int col, const TNum z)
00311 {
00312         #ifdef SAFE
00313                 checkBounds(row,col);
00314         #endif
00315         data[ getDataPos(row, col)]=z;
00316 }
00317 
00318 
00319 template <class TRing>
00320 inline typename TRing::ElementType TMatrix<TRing>::getVal(const unsigned int row,const unsigned int col) const
00321 {
00322         #ifdef SAFE
00323                 checkBounds(row,col);
00324         #endif
00325         return data[ getDataPos(row, col)];
00326 }
00327 
00328 
00329 template <class TRing>
00330 inline const typename TRing::ElementType& TMatrix<TRing>::getConstValRef(const unsigned int row,const unsigned int col) const
00331 {
00332         #ifdef SAFE
00333                 checkBounds(row,col);
00334         #endif
00335         return data[ getDataPos(row, col) ];
00336 }
00337 
00338 
00339 template <class TRing>
00340 inline typename TRing::ElementType & TMatrix<TRing>::getValRef(const unsigned int row,const unsigned int col) 
00341 {
00342         #ifdef SAFE
00343                 checkBounds(row,col);
00344         #endif
00345         return data[ getDataPos(row, col) ];
00346 }
00347 
00348 template <class TRing>
00349 inline typename TRing::ElementType* TMatrix<TRing>::getValAddr(const unsigned int row,const unsigned int col) 
00350 {
00351         #ifdef SAFE
00352                 checkBounds(row,col);
00353         #endif
00354         return &( data[  getDataPos(row, col) ] );
00355 }
00356 
00357 template <class TRing>
00358 typename TRing::ElementType& TMatrix<TRing>::getRowRef(unsigned int row)
00359 {
00360         assert(row>0 && row<rows_m );
00361         return &data[ getDataPos(row, 0)];
00362 }
00363 
00364 
00365 
00366 
00367 
00368 
00369 //------------------------------------operators----------------------------------------------------------------------
00370 
00371 
00372 template <class TRing>
00373 TMatrix<TRing>*  TMatrix<TRing>::operator*(const TMatrix<TRing>& mat) const
00374 {
00375 
00376         assert( cols_m==mat.rows_m );
00377         
00378         TMatrix<TRing>* erg = new TMatrix<TRing>(rows_m, mat.cols_m, this->ring);
00379 
00380 
00381         for (unsigned int row=0; row<rows_m; row++)
00382         {
00383                 for (unsigned int col=0; col<mat.cols_m; col++)
00384                 {
00385                         TNum val = TNum::Zero;
00386                         for (unsigned int i=0; i<mat.rows_m; i++)
00387                         {
00388                                 //   getVal(row,i);
00389                                 mat.getVal(i,col);
00390                                 ring->addInPlace( val  ,ring->multiply( getVal(row,i), mat.getVal(i,col)) );
00391                         }
00392                         erg->setVal( row, col, val);
00393                 }
00394         }
00395         return erg;
00396 }
00397 
00398 
00399 template <class TRing>
00400 TMatrix<TRing>*  TMatrix<TRing>::operator|(const TMatrix& mat)  const
00401 {
00402         assert(this->getRowNum()==mat.getRowNum() );
00403 
00404         TMatrix<TRing>* erg = new TMatrix<TRing>(rows_m, cols_m+ mat.cols_m , this->ring);
00405 
00406         for (unsigned int row=0;row<rows_m; row++ )
00407         {
00408                 for (unsigned int col=0; col< cols_m; col++)
00409                 {
00410                         erg->setVal(row,col,getVal(row,col));
00411                 }
00412                 for (unsigned int col=0; col< mat.cols_m; col++ )
00413                 {
00414                         erg->setVal(row, this->cols_m + col, mat.getVal(row,col) );
00415                 }
00416         }
00417         return erg;
00418 }
00419 
00420 
00421 
00422 template <class TRing>
00423 TMatrix<TRing>*         TMatrix<TRing>::getSubMatrix(unsigned int firstrow, unsigned int firstcol,unsigned int lastrow,unsigned int lastcol)    const
00424 {
00425         assert(  firstrow<rows_m );     assert(  lastrow<rows_m );
00426         assert(  firstcol<cols_m );     assert(  lastcol<cols_m );
00427         
00428         unsigned int newrows = lastrow-firstrow + 1;
00429         unsigned int newcols = lastcol-firstcol + 1;
00430 
00431         TMatrix<TRing>* erg = new TMatrix<TRing>(newrows, newcols, this->ring);
00432 
00433         for (unsigned int row=firstrow; row<=lastrow; row++ )
00434         {
00435                 for (unsigned int col=firstcol; col<= lastcol; col++)
00436                 {
00437                         erg->setVal( row-firstrow, col-firstcol, getVal(row,col) );
00438                 }
00439         }
00440         return erg;
00441 }
00442 
00443 
00444 template <class TRing>
00445 TVector<TRing>*  TMatrix<TRing>::operator*(TVector<TRing>& vec) const
00446 {
00447         
00448         assert(vec.getSize()==(size_t)cols_m);
00449         
00450         TVector<TRing>* erg = new TVector<TRing>(rows_m, this->ring);
00451 
00452         for (unsigned int row=0;row<rows_m;row++)
00453         {
00454                 TNum val=TNum::Zero;
00455                 for (size_t i=0; i<vec.getSize(); i++)
00456                 {
00457                         TNum val1 = getVal(row,i);
00458                         TNum val2 = vec.getVal(i);
00459 
00460                         ring->multiply(val1,val2);
00461                         ring->addInPlace(val  ,ring->multiply( getVal(row,i), vec.getVal(i)) );
00462                 }
00463                 erg->setVal( row, val);
00464         }
00465         return erg;
00466 }
00467 
00468 
00469 template <class TRing>
00470 bool TMatrix<TRing>::operator==(const TMatrix& mat) const
00471 {       
00472         if ( rows_m != mat.getRowNum() || cols_m != mat.getColNum() )
00473                 return false;
00474 
00475         
00476         for (unsigned int row=0; row<rows_m; row++)
00477         {
00478                 for (unsigned int col=0; col<cols_m; col++)
00479                 {
00480                         if ( getVal(row,col) != mat.getVal(row,col) )
00481                                 return false;
00482                 }
00483         }
00484         return true;
00485 }
00486 
00487 template <class TRing>
00488 bool TMatrix<TRing>::isIdentity() const
00489 {       
00490         for (unsigned int row=0; row<rows_m; row++)
00491         {
00492                 for (unsigned int col=0; col<cols_m; col++)
00493                 {
00494                         if (col!=row)
00495                         {
00496                                 if ( getVal(row,col) != typename TRing::ElementType(0) )
00497                                         return false;
00498                         }
00499                         else
00500                         {
00501                                 if ( getVal(row,col) != typename TRing::ElementType(1) )
00502                                         return false;
00503                         }
00504                         
00505                 }
00506         }
00507         return true;
00508 }
00509 
00510 
00511 template <class TRing>
00512 TMatrix<TRing>&  TMatrix<TRing>::operator=(const TMatrix<TRing>& mat)
00513 {
00514 
00515         if (this!=&mat)
00516         {
00517                 assert( ring==mat.ring );
00518                 delete [] data;
00519 
00520                 cols_m  = mat.cols_m;
00521                 rows_m  = mat.rows_m;
00522 
00523                 data = new TNum[rows_m*cols_m];
00524 
00525                 for (size_t i=0; i<rows_m*cols_m; i++)
00526                         data[i] = mat.data[i];
00527 
00528                 pcolumn = NULL;
00529                 pcolumn = new TNum*[rows_m];
00530 
00531                 for (unsigned int i=0; i<this->rows_m; i++)
00532                         pcolumn[i] = &data[ getDataPos(i,0) ];
00533 
00534                 assert( data!=NULL );
00535         }
00536         return *this;
00537 }
00538 
00539 
00540 template <class TRing>
00541 bool   TMatrix<TRing>::isZero() const
00542 {
00543         for (size_t i=0; i<rows_m*cols_m; i++)
00544         {
00545                 if (   data[i].isNotZero()  ) 
00546                         return false;
00547         }
00548         return true;
00549 }
00550 
00551 template <class TRing>
00552 bool   TMatrix<TRing>::isNotZero() const
00553 {
00554         for (size_t i=0; i<rows_m*cols_m; i++)
00555         {
00556                 if (   data[i].isNotZero()  ) 
00557                         return true;
00558         }
00559         return false;
00560 }
00561 
00562 //------------------------------------extract data ----------------------------------------------------------------------
00563 
00565 template <class TRing>
00566 BlockMatrix<TRing>*  TMatrix<TRing>::getBlocked(unsigned int rowBlockSize, unsigned int colBlockSize) const
00567 {
00568 
00569         BlockMatrix<TRing>*     erg      = new BlockMatrix<TRing>(rowBlockSize, colBlockSize, rows_m ,cols_m, ring);
00570 
00571         unsigned int Block = 0;
00572 
00573         for (register unsigned int h=0; h < erg->getBlocksPerCol(); h++) // run over y-coordonate of the blocks
00574         {
00575                 unsigned int upperMostBlockRow = erg->getRowBlockSize()*h;
00576 
00577                 for (register unsigned int l=0; l< erg->getBlocksPerRow(); l++) // run over x-coordonate of the blocks
00578                 { 
00579                         unsigned int leftMostBlockCol=erg->getColBlockSize()*l;
00580 
00581                         unsigned int BlockPos=0;
00582 
00583                         // run over y-coordonate in the block
00584                         for (unsigned int row = upperMostBlockRow; row< upperMostBlockRow + erg->getRowBlockSize(); row++)
00585                         {
00586                                 // run over x-coordonate in the block
00587                                 for (unsigned int col=leftMostBlockCol; col<leftMostBlockCol+erg->getColBlockSize(); col++)
00588                                 {
00589                                         erg->setBlockVal(Block,BlockPos, getVal(row,col) );
00590                                         BlockPos++;
00591                                 }
00592                         }
00593                         Block++;
00594                 }
00595                 
00596         }
00597         return erg;
00598         
00599 }
00600 
00601 
00602 template <class TRing>
00603 TMatrix<TRing>&          TMatrix<TRing>::transposeInPlace()
00604 {
00605 
00606         data    = NULL;
00607 
00608         size_t tmp=rows_m;
00609         tmp*=cols_m;
00610 
00611         TNum* newData = new TNum[ tmp ];
00612 
00613         assert(newData!=NULL);
00614 
00615 
00616         for (unsigned int row=0; row<rows_m; row++)
00617         {
00618                 for (unsigned int col=0; col<cols_m; col++)
00619                 {
00620                         newData[ col*rows_m+ row ] = data[ getDataPos(row,col) ];
00621                 }
00622         }
00623          tmp=rows_m;
00624 
00625         rows_m=cols_m;
00626 
00627         cols_m=tmp;
00628 
00629         delete[] data;
00630         data = newData;
00631 
00632         delete[] pcolumn;
00633 
00634         pcolumn = NULL;
00635         pcolumn = new TNum*[rows_m];
00636 
00637         for (unsigned int i=0; i<this->rows_m; i++)
00638                 pcolumn[i] = &data[ getDataPos(i,0) ];
00639 
00640         return *this;
00641 }
00642 
00643 
00644 template <class TRing>
00645 TMatrix<TRing>*  TMatrix<TRing>::getTransposed() const
00646 {
00647         TMatrix<TRing>* erg = new TMatrix<TRing>(cols_m, rows_m, this->ring);
00648 
00649         for (unsigned int row=0; row<rows_m; row++)
00650         {
00651                 for (unsigned int col=0; col<cols_m; col++)
00652                 {
00653                         erg->setVal(col, row, getVal(row,col));
00654                 }
00655         }
00656         return erg;
00657         
00658 }
00659 
00660 
00662 template <class TRing>
00663 typename TRing::ElementType* TMatrix<TRing>::getCol(unsigned int _col) const
00664 {
00665         assert(_col>=0 && _col<cols_m );
00666         TNum* columndata= new TNum[rows_m];
00667         for (unsigned int i=0;i<rows_m;i++)
00668                 columndata[i]=data[  getDataPos(i, _col) ];
00669         return columndata;
00670 }
00671 
00673 template <class TRing>
00674 typename TRing::ElementType* TMatrix<TRing>::getRow(unsigned int _row) const
00675 {
00676         assert(_row>=0 && _row<rows_m );
00677         TNum* rowdata= new TNum[cols_m];
00678         for (unsigned int i=0;i<cols_m;i++)
00679                 rowdata[i]=data[  getDataPos(_row, i) ];
00680 
00681         return rowdata;
00682 }
00683 
00685 template <class TRing>
00686 TVector< TRing>* TMatrix<TRing>::getColAsVector(unsigned int _col) const
00687 {
00688         assert(_col>=0 && _col<cols_m );
00689         TVector< TRing>* colVector= new TVector<TRing>(rows_m,ring, "column");
00690         for (unsigned int i=0;i<rows_m;i++)
00691                 colVector->setVal(i, data[  getDataPos(i, _col) ] );
00692         return colVector;
00693 }
00694 
00696 template <class TRing>
00697 TVector< TRing>* TMatrix<TRing>::getRowAsVector(unsigned int _row) const
00698 {
00699         assert(_row>=0 && _row<rows_m );
00700         TVector< TRing>* rowVector= new TVector<TRing>(cols_m,ring, "row");
00701         for (unsigned int i=0;i<cols_m;i++)
00702                 rowVector->setVal(i, data[  getDataPos(_row, i) ] );
00703 
00704         return rowVector;
00705 }
00706 
00708 template <class TRing>
00709 typename TRing::ElementType* TMatrix<TRing>::getDiag() const
00710 {
00711         assert(rows_m==cols_m);
00712 
00713         TNum* diag= new TNum[cols_m];
00714         for (unsigned int i=0; i<cols_m; i++)
00715                 diag[i] = data[ getDataPos(i, i) ];
00716 
00717         return diag;
00718 }
00719 
00721 template <class TRing>
00722 TVector<TRing>* TMatrix<TRing>::getTrace() const
00723 {
00724         assert(rows_m==cols_m);
00725 
00726         TVector<TRing>* erg = new TVector<TRing>(cols_m, this->ring);
00727 
00728         for (unsigned int i=0; i<cols_m; i++)
00729                 erg->setVal( i,data[ getDataPos(i, i) ] );
00730 
00731         return erg;
00732 }
00733 
00734 template <class TRing>
00735 vector<bool>    TMatrix<TRing>::getFreeVariables()
00736 {
00737         vector<bool> varFree(cols_m); 
00738 
00739         unsigned int row, col;
00740 
00741         for(row=0, col=0; col<cols_m ; col++)
00742         {       
00743                 if (row>=rows_m)
00744                 {       
00745                         varFree[col]=true;
00746                 }
00747                 else
00748                 {
00749                         if (this->pcolumn[row][col].isZero() )
00750                         {
00751                                 varFree[col]=true;
00752                         }
00753                         else 
00754                         {
00755                                 row++;
00756                                 varFree[col]=false;
00757                         }
00758                 }
00759                 
00760         }
00761         return varFree;
00762 }
00763 
00764 template <class TRing>
00765 vector<bool>    TMatrix<TRing>::getLeadingVariables()
00766 {
00767         
00768         vector<bool> leadingVariables(rows_m); 
00769 
00770         unsigned int row, col;
00771 
00772         int lastrow=0;
00773         for(row=0, col=0; col<cols_m ; col++)
00774         {       
00775                 if (row>=rows_m)
00776                 {       
00777                         //varFree[col]=true;
00778                 }
00779                 else
00780                 {
00781                         if (this.pcolumn[row][col].isZero() )
00782                         {
00783                                 //varFree[col]=true;
00784                         }
00785                         else 
00786                         {
00787                                 row++;
00788                                 //varFree[col]=false;
00789                                 lastrow=row+1;
00790                                 leadingVariables[row]=col;
00791                         }
00792                 }
00793                 
00794         }
00795         leadingVariables.resize(lastrow);
00796         return leadingVariables;
00797 }
00798 //---------------------------------------compute properties------------------------------------------------------
00800 // http://www.math.lsa.umich.edu/~hochster/419/ker.im.html
00801 // ahhh schlaue Leute: 
00802 // http://www.math.tu-dresden.de/~ganter/inf2004/Matrixslides.pdf
00803 // hier steht, wie man den Kern berechnet, wenn man eine QR-Zerlegung besitzt:
00804 // http://en.wikipedia.org/wiki/Left_null_space
00805 // DAS ist die beste Beschreibung: http://www.jstor.org/stable/2686433?seq=3
00806 // Matrix auf 'reduced row echolon' -Form bringen und dann die führenden Einsen auf die Diagonale setzen,
00807 // und dann die Einheitsmatrix abziehen!
00808 // #
00809 //# Subspaces and Echelon Forms
00810 //# David C. Lay
00811 //# The College Mathematics Journal, Vol. 24, No. 1 (Jan., 1993), pp. 57-62 
00812 template <class TRing>
00813         TMatrix<TRing>* TMatrix<TRing>::getKernel() const
00814 {
00815         
00816         TMatrix<TRing> matCopy(*this);
00817 
00818         //std::cerr << "cols_m - getRank(true)" <<  cols_m - getRank(false) << std::endl;
00819         unsigned int dimKernel = cols_m - matCopy.getRank(true);
00820         //unsigned int dimKernel = cols_m - getRank(false);
00821         if ( dimKernel==0 )
00822         {
00823                 #ifdef DEBUG
00824                 std::cerr << "dimKernel ==0" << std::endl;
00825                 #endif
00826                 return new TMatrix<TRing>( cols_m, dimKernel, ring );
00827         }
00828         //getRank(true);
00829         //unsigned int dimKernel = cols_m - getRank(true);
00830         
00831         
00832         TMatrix<TRing>* kernel = new TMatrix<TRing>(cols_m,dimKernel,ring);
00833         
00834         // 1. check if x_i is free parameter and store this info in "varFree"   
00835         vector<bool> varFree = matCopy.getFreeVariables(); 
00836 
00837         //init kernel Matrix
00838         kernel->fillZero();
00840         // 2. set current row to last row with non-zero-elements 
00841 
00842         int row = cols_m-dimKernel-1; 
00843         unsigned int free_varNumber=0; // next free parameter number
00844 
00845         for (int currentVariableNumber = cols_m-1;  currentVariableNumber>=0;   currentVariableNumber--)
00846         {
00847                 //std::cerr  << "currentVariableNumber " << currentVariableNumber << std::endl;
00848                 //if current variable is free parameter
00849                 if (varFree[currentVariableNumber])
00850                 {
00851                         // set Kernel_(variableNumber,free_varNumber)=1
00852                         kernel->setVal(currentVariableNumber,free_varNumber, 1 );
00853                         free_varNumber++; // (next free parameter number) ++
00854                 }
00855                 //if current variable is NOT free parameter
00856                 else
00857                 {
00858                         // then set current variable
00859                         //=M[currentrow][currentVariableNumber+1]*(x_(currentVariableNumber+1))+...+M[currentrow][cols_m-1]*(x_(cols_m-1))
00860                         //  x_(currentVariableNumber+1) to x_(cols_m-1) already determined and are in Kernel matrix
00861                         for (unsigned int j=currentVariableNumber+1; j<cols_m; j++)
00862                         {
00863                                 if ( !matCopy.pcolumn[row][j].isZero() )
00864                                 // wenn Eintrag j<>0, dann muss zu x_currentVariableNumber (Zeile currentVariableNumber im Kernel)
00865                                 // {- div( coeff( Val(row,j), coeff(x_curr) ) * x_j} dazuaddoert werden.
00866                                 // und x_j wurde schon berechnet und steht in der j_ten Zeile der Kernel-Matrix !
00867                                 {
00868                                         for(unsigned int i=0;i<dimKernel;i++)
00869                                         {
00870                                                 TNum    kernel_cur_i    = kernel->getVal(currentVariableNumber,i);
00871 
00872                                                 TNum    coeff           = ring->multInv(matCopy.pcolumn[row][currentVariableNumber] );
00873 
00874                                                 coeff = ring->multiply(coeff, matCopy.pcolumn[row][j]);
00875 
00876                                                 coeff = ring->addInv(coeff);
00877 
00878                                                 kernel_cur_i = ring->add( kernel_cur_i, 
00879                                                                           ring->multiply(coeff, kernel->getVal(j, i ) ) 
00880                                                                         );
00881 
00882                                                 kernel->setVal(currentVariableNumber,i, kernel_cur_i);
00883                                         }
00884                                 }
00885 
00886                         }
00887                         // change to previous row..
00888                         row--;
00889                 }
00890         }
00891         return kernel;
00892 
00893 }
00894 
00895 
00896 template <class TRing>
00897 unsigned int TMatrix<TRing>::getRank() const
00898 {       
00899         TMatrix<TRing> matCopy (*this);
00900         
00901         return matCopy.getRank(false);
00902 }
00903 
00904 
00905 
00906 template <class TRing>
00907 TMatrix<TRing>*         TMatrix<TRing>::getRowEchelonForm() const
00908 {
00909         TMatrix<TRing>* matCopy = new TMatrix<TRing>(*this);
00910 
00911         matCopy->getRank(true);
00912         
00913         return matCopy;
00914 }
00915 
00916 
00918 template <class TRing>
00919 TVector<TRing>*         TMatrix<TRing>::solveLGS(TVector<TRing> &rightHandSide)
00920 {
00921 
00922         
00923         return NULL;
00924 }
00925 
00931 template <class TRing>
00932         unsigned int TMatrix<TRing>::getRank(bool inplace)
00933         {
00934                 TNum*   dataCopy = NULL;
00935 
00936                 if (!inplace)
00937                 {
00938                         dataCopy = new TNum[rows_m*cols_m];
00939 
00940                         for (size_t i=0; i<rows_m*cols_m; i++)
00941                                 dataCopy[i] =  data[i];
00942                 }
00943                 else
00944                 {
00945                         dataCopy = data;
00946                 }
00947 
00949                 //TNum** pcolumn=new TNum*[rows_m];
00950                 TNum**  pcolumn2 = new TNum*[rows_m];
00951                 TNum*   pfaktor  = new TNum[rows_m];
00952 
00953                 for (unsigned int i=0; i<rows_m; i++)
00954                 {
00955                         pcolumn[i]  = NULL;
00956                         pcolumn2[i] = NULL;
00957                 }
00958                 TNum*           temprow;
00959                 TNum            pivot;
00960 
00961                 for (unsigned int i=0; i<this->rows_m; i++)
00962                         pcolumn[i] = &dataCopy[ getDataPos(i, 0) ];
00963 
00964                 unsigned int row        = 0;
00965                 unsigned int u;
00966                 unsigned int w  = 0;
00967                 unsigned int col        = 0;
00968                 unsigned int temprank= 0;
00969                 
00971                 while (row<this->rows_m && col<this->cols_m)
00972                 {
00973                         //search for a row with 1 in column 'col' (pivotrow)
00974                         //for(ring=row;pivotrow<0&&ring<this->rows_m;ring++)
00975                         for(unsigned int l=row; l<this->rows_m; l++)
00976                         {
00977                                 if (pcolumn[l][col].isNotZero() )
00978                                 {
00979                                         // was soll dass denn hier???
00980                                         pivot=pcolumn[l][col] ;
00981                                         //pivotrow=l;
00982                                         //found pivotrow ->,  switch rows_m 'row' and 'pivitrow'
00983                                         if (l>row)
00984                                         {
00985                                                 temprow         = pcolumn[l];
00986                                                 pcolumn[l]      = pcolumn[row];
00987                                                 pcolumn[row]    = temprow;
00988                                         }
00989                                         temprank++;
00990                                         
00991                                         //find relevant rows_m and compute factors
00992                                         for ( u=row+1, w=0;  u<this->rows_m; u++)
00993                                         {
00994                                                 if ( pcolumn[u][col].isNotZero() )
00995                                                 {
00996                                                 
00997                                                         //notice in pcolumn2  where  pcolumn[u][col]!=0
00998                                                 
00999                                                         //pfaktor[w]   = pcolumn[u][col] / pivot 
01000                                                         pfaktor[w]   = ring->multiply( ring->multInv(pivot), pcolumn[u][col]  );
01001                                                         pcolumn2[w++] = pcolumn[u];
01002                                                 }
01003                                         }
01004 
01005                                         //create zeros:
01006                                         for(unsigned int v=col;v<this->cols_m;v++)
01007                                         {
01008                                                 for(u=0;u<w;u++)
01009                                                 {
01010                                                         pcolumn2[u][v] = ring->add( TNum(pcolumn2[u][v]), 
01011                                                                                    ring->addInv( ring->multiply( pfaktor[u], 
01012                                                                                                                           pcolumn[row][v] 
01013                                                                                                                 )
01014                                                                                                         )
01015                                                                                 );
01016                                                 }
01017                                         }
01018                                         //end create zeros
01019                                         
01020                                         row++;
01021                                         /*break;*/goto weiter;
01022                                 }
01023                         }
01024                         weiter:
01025                         col++;
01026                         
01027                 }
01028                 if (!inplace)
01029                 {
01030                         for (unsigned int i=0; i<this->rows_m; i++)
01031                                 pcolumn[i] = &data[ getDataPos(i, 0) ];
01032 
01033                         if ( dataCopy!=NULL )
01034                                 { delete[] dataCopy; dataCopy=NULL; }
01035                 }
01036         
01037                 if (pcolumn2!=NULL) { delete[] pcolumn2; pcolumn2=NULL; }
01038                 if (pfaktor!=NULL) { delete[] pfaktor; pfaktor=NULL; }
01039 
01040                 return temprank;
01041         }
01042 
01043 
01044 
01046         template <class TRing>
01047         TMatrix<TRing>* TMatrix<TRing>::getRowBasis() const
01048         {
01049                 TMatrix<TRing>*   independentRows = getRowEchelonForm(); //Funktion gibt es auch in FFPAck, allerdings weiss ich nicht, wie man diese benutzt.
01050 
01051                 independentRows->setName("independent Rows");
01052 
01053 
01054                 unsigned int independentRowCount        = independentRows->getRank();
01055         
01056                 TMatrix<TRing>*   rowBasis = new TMatrix<TRing>(independentRowCount, independentRows->getColNum(),independentRows->getRing() );
01057         
01058                 // da die RowEchelon-form eventuell nicht korrekt sortiert ist, laufe ueber alle Zeilen der ZeilenstufenFormMatrix;
01059                 int currentRowIdx = 0;
01060                 for (unsigned int z=0; z < independentRows->getRowNum() ; z++)
01061                 {
01062                         TVector<typename TMatrix<TRing>::RingType > * rowAsVector = independentRows->getRowAsVector(z);
01063                         if ( rowAsVector->isNotZero() )
01064                         {
01065                                 for (unsigned int colidx=0; colidx < independentRows->getColNum() ;colidx++)
01066                                 {
01067                                         rowBasis->setVal(currentRowIdx,colidx, rowAsVector->getVal(colidx) );
01068                                 }
01069                                 currentRowIdx++;
01070                         }
01071                         delete rowAsVector;
01072                 }
01073         
01074                 delete independentRows;
01075         
01076                 return rowBasis;
01077         }
01078 
01079 
01080 
01081 
01082 
01083 //---------------------------------------IO------------------------------------------------------
01084  
01085         template <class TRing>
01086         void TMatrix<TRing>::printValue(std::ostream & os) const
01087         {
01088                 os << "{" << std::endl;
01089                 for (unsigned int i=0; i<rows_m; i++)
01090                 {
01091                         if (i>0)
01092                         {
01093                                 os << ", " << std::endl;
01094                         }
01095                         os << "{";
01096                         for (unsigned int j=0; j<cols_m; j++)
01097                         {
01098                                 if (j>0)
01099                                 {
01100                                         os << ", ";
01101                                 }
01102                                 os <<  ::std::setw( 2 ) << data[i*cols_m+j];
01103                                 
01104                         }
01105                         os << "}" ;
01106                 }               
01107                 os << std::endl << "} ";
01108         }
01109 
01110         template <class TRing>
01111         void TMatrix<TRing>::printValueInMacaulayStyle(std::ostream & os) const
01112         {
01113                 if (rows_m> 0)
01114                 {
01115                         os <<  " matrix " ;
01116                         printValue(os);
01117                 }
01118                 else  
01119                 {
01120                         os <<  " transpose matrix " ;
01121                         TMatrix<TRing>* tm = getTransposed();
01122                         tm->printValue(os);
01123                         delete tm;
01124                 }
01125         }
01126 
01129         template <class TRing>
01130         void TMatrix<TRing>::printInMacaulayStyle(std::ostream & os, bool bAssignment) const
01131         {
01132                 os << std::endl;
01133                 if (bAssignment) 
01134                         os <<  name << " = " ;
01135                 else 
01136                         os <<  "--" << name << std::endl;
01137 
01138                 printValueInMacaulayStyle(os);
01139  
01140                 if (bAssignment) 
01141                         os << ";";
01142                 os << std::endl;
01143         }
01144 
01145 
01146 template <class TRing> 
01147 std::ostream &  operator<<(std::ostream & out, const TMatrix<TRing>& z)
01148 {  
01149         z.printInMacaulayStyle(out);
01150         return out;
01151 } 
01152 
Generated on Tue Nov 23 13:10:52 2010 for centerfocus by  doxygen 1.6.3