Changeset eab750 in git for kernel/linearAlgebra.cc


Ignore:
Timestamp:
Dec 9, 2010, 12:13:25 PM (13 years ago)
Author:
Frank Seelisch <seelisch@…>
Branches:
(u'spielwiese', 'ec94ef7a30b928574c0c3daf41f6804dff5f6b69')
Children:
3fb0d8d38e07506f46e1c32801b0861beba179eb
Parents:
2f576cb8b610abaf157d16c4105e083322176057
Message:
speed-up of Hensel's lemma impl. by idea of Santiago

git-svn-id: file:///usr/local/Singular/svn/trunk@13746 2c84dea3-7e68-4137-9b89-c4e89433aadc
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/linearAlgebra.cc

    r2f576cb reab750  
    12701270  int n = (int)pDeg(f0);
    12711271  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> */
    12781275 
    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));
    13141312 
    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. */
    13171323  for (int xExp = 1; xExp <= d; xExp++)
    13181324  {
    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 */
    13241326    matrix xVec = mpNew(n + m, 1);     /* x */
    1325     matrix bVec = mpNew(n + m, 1);     /* b */
    13261327   
    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*)&notUsedMat);
     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)
    13361354        {
    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);
    13441360        }
    13451361      }
    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)
    13571365        {
    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);
    13611371        }
    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  }
    14191377 
    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.