Changeset 19bf86 in git for kernel/linearAlgebra.cc
- Timestamp:
- Jun 21, 2010, 1:20:59 PM (14 years ago)
- Branches:
- (u'spielwiese', 'fe61d9c35bf7c61f2b6cbf1b56e25e2f08d536cc')
- Children:
- e3cc9c88085d8e217de6a163ac2bc7d891c19815
- Parents:
- e558c41b132228287898863201fbd5c35b4231fd
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/linearAlgebra.cc
re558c41 r19bf86 103 103 for (int r = 1; r <= rr; r++) MATELEM(lMat, r, r) = pOne(); 104 104 105 int bestR; int bestC; int intSwap; poly pSwap; 105 int bestR; int bestC; int intSwap; poly pSwap; int cOffset = 0; 106 106 for (int r = 1; r < rr; r++) 107 107 { 108 if ((r <= cc) && (pivot(uMat, r, rr, r, r, &bestR, &bestC))) 108 if (r > cc) break; 109 while ((r + cOffset <= cc) && 110 (!pivot(uMat, r, rr, r + cOffset, r + cOffset, &bestR, &bestC))) 111 cOffset++; 112 if (r + cOffset <= cc) 109 113 { 110 114 /* swap rows with indices r and bestR in permut */ … … 114 118 115 119 /* swap rows with indices r and bestR in uMat; 116 it is sufficient to do this for columns >= r */117 for (int c = r ; c <= cc; c++)120 it is sufficient to do this for columns >= r + cOffset*/ 121 for (int c = r + cOffset; c <= cc; c++) 118 122 { 119 123 pSwap = MATELEM(uMat, r, c); … … 134 138 row with index r; 135 139 we need to adjust lMat and uMat; 136 we are certain that the matrix entry at [r, r] is non-zero: */ 137 number pivotElement = pGetCoeff(MATELEM(uMat, r, r)); 140 we are certain that the matrix entry at [r, r + cOffset] 141 is non-zero: */ 142 number pivotElement = pGetCoeff(MATELEM(uMat, r, r + cOffset)); 138 143 poly p; number n; 139 144 for (int rGauss = r + 1; rGauss <= rr; rGauss++) 140 145 { 141 p = MATELEM(uMat, rGauss, r );146 p = MATELEM(uMat, rGauss, r + cOffset); 142 147 if (p != NULL) 143 148 { … … 149 154 150 155 /* adjusting uMat: */ 151 MATELEM(uMat, rGauss, r ) = NULL; pDelete(&p);156 MATELEM(uMat, rGauss, r + cOffset) = NULL; pDelete(&p); 152 157 n = nNeg(n); 153 for (int cGauss = r + 1; cGauss <= cc; cGauss++)158 for (int cGauss = r + cOffset + 1; cGauss <= cc; cGauss++) 154 159 MATELEM(uMat, rGauss, cGauss) 155 160 = pAdd(MATELEM(uMat, rGauss, cGauss), … … 316 321 return result; 317 322 } 323 324 bool luSolveViaLUDecomp(const matrix pMat, const matrix lMat, 325 const matrix uMat, const matrix bVec, 326 matrix &xVec, int* dim) 327 { 328 int m = uMat->rows(); int n = uMat->cols(); 329 matrix cVec = mpNew(m, 1); /* for storing pMat * bVec */ 330 matrix yVec = mpNew(m, 1); /* for storing the unique solution of 331 lMat * yVec = cVec */ 332 333 /* compute cVec = pMat * bVec but without actual multiplications */ 334 for (int r = 1; r <= m; r++) 335 { 336 for (int c = 1; c <= m; c++) 337 { 338 if (MATELEM(pMat, r, c) != NULL) 339 { MATELEM(cVec, r, 1) = pCopy(MATELEM(bVec, c, 1)); break; } 340 } 341 } 342 343 /* solve lMat * yVec = cVec; this will always work as lMat is invertible; 344 moreover, no divisions are needed, since lMat[i, i] = 1, for all i */ 345 for (int r = 1; r <= m; r++) 346 { 347 poly p = pNeg(pCopy(MATELEM(cVec, r, 1))); 348 for (int c = 1; c < r; c++) 349 p = pAdd(p, ppMult_qq(MATELEM(lMat, r, c), MATELEM(yVec, c, 1) )); 350 MATELEM(yVec, r, 1) = pNeg(p); 351 } 352 353 /* determine whether uMat * xVec = yVec is solvable */ 354 bool isSolvable = true; 355 bool isZeroRow; int nonZeroRowIndex; 356 for (int r = m; r >= 1; r--) 357 { 358 isZeroRow = true; 359 for (int c = 1; c <= n; c++) 360 if (MATELEM(uMat, r, c) != NULL) { isZeroRow = false; break; } 361 if (isZeroRow) 362 { 363 if (MATELEM(yVec, r, 1) != NULL) { isSolvable = false; break; } 364 } 365 else { nonZeroRowIndex = r; break; } 366 } 367 368 if (isSolvable) 369 { 370 xVec = mpNew(n, 1); *dim = 0; 371 /* solve uMat * xVec = yVec and determine the dimension of the affine 372 solution space */ 373 int nonZeroC; int lastNonZeroC = n + 1; 374 for (int r = nonZeroRowIndex; r >= 1; r--) 375 { 376 for (nonZeroC = 1; nonZeroC <= n; nonZeroC++) 377 if (MATELEM(uMat, r, nonZeroC) != NULL) break; 378 *dim = *dim + lastNonZeroC - nonZeroC - 1; 379 poly p = pNeg(pCopy(MATELEM(yVec, r, 1))); 380 for (int c = nonZeroC + 1; c <= n; c++) 381 if (MATELEM(xVec, c, 1) != NULL) 382 p = pAdd(p, ppMult_qq(MATELEM(uMat, r, c), MATELEM(xVec, c, 1))); 383 poly q = pNSet(nInvers(pGetCoeff(MATELEM(uMat, r, nonZeroC)))); 384 MATELEM(xVec, nonZeroC, 1) = pMult(pNeg(p), q); 385 lastNonZeroC = nonZeroC; 386 } 387 } 388 389 idDelete((ideal*)&cVec); 390 idDelete((ideal*)&yVec); 391 392 return isSolvable; 393 }
Note: See TracChangeset
for help on using the changeset viewer.