00001
00002
00003
00004
00005
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
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
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
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
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
00124 for(unsigned int j = 0; j < INTERNAL_SIZE; j++)
00125 SignMatrix::mask1 = (SignMatrix::mask1 << 2) | 1;
00126 mask2 = mask1 << 1;
00127
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;
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;
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 << ((t % INTERNAL_SIZE) * 2));
00287 matrix[t / INTERNAL_SIZE] |= (val & 3) << ((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 << ((t % INTERNAL_SIZE) * 2));
00295 matrix[t / INTERNAL_SIZE] |= (val & 3) << ((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
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
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
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
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
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
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
00626 free();
00627
00628 numRows = mat.numRows;
00629 numCols = colList.size();
00630 maxNumRows = mat.maxNumRows;
00631 maxNumCols = numCols;
00632
00633 rowHdrs.resize(maxNumRows);
00634
00635 firstUnusedRow = mat.firstUnusedRow;
00636 for(unsigned int i = 0; i < maxNumRows; i++)
00637
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
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
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
00667 memcpy(matrix + i * (maxNumRows / INTERNAL_SIZE), mat.matrix + iter->colid * (mat.maxNumRows / INTERNAL_SIZE), (maxNumRows / INTERNAL_SIZE) * sizeof(INTERNAL_TYPE));
00668
00669 colHdrs[i].used = true;
00670
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
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
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
00730
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
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
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
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
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
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