FFLASMatrix.cpp

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00007 
00013 /*
00014 template <class Field >
00015 template <class TMatrix>
00016  FFpackMatrix<Field >::FFpackMatrix(const TMatrix &mat,
00017                                                 const int characteristic
00018                                                 //const Field* _F       
00019                                                                         ):
00020                                                                                 characteristic_m(characteristic),
00021                                                                                 //F( _F ), 
00022                                                                                 F(new Field((long)characteristic)),
00023                                                                                 rows_m( mat.getRowNum() ), 
00024                                                                                 cols_m( mat.getColNum() ),
00025                                                                                 name(  mat.getName() )
00026 {
00027         checkDimensions();
00028 
00029         data_m          = NULL;
00030         blocksPerRow    = 0;
00031 
00032 
00033         data_m = new typename Field::Element[rows_m*cols_m];
00034         assert(data_m!=NULL);
00035         
00036         int epsExp=0;
00037         int matrixpos=0;
00038         
00039         for (int row=0;row<rows_m;row++)
00040         {
00041                 for (int col=0;col<cols_m;col++)
00042                 {
00043                         //data_m[cols_m*row+col]=(mat.getVal(row,col)).getValue(epsExp);
00044                         data_m[matrixpos] = (mat.getVal(row,col)).getValue(epsExp);
00045                         matrixpos++;
00046                 }
00047         }
00048 }*/
00049 
00052 template <class Field >
00053 template <class TMatrix>
00054  FFpackMatrix<Field >::FFpackMatrix(const TMatrix &mat,
00055                                                 int     characteristic,
00056                                                  bool transpose ):
00057                                                                                 characteristic_m(characteristic),
00058                                                                                 F( new Field((long)characteristic) ),
00059                                                                                 rows_m( mat.getRowNum() ), 
00060                                                                                 cols_m( mat.getColNum() ), 
00061                                                                                 name( mat.getName() )
00062 {
00063         
00064         checkDimensions();
00065 
00066         data_m          = NULL;
00067         blocksPerRow    = 0;
00068 
00069 
00070         data_m = new typename Field::Element[rows_m*cols_m];
00071         assert(data_m!=NULL);
00072 
00073         int epsExp=0;
00074 
00075         int matrixpos=0;
00076         if (!transpose)
00077                 for (int row=0;row<rows_m;row++)
00078                 {
00079                         for (int col=0;col<cols_m;col++)
00080                         {
00081                                 
00082                                 //data_m[cols_m*row+col]=(mat.getVal(row,col)).getValue(epsExp);
00083                                 data_m[matrixpos]=(mat.getVal(row,col)).getValue(epsExp);
00084                                 matrixpos++;
00085                         }
00086                 }
00087         else
00088         {
00089                 rows_m = mat.getColNum();
00090                 cols_m = mat.getRowNum();
00091 
00092                 for (int row=0;row<rows_m;row++)
00093                 {
00094                         for (int col=0;col<cols_m;col++)
00095                         {
00096                                 //data_m[cols_m*row+col]=(mat.getVal(col,row)).getValue(epsExp);
00097                                 data_m[matrixpos]=(mat.getVal(col,row)).getValue(epsExp);
00098                                 matrixpos++;
00099                         }
00100                 }
00101         }
00102 }
00103 
00104 template <class Field >
00105         bool             FFpackMatrix< Field >::isZero()        const
00106 {
00107 
00108         for (int pos=0;pos <rows_m*cols_m;pos++)
00109         {                       
00110                 if (data_m[pos]!=0)
00111                         return false;
00112         }
00113                 
00114         return true;
00115 }
00116 
00117 
00119 template <class Field >
00120  FFpackMatrix< Field >::FFpackMatrix(int        _rows, 
00121                                                  int    _cols,
00122                                                  int    characteristic, 
00123                                                  string _name      ):
00124                                                                                 characteristic_m(characteristic),
00125                                                                                 F(  new Field( (long)characteristic )  ),
00126                                                                                 rows_m(_rows), 
00127                                                                                 cols_m(_cols), 
00128                                                                                 name(_name)
00129         {
00130                 checkDimensions();
00131 
00132                 data_m          = NULL;
00133                 blocksPerRow    = 0;
00134 
00135                 data_m = new typename Field::Element[_rows*_cols+1];
00136 
00137                 data_m[_rows*_cols]=0;
00138 
00139                 assert( data_m!=NULL );
00140 
00141                 for (int pos=0;pos <rows_m*cols_m;pos++)
00142                 {                       
00143                         data_m[pos]=0;
00144                 }
00145 
00146                 //memset(data_m ,0x00,rows_m*cols_m*sizeof(typename Field::Element));
00147         }
00148 
00149 
00150 
00151 
00152 
00153 template <class Field >
00154 FFpackMatrix< Field >::
00155 FFpackMatrix(typename Field::Element    *_data, 
00156                                         int             _rows,
00157                                         int             _cols,
00158                                         int characteristic, 
00159                                         string  _name     ):
00160                                                                         characteristic_m(characteristic),
00161                                                                         F( new Field( (long)characteristic) ),
00162                                                                         rows_m( _rows ), 
00163                                                                         cols_m( _cols ), 
00164                                                                         data_m( _data ),
00165                                                                         name( _name )
00166 {
00167         checkDimensions();
00168 
00169 }
00170 
00171 
00172 
00173 template <class Field >
00174  FFpackMatrix< Field >* FFpackMatrix< Field >::getRightKernel(int &RightKernelDim)
00175 {
00176         typename Field::Element *NS=NULL;
00177         size_t NullSpaceDim;
00178 
00179         //size_t lda=rows_m; - falsch!
00180         size_t lda=cols_m;
00181         size_t ldn;
00182 
00183         FFPACK::NullSpaceBasis(*F,FFLAS::FflasRight, rows_m, cols_m, data_m, lda, NS, ldn, NullSpaceDim);
00184 
00185         RightKernelDim = NullSpaceDim;
00186 
00187         if (NullSpaceDim==0)
00188                 return NULL;
00189         return new FFpackMatrix< Field >(NS, cols_m, NullSpaceDim, characteristic_m, string("Kernel("+name+")") );
00190         
00191 }
00192 
00193 
00194 /*  leading dimension - Erklärung:
00195 
00196         bei Spaltenorientierter Speicherung von Daten ist LDA die Anzahl der Elemente einer Spalte.( = #Zeilen! )
00197 
00198         Entsprechend ist bei Zeilenorientieruter Speicherung von Daten LDA die Anzahl der Elemente einer Zeile. ( = #Spalten !)
00199 
00200         */
00202 template <class Field >
00203 FFpackMatrix< Field >* FFpackMatrix< Field >::getLeftInverse()
00204 {
00205         assert(cols_m==cols_m);
00206 
00207 
00208         int NullSpaceDim=0;
00209 
00210         size_t matSize = rows_m*cols_m; // A dimension
00211         size_t lda = cols_m; // A leading dimension, if rows_m==cols_m it does not matter, what ld(A) really is.
00212         size_t ldx = cols_m; // X leading dimension, if rows_m==cols_m it does not matter, what ld(X) really is.
00213 
00214         
00215         if (rows_m ==0   )
00216         {
00217                 std::cerr << " matrix is empty!" << std::endl;
00218                 return NULL;
00219         }
00220         #ifdef DEBUG
00221                 std::cerr << "getLeftInverse: matSize " << matSize << std::endl;
00222                 std::cerr << "getLeftInverse:data_m " << *data_m << std::endl;
00223                 std::cerr << "getLeftInverse:lda " << lda<< std::endl;
00224                 std::cerr << "getLeftInverse:cols_m" << cols_m << std::endl;
00225                 std::cerr << "getLeftInverse:rows_m" << rows_m << std::endl;
00226         #endif
00227         typename Field::Element * INVDATA= NULL;
00228 
00229         INVDATA = new typename Field::Element [ matSize ];
00230 
00231         for (size_t i=0; i< matSize; i++ ) INVDATA[i]=0;
00232 
00233         #ifdef DEBUG
00234                 std::cerr << "Invert2;" << std::endl;
00235         #endif
00236         // Invert2( const Field& F, const size_t M,[in] typename Field::Element * A, const size_t lda,
00237         //      [out] typename Field::Element * X, const size_t ldx,    [out] int& nullity)
00238         FFPACK::Invert2(*F, lda, data_m, lda ,  INVDATA, ldx, NullSpaceDim);
00239         //FFPACK::Invert(*F, lda, data_m, lda, NullSpaceDim);
00240         #ifdef DEBUG
00241                 printValue(std::cerr);
00242                 
00243                 std::cerr << "Invert2 finished" << std::endl;
00244         #endif
00245 
00246         if (NullSpaceDim!=0)
00247         {
00248                 std::cerr << "FFpackMatrix< Field >* FFpackMatrix< Field > getLeftInverse :";
00249                 std::cerr << " matrix is singular!" << std::endl;
00250                 std::cerr << "NullSpaceDim" << NullSpaceDim << std::endl;
00251                 return NULL;
00252         }
00253         else
00254         {
00255                 assert(INVDATA!=0);
00256         }
00257 
00258         return new FFpackMatrix< Field >(INVDATA, cols_m, rows_m, characteristic_m, string("LeftInverse("+name+")") );
00259         //return this;
00260 }
00261 
00267 template <class Field >
00268 typename Field::Element*        FFpackMatrix< Field >::solveLGS(const typename Field::Element* rightHandSide, int & rankRef)
00269 {
00270         
00271         typename Field::Element* solution  = new typename Field::Element[ cols_m ];
00272 
00273         /*
00274         DOKUMENTATION nicht aktuell!!
00275         * @brief Rectangular system solver
00276         const Field& F          * @param Field The computation domain
00277         const FFLAS_SIDE Side   * @param Side Determine wheter the resolution is left or right looking
00278         const size_t M,                 * @param M row dimension of A
00279         const size_t N,         * @param N col dimension of A
00280         const size_t NRHS,      * @param NRHS number of columns (if Side = FflasLeft) or row (if Side = FflasRight) of the matrices X and B
00281         Field::Element *A,      * @param A input matrix
00282         const size_t lda,               * @param lda leading dimension of A
00283         Field::Element *X,
00284         const size_t ldx,
00285         const Field::Element *B, * @param B Right/Left hand side matrix. Initially contains B, finally contains the solution X.
00286         const size_t ldb,               * @param ldb leading dimension of B
00287         int * info                      * @info Success of the computation: 0 if successfull, >0 if system is inconsistent
00288                                         * @return the rank of the system
00289         
00290         ld: leading dimension:
00291                 Suppose that you have a matrix A of size 100x100 which is stored in an array 100x100. 
00292                 In this case LDA is the same as N. Now suppose that you want to work only on the submatrix A(91:100 , 1:100); 
00293                 in this case the number of rows is 10 but LDA=100. Assuming the fortran column-major ordering (which is the case in LAPACK), 
00294                 the LDA is used to define the distance in memory between elements of two consecutive columns which have the same row index. 
00295                 If you call B = A(91:100 , 1:100) then B(1,1) and B(1,2) are 100 memory locations far from each other. 
00296         */
00297 
00298         /*column-major ordering
00299         bei Spalten-Orientierter Speicherung von Daten ist LDA die Anzahl der Elemente einer Spalte.(= Anzahl Zeilen!)
00300 
00301         Entsprechend ist bei Zeilen-orientierter Speicherung von Daten LDA die Anzahl der Elemente einer Zeile. (= Anzahl Spalten!)
00302 
00303         */
00304 
00305         size_t NRHS = 1; // ist unklar , was NHRS  ist , angeblich die Anzahl der Spalten von B. 
00306         size_t ldx = 1;
00307         size_t ldb = 1;
00308         size_t lda = cols_m;
00309 
00310         int info = 1;
00311         
00312         rankRef = FFPACK::fgesv(        *F, 
00313                                                 FFPACK::FflasLeft, 
00314                                                 rows_m, 
00315                                                 cols_m, 
00316                                                 NRHS, 
00317                                                 data_m, 
00318                                                 lda, 
00319                                                 solution, 
00320                                                 ldx, 
00321                                                 rightHandSide, 
00322                                                 ldb, 
00323                                                 &info           );
00324 
00325         if (info != 0)
00326         {
00327                 //      cerr << "LGSSolve: no solutions" << endl;
00328                 return NULL;
00329         }
00330                 
00331         return solution;
00332 }
00333 
00334 
00336 template <class Field >
00337   unsigned int FFpackMatrix< Field >::getRank()
00338 {
00339         return (unsigned int)FFPACK::Rank (*F, rows_m, cols_m, data_m, rows_m);
00340 }
00341 
00342 
00343 
00344 template <class Field >
00345  typename Field::Element FFpackMatrix< Field >::getVal(int row, int col) const
00346 {
00347         #ifdef SAFE
00348                 checkBounds(row,col);
00349         #endif 
00350 
00351         return data_m[cols_m*row+col];
00352 }
00353 
00354 
00355 template <class Field >
00356  void   FFpackMatrix<Field >::setVal(int row, int col,typename Field::Element elem)
00357 {
00358         #ifdef SAFE
00359                 checkBounds(row,col);
00360         #endif 
00361 
00362         data_m[cols_m*row+col]=elem;
00363 }
00364 
00365 template <class Field >
00366  void  FFpackMatrix<Field >::checkDimensions() const
00367 {
00368         if (rows_m<=0   || cols_m<=0 )
00369         {
00370                 std::cerr << "rows_m " << rows_m << std::endl;
00371                 std::cerr << "cols_m " << cols_m << std::endl;
00372         }
00373         assert( rows_m>=0 );
00374         assert( cols_m>=0 );
00375 }
00376 
00377 template <class Field >
00378  void  FFpackMatrix<Field >::checkBounds(int row,int col) const
00379 {
00380         if (row<0  || row>=rows_m || col<0  || col>=cols_m)
00381         {
00382                 std::cerr << "row " << row << " rows_m " << rows_m << std::endl;
00383                 std::cerr << "col " << col << " cols_m " << cols_m << std::endl;
00384                 assert(false);
00385         }
00386 }
00387 
00388 template <class Field>
00389 bool FFpackMatrix<Field>::operator==(const FFpackMatrix& mat) const
00390 {       
00391         if ( rows_m != mat.getRowNum() || cols_m != mat.getColNum() )
00392                 return false;
00393 
00394         
00395         for (unsigned int row=0; row<rows_m; row++)
00396         {
00397                 for (unsigned int col=0; col<cols_m; col++)
00398                 {
00399                         if ( getVal(row,col) != mat.getVal(row,col) )
00400                                 return false;
00401                 }
00402         }
00403         return true;
00404 }
00405 
00406 
00407 
00408 template <class Field >
00409  FFpackMatrix<Field >::~FFpackMatrix()
00410         {
00411                 if (data_m!=NULL)
00412                 delete[] data_m;
00413 
00414                 if (F!=NULL)  delete F;
00415                 
00416         };
00417 
00418 
00420 template <class Field >
00421 void  FFpackMatrix<Field >::printValue(std::ostream & os) const
00422 {
00423         
00424         os << std::endl << "{" ;
00425         for ( int i=0; i<rows_m; i++)
00426         {
00427                 if (i>0)
00428                 {
00429                         os << ", " << std::endl;
00430                 }
00431                 os << "{";
00432                 
00433                 for ( int j=0; j<cols_m; j++)
00434                 {
00435                         if (j>0)
00436                         {
00437                                 os << ", ";
00438                         }
00439                         os << ::std::setw( 2 ) << getVal(i,j);
00440                         
00441                 }
00442                 os << "}" ;
00443         }               
00444         os << std::endl << "} ";
00445 }
00446 
Generated on Tue Nov 23 13:10:51 2010 for centerfocus by  doxygen 1.6.3