00001
00002
00003
00004
00005 template <class TRing>
00006 int BlockMatrix<TRing>::refit(const int number,const int multipleTo)
00007 {
00008 assert(number>0);
00009 assert(multipleTo>0);
00010
00011 int result = number;
00012 int remainder = number % multipleTo;
00013 if (remainder !=0 )
00014 result += (multipleTo-remainder);
00015 return result;
00016 }
00017
00018 template <class TRing>
00019 BlockMatrix<TRing>::BlockMatrix(int _rowBlockSize,
00020 int _colBlockSize,
00021 int _rows,
00022 int _cols,
00023 const TRing* _ring,
00024 string _name ): rows(_rows),
00025 cols(_cols),
00026 rowBlockSize(_rowBlockSize),
00027 colBlockSize(_colBlockSize),
00028 ring(_ring),
00029 name(_name),
00030 extendedRowNum( refit(rows,_rowBlockSize) ),
00031 extendedColNum( refit(cols,_colBlockSize) )
00032
00033 {
00034
00035 assert (rows>0);
00036 assert (cols>0);
00037
00038 assert (_rowBlockSize>0);
00039 assert (_colBlockSize>0);
00040
00041 data = NULL;
00042
00043 data = new TNum[ getBlockNum() * getBlockSize() ];
00044 assert( data != NULL );
00045
00046 fillZero();
00047 }
00048
00049
00050 template <class TRing>
00051 BlockMatrix<TRing>::BlockMatrix(const BlockMatrix& mat ): rows(mat.rows),
00052 cols(mat.cols),
00053 rowBlockSize(mat.rowBlockSize),
00054 colBlockSize(mat.colBlockSize),
00055 ring(mat.ring),
00056 name(mat.name),
00057 extendedRowNum(mat.extendedRowNum ),
00058 extendedColNum(mat.extendedColNum )
00059 {
00060
00061 data = NULL;
00062
00063 data = new TNum[ getBlockNum() * getBlockSize() ];
00064 #ifdef SAFE
00065 assert (getBlockNum() * getBlockSize() ==getSize() );
00066 #endif
00067 assert( data != NULL );
00068
00070 std::copy(mat.data, mat.data+getSize(), data);
00071
00072
00073 }
00074
00075
00076
00077
00078
00079
00080 template <class TRing>
00081 BlockMatrix<TRing>::~BlockMatrix()
00082 {
00083 if ( data!=NULL )
00084 delete[] data;
00085 };
00086
00087
00088
00089 template <class TRing>
00090 void BlockMatrix<TRing>::checkBounds(int row, int col) const
00091 {
00092 if (row<0 || row>=rows || col<0 || col>=cols)
00093 {
00094 std::cerr << "BlockMatrix: bound error !" << std::endl;
00095 std::cerr << "row " << row << " rows " << rows << std::endl;
00096 std::cerr << "col " << col << " cols " << cols << std::endl;
00097 exit(0);
00098 }
00099 }
00100
00101
00102 template <class TRing>
00103 void BlockMatrix<TRing>::checkBlockBounds(int _blockNr, int _blockPos) const
00104 {
00105 if ( _blockNr<0 || _blockNr >= getBlockNum() || _blockPos<0 || _blockPos>=getBlockSize())
00106 {
00107 std::cerr << "BlockMatrix: block bound error !" << std::endl;
00108 std::cerr << "_blockNr " << _blockNr << " blocks " << getBlockNum() << std::endl;
00109 std::cerr << " blockPos " << _blockPos << " blockSize " << getBlockSize() << std::endl;
00110 exit(0);
00111 }
00112 }
00113
00114
00115
00116
00117 template <class TRing>
00118 void BlockMatrix<TRing>::fillZero()
00119 {
00120
00121
00122 std::fill(data, data+getSize(), TNum::Zero);
00123 }
00124
00125
00126
00127 template <class TRing>
00128 void BlockMatrix<TRing>::randomInit(long * _randomSeed )
00129 {
00130 for (size_t dataPos = 0; dataPos < getSize(); dataPos++)
00131 {
00132 data[ dataPos ] = ring->ConvertScalar( random( _randomSeed, ring->getCharacteristic()-1) );
00133 }
00134 }
00135
00136
00137 template <class TRing>
00138 inline tBlockPos BlockMatrix<TRing>::computeBlockPos(const int row, const int col) const
00139 {
00140 int currRowBlock = row / getRowBlockSize();
00141 int currColBlock = col / getColBlockSize();
00142
00143 int currBlock = currRowBlock*getBlocksPerRow() + currColBlock;
00144
00145
00146 int currSubMatrixRow = row % getRowBlockSize();
00147 int currSubMatrixCol = col % getColBlockSize();
00148
00149 int currBlockPos = currSubMatrixRow*colBlockSize + currSubMatrixCol;
00150
00151 #ifdef SAFE
00152 checkBlockBounds(currBlock,currBlockPos);
00153 #endif
00154
00155 return tBlockPos(currBlock,currBlockPos);
00156 }
00157
00158
00159 template <class TRing>
00160 inline tPos BlockMatrix<TRing>::computeNormalPos(const int _blockNr, const int _blockPos) const
00161 {
00162
00163
00164 int currColBlock = _blockNr % getBlocksPerRow();
00165
00166
00167 int currRowBlock = _blockNr / getBlocksPerRow();
00168
00169
00170 int col=currColBlock*getColBlockSize();
00171
00172
00173 int row=currRowBlock*getRowBlockSize();
00174
00175
00176 col += _blockPos % colBlockSize;
00177
00178
00179 row += _blockPos / colBlockSize;
00180
00181 #ifdef SAFE
00182 checkBounds(row,col);
00183 #endif
00184
00185 return tPos(row,col);
00186 }
00187
00188
00189
00190 template <class TRing>
00191 inline void BlockMatrix<TRing>::setVal(const int row, const int col, const TNum z)
00192 {
00193 #ifdef SAFE
00194 checkBounds(row,col);
00195 #endif
00196
00197 tBlockPos blockPos = computeBlockPos(row,col);
00198
00199 data[ blockPos.blockNr*getBlockSize() + blockPos.blockPos ] = z;
00200 }
00201
00202
00203
00204
00205
00206 template <class TRing>
00207 inline typename TRing::ElementType BlockMatrix<TRing>::getVal(const int _row, const int _col) const
00208 {
00209 #ifdef SAFE
00210 checkBounds(_row,_col);
00211 #endif
00212 tBlockPos blockPos = computeBlockPos(_row,_col);
00213
00214 return data[ blockPos.blockNr*getBlockSize() + blockPos.blockPos ];
00215 }
00216
00217
00218 template <class TRing>
00219 inline const typename TRing::ElementType& BlockMatrix<TRing>::getConstValRef(const int _row,const int _col) const
00220 {
00221 #ifdef SAFE
00222 checkBounds(_row,_col);
00223 #endif
00224 tBlockPos blockPos = computeBlockPos(_row,_col);
00225
00226 return data[ blockPos.blockNr*getBlockSize() + blockPos.blockPos ];
00227 }
00228
00229
00230 template <class TRing>
00231 inline typename TRing::ElementType & BlockMatrix<TRing>::getValRef(const int _row,const int _col)
00232 {
00233 #ifdef SAFE
00234 checkBounds(_row,_col);
00235 #endif
00236 tBlockPos blockPos = computeBlockPos(_row,_col);
00237 return data[ blockPos.blockNr*getBlockSize() + blockPos.blockPos ];
00238 }
00239
00240
00241 template <class TRing>
00242 inline typename TRing::ElementType * BlockMatrix<TRing>::getBlockValAddr(const int _blockNr, const int _blockPos)
00243 {
00244 #ifdef SAFE
00245 checkBlockBounds(_blockNr,_blockPos);
00246 #endif
00247 return &(data[ _blockNr*getBlockSize() + _blockPos ]);
00248 }
00249
00250 template <class TRing>
00251 inline typename TRing::ElementType BlockMatrix<TRing>::getBlockVal(const int _blockNr, const int _blockPos)
00252 {
00253 #ifdef SAFE
00254 checkBlockBounds(_blockNr,_blockPos);
00255 #endif
00256 return data[ _blockNr*getBlockSize() + _blockPos ];
00257 }
00258
00259 template <class TRing>
00260 inline void BlockMatrix<TRing>::setBlockVal(const int _blockNr, const int _blockPos,const TNum z)
00261 {
00262 #ifdef SAFE
00263 checkBlockBounds(_blockNr,_blockPos);
00264 #endif
00265 data[ _blockNr*getBlockSize() + _blockPos ] = z;
00266 }
00267
00268
00269
00270
00271
00272 template <class TRing>
00273 template <class TemplateMatrix >
00274 bool BlockMatrix<TRing>::operator==(const TemplateMatrix & mat) const
00275 {
00276 if ( rows != mat.getRowNum() || cols != mat.getColNum() )
00277 return false;
00278
00279
00280 for (int row=0; row<rows; row++)
00281 {
00282 for (int col=0; col<cols; col++)
00283 {
00284 if ( getVal(row,col) != mat.getVal(row,col) )
00285 return false;
00286 }
00287 }
00288 return true;
00289 }
00290
00291
00292
00293 template <class TRing>
00294 BlockMatrix<TRing>& BlockMatrix<TRing>::operator=(const BlockMatrix<TRing>& mat)
00295 {
00296
00297 if (this!=&mat)
00298 {
00299 ring = mat.ring ;
00300 delete [] data;
00301
00302
00303 rows = mat._rows;
00304 cols = mat.cols;
00305 rowBlockSize = mat.rowBlockSize;
00306 colBlockSize = mat.colBlockSize;
00307
00308 name = mat.name;
00309 extendedRowNum = mat.extendedRowNum;
00310 extendedColNum = mat.extendedColNum ;
00311
00312
00313 data = NULL;
00314
00315 data = new TNum[ getBlockNum() * getBlockSize() ];
00316 assert( data != NULL );
00317 assert( getBlockNum() * getBlockSize() == getSize() );
00319
00320
00321 std::copy(mat.data, mat.data+getSize(), data);
00322 }
00323 return *this;
00324 }
00325
00326
00327
00328
00330 template <class TRing>
00331 TMatrix<TRing>* BlockMatrix<TRing>::unblock()
00332 {
00333
00334 TMatrix<TRing>* erg = new TMatrix<TRing>(rows,cols, this->ring);
00335
00336
00337 for (register int row=0;row<rows; row++)
00338 {
00339 for (register int col=0; col<cols; col++)
00340 {
00341 erg->setVal(row, col, getVal(row, col) );
00342 }
00343 }
00344 return erg;
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369 }
00370
00371
00373 template <class TRing>
00374 bool BlockMatrix<TRing>::isZero()
00375 {
00376 for (size_t i=0; i<getSize(); i++)
00377 {
00378 if ( !(data[i].isZero() ) )
00379 return false;
00380 }
00381 return true;
00382 }
00383
00384
00386 template <class TRing>
00387 void BlockMatrix<TRing>::printValue(ostream & os) const
00388 {
00389
00390 os << std::endl << "{" ;
00391 for (int i=0; i<rows; i++)
00392 {
00393 if (i>0)
00394 {
00395 os << ", " << std::endl;
00396 }
00397 os << "{";
00398 for (int j=0; j<cols; j++)
00399 {
00400 if (j>0)
00401 {
00402 os << ", ";
00403 }
00404 os << getVal(i,j);
00405
00406 }
00407 os << "}" ;
00408 }
00409 os << std::endl << "} ";
00410 }
00411
00412
00414 template <class TRing>
00415 void BlockMatrix<TRing>::outputMatrix(ostream & os) const
00416 {
00417 os << std::endl << name << " = " ;
00418 os << "{" ;
00419 for (int i=0; i<rows; i++)
00420 {
00421 if (i>0)
00422 {
00423 os << ", " << std::endl;
00424 }
00425 os << "{";
00426 for (int j=0; j<cols; j++)
00427 {
00428 if (j>0)
00429 {
00430 os << ", ";
00431 }
00432 os << getVal(i,j);;
00433 }
00434 os << "}" ;
00435 }
00436 os << std::endl << "};" << std::endl;
00437 }
00438
00439
00440 template <class TRing>
00441 std::ostream & operator<<(std::ostream & out, const BlockMatrix<TRing>& z)
00442 {
00443 z.outputMatrix(out);
00444 return out;
00445 }
00446