Changeset eab750 in git for kernel/linearAlgebra.cc
- Timestamp:
- Dec 9, 2010, 12:13:25 PM (13 years ago)
- Branches:
- (u'spielwiese', 'ec94ef7a30b928574c0c3daf41f6804dff5f6b69')
- Children:
- 3fb0d8d38e07506f46e1c32801b0861beba179eb
- Parents:
- 2f576cb8b610abaf157d16c4105e083322176057
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/linearAlgebra.cc
r2f576cb reab750 1270 1270 int n = (int)pDeg(f0); 1271 1271 int m = (int)pDeg(g0); 1272 matrix fMat = mpNew(n + 1, d + 1); /* fMat[i, j] is the coefficient of 1273 x^(j-1) * y^(i-1) in f */ 1274 matrix gMat = mpNew(m + 1, d + 1); /* gMat[i, j] is the coefficient of 1275 x^(j-1) * y^(i-1) in g */ 1276 matrix hMat = mpNew(n + m, d + 1); /* hMat[i, j] is the coefficient of 1277 x^(j-1) * y^(i-1) in h */ 1272 matrix aMat = mpNew(n + m, n + m); /* matrix A for linear system */ 1273 matrix pMat; matrix lMat; matrix uMat; /* for the decomposition of A */ 1274 f = pCopy(f0); g = pCopy(g0); /* initially: h = f*g mod <x^1> */ 1278 1275 1279 /* initial step: read off coefficients of f0, g0, and h */ 1280 poly l = f0; 1281 while (l != NULL) 1282 { 1283 int e = pGetExp(l, yIndex); 1284 number c = pGetCoeff(l); 1285 poly matEntry = pOne(); pSetCoeff(matEntry, nCopy(c)); 1286 MATELEM(fMat, e + 1, 1) = matEntry; 1287 l = pNext(l); 1288 } 1289 l = g0; 1290 while (l != NULL) 1291 { 1292 int e = pGetExp(l, yIndex); 1293 number c = pGetCoeff(l); 1294 poly matEntry = pOne(); pSetCoeff(matEntry, nCopy(c)); 1295 MATELEM(gMat, e + 1, 1) = matEntry; 1296 l = pNext(l); 1297 } 1298 l = h; 1299 while (l != NULL) 1300 { 1301 int eX = pGetExp(l, xIndex); 1302 if (eX <= d) /* we forget about terms with x-exponents > d */ 1303 { 1304 int eY = pGetExp(l, yIndex); 1305 if (eY <= n + m - 1) /* we forget about the leading term y^(n + m) */ 1306 { 1307 number c = pGetCoeff(l); 1308 poly matEntry = pOne(); pSetCoeff(matEntry, nCopy(c)); 1309 MATELEM(hMat, eY + 1, eX + 1) = matEntry; 1310 } 1311 } 1312 l = pNext(l); 1313 } 1276 /* initial step: read off coefficients of f0, and g0 */ 1277 poly p = f0; poly matEntry; number c; 1278 while (p != NULL) 1279 { 1280 c = nCopy(pGetCoeff(p)); 1281 matEntry = pOne(); pSetCoeff(matEntry, c); 1282 MATELEM(aMat, pGetExp(p, yIndex) + 1, 1) = matEntry; 1283 p = pNext(p); 1284 } 1285 p = g0; 1286 while (p != NULL) 1287 { 1288 c = nCopy(pGetCoeff(p)); 1289 matEntry = pOne(); pSetCoeff(matEntry, c); 1290 MATELEM(aMat, pGetExp(p, yIndex) + 1, m + 1) = matEntry; 1291 p = pNext(p); 1292 } 1293 /* fill the rest of A */ 1294 for (int row = 2; row <= n + 1; row++) 1295 for (int col = 2; col <= m; col++) 1296 { 1297 if (col > row) break; 1298 MATELEM(aMat, row, col) = pCopy(MATELEM(aMat, row - 1, col - 1)); 1299 } 1300 for (int row = n + 2; row <= n + m; row++) 1301 for (int col = row - n; col <= m; col++) 1302 MATELEM(aMat, row, col) = pCopy(MATELEM(aMat, row - 1, col - 1)); 1303 for (int row = 2; row <= n + 1; row++) 1304 for (int col = m + 2; col <= m + n; col++) 1305 { 1306 if (col - m > row) break; 1307 MATELEM(aMat, row, col) = pCopy(MATELEM(aMat, row - 1, col - 1)); 1308 } 1309 for (int row = n + 2; row <= n + m; row++) 1310 for (int col = m + row - n; col <= m + n; col++) 1311 MATELEM(aMat, row, col) = pCopy(MATELEM(aMat, row - 1, col - 1)); 1314 1312 1315 /* loop for computing entries of fMat and gMat in columns 2..(d+1) 1316 which correspond to the x-exponents 1..d */ 1313 /* constructing the LU-decomposition of A */ 1314 luDecomp(aMat, pMat, lMat, uMat); 1315 1316 /* Before the xExp-th loop, we know that h = f*g mod <x^xExp>. 1317 Afterwards the algorithm ensures h = f*g mod <x^(xExp + 1)>. 1318 Hence in the end we obtain f and g as required, i.e., 1319 h = f*g mod <x^(d+1)>. 1320 The algorithm works by solving a (m+n)x(m+n) linear equation system 1321 A*x = b with constant matrix A (as decomposed above). By theory, the 1322 system is guaranteed to have a unique solution. */ 1317 1323 for (int xExp = 1; xExp <= d; xExp++) 1318 1324 { 1319 /* We are going to setup and solve a linear equation system A * x = b, 1320 where the resulting x will give us all matrix entries fMat[i, xExp], 1321 i = 1, 2, ..., n; and gMat[j, xExp], j = 1, 2, ..., m. 1322 (Theory ensures that the system is uniquely solvable.) */ 1323 matrix aMat = mpNew(n + m, n + m); /* A */ 1325 matrix bVec = mpNew(n + m, 1); /* b */ 1324 1326 matrix xVec = mpNew(n + m, 1); /* x */ 1325 matrix bVec = mpNew(n + m, 1); /* b */1326 1327 1327 /* setup b */ 1328 bool isZeroVector = true; 1329 for (int row = 1; row <= n + m; row++) 1330 { 1331 poly p = pCopy(MATELEM(hMat, row, xExp + 1)); 1332 for (int j = 1; j <= row; j++) 1333 { 1334 if (j > m + 1) break; 1335 if (row + 1 - j <= n + 1) 1328 p = ppMult_qq(f, g); 1329 p = pAdd(pCopy(h), pNeg(p)); /* p = h - f*g */ 1330 /* we collect all terms in p with x-exponent = xExp and use their 1331 coefficients to build the vector b */ 1332 int bIsZeroVector = true; 1333 while (p != NULL) 1334 { 1335 if (pGetExp(p, xIndex) == xExp) 1336 { 1337 number c = nCopy(pGetCoeff(p)); 1338 poly matEntry = pOne(); pSetCoeff(matEntry, c); 1339 MATELEM(bVec, pGetExp(p, yIndex) + 1, 1) = matEntry; 1340 if (matEntry != NULL) bIsZeroVector = false; 1341 } 1342 pLmDelete(&p); /* destruct leading term of p and move to next term */ 1343 } 1344 /* solve the linear equation system */ 1345 if (!bIsZeroVector) /* otherwise x = 0 and f, g do not change */ 1346 { 1347 matrix notUsedMat; 1348 luSolveViaLUDecomp(pMat, lMat, uMat, bVec, xVec, notUsedMat); 1349 idDelete((ideal*)¬UsedMat); 1350 /* augment f and g by newly computed terms */ 1351 for (int row = 1; row <= m; row++) 1352 { 1353 if (MATELEM(xVec, row, 1) != NULL) 1336 1354 { 1337 for (int i = 1; i <= xExp + 1; i++) 1338 { 1339 poly q = ppMult_qq(MATELEM(fMat, row + 1 - j, xExp + 2 - i), 1340 MATELEM(gMat, j, i)); 1341 q = pNeg(q); 1342 p = pAdd(p, q); 1343 } 1355 p = pCopy(MATELEM(xVec, row, 1)); /* p = c */ 1356 pSetExp(p, xIndex, xExp); /* p = c * x^xExp */ 1357 pSetExp(p, yIndex, row - 1); /* p = c * x^xExp * y^i */ 1358 pSetm(p); 1359 g = pAdd(g, p); 1344 1360 } 1345 1361 } 1346 MATELEM(bVec, row, 1) = p; 1347 if (p != NULL) isZeroVector = false; 1348 } 1349 1350 /* setup A (only if b is not the zero vector) */ 1351 if (!isZeroVector) 1352 { 1353 for (int row = 1; row <= n + m; row++) 1354 { 1355 int k = row; 1356 for (int col = 1; col <= n; col++) 1362 for (int row = m + 1; row <= m + n; row++) 1363 { 1364 if (MATELEM(xVec, row, 1) != NULL) 1357 1365 { 1358 if (k <= m + 1) MATELEM(aMat, row, col) = pCopy(MATELEM(gMat, k, 1)); 1359 k--; 1360 if (k == 0) break; 1366 p = pCopy(MATELEM(xVec, row, 1)); /* p = c */ 1367 pSetExp(p, xIndex, xExp); /* p = c * x^xExp */ 1368 pSetExp(p, yIndex, row - m - 1); /* p = c * x^xExp * y^i */ 1369 pSetm(p); 1370 f = pAdd(f, p); 1361 1371 } 1362 k = row; 1363 for (int col = n + 1; col <= n + m; col++) 1364 { 1365 if (k <= n + 1) MATELEM(aMat, row, col) = pCopy(MATELEM(fMat, k, 1)); 1366 k--; 1367 if (k == 0) break; 1368 } 1369 } 1370 } 1371 1372 /* computation of x */ 1373 if (!isZeroVector) 1374 { 1375 matrix pMat; matrix lMat; matrix uMat; matrix wMat; 1376 luDecomp(aMat, pMat, lMat, uMat); 1377 luSolveViaLUDecomp(pMat, lMat, uMat, bVec, xVec, wMat); 1378 idDelete((ideal*)&pMat); idDelete((ideal*)&lMat); 1379 idDelete((ideal*)&uMat); idDelete((ideal*)&wMat); 1380 } 1381 1382 /* fill (xExp + 1)-columns of fMat and gMat */ 1383 for (int row = 1; row <= n; row++) 1384 MATELEM(fMat, row, xExp + 1) = pCopy(MATELEM(xVec, row, 1)); 1385 for (int row = 1; row <= m; row++) 1386 MATELEM(gMat, row, xExp + 1) = pCopy(MATELEM(xVec, n + row, 1)); 1387 1388 /* clean-up */ 1389 idDelete((ideal*)&aMat); idDelete((ideal*)&xVec); idDelete((ideal*)&bVec); 1390 } 1391 1392 /* build f and g from fMat and gMat, respectively */ 1393 f = NULL; 1394 for (int i = 0; i <= n; i++) 1395 for (int j = 0; j <= d; j++) 1396 { 1397 poly term = pCopy(MATELEM(fMat, i + 1, j + 1)); // coeff 1398 if (term != NULL) 1399 { 1400 pSetExp(term, xIndex, j); // ... * x^j 1401 pSetExp(term, yIndex, i); // ... * y^i 1402 pSetm(term); 1403 f = pAdd(f, term); 1404 } 1405 } 1406 g = NULL; 1407 for (int i = 0; i <= m; i++) 1408 for (int j = 0; j <= d; j++) 1409 { 1410 poly term = pCopy(MATELEM(gMat, i + 1, j + 1)); // coeff 1411 if (term != NULL) 1412 { 1413 pSetExp(term, xIndex, j); // ... * x^j 1414 pSetExp(term, yIndex, i); // ... * y^i 1415 pSetm(term); 1416 g = pAdd(g, term); 1417 } 1418 } 1372 } 1373 } 1374 /* clean-up loop-dependent vectors */ 1375 idDelete((ideal*)&bVec); idDelete((ideal*)&xVec); 1376 } 1419 1377 1420 /* clean-up */ 1421 idDelete((ideal*)&fMat); 1422 idDelete((ideal*)&gMat); 1423 idDelete((ideal*)&hMat); 1424 } 1425 1378 /* clean-up matrices A, P, L and U */ 1379 idDelete((ideal*)&aMat); idDelete((ideal*)&pMat); 1380 idDelete((ideal*)&lMat); idDelete((ideal*)&uMat); 1381 } 1382
Note: See TracChangeset
for help on using the changeset viewer.