00001
00002
00003
00004
00005
00007
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
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
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
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
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
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
00195
00196
00197
00198
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;
00211 size_t lda = cols_m;
00212 size_t ldx = cols_m;
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
00237
00238 FFPACK::Invert2(*F, lda, data_m, lda , INVDATA, ldx, NullSpaceDim);
00239
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
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
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 size_t NRHS = 1;
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
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