SignMatrix.h

Go to the documentation of this file.
00001 /*
00002  * SignMatrix.h
00003  *
00004  *  Created on: 21.03.2011
00005  *      Author: Juern
00006  */
00007 
00008 #ifndef SIGNMATRIX_H_
00009 #define SIGNMATRIX_H_
00010 
00011 namespace PC
00012 {
00013 
00023 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE> class SignMatrix;
00024 struct Row {unsigned int rowid; static const unsigned int UNDEFINED = ~0; Row():rowid(UNDEFINED){}};
00025 struct Col {unsigned int colid; static const unsigned int UNDEFINED = ~0; Col():colid(UNDEFINED){}};
00026 const Row UNDEFINED_ROW;
00027 const Col UNDEFINED_COL;
00028 
00029 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00030 class SignMatrix
00031 {
00032 private:
00033         unsigned int            numRows, numCols;
00034         unsigned int            maxNumRows, maxNumCols;
00035         int                             firstUnusedRow;
00036         int                             firstUnusedCol;
00037 
00038         INTERNAL_TYPE*          matrix;
00039         struct intRowHdr {unsigned int rowno, row; RowHdr rh; int nextUnused; bool used;};
00040         struct intColHdr {unsigned int colno, col; ColHdr ch; int nextUnused; bool used;};
00041         std::vector<intRowHdr>  rowHdrs;
00042         std::vector<intColHdr>  colHdrs;
00043 
00044         static const double     EXTEND_CONDITION = 1.2;
00045         static const double     EXTEND_FACTOR = 2.0;
00046         const unsigned int      INTERNAL_SIZE;
00047         INTERNAL_TYPE           mask1, mask2;
00048 
00049         void                            extend(unsigned int rows, unsigned int cols);
00050 
00051         Row                                     insertRow(unsigned int rowNo, RowHdr rowHdr);
00052         Col                                     insertCol(unsigned int colNo, ColHdr colHdr);
00053         void                            free();
00054 public:
00055                                                 SignMatrix(unsigned int rows = 0, unsigned int cols = 0, unsigned int maxR = 16, unsigned int maxC = 16);
00056         virtual                         ~SignMatrix();
00057         // Access matrix and headers
00058         unsigned int            getNumRows() const;
00059         unsigned int            getNumCols() const;
00060         Row                                     getRow(unsigned int rowNo) const;
00061         unsigned int            getRowNumber(Row row) const;
00062         Col                                     getCol(unsigned int colNo) const;
00063         unsigned int            getColNumber(Col col) const;
00064         Sign                            operator()(unsigned int rowNo, unsigned int colNo) const;
00065         Sign                            operator()(Row row, Col col) const;
00066         Sign                            operator()(Row row, unsigned int colNo) const;
00067         Sign                            operator()(unsigned int rowNo, Col col) const;
00068         void                            setEntry(unsigned int rowNo, unsigned int colNo, Sign val);
00069         void                            setEntry(Row row, Col col, Sign val);
00070         void                            setEntry(Row row, unsigned int colNo, Sign val);
00071         void                            setEntry(unsigned int rowNo, Col col, Sign val);
00072         RowHdr&                         rowHdr(unsigned int rowNo);
00073         RowHdr&                         rowHdr(Row col);
00074         ColHdr&                         colHdr(unsigned int colNo);
00075         ColHdr&                         colHdr(Col col);
00076         // Operations on columns
00077         bool                            columnsEqual(Col col1, Col col2);
00078         Col                                     insertZeroCol(unsigned int colNo, ColHdr colHdr = ColHdr());
00079         Col                                     insertUnitCol(unsigned int colNo, unsigned int i, ColHdr colHdr = ColHdr());
00080         Col                                     insertInvCol(Col sourceCol, unsigned int targetColNo, ColHdr targetColHdr = ColHdr());
00081         Col                                     insertColSum(Col sourceCol1, Col sourceCol2, unsigned int targetColNo, ColHdr targetColHdr = ColHdr());
00082         Col                                     insertColCopy(Col sourceCol, unsigned int targetColNo);
00083         Col                                     insertIntersectionCol(Col sourceCol1, Col sourceCol2, unsigned int targetColNo, ColHdr targetColHdr = ColHdr());
00084         void                            addToCol(Col sourceCol, Col targetCol);
00085         void                            deleteCol(Col col);
00086         void                            moveCol(Col col, unsigned int newColNo);
00087         // Operations on rows
00088         Row                                     insertZeroRow(unsigned int rowNo, RowHdr rowHdr = RowHdr());
00089         Row                                     insertRowCopy(Row sourceRow, unsigned int targetRowNo);
00090         void                            deleteRow(Row row);
00091         void                            moveRow(Row row, unsigned int newRowNo);
00092         // Other matrix operations
00093         void                            clone(const SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>& mat, std::list<Col>& colList);
00094         void                            insertMatrix(const SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>& mat, unsigned int rowOffset, unsigned int colOffset);
00095         void                            printMatrix(std::ostream& os = std::cout) const;
00096 #ifdef DEBUG
00097         bool                            checkInternalIntegrity();
00098 #endif
00099 };
00100 
00101 
00110 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00111 SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::SignMatrix(unsigned int rows, unsigned int cols, unsigned int maxR, unsigned int maxC)
00112 :       numRows(rows),
00113         numCols(cols),
00114         firstUnusedRow(-1),
00115         firstUnusedCol(-1),
00116         matrix(NULL),
00117         rowHdrs(),
00118         colHdrs(),
00119         INTERNAL_SIZE(sizeof(INTERNAL_TYPE) << 2)
00120 {
00121         maxNumRows = (((std::max(maxR, rows) + INTERNAL_SIZE - 1) / INTERNAL_SIZE) * INTERNAL_SIZE);
00122         maxNumCols = std::max(maxC, cols);
00123         // Initialize masks
00124         for(unsigned int j = 0; j < INTERNAL_SIZE; j++)
00125                 SignMatrix::mask1 = (SignMatrix::mask1 << 2) | 1/*0b01*/;
00126         mask2 = mask1 << 1;
00127         // Allocate memory
00128         if(maxNumRows * maxNumCols > 0)
00129         {
00130                 matrix = new INTERNAL_TYPE[maxNumCols * (maxNumRows / INTERNAL_SIZE)];
00131                 assert(matrix != NULL);
00132                 memset(matrix, 0, maxNumCols * (maxNumRows / INTERNAL_SIZE) * sizeof(INTERNAL_TYPE));
00133         }
00134         if(maxNumRows > 0)
00135         {
00136                 rowHdrs.resize(maxNumRows);
00137 
00138                 for(unsigned int i = 0; i < numRows; i++)
00139                 {
00140                         rowHdrs[i].used = true;
00141                         rowHdrs[i].row = i;
00142                         rowHdrs[i].rowno = i;
00143                 }
00144                 if(numRows < maxNumRows)
00145                         firstUnusedRow = numRows;
00146                 else
00147                         firstUnusedRow = -1;
00148 
00149                 for(unsigned int i = numRows; i < maxNumRows; i++)
00150                 {
00151                         rowHdrs[i].used = false;
00152                         rowHdrs[i].nextUnused = i + 1;
00153                 }
00154                 rowHdrs[maxNumRows-1].nextUnused = -1;
00155         }
00156         if(maxNumCols > 0)
00157         {
00158                 colHdrs.resize(maxNumCols);
00159 
00160                 for(unsigned int i = 0; i < numCols; i++)
00161                 {
00162                         colHdrs[i].used = true;
00163                         colHdrs[i].col = i;
00164                         colHdrs[i].colno = i;
00165                 }
00166                 if(numCols < maxNumCols)
00167                         firstUnusedCol = numCols;
00168                 else
00169                         firstUnusedCol = -1;
00170                 for(unsigned int i = numCols; i < maxNumCols; i++)
00171                 {
00172                         colHdrs[i].used = false;
00173                         colHdrs[i].nextUnused = i + 1;
00174                 }
00175                 colHdrs[maxNumCols-1].nextUnused = -1;
00176         }
00177 }
00178 
00184 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00185 SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::~SignMatrix()
00186 {
00187         free();
00188 }
00189 
00193 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00194 void SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::free()
00195 {
00196         if(matrix != NULL)
00197         {
00198                 delete [] matrix;
00199                 matrix = NULL;
00200         }
00201         rowHdrs.empty();
00202         colHdrs.empty();
00203 
00204         numRows = 0; numCols = 0;
00205         maxNumRows = 0; maxNumCols = 0;
00206 }
00207 
00211 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00212 inline unsigned int SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::getNumRows() const
00213 {
00214         return numRows;
00215 }
00216 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00217 inline unsigned int SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::getNumCols() const
00218 {
00219         return numCols;
00220 }
00221 
00226 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00227 inline Row SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::getRow(unsigned int rowNo) const
00228 {
00229         assert(rowNo < numRows && rowHdrs[rowHdrs[rowNo].row].used);
00230         Row row; row.rowid = rowHdrs[rowNo].row;
00231         return row;
00232 }
00233 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00234 inline unsigned int SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::getRowNumber(Row row) const
00235 {
00236         assert(row.rowid < maxNumRows && rowHdrs[row.rowid].rowno < numRows && rowHdrs[row.rowid].used);
00237         return rowHdrs[row.rowid].rowno;
00238 }
00239 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00240 inline Col SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::getCol(unsigned int colNo) const
00241 {
00242         assert(colNo < numCols && colHdrs[colHdrs[colNo].col].used);
00243         Col col; col.colid = colHdrs[colNo].col;
00244         return col;
00245 }
00246 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00247 inline unsigned int SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::getColNumber(Col col) const
00248 {
00249         assert(col.colid < maxNumCols && colHdrs[col.colid].colno < numCols && colHdrs[col.colid].used);
00250         return colHdrs[col.colid].colno;
00251 }
00252 
00257 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00258 inline Sign SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::operator()(Row row, Col col) const
00259 {
00260         assert(row.rowid < maxNumRows && col.colid < maxNumCols && rowHdrs[row.rowid].rowno < numRows && colHdrs[col.colid].colno < numCols && rowHdrs[row.rowid].used && colHdrs[col.colid].used);
00261         unsigned long long  t = row.rowid + col.colid * maxNumRows;
00262         return (matrix[t / INTERNAL_SIZE] >> ((t % INTERNAL_SIZE) * 2)) & 3/*0b11*/;
00263 }
00264 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00265 inline Sign SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::operator()(unsigned int rowNo, unsigned int colNo) const
00266 {
00267         assert(rowNo < numRows && colNo < numCols && rowHdrs[rowHdrs[rowNo].row].used && colHdrs[colHdrs[colNo].col].used);
00268         unsigned long long t = rowHdrs[rowNo].row + colHdrs[colNo].col * maxNumRows;
00269         return (matrix[t / INTERNAL_SIZE] >> ((t % INTERNAL_SIZE) * 2)) & 3/*0b11*/;
00270 }
00271 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00272 Sign SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::operator()(Row row, unsigned int colNo) const
00273 {
00274         return operator()(row, getCol(colNo));
00275 }
00276 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00277 Sign SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::operator()(unsigned int rowNo, Col col) const
00278 {
00279         return operator()(getRow(rowNo), col);
00280 }
00281 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00282 inline void SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::setEntry(Row row, Col col, Sign val)
00283 {
00284         assert(row.rowid < maxNumRows && col.colid < maxNumCols && rowHdrs[row.rowid].rowno < numRows && colHdrs[col.colid].colno < numCols && rowHdrs[row.rowid].used && colHdrs[col.colid].used);
00285         unsigned long long t = row.rowid + col.colid * maxNumRows;
00286         matrix[t / INTERNAL_SIZE] &= ~(3/*0b11*/ << ((t % INTERNAL_SIZE) * 2));
00287         matrix[t / INTERNAL_SIZE] |= (val & 3/*0b11*/) << ((t % INTERNAL_SIZE) * 2);
00288 }
00289 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00290 inline void SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::setEntry(unsigned int rowNo, unsigned int colNo, Sign val)
00291 {
00292         assert(rowNo < numRows && colNo < numCols && rowHdrs[rowHdrs[rowNo].row].used && colHdrs[colHdrs[colNo].col].used);
00293         unsigned long long t = rowHdrs[rowNo].row + colHdrs[colNo].col * maxNumRows;
00294         matrix[t / INTERNAL_SIZE] &= ~(3/*0b11*/ << ((t % INTERNAL_SIZE) * 2));
00295         matrix[t / INTERNAL_SIZE] |= (val & 3/*0b11*/) << ((t % INTERNAL_SIZE) * 2);
00296 }
00297 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00298 void SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::setEntry(Row row, unsigned int colNo, Sign val)
00299 {
00300         setEntry(row, getCol(colNo), val);
00301 }
00302 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00303 void SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::setEntry(unsigned int rowNo, Col col, Sign val)
00304 {
00305         setEntry(getRow(rowNo), col, val);
00306 }
00307 
00312 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00313 inline RowHdr& SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::rowHdr(unsigned int rowNo)
00314 {
00315         assert(rowNo < numRows && rowHdrs[rowHdrs[rowNo].row].used);
00316         return rowHdr(getRow(rowNo));
00317 }
00318 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00319 inline RowHdr& SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::rowHdr(Row row)
00320 {
00321         assert(row.rowid < maxNumRows && rowHdrs[row.rowid].rowno < numRows && rowHdrs[row.rowid].used);
00322         return rowHdrs[row.rowid].rh;
00323 }
00324 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00325 inline ColHdr& SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::colHdr(unsigned int colNo)
00326 {
00327         assert(colNo < numCols && colHdrs[colHdrs[colNo].col].used);
00328         return colHdr(getCol(colNo));
00329 }
00330 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00331 inline ColHdr& SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::colHdr(Col col)
00332 {
00333         assert(col.colid < maxNumCols && colHdrs[col.colid].colno < numCols && colHdrs[col.colid].used);
00334         return colHdrs[col.colid].ch;
00335 }
00336 
00340 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00341 void SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::printMatrix(std::ostream& os) const
00342 {
00343         os << "Matrix with " << numRows << " rows and " << numCols << " columns:" << std::endl;
00344         for(unsigned int i = 0; i < numRows; i++)
00345         {
00346                 for(unsigned int j = 0; j < numCols; j++)
00347                         os << std::setw(3) << (operator()(i, j) == PLUS ? "+1" : (operator()(i, j) == MINUS ? "-1" : "0"));
00348                 os << std::endl;
00349         }
00350         os << std::endl;
00351 }
00352 
00357 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00358 bool SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::columnsEqual(Col col1, Col col2)
00359 {
00360         assert(col1.colid < maxNumCols && col2.colid < maxNumCols && colHdrs[col1.colid].colno < numCols && colHdrs[col2.colid].colno < numCols && colHdrs[col1.colid].used && colHdrs[col2.colid].used);
00361         for(unsigned int i = 0; i < numRows; i++)
00362                 if(operator()(getRow(i), col1) != operator()(getRow(i), col2))
00363                         return false;
00364         return true;
00365 }
00366 
00373 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00374 Col SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::insertZeroCol(unsigned int colNo, ColHdr colHdr)
00375 {
00376         Col col = insertCol(colNo, colHdr);
00377         memset(matrix + col.colid * (maxNumRows / INTERNAL_SIZE), 0, (maxNumRows / INTERNAL_SIZE) * sizeof(INTERNAL_TYPE));
00378         return col;
00379 }
00380 
00387 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00388 Col SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::insertUnitCol(unsigned int colNo, unsigned int i, ColHdr colHdr)
00389 {
00390         assert(i < numRows);
00391         Col col = insertCol(colNo, colHdr);
00392         memset(matrix + col.colid * (maxNumRows / INTERNAL_SIZE), 0, (maxNumRows / INTERNAL_SIZE) * sizeof(INTERNAL_TYPE));
00393         Row row; row.rowid = rowHdrs[i].row;
00394         setEntry(row, col, 1);
00395         return col;
00396 }
00397 
00404 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00405 Col SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::insertInvCol(Col sourceCol, unsigned int targetColNo, ColHdr targetColHdr)
00406 {
00407         assert(sourceCol.colid < maxNumCols && colHdrs[sourceCol.colid].colno < numCols && colHdrs[sourceCol.colid].used);
00408         Col col = insertCol(targetColNo, targetColHdr);
00409         for(unsigned int i = 0; i < (maxNumRows / INTERNAL_SIZE); i++)
00410         {
00411                 unsigned int t = col.colid * (maxNumRows / INTERNAL_SIZE) + i;
00412                 matrix[t] = ~matrix[sourceCol.colid * (maxNumRows / INTERNAL_SIZE) + i];
00413                 INTERNAL_TYPE x = ((matrix[t] & mask1) << 1) & (matrix[t] & mask2);
00414                 matrix[t] = matrix[t] ^ x ^ (x >> 1);
00415         }
00416         return col;
00417 }
00418 
00426 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00427 Col SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::insertColSum(Col sourceCol1, Col sourceCol2, unsigned int targetColNo, ColHdr targetColHdr)
00428 {
00429         assert(sourceCol1.colid < maxNumCols && sourceCol2.colid < maxNumCols && colHdrs[sourceCol1.colid].colno < numCols && colHdrs[sourceCol2.colid].colno < numCols && colHdrs[sourceCol1.colid].used && colHdrs[sourceCol2.colid].used);
00430         Col col = insertCol(targetColNo, targetColHdr);
00431         for(unsigned int i = 0; i < (maxNumRows / INTERNAL_SIZE); i++)
00432         {
00433                 unsigned int t = col.colid * (maxNumRows / INTERNAL_SIZE) + i;
00434                 matrix[t] = matrix[sourceCol1.colid * (maxNumRows / INTERNAL_SIZE) + i] | matrix[sourceCol2.colid * (maxNumRows / INTERNAL_SIZE) + i];
00435                 INTERNAL_TYPE x = ((matrix[t] & mask1) << 1) & (matrix[t] & mask2);
00436                 matrix[t] = matrix[t] ^ x ^ (x >> 1);
00437         }
00438         return col;
00439 }
00440 
00447 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00448 Col SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::insertColCopy(Col sourceCol, unsigned int targetColNo)
00449 {
00450         assert(sourceCol.colid < maxNumCols && colHdrs[sourceCol.colid].colno < numCols && colHdrs[sourceCol.colid].used);
00451         Col col = insertCol(targetColNo, ColHdr());
00452         memcpy(matrix + col.colid * (maxNumRows / INTERNAL_SIZE), matrix + sourceCol.colid * (maxNumRows / INTERNAL_SIZE), (maxNumRows / INTERNAL_SIZE) * sizeof(INTERNAL_TYPE));
00453         return col;
00454 }
00455 
00456 
00457 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00458 Col SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::insertIntersectionCol(Col sourceCol1, Col sourceCol2, unsigned int targetColNo, ColHdr targetColHdr )
00459 {
00460         assert(sourceCol1.colid < maxNumCols && sourceCol2.colid < maxNumCols && colHdrs[sourceCol1.colid].colno < numCols && colHdrs[sourceCol2.colid].colno < numCols && colHdrs[sourceCol1.colid].used && colHdrs[sourceCol2.colid].used);
00461         Col col = insertCol(targetColNo, targetColHdr);
00462         for(unsigned int i = 0; i < (maxNumRows / INTERNAL_SIZE); i++)
00463         {
00464                 unsigned int t = col.colid * (maxNumRows / INTERNAL_SIZE) + i;
00465                 matrix[t] = matrix[sourceCol1.colid * (maxNumRows / INTERNAL_SIZE) + i] & matrix[sourceCol2.colid * (maxNumRows / INTERNAL_SIZE) + i];
00466         }
00467         return col;
00468 }
00469 
00470 
00476 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00477 void SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::addToCol(Col sourceCol, Col targetCol)
00478 {
00479         assert(sourceCol.colid < maxNumCols && targetCol.colid < maxNumCols && colHdrs[sourceCol.colid].colno < numCols && colHdrs[targetCol.colid].colno < numCols && colHdrs[sourceCol.colid].used && colHdrs[targetCol.colid].used);
00480         for(unsigned int i = 0; i < (maxNumRows / INTERNAL_SIZE); i++)
00481         {
00482                 unsigned int t = targetCol.colid * (maxNumRows / INTERNAL_SIZE) + i;
00483                 matrix[t] |= matrix[sourceCol.colid * (maxNumRows / INTERNAL_SIZE) + i];
00484                 INTERNAL_TYPE x = ((matrix[t] & mask1) << 1) & (matrix[t] & mask2);
00485                 matrix[t] = matrix[t] ^ x ^ (x >> 1);
00486         }
00487 }
00488 
00492 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00493 void SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::deleteCol(Col col)
00494 {
00495         assert(col.colid < maxNumCols && colHdrs[col.colid].colno < numCols && colHdrs[col.colid].used);
00496         // Decrease all column numbers greater that that of col by one.
00497         for(unsigned int i = colHdrs[col.colid].colno + 1; i < numCols; i++)
00498         {
00499                 colHdrs[colHdrs[i].col].colno--;
00500                 colHdrs[i - 1].col = colHdrs[i].col;
00501         }
00502         // Mark col as unused.
00503         colHdrs[col.colid].nextUnused = firstUnusedCol;
00504         firstUnusedCol = col.colid;
00505         colHdrs[col.colid].used = false;
00506         numCols--;
00507 }
00508 
00513 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00514 void SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::moveCol(Col col, unsigned int newColNo)
00515 {
00516         assert(col.colid < maxNumCols && colHdrs[col.colid].colno < numCols && newColNo < numCols);
00517         if(colHdrs[col.colid].colno > newColNo)
00518         {
00519                 for(unsigned int i = colHdrs[col.colid].colno; i > newColNo; i--)
00520                 {
00521                         colHdrs[colHdrs[i - 1].col].colno++;
00522                         colHdrs[i].col = colHdrs[i - 1].col;
00523                 }
00524                 colHdrs[col.colid].colno = newColNo;
00525                 colHdrs[newColNo].col = col.colid;
00526         }
00527         else if(colHdrs[col.colid].colno < newColNo)
00528         {
00529                 for(unsigned int i = colHdrs[col.colid].colno + 1; i <= newColNo; i++)
00530                 {
00531                         colHdrs[colHdrs[i].col].colno--;
00532                         colHdrs[i - 1].col = colHdrs[i].col;
00533                 }
00534                 colHdrs[col.colid].colno = newColNo;
00535                 colHdrs[newColNo].col = col.colid;
00536         }
00537         // else: nothing to be done
00538 }
00539 
00544 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00545 Row SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::insertZeroRow(unsigned int rowNo, RowHdr rowHdr)
00546 {
00547         Row row = insertRow(rowNo, rowHdr);
00548         for(unsigned int i = 0; i < numCols; i++)
00549                 setEntry(row, getCol(i), 0);
00550         return row;
00551 }
00552 
00557 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00558 Row SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::insertRowCopy(Row sourceRow, unsigned int targetRowNo)
00559 {
00560         assert(sourceRow.rowid < maxNumRows && rowHdrs[sourceRow.rowid].rowno < numRows && rowHdrs[sourceRow.rowid].used);
00561         Row row = insertRow(targetRowNo, rowHdrs[sourceRow.rowid].rh);
00562         for(unsigned int i = 0; i < numCols; i++)
00563                 setEntry(row, getCol(i), operator()(sourceRow, getCol(i)));
00564         return row;
00565 }
00566 
00570 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00571 void SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::deleteRow(Row row)
00572 {
00573         assert(row.rowid < maxNumRows && rowHdrs[row.rowid].rowno < numRows && rowHdrs[row.rowid].used);
00574         // Decrease all row numbers greater that that of row by one.
00575         for(unsigned int i = rowHdrs[row.rowid].rowno + 1; i < numRows; i++)
00576         {
00577                 rowHdrs[rowHdrs[i].row].rowno--;
00578                 rowHdrs[i - 1].row = rowHdrs[i].row;
00579         }
00580         // Mark row as unused.
00581         rowHdrs[row.rowid].nextUnused = firstUnusedRow;
00582         firstUnusedRow = row.rowid;
00583         rowHdrs[row.rowid].used = false;
00584         numRows--;
00585 }
00586 
00591 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00592 void SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::moveRow(Row row, unsigned int newRowNo)
00593 {
00594         assert(row.rowid < maxNumRows && rowHdrs[row.rowid].rowno < numRows && newRowNo < numRows);
00595         if(rowHdrs[row.rowid].rowno > newRowNo)
00596         {
00597                 for(unsigned int i = rowHdrs[row.rowid].rowno; i > newRowNo; i--)
00598                 {
00599                         rowHdrs[rowHdrs[i - 1].row].rowno++;
00600                         rowHdrs[i].row = rowHdrs[i - 1].row;
00601                 }
00602                 rowHdrs[row.rowid].rowno = newRowNo;
00603                 rowHdrs[newRowNo].row = row.rowid;
00604         }
00605         else if(rowHdrs[row.rowid].rowno < newRowNo)
00606         {
00607                 for(unsigned int i = rowHdrs[row.rowid].rowno + 1; i <= newRowNo; i++)
00608                 {
00609                         rowHdrs[rowHdrs[i].row].rowno--;
00610                         rowHdrs[i - 1].row = rowHdrs[i].row;
00611                 }
00612                 rowHdrs[row.rowid].rowno = newRowNo;
00613                 rowHdrs[newRowNo].row = row.rowid;
00614         }
00615         // else: nothing to be done
00616 }
00617 
00622 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00623 void SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::clone(const SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>& mat, std::list<Col>& colList)
00624 {
00625         // Delete this matrix
00626         free();
00627         // Determine size
00628         numRows = mat.numRows;
00629         numCols = colList.size();
00630         maxNumRows = mat.maxNumRows;
00631         maxNumCols = numCols;
00632         // Copy row headers
00633         rowHdrs.resize(maxNumRows);
00634 
00635         firstUnusedRow = mat.firstUnusedRow;
00636         for(unsigned int i = 0; i < maxNumRows/*numRows*/; i++)
00637                 //      rowHdrs[i] = mat.rowHdrs[i];
00638         {
00639                 rowHdrs[i].row = mat.rowHdrs[i].row;
00640                 rowHdrs[i].rowno = mat.rowHdrs[i].rowno;
00641                 rowHdrs[i].used = mat.rowHdrs[i].used;
00642                 rowHdrs[i].nextUnused = mat.rowHdrs[i].nextUnused;
00643         }
00644 
00645         // Column headers are copied later, for now just make room for them
00646         colHdrs.resize(maxNumCols);
00647         if(numCols < maxNumCols)
00648                 firstUnusedCol = numCols;
00649         else
00650                 firstUnusedCol = -1;
00651         for(unsigned int i = numCols; i < maxNumCols; i++)
00652         {
00653                 colHdrs[i].used = false;
00654                 colHdrs[i].nextUnused = i + 1;
00655         }
00656         colHdrs[maxNumCols-1].nextUnused = -1;
00657         // Copy matrix
00658         if(maxNumRows * maxNumCols > 0)
00659         {
00660                 matrix = new INTERNAL_TYPE[maxNumCols * (maxNumRows / INTERNAL_SIZE)];
00661                 assert(matrix != NULL);
00662                 memset(matrix, 0, maxNumCols * (maxNumRows / INTERNAL_SIZE) * sizeof(INTERNAL_TYPE));
00663                 unsigned int i = 0;
00664                 for(std::list<Col>::iterator iter = colList.begin(); iter != colList.end(); iter++)
00665                 {
00666                         // Copy column
00667                         memcpy(matrix + i * (maxNumRows / INTERNAL_SIZE), mat.matrix + iter->colid * (mat.maxNumRows / INTERNAL_SIZE), (maxNumRows / INTERNAL_SIZE) * sizeof(INTERNAL_TYPE));
00668                         // Set column header
00669                         colHdrs[i].used = true;
00670                         //colHdrs[i].ch = mat.colHdr(*iter);
00671                         colHdrs[i].colno = i;
00672                         colHdrs[i].col = i;
00673                         iter->colid = i;
00674                         i++;
00675                 }
00676         }
00677 }
00678 
00683 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00684 void SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::insertMatrix(const SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>& mat, unsigned int rowOffset, unsigned int colOffset)
00685 {
00686         //FIXME: This needs to be sped up!
00687         throw " should not use this function insertMatrix!";
00688         if(rowOffset + mat.numRows < maxNumRows || colOffset + mat.numCols < maxNumCols)
00689                 extend(rowOffset + mat.numRows, colOffset + mat.numCols);
00690 
00691         for(unsigned int c = 0; c < mat.numCols; c++)
00692                 insertZeroCol(colOffset + c, mat.colHdrs[mat.colHdrs[c].col].ch);
00693         for(unsigned int r = 0; r < mat.numRows; r++)
00694                 insertZeroRow(rowOffset + r, mat.rowHdrs[mat.rowHdrs[r].row].rh);
00695         for(unsigned int c = 0; c < mat.numCols; c++)
00696                 for(unsigned int r = 0; r < mat.numRows; r++)
00697                         setEntry(rowOffset + r, colOffset + c, mat.operator()(r, c));
00698 }
00699 
00700 
00705 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00706 void SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::extend(unsigned int rows, unsigned int cols)
00707 {
00708         unsigned int    newNumRows, newNumCols;
00709         if(rows * EXTEND_CONDITION > maxNumRows)
00710         {
00711                 newNumRows = std::max(rows, (unsigned int)ceil((maxNumRows * EXTEND_FACTOR)));
00712                 newNumRows = ((newNumRows + INTERNAL_SIZE - 1) / INTERNAL_SIZE) * INTERNAL_SIZE;
00713         }
00714         else
00715                 newNumRows = maxNumRows;
00716         if(cols * EXTEND_CONDITION > maxNumCols)
00717                 newNumCols = std::max(cols, (unsigned int)ceil((maxNumCols * EXTEND_FACTOR)));
00718         else
00719                 newNumCols = maxNumCols;
00720         // Reallocate
00721         if(newNumCols > maxNumCols || newNumRows > maxNumRows)
00722         {
00723                 INTERNAL_TYPE* newMatrix = NULL;
00724                 if((unsigned long long)newNumCols * (unsigned long long)newNumRows > 0)
00725                 {
00726                         newMatrix = new INTERNAL_TYPE[newNumCols * (newNumRows / INTERNAL_SIZE)];
00727                         memset(newMatrix, 0, newNumCols * (newNumRows / INTERNAL_SIZE) * sizeof(INTERNAL_TYPE));
00728                         for(unsigned int j = 0; j < numCols; j++)
00729                                 //for(unsigned int i = 0; i < numRows; i++)
00730                                 //      newMatrix[i + j * newNumRows] = operator()(i, j);
00731                                 memcpy(newMatrix + j * (newNumRows / INTERNAL_SIZE), matrix + j * (maxNumRows / INTERNAL_SIZE), (maxNumRows / INTERNAL_SIZE) * sizeof(INTERNAL_TYPE));
00732                 }
00733                 if(matrix != NULL)
00734                         delete [] matrix;
00735                 matrix = newMatrix;
00736         }
00737         if(newNumRows > maxNumRows)
00738         {
00739                 rowHdrs.resize(newNumRows);
00740 
00741                 for(unsigned int i = maxNumRows; i < newNumRows; i++)
00742                 {
00743                         rowHdrs[i].used = false;
00744                         rowHdrs[i].nextUnused = i + 1;
00745                 }
00746                 rowHdrs[newNumRows-1].nextUnused = firstUnusedRow;
00747                 firstUnusedRow = maxNumRows;
00748                 maxNumRows = newNumRows;
00749         }
00750         if(newNumCols > maxNumCols)
00751         {
00752                 colHdrs.resize(newNumCols);
00753                 for(unsigned int i = maxNumCols; i < newNumCols; i++)
00754                 {
00755                         colHdrs[i].used = false;
00756                         colHdrs[i].nextUnused = i + 1;
00757                 }
00758                 colHdrs[newNumCols-1].nextUnused = firstUnusedCol;
00759                 firstUnusedCol = maxNumCols;
00760 
00761                 maxNumCols = newNumCols;
00762         }
00763 }
00764 
00772 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00773 Row SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::insertRow(unsigned int rowNo, RowHdr rowHdr)
00774 {
00775         assert(rowNo <= numRows);
00776         //checkExtend(numRows + 1, numCols);
00777         if(firstUnusedRow == -1)
00778         {
00779                 assert(numRows == maxNumRows);
00780                 extend(numRows + 1, numCols);
00781         }
00782         assert(firstUnusedRow != -1);
00783 
00784         int n = firstUnusedRow;
00785         firstUnusedRow = rowHdrs[n].nextUnused;
00786 
00787         assert(!rowHdrs[n].used);
00788 
00789         // Increment all row numbers >= rowNo by one
00790         for(unsigned int j = numRows; j > rowNo; j--)
00791         {
00792                 rowHdrs[j].row = rowHdrs[j - 1].row;
00793                 rowHdrs[rowHdrs[j].row].rowno++;
00794         }
00795         // Insert the new row
00796         rowHdrs[n].used = true;
00797         rowHdrs[n].rowno = rowNo;
00798         rowHdrs[n].rh = rowHdr;
00799         rowHdrs[rowNo].row = n;
00800         numRows++;
00801         Row row; row.rowid = n;
00802         return row;
00803 }
00804 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00805 Col SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::insertCol(unsigned int colNo, ColHdr colHdr)
00806 {
00807         assert(colNo <= numCols);
00808 
00809         if(firstUnusedCol == -1)
00810         {
00811                 assert(numCols == maxNumCols);
00812                 extend(numRows , numCols+ 1);
00813         }
00814         assert(firstUnusedCol != -1);
00815 
00816         int n = firstUnusedCol;
00817         firstUnusedCol = colHdrs[n].nextUnused;
00818 
00819         assert(!colHdrs[n].used);
00820         // Increment all row numbers >= rowNo by one
00821         for(unsigned int j = numCols; j > colNo; j--)
00822         {
00823                 colHdrs[j].col = colHdrs[j - 1].col;
00824                 colHdrs[colHdrs[j].col].colno++;
00825         }
00826 
00827         // Insert the new column
00828         colHdrs[n].used = true;
00829         colHdrs[n].colno = colNo;
00830         colHdrs[n].ch = colHdr;
00831         colHdrs[colNo].col = n;
00832         numCols++;
00833         Col col; col.colid = n;
00834         return col;
00835 }
00836 
00837 #ifdef DEBUG
00838 template<class RowHdr, class ColHdr, typename INTERNAL_TYPE>
00839 bool SignMatrix<RowHdr, ColHdr, INTERNAL_TYPE>::checkInternalIntegrity()
00840 {
00841         for(unsigned int i = 0; i < numRows; i++)
00842         {
00843                 for(unsigned int j = 0; j < numRows; j++)
00844                 {
00845                         if(operator()(i, j) != ZERO && operator()(i, j) != PLUS && operator()(i, j) != MINUS)
00846                         {
00847                                 std::cout << "Matrixfehler in Zeile " << i << ", Spalte " << j << std::endl;
00848                                 std::cout.flush();
00849                                 assert(false);
00850                         }
00851                 }
00852         }
00853 }
00854 #endif
00855 
00856 }
00857 
00858 #endif /* SIGNMATRIX_H_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Mon Sep 26 18:43:45 2011 for CRyptography And Groups (CRAG) by  doxygen 1.6.1