Changeset 08daea in git
- Timestamp:
- Nov 22, 2010, 11:12:46 AM (13 years ago)
- Branches:
- (u'spielwiese', '0d6b7fcd9813a1ca1ed4220cfa2b104b97a0a003')
- Children:
- fb8ba2756f35787214f1a0b5702e31e4b853de97
- Parents:
- cde7084dc141670809afd29cafbd9c571bd9fc3a
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
Singular/tesths.cc
rcde708 r08daea 55 55 //On(SW_USE_FF_MOD_GCD); 56 56 //On(SW_USE_fieldGCD); 57 O ff(SW_USE_EZGCD_P);57 On(SW_USE_EZGCD_P); 58 58 On(SW_USE_QGCD); 59 59 Off(SW_USE_NTL_SORT); // may be changed by an command line option -
factory/cf_gcd.cc
rcde708 r08daea 566 566 else if (isOn( SW_USE_EZGCD_P ) && (!fc_and_gc_Univariate)) 567 567 { 568 if ( pe == 1 )568 /*if ( pe == 1 ) 569 569 fc = fin_ezgcd( fc, gc ); 570 570 else if ( pe > 0 )// no variable at position 1 … … 580 580 gc = swapvar( gc, Variable(pe), Variable(1) ); 581 581 fc = swapvar( fin_ezgcd( fc, gc ), Variable(1), Variable(pe) ); 582 } 582 }*/ 583 fc= EZGCD_P (fc, gc); 583 584 } 584 585 else if (isOn(SW_USE_GCD_P)) -
factory/cf_gcd_smallp.cc
rcde708 r08daea 30 30 #include "ftmpl_functions.h" 31 31 #include "cf_random.h" 32 #include "ffreval.h" 33 #include "facHensel.h" 32 34 33 35 // iinline helper functions: … … 46 48 TIMING_DEFINE_PRINT(newton_interpolation); 47 49 50 static const double log2exp= 1.442695041; 51 48 52 /// compressing two polynomials F and G, M is used for compressing, 49 53 /// N to reverse the compression 50 54 static inline 51 55 int myCompress (const CanonicalForm& F, const CanonicalForm& G, CFMap & M, 52 CFMap & N, bool &topLevel)56 CFMap & N, bool topLevel) 53 57 { 54 58 int n= tmax (F.level(), G.level()); … … 205 209 return 1; 206 210 } 211 207 212 208 213 int … … 1359 1364 } 1360 1365 1366 CFArray 1367 solveVandermonde (const CFArray& M, const CFArray& A) 1368 { 1369 int r= M.size(); 1370 ASSERT (A.size() == r, "vector does not have right size"); 1371 1372 if (r == 1) 1373 { 1374 CFArray result= CFArray (1); 1375 result [0]= A [0] / M [0]; 1376 return result; 1377 } 1378 // check solvability 1379 bool notDistinct= false; 1380 for (int i= 0; i < r - 1; i++) 1381 { 1382 for (int j= i + 1; j < r; j++) 1383 { 1384 if (M [i] == M [j]) 1385 { 1386 notDistinct= true; 1387 break; 1388 } 1389 } 1390 } 1391 if (notDistinct) 1392 return CFArray(); 1393 1394 CanonicalForm master= 1; 1395 Variable x= Variable (1); 1396 for (int i= 0; i < r; i++) 1397 master *= x - M [i]; 1398 CFList Pj; 1399 CanonicalForm tmp; 1400 for (int i= 0; i < r; i++) 1401 { 1402 tmp= master/(x - M [i]); 1403 tmp /= tmp (M [i], 1); 1404 Pj.append (tmp); 1405 } 1406 CFArray result= CFArray (r); 1407 1408 CFListIterator j= Pj; 1409 for (int i= 1; i <= r; i++, j++) 1410 { 1411 tmp= 0; 1412 for (int l= 0; l < A.size(); l++) 1413 tmp += A[l]*j.getItem()[l]; 1414 result[i - 1]= tmp; 1415 } 1416 return result; 1417 } 1418 1419 CFArray 1420 solveGeneralVandermonde (const CFArray& M, const CFArray& A) 1421 { 1422 int r= M.size(); 1423 ASSERT (c == r, "number of columns and rows not equal"); 1424 ASSERT (A.size() == r, "vector does not have right size"); 1425 if (r == 1) 1426 { 1427 CFArray result= CFArray (1); 1428 result [0]= A[0] / M [0]; 1429 return result; 1430 } 1431 // check solvability 1432 bool notDistinct= false; 1433 for (int i= 0; i < r - 1; i++) 1434 { 1435 for (int j= i + 1; j < r; j++) 1436 { 1437 if (M [i] == M [j]) 1438 { 1439 notDistinct= true; 1440 break; 1441 } 1442 } 1443 } 1444 if (notDistinct) 1445 return CFArray(); 1446 1447 CanonicalForm master= 1; 1448 Variable x= Variable (1); 1449 for (int i= 0; i < r; i++) 1450 master *= x - M [i]; 1451 master *= x; 1452 CFList Pj; 1453 CanonicalForm tmp; 1454 for (int i= 0; i < r; i++) 1455 { 1456 tmp= master/(x - M [i]); 1457 tmp /= tmp (M [i], 1); 1458 Pj.append (tmp); 1459 } 1460 1461 CFArray result= CFArray (r); 1462 1463 CFListIterator j= Pj; 1464 for (int i= 1; i <= r; i++, j++) 1465 { 1466 tmp= 0; 1467 1468 for (int l= 1; l <= A.size(); l++) 1469 tmp += A[l - 1]*j.getItem()[l]; 1470 result[i - 1]= tmp; 1471 } 1472 return result; 1473 } 1474 1475 /// M in row echolon form, rk rank of M 1476 CFArray 1477 readOffSolution (const CFMatrix& M, const long rk) 1478 { 1479 CFArray result= CFArray (rk); 1480 CanonicalForm tmp1, tmp2, tmp3; 1481 for (int i= rk; i >= 1; i--) 1482 { 1483 tmp3= 0; 1484 tmp1= M (i, M.columns()); 1485 for (int j= M.columns() - 1; j >= 1; j--) 1486 { 1487 tmp2= M (i, j); 1488 if (j == i) 1489 break; 1490 else 1491 tmp3 += tmp2*result[j - 1]; 1492 } 1493 result[i - 1]= (tmp1 - tmp3)/tmp2; 1494 } 1495 return result; 1496 } 1497 1498 CFArray 1499 readOffSolution (const CFMatrix& M, const CFArray& L, const CFArray& partialSol) 1500 { 1501 CFArray result= CFArray (M.rows()); 1502 CanonicalForm tmp1, tmp2, tmp3; 1503 int k; 1504 for (int i= M.rows(); i >= 1; i--) 1505 { 1506 tmp3= 0; 1507 tmp1= L[i - 1]; 1508 k= 0; 1509 for (int j= M.columns(); j >= 1; j--, k++) 1510 { 1511 tmp2= M (i, j); 1512 if (j == i) 1513 break; 1514 else 1515 { 1516 if (k > partialSol.size() - 1) 1517 tmp3 += tmp2*result[j - 1]; 1518 else 1519 tmp3 += tmp2*partialSol[partialSol.size() - k - 1]; 1520 } 1521 } 1522 result [i - 1]= (tmp1 - tmp3)/tmp2; 1523 } 1524 return result; 1525 } 1526 1527 long 1528 gaussianElimFp (CFMatrix& M, CFArray& L) 1529 { 1530 ASSERT (L.size() <= M.rows(), "dimension exceeded"); 1531 CFMatrix *N; 1532 N= new CFMatrix (M.rows(), M.columns() + 1); 1533 1534 for (int i= 1; i <= M.rows(); i++) 1535 for (int j= 1; j <= M.columns(); j++) 1536 (*N) (i, j)= M (i, j); 1537 1538 int j= 1; 1539 for (int i= 0; i < L.size(); i++, j++) 1540 (*N) (j, M.columns() + 1)= L[i]; 1541 int p= getCharacteristic (); 1542 zz_p::init (p); 1543 mat_zz_p *NTLN= convertFacCFMatrix2NTLmat_zz_p(*N); 1544 long rk= gauss (*NTLN); 1545 1546 N= convertNTLmat_zz_p2FacCFMatrix (*NTLN); 1547 1548 L= CFArray (M.rows()); 1549 for (int i= 0; i < M.rows(); i++) 1550 L[i]= (*N) (i + 1, M.columns() + 1); 1551 M= (*N) (1, M.rows(), 1, M.columns()); 1552 return rk; 1553 } 1554 1555 long 1556 gaussianElimFq (CFMatrix& M, CFArray& L, const Variable& alpha) 1557 { 1558 ASSERT (L.size() <= M.rows(), "dimension exceeded"); 1559 CFMatrix *N; 1560 N= new CFMatrix (M.rows(), M.columns() + 1); 1561 1562 for (int i= 1; i <= M.rows(); i++) 1563 for (int j= 1; j <= M.columns(); j++) 1564 (*N) (i, j)= M (i, j); 1565 1566 int j= 1; 1567 for (int i= 0; i < L.size(); i++, j++) 1568 (*N) (j, M.columns() + 1)= L[i]; 1569 int p= getCharacteristic (); 1570 zz_p::init (p); 1571 zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo (alpha)); 1572 zz_pE::init (NTLMipo); 1573 mat_zz_pE *NTLN= convertFacCFMatrix2NTLmat_zz_pE(*N); 1574 long rk= gauss (*NTLN); 1575 1576 N= convertNTLmat_zz_pE2FacCFMatrix (*NTLN, alpha); 1577 1578 M= (*N) (1, M.rows(), 1, M.columns()); 1579 L= CFArray (M.rows()); 1580 for (int i= 0; i < M.rows(); i++) 1581 L[i]= (*N) (i + 1, M.columns() + 1); 1582 return rk; 1583 } 1584 1585 CFArray 1586 solveSystemFp (const CFMatrix& M, const CFArray& L) 1587 { 1588 ASSERT (L.size() <= M.rows(), "dimension exceeded"); 1589 CFMatrix *N; 1590 N= new CFMatrix (M.rows(), M.columns() + 1); 1591 1592 for (int i= 1; i <= M.rows(); i++) 1593 for (int j= 1; j <= M.columns(); j++) 1594 (*N) (i, j)= M (i, j); 1595 1596 int j= 1; 1597 for (int i= 0; i < L.size(); i++, j++) 1598 (*N) (j, M.columns() + 1)= L[i]; 1599 int p= getCharacteristic (); 1600 zz_p::init (p); 1601 mat_zz_p *NTLN= convertFacCFMatrix2NTLmat_zz_p(*N); 1602 long rk= gauss (*NTLN); 1603 if (rk != M.columns()) 1604 return CFArray(); 1605 1606 N= convertNTLmat_zz_p2FacCFMatrix (*NTLN); 1607 1608 CFArray A= readOffSolution (*N, rk); 1609 1610 return A; 1611 } 1612 1613 CFArray 1614 solveSystemFq (const CFMatrix& M, const CFArray& L, const Variable& alpha) 1615 { 1616 ASSERT (L.size() <= M.rows(), "dimension exceeded"); 1617 CFMatrix *N; 1618 N= new CFMatrix (M.rows(), M.columns() + 1); 1619 1620 for (int i= 1; i <= M.rows(); i++) 1621 for (int j= 1; j <= M.columns(); j++) 1622 (*N) (i, j)= M (i, j); 1623 int j= 1; 1624 for (int i= 0; i < L.size(); i++, j++) 1625 (*N) (j, M.columns() + 1)= L[i]; 1626 int p= getCharacteristic (); 1627 zz_p::init (p); 1628 zz_pX NTLMipo= convertFacCF2NTLzzpX (getMipo (alpha)); 1629 zz_pE::init (NTLMipo); 1630 mat_zz_pE *NTLN= convertFacCFMatrix2NTLmat_zz_pE(*N); 1631 long rk= gauss (*NTLN); 1632 if (rk != M.columns()) 1633 return CFArray(); 1634 1635 N= convertNTLmat_zz_pE2FacCFMatrix (*NTLN, alpha); 1636 1637 CFArray A= readOffSolution (*N, rk); 1638 1639 return A; 1640 } 1641 1642 CFArray 1643 getMonoms (const CanonicalForm& F) 1644 { 1645 if (F.inCoeffDomain()) 1646 { 1647 CFArray result= CFArray (1); 1648 result [0]= 1; 1649 return result; 1650 } 1651 if (F.isUnivariate()) 1652 { 1653 CFArray result= CFArray (size(F)); 1654 int j= 0; 1655 for (CFIterator i= F; i.hasTerms(); i++, j++) 1656 result[j]= power (F.mvar(), i.exp()); 1657 return result; 1658 } 1659 int numMon= size (F); 1660 CFArray result= CFArray (numMon); 1661 int j= 0; 1662 CFArray recResult; 1663 Variable x= F.mvar(); 1664 CanonicalForm powX; 1665 for (CFIterator i= F; i.hasTerms(); i++) 1666 { 1667 powX= power (x, i.exp()); 1668 recResult= getMonoms (i.coeff()); 1669 for (int k= 0; k < recResult.size(); k++) 1670 result[j+k]= powX*recResult[k]; 1671 j += recResult.size(); 1672 } 1673 return result; 1674 } 1675 1676 CFArray 1677 evaluateMonom (const CanonicalForm& F, const CFList& evalPoints) 1678 { 1679 if (F.inCoeffDomain()) 1680 { 1681 CFArray result= CFArray (1); 1682 result [0]= F; 1683 return result; 1684 } 1685 if (F.isUnivariate()) 1686 { 1687 ASSERT (evalPoints.length() == 1, 1688 "expected an eval point with only one component"); 1689 CFArray result= CFArray (size(F)); 1690 int j= 0; 1691 CanonicalForm evalPoint= evalPoints.getLast(); 1692 for (CFIterator i= F; i.hasTerms(); i++, j++) 1693 result[j]= power (evalPoint, i.exp()); 1694 return result; 1695 } 1696 int numMon= size (F); 1697 CFArray result= CFArray (numMon); 1698 int j= 0; 1699 CanonicalForm evalPoint= evalPoints.getLast(); 1700 CFList buf= evalPoints; 1701 buf.removeLast(); 1702 CFArray recResult; 1703 CanonicalForm powEvalPoint; 1704 for (CFIterator i= F; i.hasTerms(); i++) 1705 { 1706 powEvalPoint= power (evalPoint, i.exp()); 1707 recResult= evaluateMonom (i.coeff(), buf); 1708 for (int k= 0; k < recResult.size(); k++) 1709 result[j+k]= powEvalPoint*recResult[k]; 1710 j += recResult.size(); 1711 } 1712 return result; 1713 } 1714 1715 CFArray 1716 evaluate (const CFArray& A, const CFList& evalPoints) 1717 { 1718 CFArray result= A.size(); 1719 CanonicalForm tmp; 1720 int k; 1721 for (int i= 0; i < A.size(); i++) 1722 { 1723 tmp= A[i]; 1724 k= 1; 1725 for (CFListIterator j= evalPoints; j.hasItem(); j++, k++) 1726 tmp= tmp (j.getItem(), k); 1727 result[i]= tmp; 1728 } 1729 return result; 1730 } 1731 1732 CFList 1733 evaluationPoints (const CanonicalForm& F, const CanonicalForm& G, 1734 CanonicalForm& Feval, CanonicalForm& Geval, 1735 const CanonicalForm& LCF, const bool& GF, 1736 const Variable& alpha, bool& fail, CFList& list 1737 ) 1738 { 1739 int k= tmax (F.level(), G.level()) - 1; 1740 Variable x= Variable (1); 1741 CFList result; 1742 FFRandom genFF; 1743 GFRandom genGF; 1744 int p= getCharacteristic (); 1745 int bound; 1746 if (alpha != Variable (1)) 1747 { 1748 bound= ipower (p, degree (getMipo(alpha))); 1749 bound= ipower (bound, k); 1750 } 1751 else if (GF) 1752 { 1753 bound= ipower (p, getGFDegree()); 1754 bound= ipower (bound, k); 1755 } 1756 else 1757 bound= ipower (p, k); 1758 1759 CanonicalForm random; 1760 int j; 1761 bool zeroOneOccured= false; 1762 bool allEqual= false; 1763 CanonicalForm buf; 1764 do 1765 { 1766 random= 0; 1767 // possible overflow if list.length() does not fit into a int 1768 if (list.length() >= bound) 1769 { 1770 fail= true; 1771 break; 1772 } 1773 for (int i= 0; i < k; i++) 1774 { 1775 if (GF) 1776 { 1777 result.append (genGF.generate()); 1778 random += result.getLast()*power (x, i); 1779 } 1780 else if (alpha != Variable(1)) 1781 { 1782 AlgExtRandomF genAlgExt (alpha); 1783 result.append (genAlgExt.generate()); 1784 random += result.getLast()*power (x, i); 1785 } 1786 else 1787 { 1788 result.append (genFF.generate()); 1789 random += result.getLast()*power (x, i); 1790 } 1791 if (result.getLast().isOne() || result.getLast().isZero()) 1792 zeroOneOccured= true; 1793 } 1794 if (find (list, random)) 1795 { 1796 zeroOneOccured= false; 1797 allEqual= false; 1798 result= CFList(); 1799 continue; 1800 } 1801 if (zeroOneOccured) 1802 { 1803 list.append (random); 1804 zeroOneOccured= false; 1805 allEqual= false; 1806 result= CFList(); 1807 continue; 1808 } 1809 // no zero at this point 1810 if (k > 1) 1811 { 1812 allEqual= true; 1813 CFIterator iter= random; 1814 buf= iter.coeff(); 1815 iter++; 1816 for (; iter.hasTerms(); iter++) 1817 if (buf != iter.coeff()) 1818 allEqual= false; 1819 } 1820 if (allEqual) 1821 { 1822 list.append (random); 1823 allEqual= false; 1824 zeroOneOccured= false; 1825 result= CFList(); 1826 continue; 1827 } 1828 1829 Feval= F; 1830 Geval= G; 1831 CanonicalForm LCeval= LCF; 1832 j= 1; 1833 for (CFListIterator i= result; i.hasItem(); i++, j++) 1834 { 1835 Feval= Feval (i.getItem(), j); 1836 Geval= Geval (i.getItem(), j); 1837 LCeval= LCeval (i.getItem(), j); 1838 } 1839 1840 if (LCeval.isZero()) 1841 { 1842 if (!find (list, random)) 1843 list.append (random); 1844 zeroOneOccured= false; 1845 allEqual= false; 1846 result= CFList(); 1847 continue; 1848 } 1849 1850 if (list.length() >= bound) 1851 { 1852 fail= true; 1853 break; 1854 } 1855 } while (find (list, random)); 1856 1857 return result; 1858 } 1859 1860 /// multiply two lists componentwise 1861 void mult (CFList& L1, const CFList& L2) 1862 { 1863 ASSERT (L1.length() == L2.length(), "lists of the same size expected"); 1864 1865 CFListIterator j= L2; 1866 for (CFListIterator i= L1; i.hasItem(); i++, j++) 1867 i.getItem() *= j.getItem(); 1868 } 1869 1870 void eval (const CanonicalForm& A, const CanonicalForm& B, CanonicalForm& Aeval, 1871 CanonicalForm& Beval, const CFList& L) 1872 { 1873 Aeval= A; 1874 Beval= B; 1875 int j= 1; 1876 for (CFListIterator i= L; i.hasItem(); i++, j++) 1877 { 1878 Aeval= Aeval (i.getItem(), j); 1879 Beval= Beval (i.getItem(), j); 1880 } 1881 } 1882 1883 CanonicalForm 1884 monicSparseInterpol (const CanonicalForm& F, const CanonicalForm& G, 1885 const CanonicalForm& skeleton, const Variable& alpha, 1886 bool& fail, CFArray*& coeffMonoms, CFArray& Monoms 1887 ) 1888 { 1889 CanonicalForm A= F; 1890 CanonicalForm B= G; 1891 if (F.isZero() && degree(G) > 0) return G/Lc(G); 1892 else if (G.isZero() && degree (F) > 0) return F/Lc(F); 1893 else if (F.isZero() && G.isZero()) return F.genOne(); 1894 if (F.inBaseDomain() || G.inBaseDomain()) return F.genOne(); 1895 if (F.isUnivariate() && fdivides(F, G)) return F/Lc(F); 1896 if (G.isUnivariate() && fdivides(G, F)) return G/Lc(G); 1897 if (F == G) return F/Lc(F); 1898 1899 CFMap M,N; 1900 int best_level= myCompress (A, B, M, N, false); 1901 1902 if (best_level == 0) 1903 return B.genOne(); 1904 1905 A= M(A); 1906 B= M(B); 1907 1908 Variable x= Variable (1); 1909 ASSERT (degree (A, y) == 0, "expected degree (F, 1) == 0"); 1910 ASSERT (degree (B, y) == 0, "expected degree (G, 1) == 0"); 1911 1912 //univariate case 1913 if (A.isUnivariate() && B.isUnivariate()) 1914 return N (gcd (A, B)); 1915 1916 CanonicalForm skel= M(skeleton); 1917 CanonicalForm cA, cB; // content of A and B 1918 CanonicalForm ppA, ppB; // primitive part of A and B 1919 CanonicalForm gcdcAcB; 1920 cA = uni_content (A); 1921 cB = uni_content (B); 1922 gcdcAcB= gcd (cA, cB); 1923 ppA= A/cA; 1924 ppB= B/cB; 1925 1926 CanonicalForm lcA, lcB; // leading coefficients of A and B 1927 CanonicalForm gcdlcAlcB; 1928 lcA= uni_lcoeff (ppA); 1929 lcB= uni_lcoeff (ppB); 1930 1931 if (fdivides (lcA, lcB)) 1932 { 1933 if (fdivides (A, B)) 1934 return F/Lc(F); 1935 } 1936 if (fdivides (lcB, lcA)) 1937 { 1938 if (fdivides (B, A)) 1939 return G/Lc(G); 1940 } 1941 1942 gcdlcAlcB= gcd (lcA, lcB); 1943 int skelSize= size (skel, skel.mvar()); 1944 1945 int j= 0; 1946 int biggestSize= 0; 1947 1948 for (CFIterator i= skel; i.hasTerms(); i++, j++) 1949 biggestSize= tmax (biggestSize, size (i.coeff())); 1950 1951 CanonicalForm g, Aeval, Beval; 1952 1953 CFList evalPoints; 1954 bool evalFail= false; 1955 CFList list; 1956 bool GF= false; 1957 CanonicalForm LCA= LC (A); 1958 CanonicalForm tmp; 1959 CFArray gcds= CFArray (biggestSize); 1960 CFList * pEvalPoints= new CFList [biggestSize]; 1961 Variable V_buf= alpha; 1962 CFList source, dest; 1963 CanonicalForm prim_elem, im_prim_elem; 1964 for (int i= 0; i < biggestSize; i++) 1965 { 1966 if (i == 0) 1967 evalPoints= evaluationPoints (A, B, Aeval, Beval, LCA, GF, V_buf, evalFail, 1968 list); 1969 else 1970 { 1971 mult (evalPoints, pEvalPoints [0]); 1972 eval (A, B, Aeval, Beval, evalPoints); 1973 } 1974 1975 if (evalFail) 1976 { 1977 if (V_buf != Variable (1)) 1978 { 1979 do 1980 { 1981 int num_vars= tmin (getNumVars(A), getNumVars(B)); 1982 int d= totaldegree (A, Variable(2), Variable (A.level())); 1983 d= tmin (d, totaldegree (B, Variable(2), Variable (B.level()))); 1984 Variable V_buf2= V_buf; 1985 choose_extension (d, num_vars, V_buf2); 1986 source= CFList(); 1987 dest= CFList(); 1988 1989 bool prim_fail= false; 1990 Variable V_buf3; 1991 prim_elem= primitiveElement (V_buf, V_buf3, prim_fail); 1992 1993 ASSERT (!prim_fail, "failure in integer factorizer"); 1994 if (prim_fail) 1995 ; //ERROR 1996 else 1997 im_prim_elem= mapPrimElem (prim_elem, V_buf, V_buf2); 1998 1999 DEBOUTLN (cerr, "getMipo (alpha)= " << getMipo (V_buf)); 2000 DEBOUTLN (cerr, "getMipo (alpha)= " << getMipo (V_buf2)); 2001 2002 for (CFListIterator j= list; j.hasItem(); j++) 2003 j.getItem()= mapUp (j.getItem(), V_buf, V_buf2, prim_elem, 2004 im_prim_elem, source, dest); 2005 for (int k= 0; k < i; k++) 2006 { 2007 for (CFListIterator j= pEvalPoints[k]; j.hasItem(); j++) 2008 j.getItem()= mapUp (j.getItem(), V_buf, V_buf2, prim_elem, 2009 im_prim_elem, source, dest); 2010 gcds[k]= mapUp (gcds[k], V_buf, V_buf2, prim_elem, im_prim_elem, 2011 source, dest); 2012 } 2013 2014 if (alpha != Variable (1)) 2015 { 2016 A= mapUp (A, V_buf, V_buf2, prim_elem, im_prim_elem, source,dest); 2017 B= mapUp (B, V_buf, V_buf2, prim_elem, im_prim_elem, source,dest); 2018 } 2019 evalFail= false; 2020 evalPoints= evaluationPoints (A, B, Aeval, Beval, LCA, GF, V_buf, 2021 evalFail, list); 2022 } while (evalFail); 2023 } 2024 else 2025 { 2026 CanonicalForm mipo; 2027 int deg= 2; 2028 do { 2029 mipo= randomIrredpoly (deg, x); 2030 V_buf= rootOf (mipo); 2031 evalFail= false; 2032 evalPoints= evaluationPoints (A, B, Aeval, Beval, LCA, GF, V_buf, 2033 evalFail, list); 2034 deg++; 2035 } while (evalFail); 2036 } 2037 } 2038 2039 g= gcd (Aeval, Beval); 2040 g /= Lc (g); 2041 2042 if (degree (g) != degree (skel) || (skelSize != size (g))) 2043 { 2044 delete[] pEvalPoints; 2045 fail= true; 2046 return 0; 2047 } 2048 CFIterator l= skel; 2049 for (CFIterator k= g; k.hasTerms(); k++, l++) 2050 { 2051 if (k.exp() != l.exp()) 2052 { 2053 delete[] pEvalPoints; 2054 fail= true; 2055 return 0; 2056 } 2057 } 2058 pEvalPoints[i]= evalPoints; 2059 gcds[i]= g; 2060 2061 tmp= 0; 2062 int j= 0; 2063 for (CFListIterator k= evalPoints; k.hasItem(); k++, j++) 2064 tmp += k.getItem()*power (x, j); 2065 list.append (tmp); 2066 } 2067 2068 if (Monoms.size() == 0) 2069 Monoms= getMonoms (skel); 2070 if (coeffMonoms == NULL) 2071 coeffMonoms= new CFArray [skelSize]; 2072 j= 0; 2073 for (CFIterator i= skel; i.hasTerms(); i++, j++) 2074 coeffMonoms[j]= getMonoms (i.coeff()); 2075 2076 CFArray* pL= new CFArray [skelSize]; 2077 CFArray* pM= new CFArray [skelSize]; 2078 for (int i= 0; i < biggestSize; i++) 2079 { 2080 CFIterator l= gcds [i]; 2081 evalPoints= pEvalPoints [i]; 2082 for (int k= 0; k < skelSize; k++, l++) 2083 { 2084 if (i == 0) 2085 pL[k]= CFArray (biggestSize); 2086 pL[k] [i]= l.coeff(); 2087 2088 if (i == 0) 2089 pM[k]= evaluate (coeffMonoms [k], evalPoints); 2090 } 2091 } 2092 2093 CFArray solution; 2094 CanonicalForm result= 0; 2095 int ind= 0; 2096 CFArray bufArray; 2097 CFMatrix Mat; 2098 for (int k= 0; k < skelSize; k++) 2099 { 2100 if (biggestSize != coeffMonoms[k].size()) 2101 { 2102 bufArray= CFArray (coeffMonoms[k].size()); 2103 for (int i= 0; i < coeffMonoms[k].size(); i++) 2104 bufArray [i]= pL[k] [i]; 2105 solution= solveGeneralVandermonde (pM [k], bufArray); 2106 } 2107 else 2108 solution= solveGeneralVandermonde (pM [k], pL[k]); 2109 2110 if (solution.size() == 0) 2111 { 2112 delete[] pEvalPoints; 2113 delete[] pM; 2114 delete[] pL; 2115 delete[] coeffMonoms; 2116 fail= true; 2117 return 0; 2118 } 2119 for (int l= 0; l < solution.size(); l++) 2120 result += solution[l]*Monoms [ind + l]; 2121 ind += solution.size(); 2122 } 2123 2124 delete[] pEvalPoints; 2125 delete[] pM; 2126 delete[] pL; 2127 2128 if (alpha != Variable (1) && V_buf != alpha) 2129 { 2130 CFList u, v; 2131 result= mapDown (result, prim_elem, im_prim_elem, alpha, u, v); 2132 } 2133 2134 result= N(result); 2135 if (fdivides (result, F) && fdivides (result, G)) 2136 return result; 2137 else 2138 { 2139 delete[] coeffMonoms; 2140 fail= true; 2141 return 0; 2142 } 2143 } 2144 2145 CanonicalForm 2146 nonMonicSparseInterpol (const CanonicalForm& F, const CanonicalForm& G, 2147 const CanonicalForm& skeleton, const Variable& alpha, 2148 bool& fail, CFArray*& coeffMonoms, CFArray& Monoms 2149 ) 2150 { 2151 CanonicalForm A= F; 2152 CanonicalForm B= G; 2153 if (F.isZero() && degree(G) > 0) return G/Lc(G); 2154 else if (G.isZero() && degree (F) > 0) return F/Lc(F); 2155 else if (F.isZero() && G.isZero()) return F.genOne(); 2156 if (F.inBaseDomain() || G.inBaseDomain()) return F.genOne(); 2157 if (F.isUnivariate() && fdivides(F, G)) return F/Lc(F); 2158 if (G.isUnivariate() && fdivides(G, F)) return G/Lc(G); 2159 if (F == G) return F/Lc(F); 2160 2161 CFMap M,N; 2162 int best_level= myCompress (A, B, M, N, false); 2163 2164 if (best_level == 0) 2165 return B.genOne(); 2166 2167 A= M(A); 2168 B= M(B); 2169 2170 Variable x= Variable (1); 2171 ASSERT (degree (A, y) == 0, "expected degree (F, 1) == 0"); 2172 ASSERT (degree (B, y) == 0, "expected degree (G, 1) == 0"); 2173 2174 //univariate case 2175 if (A.isUnivariate() && B.isUnivariate()) 2176 return N (gcd (A, B)); 2177 2178 CanonicalForm skel= M(skeleton); 2179 2180 CanonicalForm cA, cB; // content of A and B 2181 CanonicalForm ppA, ppB; // primitive part of A and B 2182 CanonicalForm gcdcAcB; 2183 cA = uni_content (A); 2184 cB = uni_content (B); 2185 gcdcAcB= gcd (cA, cB); 2186 ppA= A/cA; 2187 ppB= B/cB; 2188 2189 CanonicalForm lcA, lcB; // leading coefficients of A and B 2190 CanonicalForm gcdlcAlcB; 2191 lcA= uni_lcoeff (ppA); 2192 lcB= uni_lcoeff (ppB); 2193 2194 if (fdivides (lcA, lcB)) 2195 { 2196 if (fdivides (A, B)) 2197 return F/Lc(F); 2198 } 2199 if (fdivides (lcB, lcA)) 2200 { 2201 if (fdivides (B, A)) 2202 return G/Lc(G); 2203 } 2204 2205 gcdlcAlcB= gcd (lcA, lcB); 2206 int skelSize= size (skel, skel.mvar()); 2207 2208 int j= 0; 2209 int biggestSize= 0; 2210 int bufSize; 2211 int numberUni= 0; 2212 for (CFIterator i= skel; i.hasTerms(); i++, j++) 2213 { 2214 bufSize= size (i.coeff()); 2215 biggestSize= tmax (biggestSize, bufSize); 2216 numberUni += bufSize; 2217 } 2218 numberUni--; 2219 numberUni= (int) ceil ( (double) numberUni / (skelSize - 1)); 2220 biggestSize= tmax (biggestSize , numberUni); 2221 2222 numberUni= biggestSize + size (LC(skel)) - 1; 2223 int biggestSize2= tmax (numberUni, biggestSize); 2224 2225 CanonicalForm g, Aeval, Beval; 2226 2227 CFList evalPoints; 2228 CFArray coeffEval; 2229 bool evalFail= false; 2230 CFList list; 2231 bool GF= false; 2232 CanonicalForm LCA= LC (A); 2233 CanonicalForm tmp; 2234 CFArray gcds= CFArray (biggestSize); 2235 CFList * pEvalPoints= new CFList [biggestSize]; 2236 Variable V_buf= alpha; 2237 CFList source, dest; 2238 CanonicalForm prim_elem, im_prim_elem; 2239 for (int i= 0; i < biggestSize; i++) 2240 { 2241 if (i == 0) 2242 { 2243 if (getCharacteristic() > 3) 2244 evalPoints= evaluationPoints (A, B, Aeval, Beval, LCA, GF, V_buf, 2245 evalFail, list); 2246 else 2247 evalFail= true; 2248 2249 if (evalFail) 2250 { 2251 if (V_buf != Variable (1)) 2252 { 2253 do 2254 { 2255 int num_vars= tmin (getNumVars(A), getNumVars(B)); 2256 int d= totaldegree (A, Variable(2), Variable (A.level())); 2257 d= tmin (d, totaldegree (B, Variable(2), Variable (B.level()))); 2258 Variable V_buf2= V_buf; 2259 choose_extension (d, num_vars, V_buf2); 2260 source= CFList(); 2261 dest= CFList(); 2262 2263 bool prim_fail= false; 2264 Variable V_buf3; 2265 prim_elem= primitiveElement (V_buf, V_buf3, prim_fail); 2266 2267 ASSERT (!prim_fail, "failure in integer factorizer"); 2268 if (prim_fail) 2269 ; //ERROR 2270 else 2271 im_prim_elem= mapPrimElem (prim_elem, V_buf, V_buf2); 2272 2273 DEBOUTLN (cerr, "getMipo (alpha)= " << getMipo (V_buf)); 2274 DEBOUTLN (cerr, "getMipo (alpha)= " << getMipo (V_buf2)); 2275 2276 for (CFListIterator i= list; i.hasItem(); i++) 2277 i.getItem()= mapUp (i.getItem(), V_buf, V_buf2, prim_elem, 2278 im_prim_elem, source, dest); 2279 evalFail= false; 2280 evalPoints= evaluationPoints (A, B, Aeval, Beval, LCA, GF, V_buf, 2281 evalFail, list); 2282 } while (evalFail); 2283 } 2284 else 2285 { 2286 CanonicalForm mipo; 2287 int deg= 2; 2288 do { 2289 mipo= randomIrredpoly (deg, x); 2290 V_buf= rootOf (mipo); 2291 evalFail= false; 2292 evalPoints= evaluationPoints (A, B, Aeval, Beval, LCA, GF, V_buf, 2293 evalFail, list); 2294 deg++; 2295 } while (evalFail); 2296 } 2297 } 2298 } 2299 else 2300 { 2301 mult (evalPoints, pEvalPoints[0]); 2302 eval (A, B, Aeval, Beval, evalPoints); 2303 } 2304 2305 g= gcd (Aeval, Beval); 2306 g /= Lc (g); 2307 2308 if (degree (g) != degree (skel) || (skelSize != size (g))) 2309 { 2310 delete[] pEvalPoints; 2311 fail= true; 2312 return 0; 2313 } 2314 CFIterator l= skel; 2315 for (CFIterator k= g; k.hasTerms(); k++, l++) 2316 { 2317 if (k.exp() != l.exp()) 2318 { 2319 delete[] pEvalPoints; 2320 fail= true; 2321 return 0; 2322 } 2323 } 2324 pEvalPoints[i]= evalPoints; 2325 gcds[i]= g; 2326 2327 tmp= 0; 2328 int j= 0; 2329 for (CFListIterator k= evalPoints; k.hasItem(); k++, j++) 2330 tmp += k.getItem()*power (x, j); 2331 list.append (tmp); 2332 } 2333 2334 if (Monoms.size() == 0) 2335 Monoms= getMonoms (skel); 2336 2337 if (coeffMonoms == NULL) 2338 coeffMonoms= new CFArray [skelSize]; 2339 2340 j= 0; 2341 for (CFIterator i= skel; i.hasTerms(); i++, j++) 2342 coeffMonoms[j]= getMonoms (i.coeff()); 2343 2344 int minimalColumnsIndex; 2345 if (skelSize > 1) 2346 minimalColumnsIndex= 1; 2347 else 2348 minimalColumnsIndex= 0; 2349 int minimalColumns; 2350 2351 CFArray* pM= new CFArray [skelSize]; 2352 CFMatrix Mat; 2353 // find the Matrix with minimal number of columns 2354 for (int i= 0; i < skelSize; i++) 2355 { 2356 pM[i]= CFArray (coeffMonoms[i].size()); 2357 if (i == 1) 2358 minimalColumns= coeffMonoms[i].size(); 2359 if (i > 1) 2360 { 2361 if (minimalColumns > coeffMonoms[i].size()) 2362 { 2363 minimalColumns= coeffMonoms[i].size(); 2364 minimalColumnsIndex= i; 2365 } 2366 } 2367 } 2368 CFMatrix* pMat= new CFMatrix [2]; 2369 pMat[0]= CFMatrix (biggestSize, coeffMonoms[0].size()); 2370 pMat[1]= CFMatrix (biggestSize, coeffMonoms[minimalColumnsIndex].size()); 2371 CFArray* pL= new CFArray [skelSize]; 2372 for (int i= 0; i < biggestSize; i++) 2373 { 2374 CFIterator l= gcds [i]; 2375 evalPoints= pEvalPoints [i]; 2376 for (int k= 0; k < skelSize; k++, l++) 2377 { 2378 if (i == 0) 2379 pL[k]= CFArray (biggestSize); 2380 pL[k] [i]= l.coeff(); 2381 2382 if (i == 0 && k != 0 && k != minimalColumnsIndex) 2383 pM[k]= evaluate (coeffMonoms[k], evalPoints); 2384 else if (i == 0 && (k == 0 || k == minimalColumnsIndex)) 2385 coeffEval= evaluate (coeffMonoms[k], evalPoints); 2386 if (i > 0 && (k == 0 || k == minimalColumnsIndex)) 2387 coeffEval= evaluate (coeffMonoms[k], evalPoints); 2388 2389 if (k == 0) 2390 { 2391 if (pMat[k].rows() >= i + 1) 2392 { 2393 for (int ind= 1; ind < coeffEval.size() + 1; ind++) 2394 pMat[k] (i + 1, ind)= coeffEval[ind - 1]; 2395 } 2396 } 2397 if (k == minimalColumnsIndex) 2398 { 2399 if (pMat[1].rows() >= i + 1) 2400 { 2401 for (int ind= 1; ind < coeffEval.size() + 1; ind++) 2402 pMat[1] (i + 1, ind)= coeffEval[ind - 1]; 2403 } 2404 } 2405 } 2406 } 2407 2408 CFArray solution; 2409 CanonicalForm result= 0; 2410 int ind= 1; 2411 int matRows, matColumns; 2412 matRows= pMat[1].rows(); 2413 matColumns= pMat[0].columns() - 1; 2414 matColumns += pMat[1].columns(); 2415 2416 Mat= CFMatrix (matRows, matColumns); 2417 for (int i= 1; i <= matRows; i++) 2418 for (int j= 1; j <= pMat[1].columns(); j++) 2419 Mat (i, j)= pMat[1] (i, j); 2420 2421 for (int j= pMat[1].columns() + 1; j <= matColumns; 2422 j++, ind++) 2423 { 2424 for (int i= 1; i <= matRows; i++) 2425 Mat (i, j)= (-pMat [0] (i, ind + 1))*pL[minimalColumnsIndex] [i - 1]; 2426 } 2427 2428 CFArray firstColumn= CFArray (pMat[0].rows()); 2429 for (int i= 0; i < pMat[0].rows(); i++) 2430 firstColumn [i]= pMat[0] (i + 1, 1); 2431 2432 CFArray bufArray= pL[minimalColumnsIndex]; 2433 2434 for (int i= 0; i < biggestSize; i++) 2435 pL[minimalColumnsIndex] [i] *= firstColumn[i]; 2436 2437 CFMatrix bufMat= pMat[1]; 2438 pMat[1]= Mat; 2439 2440 if (V_buf != x) 2441 solution= solveSystemFq (pMat[1], 2442 pL[minimalColumnsIndex], V_buf); 2443 else 2444 solution= solveSystemFp (pMat[1], 2445 pL[minimalColumnsIndex]); 2446 2447 if (solution.size() == 0) 2448 { //Javadi's method failed, try deKleine, Monagan, Wittkopf instead 2449 CFMatrix bufMat0= pMat[0]; 2450 delete [] pMat; 2451 pMat= new CFMatrix [skelSize]; 2452 pL[minimalColumnsIndex]= bufArray; 2453 CFList* bufpEvalPoints; 2454 CFArray bufGcds; 2455 if (biggestSize != biggestSize2) 2456 { 2457 bufpEvalPoints= pEvalPoints; 2458 pEvalPoints= new CFList [biggestSize2]; 2459 bufGcds= gcds; 2460 gcds= CFArray (biggestSize2); 2461 for (int i= 0; i < biggestSize; i++) 2462 { 2463 pEvalPoints[i]= bufpEvalPoints [i]; 2464 gcds[i]= bufGcds[i]; 2465 } 2466 for (int i= 0; i < biggestSize2 - biggestSize; i++) 2467 { 2468 mult (evalPoints, pEvalPoints[0]); 2469 eval (A, B, Aeval, Beval, evalPoints); 2470 g= gcd (Aeval, Beval); 2471 g /= Lc (g); 2472 if (degree (g) != degree (skel) || (skelSize != size (g))) 2473 { 2474 delete[] pEvalPoints; 2475 delete[] pMat; 2476 delete[] pL; 2477 delete[] coeffMonoms; 2478 delete[] pM; 2479 fail= true; 2480 return 0; 2481 } 2482 CFIterator l= skel; 2483 for (CFIterator k= g; k.hasTerms(); k++, l++) 2484 { 2485 if (k.exp() != l.exp()) 2486 { 2487 delete[] pEvalPoints; 2488 delete[] pMat; 2489 delete[] pL; 2490 delete[] coeffMonoms; 2491 delete[] pM; 2492 fail= true; 2493 return 0; 2494 } 2495 } 2496 pEvalPoints[i + biggestSize]= evalPoints; 2497 gcds[i + biggestSize]= g; 2498 } 2499 } 2500 for (int i= 0; i < biggestSize; i++) 2501 { 2502 CFIterator l= gcds [i]; 2503 evalPoints= pEvalPoints [i]; 2504 for (int k= 1; k < skelSize; k++, l++) 2505 { 2506 if (i == 0) 2507 pMat[k]= CFMatrix (biggestSize2,coeffMonoms[k].size()+biggestSize2-1); 2508 if (k == minimalColumnsIndex) 2509 continue; 2510 coeffEval= evaluate (coeffMonoms[k], evalPoints); 2511 if (pMat[k].rows() >= i + 1) 2512 { 2513 for (int ind= 1; ind < coeffEval.size() + 1; ind++) 2514 pMat[k] (i + 1, ind)= coeffEval[ind - 1]; 2515 } 2516 } 2517 } 2518 Mat= bufMat0; 2519 pMat[0]= CFMatrix (biggestSize2, coeffMonoms[0].size() + biggestSize2 - 1); 2520 for (int j= 1; j <= Mat.rows(); j++) 2521 for (int k= 1; k <= Mat.columns(); k++) 2522 pMat [0] (j,k)= Mat (j,k); 2523 Mat= bufMat; 2524 for (int j= 1; j <= Mat.rows(); j++) 2525 for (int k= 1; k <= Mat.columns(); k++) 2526 pMat [minimalColumnsIndex] (j,k)= Mat (j,k); 2527 // write old matrix entries into new matrices 2528 for (int i= 0; i < skelSize; i++) 2529 { 2530 bufArray= pL[i]; 2531 pL[i]= CFArray (biggestSize2); 2532 for (int j= 0; j < bufArray.size(); j++) 2533 pL[i] [j]= bufArray [j]; 2534 } 2535 //write old vector entries into new and add new entries to old matrices 2536 for (int i= 0; i < biggestSize2 - biggestSize; i++) 2537 { 2538 CFIterator l= gcds [i + biggestSize]; 2539 evalPoints= pEvalPoints [i + biggestSize]; 2540 for (int k= 0; k < skelSize; k++, l++) 2541 { 2542 pL[k] [i + biggestSize]= l.coeff(); 2543 coeffEval= evaluate (coeffMonoms[k], evalPoints); 2544 if (pMat[k].rows() >= i + biggestSize + 1) 2545 { 2546 for (int ind= 1; ind < coeffEval.size() + 1; ind++) 2547 pMat[k] (i + biggestSize + 1, ind)= coeffEval[ind - 1]; 2548 } 2549 } 2550 } 2551 // begin new 2552 for (int i= 0; i < skelSize; i++) 2553 { 2554 if (pL[i].size() > 1) 2555 { 2556 for (int j= 2; j <= pMat[i].rows(); j++) 2557 pMat[i] (j, coeffMonoms[i].size() + j - 1)= 2558 -pL[i] [j - 1]; 2559 } 2560 } 2561 2562 long rk; 2563 matColumns= biggestSize2 - 1; 2564 matRows= 0; 2565 for (int i= 0; i < skelSize; i++) 2566 { 2567 if (V_buf == x) 2568 rk= gaussianElimFp (pMat[i], pL[i]); 2569 else 2570 rk= gaussianElimFq (pMat[i], pL[i], V_buf); 2571 2572 if (pMat[i] (coeffMonoms[i].size(), coeffMonoms[i].size()) == 0) 2573 { 2574 delete[] pEvalPoints; 2575 delete[] pMat; 2576 delete[] pL; 2577 delete[] coeffMonoms; 2578 delete[] pM; 2579 fail= true; 2580 return 0; 2581 } 2582 matRows += pMat[i].rows() - coeffMonoms[i].size(); 2583 } 2584 2585 CFMatrix bufMat; 2586 Mat= CFMatrix (matRows, matColumns); 2587 ind= 0; 2588 bufArray= CFArray (matRows); 2589 CFArray bufArray2; 2590 for (int i= 0; i < skelSize; i++) 2591 { 2592 bufMat= pMat[i] (coeffMonoms[i].size() + 1, pMat[i].rows(), 2593 coeffMonoms[i].size() + 1, pMat[i].columns()); 2594 2595 for (int j= 1; j <= bufMat.rows(); j++) 2596 for (int k= 1; k <= bufMat.columns(); k++) 2597 Mat (j + ind, k)= bufMat(j, k); 2598 bufArray2= coeffMonoms[i].size(); 2599 for (int j= 1; j <= pMat[i].rows(); j++) 2600 { 2601 if (j > coeffMonoms[i].size()) 2602 bufArray [j-coeffMonoms[i].size() + ind - 1]= pL[i] [j - 1]; 2603 else 2604 bufArray2 [j - 1]= pL[i] [j - 1]; 2605 } 2606 pL[i]= bufArray2; 2607 ind += bufMat.rows(); 2608 pMat[i]= pMat[i] (1, coeffMonoms[i].size(), 1, pMat[i].columns()); 2609 } 2610 2611 if (V_buf != x) 2612 solution= solveSystemFq (Mat, bufArray, V_buf); 2613 else 2614 solution= solveSystemFp (Mat, bufArray); 2615 2616 if (solution.size() == 0) 2617 { 2618 delete[] pEvalPoints; 2619 delete[] pMat; 2620 delete[] pL; 2621 delete[] coeffMonoms; 2622 delete[] pM; 2623 fail= true; 2624 return 0; 2625 } 2626 2627 ind= 0; 2628 result= 0; 2629 CFArray bufSolution; 2630 for (int i= 0; i < skelSize; i++) 2631 { 2632 bufSolution= readOffSolution (pMat[i], pL[i], solution); 2633 for (int i= 0; i < bufSolution.size(); i++, ind++) 2634 result += Monoms [ind]*bufSolution[i]; 2635 } 2636 if (alpha != Variable (1) && V_buf != alpha) 2637 { 2638 CFList u, v; 2639 result= mapDown (result, prim_elem, im_prim_elem, alpha, u, v); 2640 } 2641 result= N(result); 2642 if (fdivides (result, F) && fdivides (result, G)) 2643 return result; 2644 else 2645 { 2646 fail= true; 2647 return 0; 2648 } 2649 } // end of deKleine, Monagan & Wittkopf 2650 2651 result += Monoms[0]; 2652 int ind2= 0, ind3= 2; 2653 ind= 0; 2654 for (int l= 0; l < minimalColumnsIndex; l++) 2655 ind += coeffMonoms[l].size(); 2656 for (int l= solution.size() - pMat[0].columns() + 1; l < solution.size(); 2657 l++, ind2++, ind3++) 2658 { 2659 result += solution[l]*Monoms [1 + ind2]; 2660 for (int i= 0; i < pMat[0].rows(); i++) 2661 firstColumn[i] += solution[l]*pMat[0] (i + 1, ind3); 2662 } 2663 for (int l= 0; l < solution.size() + 1 - pMat[0].columns(); l++) 2664 result += solution[l]*Monoms [ind + l]; 2665 ind= coeffMonoms[0].size(); 2666 for (int k= 1; k < skelSize; k++) 2667 { 2668 if (k == minimalColumnsIndex) 2669 { 2670 ind += coeffMonoms[k].size(); 2671 continue; 2672 } 2673 if (k != minimalColumnsIndex) 2674 { 2675 for (int i= 0; i < biggestSize; i++) 2676 pL[k] [i] *= firstColumn [i]; 2677 } 2678 2679 if (biggestSize != coeffMonoms[k].size() && k != minimalColumnsIndex) 2680 { 2681 bufArray= CFArray (coeffMonoms[k].size()); 2682 for (int i= 0; i < bufArray.size(); i++) 2683 bufArray [i]= pL[k] [i]; 2684 solution= solveGeneralVandermonde (pM[k], bufArray); 2685 } 2686 else 2687 solution= solveGeneralVandermonde (pM[k], pL[k]); 2688 2689 if (solution.size() == 0) 2690 { 2691 delete[] pEvalPoints; 2692 delete[] pMat; 2693 delete[] pL; 2694 delete[] coeffMonoms; 2695 delete[] pM; 2696 fail= true; 2697 return 0; 2698 } 2699 if (k != minimalColumnsIndex) 2700 { 2701 for (int l= 0; l < solution.size(); l++) 2702 result += solution[l]*Monoms [ind + l]; 2703 ind += solution.size(); 2704 } 2705 } 2706 2707 delete[] pEvalPoints; 2708 delete[] pMat; 2709 delete[] pL; 2710 delete[] pM; 2711 2712 if (alpha != Variable (1) && V_buf != alpha) 2713 { 2714 CFList u, v; 2715 result= mapDown (result, prim_elem, im_prim_elem, alpha, u, v); 2716 } 2717 result= N(result); 2718 2719 if (fdivides (result, F) && fdivides (result, G)) 2720 return result; 2721 else 2722 { 2723 delete[] coeffMonoms; 2724 fail= true; 2725 return 0; 2726 } 2727 } 2728 2729 CanonicalForm sparseGCDFq (const CanonicalForm& F, const CanonicalForm& G, 2730 const Variable & alpha, CFList& l, bool& topLevel) 2731 { 2732 CanonicalForm A= F; 2733 CanonicalForm B= G; 2734 if (F.isZero() && degree(G) > 0) return G/Lc(G); 2735 else if (G.isZero() && degree (F) > 0) return F/Lc(F); 2736 else if (F.isZero() && G.isZero()) return F.genOne(); 2737 if (F.inBaseDomain() || G.inBaseDomain()) return F.genOne(); 2738 if (F.isUnivariate() && fdivides(F, G)) return F/Lc(F); 2739 if (G.isUnivariate() && fdivides(G, F)) return G/Lc(G); 2740 if (F == G) return F/Lc(F); 2741 2742 CFMap M,N; 2743 int best_level= myCompress (A, B, M, N, topLevel); 2744 2745 if (best_level == 0) return B.genOne(); 2746 2747 A= M(A); 2748 B= M(B); 2749 2750 Variable x= Variable (1); 2751 2752 //univariate case 2753 if (A.isUnivariate() && B.isUnivariate()) 2754 return N (gcd (A, B)); 2755 2756 int substitute= substituteCheck (A, B); 2757 2758 if (substitute > 1) 2759 subst (A, B, A, B, substitute); 2760 2761 CanonicalForm cA, cB; // content of A and B 2762 CanonicalForm ppA, ppB; // primitive part of A and B 2763 CanonicalForm gcdcAcB; 2764 if (topLevel) 2765 { 2766 if (best_level <= 2) 2767 gcdcAcB= extractContents (A, B, cA, cB, ppA, ppB, best_level); 2768 else 2769 gcdcAcB= extractContents (A, B, cA, cB, ppA, ppB, 2); 2770 } 2771 else 2772 { 2773 cA = uni_content (A); 2774 cB = uni_content (B); 2775 gcdcAcB= gcd (cA, cB); 2776 ppA= A/cA; 2777 ppB= B/cB; 2778 } 2779 2780 CanonicalForm lcA, lcB; // leading coefficients of A and B 2781 CanonicalForm gcdlcAlcB; 2782 lcA= uni_lcoeff (ppA); 2783 lcB= uni_lcoeff (ppB); 2784 2785 if (fdivides (lcA, lcB)) 2786 { 2787 if (fdivides (A, B)) 2788 return F/Lc(F); 2789 } 2790 if (fdivides (lcB, lcA)) 2791 { 2792 if (fdivides (B, A)) 2793 return G/Lc(G); 2794 } 2795 2796 gcdlcAlcB= gcd (lcA, lcB); 2797 2798 int d= totaldegree (ppA, Variable (2), Variable (ppA.level())); 2799 int d0; 2800 2801 if (d == 0) 2802 { 2803 if (substitute > 1) 2804 return N(reverseSubst (gcdcAcB, substitute)); 2805 else 2806 return N(gcdcAcB); 2807 } 2808 d0= totaldegree (ppB, Variable (2), Variable (ppB.level())); 2809 2810 if (d0 < d) 2811 d= d0; 2812 2813 if (d == 0) 2814 { 2815 if (substitute > 1) 2816 return N(reverseSubst (gcdcAcB, substitute)); 2817 else 2818 return N(gcdcAcB); 2819 } 2820 2821 CanonicalForm m, random_element, G_m, G_random_element, H, cH, ppH, skeleton; 2822 CanonicalForm newtonPoly= 1; 2823 m= gcdlcAlcB; 2824 G_m= 0; 2825 H= 0; 2826 bool fail= false; 2827 topLevel= false; 2828 bool inextension= false; 2829 Variable V_buf= alpha; 2830 CanonicalForm prim_elem, im_prim_elem; 2831 CFList source, dest; 2832 do // first do 2833 { 2834 random_element= randomElement (m, V_buf, l, fail); 2835 if (random_element == 0 && !fail) 2836 { 2837 if (!find (l, random_element)) 2838 l.append (random_element); 2839 continue; 2840 } 2841 if (fail) 2842 { 2843 source= CFList(); 2844 dest= CFList(); 2845 int num_vars= tmin (getNumVars(A), getNumVars(B)); 2846 num_vars--; 2847 2848 choose_extension (d, num_vars, V_buf); 2849 bool prim_fail= false; 2850 Variable V_buf2; 2851 prim_elem= primitiveElement (alpha, V_buf2, prim_fail); 2852 2853 ASSERT (!prim_fail, "failure in integer factorizer"); 2854 if (prim_fail) 2855 ; //ERROR 2856 else 2857 im_prim_elem= mapPrimElem (prim_elem, alpha, V_buf); 2858 2859 DEBOUTLN (cerr, "getMipo (alpha)= " << getMipo (alpha)); 2860 DEBOUTLN (cerr, "getMipo (V_buf2)= " << getMipo (V_buf2)); 2861 inextension= true; 2862 for (CFListIterator i= l; i.hasItem(); i++) 2863 i.getItem()= mapUp (i.getItem(), alpha, V_buf, prim_elem, 2864 im_prim_elem, source, dest); 2865 m= mapUp (m, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 2866 G_m= mapUp (G_m, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 2867 newtonPoly= mapUp (newtonPoly, alpha, V_buf, prim_elem, im_prim_elem, 2868 source, dest); 2869 ppA= mapUp (ppA, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 2870 ppB= mapUp (ppB, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 2871 gcdlcAlcB= mapUp (gcdlcAlcB, alpha, V_buf, prim_elem, im_prim_elem, 2872 source, dest); 2873 2874 fail= false; 2875 random_element= randomElement (m, V_buf, l, fail ); 2876 DEBOUTLN (cerr, "fail= " << fail); 2877 CFList list; 2878 TIMING_START (gcd_recursion); 2879 G_random_element= 2880 sparseGCDFq (ppA (random_element, x), ppB (random_element, x), V_buf, 2881 list, topLevel); 2882 TIMING_END_AND_PRINT (gcd_recursion, 2883 "time for recursive call: "); 2884 DEBOUTLN (cerr, "G_random_element= " << G_random_element); 2885 } 2886 else 2887 { 2888 CFList list; 2889 TIMING_START (gcd_recursion); 2890 G_random_element= 2891 sparseGCDFq (ppA(random_element, x), ppB(random_element, x), V_buf, 2892 list, topLevel); 2893 TIMING_END_AND_PRINT (gcd_recursion, 2894 "time for recursive call: "); 2895 DEBOUTLN (cerr, "G_random_element= " << G_random_element); 2896 } 2897 2898 d0= totaldegree (G_random_element, Variable(2), 2899 Variable (G_random_element.level())); 2900 if (d0 == 0) 2901 { 2902 if (substitute > 1) 2903 return N(reverseSubst (gcdcAcB, substitute)); 2904 else 2905 return N(gcdcAcB); 2906 } 2907 if (d0 > d) 2908 { 2909 if (!find (l, random_element)) 2910 l.append (random_element); 2911 continue; 2912 } 2913 2914 G_random_element= 2915 (gcdlcAlcB(random_element, x)/uni_lcoeff (G_random_element)) 2916 * G_random_element; 2917 2918 skeleton= G_random_element; 2919 d0= totaldegree (G_random_element, Variable(2), 2920 Variable(G_random_element.level())); 2921 if (d0 < d) 2922 { 2923 m= gcdlcAlcB; 2924 newtonPoly= 1; 2925 G_m= 0; 2926 d= d0; 2927 } 2928 2929 H= newtonInterp (random_element, G_random_element, newtonPoly, G_m, x); 2930 if (uni_lcoeff (H) == gcdlcAlcB) 2931 { 2932 cH= uni_content (H); 2933 ppH= H/cH; 2934 if (inextension) 2935 { 2936 CFList u, v; 2937 //maybe it's better to test if ppH is an element of F(\alpha) before 2938 //mapping down 2939 DEBOUTLN (cerr, "ppH before mapDown= " << ppH); 2940 ppH= mapDown (ppH, prim_elem, im_prim_elem, alpha, u, v); 2941 ppH /= Lc(ppH); 2942 DEBOUTLN (cerr, "ppH after mapDown= " << ppH); 2943 if (fdivides (ppH, A) && fdivides (ppH, B)) 2944 { 2945 if (substitute > 1) 2946 { 2947 ppH= reverseSubst (ppH, substitute); 2948 gcdcAcB= reverseSubst (gcdcAcB, substitute); 2949 } 2950 return N(gcdcAcB*ppH); 2951 } 2952 } 2953 else if (fdivides (ppH, A) && fdivides (ppH, B)) 2954 { 2955 if (substitute > 1) 2956 { 2957 ppH= reverseSubst (ppH, substitute); 2958 gcdcAcB= reverseSubst (gcdcAcB, substitute); 2959 } 2960 return N(gcdcAcB*ppH); 2961 } 2962 } 2963 G_m= H; 2964 newtonPoly= newtonPoly*(x - random_element); 2965 m= m*(x - random_element); 2966 if (!find (l, random_element)) 2967 l.append (random_element); 2968 2969 if (getCharacteristic () > 3 && size (skeleton) < 100 2970 || size (skeleton) < 10) 2971 { 2972 CFArray Monoms; 2973 CFArray *coeffMonoms= NULL; 2974 do //second do 2975 { 2976 random_element= randomElement (m, V_buf, l, fail); 2977 if (random_element == 0 && !fail) 2978 { 2979 if (!find (l, random_element)) 2980 l.append (random_element); 2981 continue; 2982 } 2983 if (fail) 2984 { 2985 source= CFList(); 2986 dest= CFList(); 2987 int num_vars= tmin (getNumVars(A), getNumVars(B)); 2988 num_vars--; 2989 2990 choose_extension (d, num_vars, V_buf); 2991 bool prim_fail= false; 2992 Variable V_buf2; 2993 prim_elem= primitiveElement (alpha, V_buf2, prim_fail); 2994 2995 ASSERT (!prim_fail, "failure in integer factorizer"); 2996 if (prim_fail) 2997 ; //ERROR 2998 else 2999 im_prim_elem= mapPrimElem (prim_elem, alpha, V_buf); 3000 3001 DEBOUTLN (cerr, "getMipo (alpha)= " << getMipo (alpha)); 3002 DEBOUTLN (cerr, "getMipo (V_buf2)= " << getMipo (V_buf2)); 3003 inextension= true; 3004 for (CFListIterator i= l; i.hasItem(); i++) 3005 i.getItem()= mapUp (i.getItem(), alpha, V_buf, prim_elem, 3006 im_prim_elem, source, dest); 3007 m= mapUp (m, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 3008 G_m= mapUp (G_m, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 3009 newtonPoly= mapUp (newtonPoly, alpha, V_buf, prim_elem, im_prim_elem, 3010 source, dest); 3011 ppA= mapUp (ppA, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 3012 ppB= mapUp (ppB, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 3013 3014 gcdlcAlcB= mapUp (gcdlcAlcB, alpha, V_buf, prim_elem, im_prim_elem, 3015 source, dest); 3016 3017 fail= false; 3018 random_element= randomElement (m, V_buf, l, fail); 3019 DEBOUTLN (cerr, "fail= " << fail); 3020 CFList list; 3021 TIMING_START (gcd_recursion); 3022 3023 //sparseInterpolation 3024 bool sparseFail= false; 3025 if (LC (skeleton).inCoeffDomain()) 3026 G_random_element= 3027 monicSparseInterpol (ppA (random_element, x), ppB(random_element,x), 3028 skeleton,V_buf, sparseFail, coeffMonoms,Monoms); 3029 else 3030 G_random_element= 3031 nonMonicSparseInterpol (ppA(random_element,x),ppB(random_element,x), 3032 skeleton, V_buf, sparseFail, coeffMonoms, 3033 Monoms); 3034 if (sparseFail) 3035 break; 3036 3037 TIMING_END_AND_PRINT (gcd_recursion, 3038 "time for recursive call: "); 3039 DEBOUTLN (cerr, "G_random_element= " << G_random_element); 3040 } 3041 else 3042 { 3043 CFList list; 3044 TIMING_START (gcd_recursion); 3045 bool sparseFail= false; 3046 if (LC (skeleton).inCoeffDomain()) 3047 G_random_element= 3048 monicSparseInterpol (ppA (random_element, x),ppB(random_element, x), 3049 skeleton,V_buf, sparseFail,coeffMonoms, Monoms); 3050 else 3051 G_random_element= 3052 nonMonicSparseInterpol (ppA(random_element,x),ppB(random_element,x), 3053 skeleton, V_buf, sparseFail, coeffMonoms, 3054 Monoms); 3055 if (sparseFail) 3056 break; 3057 3058 TIMING_END_AND_PRINT (gcd_recursion, 3059 "time for recursive call: "); 3060 DEBOUTLN (cerr, "G_random_element= " << G_random_element); 3061 } 3062 3063 d0= totaldegree (G_random_element, Variable(2), 3064 Variable (G_random_element.level())); 3065 if (d0 == 0) 3066 { 3067 if (substitute > 1) 3068 return N(reverseSubst (gcdcAcB, substitute)); 3069 else 3070 return N(gcdcAcB); 3071 } 3072 if (d0 > d) 3073 { 3074 if (!find (l, random_element)) 3075 l.append (random_element); 3076 continue; 3077 } 3078 3079 G_random_element= 3080 (gcdlcAlcB(random_element, x)/uni_lcoeff (G_random_element)) 3081 * G_random_element; 3082 3083 d0= totaldegree (G_random_element, Variable(2), 3084 Variable(G_random_element.level())); 3085 if (d0 < d) 3086 { 3087 m= gcdlcAlcB; 3088 newtonPoly= 1; 3089 G_m= 0; 3090 d= d0; 3091 } 3092 3093 TIMING_START (newton_interpolation); 3094 H= newtonInterp (random_element, G_random_element, newtonPoly, G_m, x); 3095 TIMING_END_AND_PRINT (newton_interpolation, 3096 "time for newton interpolation: "); 3097 3098 //termination test 3099 if (uni_lcoeff (H) == gcdlcAlcB) 3100 { 3101 cH= uni_content (H); 3102 ppH= H/cH; 3103 if (inextension) 3104 { 3105 CFList u, v; 3106 //maybe it's better to test if ppH is an element of F(\alpha) before 3107 //mapping down 3108 DEBOUTLN (cerr, "ppH before mapDown= " << ppH); 3109 ppH= mapDown (ppH, prim_elem, im_prim_elem, alpha, u, v); 3110 ppH /= Lc(ppH); 3111 DEBOUTLN (cerr, "ppH after mapDown= " << ppH); 3112 if (fdivides (ppH, A) && fdivides (ppH, B)) 3113 { 3114 if (substitute > 1) 3115 { 3116 ppH= reverseSubst (ppH, substitute); 3117 gcdcAcB= reverseSubst (gcdcAcB, substitute); 3118 } 3119 return N(gcdcAcB*ppH); 3120 } 3121 } 3122 else if (fdivides (ppH, A) && fdivides (ppH, B)) 3123 { 3124 if (substitute > 1) 3125 { 3126 ppH= reverseSubst (ppH, substitute); 3127 gcdcAcB= reverseSubst (gcdcAcB, substitute); 3128 } 3129 return N(gcdcAcB*ppH); 3130 } 3131 } 3132 3133 G_m= H; 3134 newtonPoly= newtonPoly*(x - random_element); 3135 m= m*(x - random_element); 3136 if (!find (l, random_element)) 3137 l.append (random_element); 3138 3139 } while (1); 3140 } 3141 } while (1); 3142 } 3143 3144 CanonicalForm sparseGCDFp (const CanonicalForm& F, const CanonicalForm& G, 3145 bool& topLevel, CFList& l) 3146 { 3147 CanonicalForm A= F; 3148 CanonicalForm B= G; 3149 if (F.isZero() && degree(G) > 0) return G/Lc(G); 3150 else if (G.isZero() && degree (F) > 0) return F/Lc(F); 3151 else if (F.isZero() && G.isZero()) return F.genOne(); 3152 if (F.inBaseDomain() || G.inBaseDomain()) return F.genOne(); 3153 if (F.isUnivariate() && fdivides(F, G)) return F/Lc(F); 3154 if (G.isUnivariate() && fdivides(G, F)) return G/Lc(G); 3155 if (F == G) return F/Lc(F); 3156 3157 CFMap M,N; 3158 int best_level= myCompress (A, B, M, N, topLevel); 3159 3160 if (best_level == 0) return B.genOne(); 3161 3162 A= M(A); 3163 B= M(B); 3164 3165 Variable x= Variable (1); 3166 3167 //univariate case 3168 if (A.isUnivariate() && B.isUnivariate()) 3169 return N (gcd (A, B)); 3170 3171 int substitute= substituteCheck (A, B); 3172 3173 if (substitute > 1) 3174 subst (A, B, A, B, substitute); 3175 3176 CanonicalForm cA, cB; // content of A and B 3177 CanonicalForm ppA, ppB; // primitive part of A and B 3178 CanonicalForm gcdcAcB; 3179 if (topLevel) 3180 { 3181 if (best_level <= 2) 3182 gcdcAcB= extractContents (A, B, cA, cB, ppA, ppB, best_level); 3183 else 3184 gcdcAcB= extractContents (A, B, cA, cB, ppA, ppB, 2); 3185 } 3186 else 3187 { 3188 cA = uni_content (A); 3189 cB = uni_content (B); 3190 gcdcAcB= gcd (cA, cB); 3191 ppA= A/cA; 3192 ppB= B/cB; 3193 } 3194 3195 CanonicalForm lcA, lcB; // leading coefficients of A and B 3196 CanonicalForm gcdlcAlcB; 3197 lcA= uni_lcoeff (ppA); 3198 lcB= uni_lcoeff (ppB); 3199 3200 if (fdivides (lcA, lcB)) 3201 { 3202 if (fdivides (A, B)) 3203 return F/Lc(F); 3204 } 3205 if (fdivides (lcB, lcA)) 3206 { 3207 if (fdivides (B, A)) 3208 return G/Lc(G); 3209 } 3210 3211 gcdlcAlcB= gcd (lcA, lcB); 3212 3213 int d= totaldegree (ppA, Variable (2), Variable (ppA.level())); 3214 int d0; 3215 3216 if (d == 0) 3217 { 3218 if (substitute > 1) 3219 return N(reverseSubst (gcdcAcB, substitute)); 3220 else 3221 return N(gcdcAcB); 3222 } 3223 d0= totaldegree (ppB, Variable (2), Variable (ppB.level())); 3224 3225 if (d0 < d) 3226 d= d0; 3227 3228 if (d == 0) 3229 { 3230 if (substitute > 1) 3231 return N(reverseSubst (gcdcAcB, substitute)); 3232 else 3233 return N(gcdcAcB); 3234 } 3235 3236 CanonicalForm m, random_element, G_m, G_random_element, H, cH, ppH, skeleton; 3237 CanonicalForm newtonPoly= 1; 3238 m= gcdlcAlcB; 3239 G_m= 0; 3240 H= 0; 3241 bool fail= false; 3242 bool topLevel2= topLevel; 3243 int loops= 0; 3244 topLevel= false; 3245 bool inextension= false; 3246 bool inextensionextension= false; 3247 Variable V_buf, alpha; 3248 CanonicalForm prim_elem, im_prim_elem; 3249 CFList source, dest; 3250 do //first do 3251 { 3252 if (inextension) 3253 random_element= randomElement (m, alpha, l, fail); 3254 else 3255 random_element= FpRandomElement (m, l, fail); 3256 if (random_element == 0 && !fail) 3257 { 3258 if (!find (l, random_element)) 3259 l.append (random_element); 3260 continue; 3261 } 3262 3263 if (!fail && !inextension) 3264 { 3265 CFList list; 3266 TIMING_START (gcd_recursion); 3267 G_random_element= 3268 sparseGCDFp (ppA (random_element,x), ppB (random_element,x), topLevel, 3269 list); 3270 TIMING_END_AND_PRINT (gcd_recursion, 3271 "time for recursive call: "); 3272 DEBOUTLN (cerr, "G_random_element= " << G_random_element); 3273 } 3274 else if (!fail && inextension) 3275 { 3276 CFList list; 3277 TIMING_START (gcd_recursion); 3278 G_random_element= 3279 sparseGCDFq (ppA (random_element, x), ppB (random_element, x), alpha, 3280 list, topLevel); 3281 TIMING_END_AND_PRINT (gcd_recursion, 3282 "time for recursive call: "); 3283 DEBOUTLN (cerr, "G_random_element= " << G_random_element); 3284 } 3285 else if (fail && !inextension) 3286 { 3287 source= CFList(); 3288 dest= CFList(); 3289 CFList list; 3290 CanonicalForm mipo; 3291 int deg= 2; 3292 do 3293 { 3294 mipo= randomIrredpoly (deg, x); 3295 alpha= rootOf (mipo); 3296 inextension= true; 3297 fail= false; 3298 random_element= randomElement (m, alpha, l, fail); 3299 deg++; 3300 } while (fail); 3301 list= CFList(); 3302 TIMING_START (gcd_recursion); 3303 G_random_element= 3304 sparseGCDFq (ppA (random_element, x), ppB (random_element, x), alpha, 3305 list, topLevel); 3306 TIMING_END_AND_PRINT (gcd_recursion, 3307 "time for recursive call: "); 3308 DEBOUTLN (cerr, "G_random_element= " << G_random_element); 3309 } 3310 else if (fail && inextension) 3311 { 3312 source= CFList(); 3313 dest= CFList(); 3314 int num_vars= tmin (getNumVars(A), getNumVars(B)); 3315 num_vars--; 3316 V_buf= alpha; 3317 choose_extension (d, num_vars, V_buf); 3318 bool prim_fail= false; 3319 Variable V_buf2; 3320 CanonicalForm prim_elem, im_prim_elem; 3321 prim_elem= primitiveElement (alpha, V_buf2, prim_fail); 3322 3323 ASSERT (!prim_fail, "failure in integer factorizer"); 3324 if (prim_fail) 3325 ; //ERROR 3326 else 3327 im_prim_elem= mapPrimElem (prim_elem, alpha, V_buf); 3328 3329 DEBOUTLN (cerr, "getMipo (alpha)= " << getMipo (alpha)); 3330 DEBOUTLN (cerr, "getMipo (alpha)= " << getMipo (V_buf2)); 3331 3332 inextensionextension= true; 3333 for (CFListIterator i= l; i.hasItem(); i++) 3334 i.getItem()= mapUp (i.getItem(), alpha, V_buf, prim_elem, 3335 im_prim_elem, source, dest); 3336 m= mapUp (m, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 3337 G_m= mapUp (G_m, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 3338 newtonPoly= mapUp (newtonPoly, alpha, V_buf, prim_elem, im_prim_elem, 3339 source, dest); 3340 ppA= mapUp (ppA, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 3341 ppB= mapUp (ppB, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 3342 gcdlcAlcB= mapUp (gcdlcAlcB, alpha, V_buf, prim_elem, im_prim_elem, 3343 source, dest); 3344 fail= false; 3345 random_element= randomElement (m, V_buf, l, fail ); 3346 DEBOUTLN (cerr, "fail= " << fail); 3347 CFList list; 3348 TIMING_START (gcd_recursion); 3349 G_random_element= 3350 sparseGCDFq (ppA (random_element, x), ppB (random_element, x), V_buf, 3351 list, topLevel); 3352 TIMING_END_AND_PRINT (gcd_recursion, 3353 "time for recursive call: "); 3354 DEBOUTLN (cerr, "G_random_element= " << G_random_element); 3355 alpha= V_buf; 3356 } 3357 3358 d0= totaldegree (G_random_element, Variable(2), 3359 Variable (G_random_element.level())); 3360 if (d0 == 0) 3361 { 3362 if (substitute > 1) 3363 return N(reverseSubst (gcdcAcB, substitute)); 3364 else 3365 return N(gcdcAcB); 3366 } 3367 if (d0 > d) 3368 { 3369 if (!find (l, random_element)) 3370 l.append (random_element); 3371 continue; 3372 } 3373 3374 G_random_element= 3375 (gcdlcAlcB(random_element, x)/uni_lcoeff (G_random_element)) 3376 * G_random_element; 3377 3378 skeleton= G_random_element; 3379 3380 d0= totaldegree (G_random_element, Variable(2), 3381 Variable(G_random_element.level())); 3382 if (d0 < d) 3383 { 3384 m= gcdlcAlcB; 3385 newtonPoly= 1; 3386 G_m= 0; 3387 d= d0; 3388 } 3389 3390 H= newtonInterp (random_element, G_random_element, newtonPoly, G_m, x); 3391 3392 if (uni_lcoeff (H) == gcdlcAlcB) 3393 { 3394 cH= uni_content (H); 3395 ppH= H/cH; 3396 ppH /= Lc (ppH); 3397 DEBOUTLN (cerr, "ppH= " << ppH); 3398 3399 if (fdivides (ppH, A) && fdivides (ppH, B)) 3400 { 3401 if (substitute > 1) 3402 { 3403 ppH= reverseSubst (ppH, substitute); 3404 gcdcAcB= reverseSubst (gcdcAcB, substitute); 3405 } 3406 return N(gcdcAcB*ppH); 3407 } 3408 } 3409 G_m= H; 3410 newtonPoly= newtonPoly*(x - random_element); 3411 m= m*(x - random_element); 3412 if (!find (l, random_element)) 3413 l.append (random_element); 3414 3415 if ((getCharacteristic() > 3 && size (skeleton) < 100) || 3416 size (skeleton) < 10) 3417 { 3418 CFArray Monoms; 3419 CFArray* coeffMonoms= NULL; 3420 3421 do //second do 3422 { 3423 if (inextension) 3424 random_element= randomElement (m, alpha, l, fail); 3425 else 3426 random_element= FpRandomElement (m, l, fail); 3427 if (random_element == 0 && !fail) 3428 { 3429 if (!find (l, random_element)) 3430 l.append (random_element); 3431 continue; 3432 } 3433 3434 bool sparseFail= false; 3435 if (!fail && !inextension) 3436 { 3437 CFList list; 3438 TIMING_START (gcd_recursion); 3439 if (LC (skeleton).inCoeffDomain()) 3440 G_random_element= 3441 monicSparseInterpol(ppA(random_element, x), ppB (random_element, x), 3442 skeleton, Variable(1), sparseFail, coeffMonoms, 3443 Monoms); 3444 else 3445 G_random_element= 3446 nonMonicSparseInterpol(ppA(random_element,x), ppB(random_element,x), 3447 skeleton, Variable (1), sparseFail, 3448 coeffMonoms, Monoms); 3449 TIMING_END_AND_PRINT (gcd_recursion, 3450 "time for recursive call: "); 3451 DEBOUTLN (cerr, "G_random_element= " << G_random_element); 3452 } 3453 else if (!fail && inextension) 3454 { 3455 CFList list; 3456 TIMING_START (gcd_recursion); 3457 if (LC (skeleton).inCoeffDomain()) 3458 G_random_element= 3459 monicSparseInterpol(ppA (random_element,x), ppB (random_element, x), 3460 skeleton, alpha, sparseFail, coeffMonoms, 3461 Monoms); 3462 else 3463 G_random_element= 3464 nonMonicSparseInterpol(ppA(random_element,x), ppB(random_element,x), 3465 skeleton, alpha, sparseFail, coeffMonoms, 3466 Monoms); 3467 TIMING_END_AND_PRINT (gcd_recursion, 3468 "time for recursive call: "); 3469 DEBOUTLN (cerr, "G_random_element= " << G_random_element); 3470 } 3471 else if (fail && !inextension) 3472 { 3473 source= CFList(); 3474 dest= CFList(); 3475 CFList list; 3476 CanonicalForm mipo; 3477 int deg= 2; 3478 do 3479 { 3480 mipo= randomIrredpoly (deg, x); 3481 alpha= rootOf (mipo); 3482 inextension= true; 3483 fail= false; 3484 random_element= randomElement (m, alpha, l, fail); 3485 deg++; 3486 } while (fail); 3487 list= CFList(); 3488 TIMING_START (gcd_recursion); 3489 if (LC (skeleton).inCoeffDomain()) 3490 G_random_element= 3491 monicSparseInterpol (ppA (random_element,x), ppB (random_element,x), 3492 skeleton, alpha, sparseFail, coeffMonoms, 3493 Monoms); 3494 else 3495 G_random_element= 3496 nonMonicSparseInterpol(ppA(random_element,x), ppB(random_element,x), 3497 skeleton, alpha, sparseFail, coeffMonoms, 3498 Monoms); 3499 TIMING_END_AND_PRINT (gcd_recursion, 3500 "time for recursive call: "); 3501 DEBOUTLN (cerr, "G_random_element= " << G_random_element); 3502 } 3503 else if (fail && inextension) 3504 { 3505 source= CFList(); 3506 dest= CFList(); 3507 int num_vars= tmin (getNumVars(A), getNumVars(B)); 3508 num_vars--; 3509 V_buf= alpha; 3510 choose_extension (d, num_vars, V_buf); 3511 bool prim_fail= false; 3512 Variable V_buf2; 3513 CanonicalForm prim_elem, im_prim_elem; 3514 prim_elem= primitiveElement (alpha, V_buf2, prim_fail); 3515 3516 ASSERT (!prim_fail, "failure in integer factorizer"); 3517 if (prim_fail) 3518 ; //ERROR 3519 else 3520 im_prim_elem= mapPrimElem (prim_elem, alpha, V_buf); 3521 3522 DEBOUTLN (cerr, "getMipo (alpha)= " << getMipo (alpha)); 3523 DEBOUTLN (cerr, "getMipo (alpha)= " << getMipo (V_buf2)); 3524 3525 inextensionextension= true; 3526 for (CFListIterator i= l; i.hasItem(); i++) 3527 i.getItem()= mapUp (i.getItem(), alpha, V_buf, prim_elem, 3528 im_prim_elem, source, dest); 3529 m= mapUp (m, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 3530 G_m= mapUp (G_m, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 3531 newtonPoly= mapUp (newtonPoly, alpha, V_buf, prim_elem, im_prim_elem, 3532 source, dest); 3533 ppA= mapUp (ppA, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 3534 ppB= mapUp (ppB, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 3535 gcdlcAlcB= mapUp (gcdlcAlcB, alpha, V_buf, prim_elem, im_prim_elem, 3536 source, dest); 3537 fail= false; 3538 random_element= randomElement (m, V_buf, l, fail ); 3539 DEBOUTLN (cerr, "fail= " << fail); 3540 CFList list; 3541 TIMING_START (gcd_recursion); 3542 if (LC (skeleton).inCoeffDomain()) 3543 G_random_element= 3544 monicSparseInterpol (ppA (random_element, x), ppB (random_element, x), 3545 skeleton, V_buf, sparseFail, coeffMonoms, 3546 Monoms); 3547 else 3548 G_random_element= 3549 nonMonicSparseInterpol (ppA(random_element,x), ppB(random_element,x), 3550 skeleton, V_buf, sparseFail, 3551 coeffMonoms, Monoms); 3552 TIMING_END_AND_PRINT (gcd_recursion, 3553 "time for recursive call: "); 3554 DEBOUTLN (cerr, "G_random_element= " << G_random_element); 3555 alpha= V_buf; 3556 } 3557 3558 if (sparseFail) 3559 break; 3560 3561 d0= totaldegree (G_random_element, Variable(2), 3562 Variable (G_random_element.level())); 3563 if (d0 == 0) 3564 { 3565 if (substitute > 1) 3566 return N(reverseSubst (gcdcAcB, substitute)); 3567 else 3568 return N(gcdcAcB); 3569 } 3570 if (d0 > d) 3571 { 3572 if (!find (l, random_element)) 3573 l.append (random_element); 3574 continue; 3575 } 3576 3577 G_random_element= 3578 (gcdlcAlcB(random_element, x)/uni_lcoeff (G_random_element)) 3579 * G_random_element; 3580 3581 d0= totaldegree (G_random_element, Variable(2), 3582 Variable(G_random_element.level())); 3583 if (d0 < d) 3584 { 3585 m= gcdlcAlcB; 3586 newtonPoly= 1; 3587 G_m= 0; 3588 d= d0; 3589 } 3590 3591 TIMING_START (newton_interpolation); 3592 H= newtonInterp (random_element, G_random_element, newtonPoly, G_m, x); 3593 TIMING_END_AND_PRINT (newton_interpolation, 3594 "time for newton interpolation: "); 3595 3596 //termination test 3597 if (uni_lcoeff (H) == gcdlcAlcB) 3598 { 3599 cH= uni_content (H); 3600 ppH= H/cH; 3601 ppH /= Lc (ppH); 3602 DEBOUTLN (cerr, "ppH= " << ppH); 3603 if (fdivides (ppH, A) && fdivides (ppH, B)) 3604 { 3605 if (substitute > 1) 3606 { 3607 ppH= reverseSubst (ppH, substitute); 3608 gcdcAcB= reverseSubst (gcdcAcB, substitute); 3609 } 3610 return N(gcdcAcB*ppH); 3611 } 3612 } 3613 3614 G_m= H; 3615 newtonPoly= newtonPoly*(x - random_element); 3616 m= m*(x - random_element); 3617 if (!find (l, random_element)) 3618 l.append (random_element); 3619 3620 } while (1); //end of second do 3621 } 3622 } while (1); //end of first do 3623 } 3624 3625 static inline 3626 int compress4EZGCD (const CanonicalForm& F, const CanonicalForm& G, CFMap & M, 3627 CFMap & N, int& both_non_zero) 3628 { 3629 int n= tmax (F.level(), G.level()); 3630 int * degsf= new int [n + 1]; 3631 int * degsg= new int [n + 1]; 3632 3633 for (int i = 0; i <= n; i++) 3634 degsf[i]= degsg[i]= 0; 3635 3636 degsf= degrees (F, degsf); 3637 degsg= degrees (G, degsg); 3638 3639 both_non_zero= 0; 3640 int f_zero= 0; 3641 int g_zero= 0; 3642 int both_zero= 0; 3643 3644 for (int i= 1; i <= n; i++) 3645 { 3646 if (degsf[i] != 0 && degsg[i] != 0) 3647 { 3648 both_non_zero++; 3649 continue; 3650 } 3651 if (degsf[i] == 0 && degsg[i] != 0 && i <= G.level()) 3652 { 3653 f_zero++; 3654 continue; 3655 } 3656 if (degsg[i] == 0 && degsf[i] && i <= F.level()) 3657 { 3658 g_zero++; 3659 continue; 3660 } 3661 } 3662 3663 if (both_non_zero == 0) return 0; 3664 3665 // map Variables which do not occur in both polynomials to higher levels 3666 int k= 1; 3667 int l= 1; 3668 for (int i= 1; i <= n; i++) 3669 { 3670 if (degsf[i] != 0 && degsg[i] == 0 && i <= F.level()) 3671 { 3672 if (k + both_non_zero != i) 3673 { 3674 M.newpair (Variable (i), Variable (k + both_non_zero)); 3675 N.newpair (Variable (k + both_non_zero), Variable (i)); 3676 } 3677 k++; 3678 } 3679 if (degsf[i] == 0 && degsg[i] != 0 && i <= G.level()) 3680 { 3681 if (l + g_zero + both_non_zero != i) 3682 { 3683 M.newpair (Variable (i), Variable (l + g_zero + both_non_zero)); 3684 N.newpair (Variable (l + g_zero + both_non_zero), Variable (i)); 3685 } 3686 l++; 3687 } 3688 } 3689 3690 // sort Variables x_{i} in decreasing order of 3691 // min(deg_{x_{i}}(f),deg_{x_{i}}(g)) 3692 int m= tmin (F.level(), G.level()); 3693 int max_min_deg; 3694 k= both_non_zero; 3695 l= 0; 3696 int i= 1; 3697 while (k > 0) 3698 { 3699 max_min_deg= tmin (degsf[i], degsg[i]); 3700 while (max_min_deg == 0) 3701 { 3702 i++; 3703 max_min_deg= tmin (degsf[i], degsg[i]); 3704 } 3705 for (int j= i + 1; j <= m; j++) 3706 { 3707 if ((tmin (degsf[j],degsg[j]) < max_min_deg) && 3708 (tmin (degsf[j], degsg[j]) != 0)) 3709 { 3710 max_min_deg= tmin (degsf[j], degsg[j]); 3711 l= j; 3712 } 3713 } 3714 3715 if (l != 0) 3716 { 3717 if (l != k) 3718 { 3719 M.newpair (Variable (l), Variable(k)); 3720 N.newpair (Variable (k), Variable(l)); 3721 degsf[l]= 0; 3722 degsg[l]= 0; 3723 l= 0; 3724 } 3725 else 3726 { 3727 degsf[l]= 0; 3728 degsg[l]= 0; 3729 l= 0; 3730 } 3731 } 3732 else if (l == 0) 3733 { 3734 if (i != k) 3735 { 3736 M.newpair (Variable (i), Variable (k)); 3737 N.newpair (Variable (k), Variable (i)); 3738 degsf[i]= 0; 3739 degsg[i]= 0; 3740 } 3741 else 3742 { 3743 degsf[i]= 0; 3744 degsg[i]= 0; 3745 } 3746 i++; 3747 } 3748 k--; 3749 } 3750 3751 delete [] degsf; 3752 delete [] degsg; 3753 3754 return both_non_zero; 3755 } 3756 3757 static inline 3758 CanonicalForm myShift2Zero (const CanonicalForm& F, CFList& Feval, 3759 const CFList& evaluation) 3760 { 3761 CanonicalForm A= F; 3762 int k= 2; 3763 for (CFListIterator i= evaluation; i.hasItem(); i++, k++) 3764 A= A (Variable (k) + i.getItem(), k); 3765 3766 CanonicalForm buf= A; 3767 Feval= CFList(); 3768 Feval.append (buf); 3769 for (k= evaluation.length() + 1; k > 2; k--) 3770 { 3771 buf= mod (buf, Variable (k)); 3772 Feval.insert (buf); 3773 } 3774 return A; 3775 } 3776 3777 static inline 3778 CanonicalForm myReverseShift (const CanonicalForm& F, const CFList& evaluation) 3779 { 3780 int l= evaluation.length() + 1; 3781 CanonicalForm result= F; 3782 CFListIterator j= evaluation; 3783 for (int i= 2; i < l + 1; i++, j++) 3784 { 3785 if (F.level() < i) 3786 continue; 3787 result= result (Variable (i) - j.getItem(), i); 3788 } 3789 return result; 3790 } 3791 3792 static inline 3793 bool Hensel_P (const CanonicalForm & U, CFArray & G, const Evaluation & A, 3794 const Variable & x, const CFArray& LCs ) 3795 { 3796 CFList factors; 3797 factors.append (G[1]); 3798 factors.append (G[2]); 3799 CFList evaluation; 3800 for (int i= A.min(); i <= A.max(); i++) 3801 evaluation.append (A [i]); 3802 CFList UEval; 3803 CanonicalForm shiftedU= myShift2Zero (U, UEval, evaluation); 3804 CFArray shiftedLCs= CFArray (2); 3805 CFList shiftedLCsEval1, shiftedLCsEval2; 3806 shiftedLCs[0]= myShift2Zero (LCs[1], shiftedLCsEval1, evaluation); 3807 shiftedLCs[1]= myShift2Zero (LCs[2], shiftedLCsEval2, evaluation); 3808 CanonicalForm LcUEval= LC (UEval.getFirst(), x); 3809 factors.insert (1); 3810 int liftBound= degree (UEval.getLast(), 2) + 1; 3811 CFArray Pi; 3812 CFMatrix M= CFMatrix (liftBound, factors.length() - 1); 3813 CFList diophant; 3814 CFArray lcs= CFArray (2); 3815 lcs [0]= shiftedLCsEval1.getFirst(); 3816 lcs [1]= shiftedLCsEval2.getFirst(); 3817 henselLift122 (UEval.getFirst(), factors, liftBound, Pi, diophant, M, 3818 lcs, false); 3819 3820 bool noChange= true; 3821 for (CFListIterator i= factors; i.hasItem(); i++) 3822 { 3823 if (degree (i.getItem(), 2) != 0) 3824 noChange= false; 3825 } 3826 if (noChange) 3827 return !noChange; 3828 int * liftBounds; 3829 if (U.level() > 2) 3830 { 3831 liftBounds= new int [U.level() - 1]; 3832 liftBounds[0]= liftBound; 3833 for (int i= 1; i < U.level() - 1; i++) 3834 liftBounds[i]= degree (shiftedU, Variable (i + 2)) + 1; 3835 factors= henselLift2 (UEval, factors, liftBounds, U.level() - 1, false, 3836 shiftedLCsEval1, shiftedLCsEval2, Pi, diophant); 3837 } 3838 G[1]= factors.getFirst(); 3839 G[2]= factors.getLast(); 3840 G[1]= myReverseShift (G[1], evaluation); 3841 G[2]= myReverseShift (G[2], evaluation); 3842 return true; 3843 } 3844 3845 static inline 3846 bool findeval_P (const CanonicalForm & F, const CanonicalForm & G, 3847 CanonicalForm & Fb, CanonicalForm & Gb, CanonicalForm & Db, 3848 FFREvaluation & b, int delta, int degF, int degG, int maxeval, 3849 int & count) 3850 { 3851 if( count == 0 && delta != 0) 3852 { 3853 if( count++ > maxeval ) 3854 return false; 3855 } 3856 if (count > 0) 3857 { 3858 b.nextpoint(); 3859 if (count++ > maxeval) 3860 return false; 3861 } 3862 while( true ) 3863 { 3864 Fb = b( F ); 3865 if( degree( Fb, 1 ) == degF ) 3866 { 3867 Gb = b( G ); 3868 if( degree( Gb, 1 ) == degG ) 3869 { 3870 Db = gcd( Fb, Gb ); 3871 if( delta > 0 ) 3872 { 3873 if( degree( Db, 1 ) <= delta ) 3874 return true; 3875 } 3876 else 3877 return true; 3878 } 3879 } 3880 b.nextpoint(); 3881 if( count++ > maxeval ) 3882 return false; 3883 } 3884 } 3885 3886 // parameters for heuristic 3887 static int maxNumEval= 200; 3888 static int sizePerVars1= 500; //try dense gcd if size/#variables is bigger 3889 static int sizePerVars2= 290; //try psr gcd if size/#variables is less 3890 3891 /// Extended Zassenhaus GCD for finite fields 3892 CanonicalForm EZGCD_P( const CanonicalForm & FF, const CanonicalForm & GG ) 3893 { 3894 if (FF.isZero() && degree(GG) > 0) return GG/Lc(GG); 3895 else if (GG.isZero() && degree (FF) > 0) return FF/Lc(FF); 3896 else if (FF.isZero() && GG.isZero()) return FF.genOne(); 3897 if (FF.inBaseDomain() || GG.inBaseDomain()) return FF.genOne(); 3898 if (FF.isUnivariate() && fdivides(FF, GG)) return FF/Lc(FF); 3899 if (GG.isUnivariate() && fdivides(GG, FF)) return GG/Lc(GG); 3900 if (FF == GG) return FF/Lc(FF); 3901 3902 CanonicalForm F, G, f, g, d, Fb, Gb, Db, Fbt, Gbt, Dbt, B0, B, D0, lcF, lcG, 3903 lcD; 3904 CFArray DD( 1, 2 ), lcDD( 1, 2 ); 3905 int degF, degG, delta, count; 3906 int maxeval; 3907 maxeval= tmin((getCharacteristic()/ 3908 (int)(ilog2(getCharacteristic())*log2exp))*2, maxNumEval); 3909 count= 0; // number of eval. used 3910 FFREvaluation b, bt; 3911 bool gcdfound = false; 3912 Variable x = Variable(1); 3913 3914 F= FF; 3915 G= GG; 3916 3917 CFMap M,N; 3918 int smallestDegLev; 3919 int best_level= compress4EZGCD (F, G, M, N, smallestDegLev); 3920 3921 if (best_level == 0) return G.genOne(); 3922 3923 F= M (F); 3924 G= M (G); 3925 3926 f = content( F, x ); g = content( G, x ); 3927 d = gcd( f, g ); 3928 F /= f; G /= g; 3929 3930 if( F.isUnivariate() && G.isUnivariate() ) 3931 { 3932 if( F.mvar() == G.mvar() ) 3933 d *= gcd( F, G ); 3934 return N (d); 3935 } 3936 3937 int maxNumVars= tmax (getNumVars (F), getNumVars (G)); 3938 Variable a,bv; 3939 int sizeF= size (F); 3940 int sizeG= size (G); 3941 3942 if (sizeF/maxNumVars > sizePerVars1 && sizeG/maxNumVars > sizePerVars1) 3943 { 3944 if (hasFirstAlgVar (F, a) || hasFirstAlgVar (G, a)) 3945 return N (d*GCD_Fp_extension (F, G, a)); 3946 else if (CFFactory::gettype() == GaloisFieldDomain) 3947 return N (d*GCD_GF (F, G)); 3948 else 3949 return N (d*GCD_small_p (F, G)); 3950 } 3951 3952 if( gcd_test_one( F, G, false ) ) 3953 { 3954 return N (d); 3955 } 3956 3957 lcF = LC( F, x ); lcG = LC( G, x ); 3958 lcD = gcd( lcF, lcG ); 3959 3960 delta = 0; 3961 degF = degree( F, x ); degG = degree( G, x ); 3962 if(hasFirstAlgVar(F,a)) 3963 { 3964 if(hasFirstAlgVar(G,bv)) 3965 { 3966 if(bv.level() > a.level()) 3967 a = bv; 3968 } 3969 b = FFREvaluation( 2, tmax(F.level(), G.level()), AlgExtRandomF( a ) ); 3970 } 3971 else // F not in extension 3972 { 3973 if(hasFirstAlgVar(G,a)) 3974 b = FFREvaluation( 2, tmax(F.level(), G.level()), AlgExtRandomF( a ) ); 3975 else 3976 { // both not in extension given by algebraic variable 3977 if (CFFactory::gettype() != GaloisFieldDomain) 3978 b = FFREvaluation( 2, tmax(F.level(), G.level()), FFRandom() ); 3979 else 3980 b = FFREvaluation( 2, tmax(F.level(), G.level()), GFRandom() ); 3981 } 3982 } 3983 CanonicalForm cand; 3984 while( !gcdfound ) 3985 { 3986 if( !findeval_P( F, G, Fb, Gb, Db, b, delta, degF, degG, maxeval, count )) 3987 { // too many eval. used --> try another method 3988 if (sizeF/maxNumVars < sizePerVars2 && sizeG/maxNumVars < sizePerVars2) 3989 { 3990 CanonicalForm dummy1, dummy2; 3991 Variable y= Variable (tmax (F.level(), G.level())); 3992 Variable z= Variable (smallestDegLev); 3993 dummy1= swapvar (F, x, y); 3994 dummy2= swapvar (G, x, y); 3995 if (size (psr (dummy1, dummy2, y)) <= tmin (size (F), size (G))) 3996 { 3997 Off (SW_USE_EZGCD_P); 3998 CanonicalForm result= swapvar (gcd (dummy1,dummy2), x, y); 3999 On (SW_USE_EZGCD_P); 4000 return N (d*result); 4001 } 4002 } 4003 if (hasFirstAlgVar (F, a) || hasFirstAlgVar (G, a)) 4004 return N (d*sparseGCDFq (F, G, a)); 4005 if (CFFactory::gettype() == GaloisFieldDomain) 4006 return N (d*GCD_GF (F, G)); 4007 else 4008 return N (d*sparseGCDFp (F,G)); 4009 } 4010 delta = degree( Db ); 4011 if( delta == 0 ) 4012 return N (d); 4013 while( true ) 4014 { 4015 bt = b; 4016 if( !findeval_P(F,G,Fbt,Gbt,Dbt, bt, delta, degF, degG, maxeval, count )) 4017 { // too many eval. used --> try another method 4018 if (sizeF/maxNumVars < sizePerVars2 && sizeG/maxNumVars < sizePerVars2) 4019 { 4020 CanonicalForm dummy1, dummy2; 4021 Variable y= Variable (tmax (F.level(), G.level())); 4022 Variable z= Variable (smallestDegLev); 4023 dummy1= swapvar (F, x, y); 4024 dummy2= swapvar (G, x, y); 4025 if (size (psr (dummy1, dummy2, y)) <= tmin (size (F), size (G))) 4026 { 4027 Off (SW_USE_EZGCD_P); 4028 CanonicalForm result= swapvar (gcd (dummy1,dummy2), x, y); 4029 On (SW_USE_EZGCD_P); 4030 return N (d*result); 4031 } 4032 } 4033 if (hasFirstAlgVar (F, a) || hasFirstAlgVar (G, a)) 4034 return N (d*sparseGCDFq (F, G, a)); 4035 if (CFFactory::gettype() == GaloisFieldDomain) 4036 return N (d*GCD_GF (F, G)); 4037 else 4038 return N (d*sparseGCDFp (F,G)); 4039 } 4040 int dd = degree( Dbt ); 4041 if( dd == 0 ) 4042 return N (d); 4043 if( dd == delta ) 4044 break; 4045 if( dd < delta ) 4046 { 4047 delta = dd; 4048 b = bt; 4049 Db = Dbt; Fb = Fbt; Gb = Gbt; 4050 } 4051 } 4052 if( degF <= degG && delta == degF && fdivides( F, G ) ) 4053 return N (d*F); 4054 if( degG < degF && delta == degG && fdivides( G, F ) ) 4055 return N (d*G); 4056 if( delta != degF && delta != degG ) 4057 { 4058 bool B_is_F; 4059 CanonicalForm xxx1, xxx2; 4060 CanonicalForm buf; 4061 DD[1] = Fb / Db; 4062 buf= Gb/Db; 4063 xxx1 = gcd( DD[1], Db ); 4064 xxx2 = gcd( buf, Db ); 4065 if (((xxx1.inCoeffDomain() && xxx2.inCoeffDomain()) && 4066 (size (F) <= size (G))) 4067 || (xxx1.inCoeffDomain() && !xxx2.inCoeffDomain())) 4068 { 4069 B = F; 4070 DD[2] = Db; 4071 lcDD[1] = lcF; 4072 lcDD[2] = lcD; 4073 B_is_F = true; 4074 } 4075 else if (((xxx1.inCoeffDomain() && xxx2.inCoeffDomain()) && 4076 (size (G) < size (F))) 4077 || (!xxx1.inCoeffDomain() && xxx2.inCoeffDomain())) 4078 { 4079 DD[1] = buf; 4080 B = G; 4081 DD[2] = Db; 4082 lcDD[1] = lcG; 4083 lcDD[2] = lcD; 4084 B_is_F = false; 4085 } 4086 else // special case handling 4087 { 4088 if (sizeF/maxNumVars < sizePerVars2 && sizeG/maxNumVars < sizePerVars2) 4089 { 4090 CanonicalForm dummy1, dummy2; 4091 Variable y= Variable (tmax (F.level(), G.level())); 4092 Variable z= Variable (smallestDegLev); 4093 dummy1= swapvar (F, x, y); 4094 dummy2= swapvar (G, x, y); 4095 if (size (psr (dummy1, dummy2, y)) <= tmin (size (F), size (G))) 4096 { 4097 Off (SW_USE_EZGCD_P); 4098 CanonicalForm result= swapvar (gcd (dummy1,dummy2), x, y); 4099 On (SW_USE_EZGCD_P); 4100 return N (d*result); 4101 } 4102 } 4103 if (hasFirstAlgVar (F, a) || hasFirstAlgVar (G, a)) 4104 return N (d*sparseGCDFq (F, G, a)); 4105 if (CFFactory::gettype() == GaloisFieldDomain) 4106 return N (d*GCD_GF (F, G)); 4107 else 4108 return N (d*sparseGCDFp (F,G)); 4109 } 4110 DD[2] = DD[2] * ( b( lcDD[2] ) / lc( DD[2] ) ); 4111 DD[1] = DD[1] * ( b( lcDD[1] ) / lc( DD[1] ) ); 4112 4113 gcdfound= Hensel_P (B*lcD, DD, b, x, lcDD); 4114 4115 if( gcdfound ) 4116 { 4117 cand = DD[2] / content( DD[2], Variable(1) ); 4118 if( B_is_F ) 4119 gcdfound = fdivides( cand, G ); 4120 else 4121 gcdfound = fdivides( cand, F ); 4122 } 4123 } 4124 delta= 0; 4125 } 4126 return N (d*cand); 4127 } 4128 4129 1361 4130 #endif -
factory/cf_gcd_smallp.h
rcde708 r08daea 63 63 } 64 64 65 CanonicalForm sparseGCDFp (const CanonicalForm& F, const CanonicalForm& G, 66 bool& topLevel, CFList& l); 67 68 /// Zippel's sparse GCD over Fp 69 static inline 70 CanonicalForm sparseGCDFp (const CanonicalForm& A, const CanonicalForm& B) 71 { 72 ASSERT (CFFactory::gettype() == GaloisFieldDomain, 73 "GF as base field expected"); 74 CFList list; 75 bool topLevel= true; 76 return sparseGCDFp (A, B, topLevel, list); 77 } 78 79 /// Zippel's sparse GCD over Fq 80 CanonicalForm 81 sparseGCDFq (const CanonicalForm& F, const CanonicalForm& G, 82 const Variable& alpha, CFList& l, bool& topLevel); 83 84 static inline 85 CanonicalForm sparseGCDFq (const CanonicalForm& A, const CanonicalForm& B, 86 const Variable& alpha) 87 { 88 CFList list; 89 bool topLevel= true; 90 return sparseGCDFq (A, B, alpha, list, topLevel); 91 } 92 93 /// extended Zassenhaus GCD 94 CanonicalForm 95 EZGCD_P (const CanonicalForm& A, const CanonicalForm& B); 96 65 97 CanonicalForm 66 98 randomIrredpoly (int i, const Variable & x) ; -
factory/cf_map_ext.cc
rcde708 r08daea 340 340 return 0; 341 341 } while (1); 342 zz_pE::init (NTL_mipo); 343 zz_pEX NTL_alpha_mipo= convertFacCF2NTLzz_pEX (mipo, NTL_mipo); 344 zz_pE root= FindRoot (NTL_alpha_mipo); 342 zz_pX alpha_mipo= convertFacCF2NTLzzpX (mipo); 343 zz_pE::init (alpha_mipo); 344 zz_pEX NTL_beta_mipo= to_zz_pEX (NTL_mipo); 345 zz_pE root= FindRoot (NTL_beta_mipo); 345 346 return convertNTLzzpE2CF (root, alpha); 346 347 } -
factory/cf_random.cc
rcde708 r08daea 65 65 CanonicalForm GFRandom::generate () const 66 66 { 67 return CanonicalForm( int2imm_gf( factoryrandom( gf_q ) ) ); 67 int i= factoryrandom( gf_q ); 68 if ( i == gf_q1 ) i++; 69 return CanonicalForm( int2imm_gf( i ) ); 68 70 } 69 71 -
factory/facHensel.cc
rcde708 r08daea 26 26 #include "facHensel.h" 27 27 #include "cf_util.h" 28 #include "fac_util.h" 29 #include "cf_algorithm.h" 28 30 29 31 #ifdef HAVE_NTL … … 1553 1555 } 1554 1556 1557 void 1558 henselStep122 (const CanonicalForm& F, const CFList& factors, 1559 CFArray& bufFactors, const CFList& diophant, CFMatrix& M, 1560 CFArray& Pi, int j, const CFArray& LCs) 1561 { 1562 Variable x= F.mvar(); 1563 CanonicalForm xToJ= power (x, j); 1564 1565 CanonicalForm E; 1566 // compute the error 1567 if (degree (Pi [factors.length() - 2], x) > 0) 1568 E= F[j] - Pi [factors.length() - 2] [j]; 1569 else 1570 E= F[j]; 1571 1572 CFArray buf= CFArray (diophant.length()); 1573 1574 int k= 0; 1575 CanonicalForm remainder; 1576 // actual lifting 1577 for (CFListIterator i= diophant; i.hasItem(); i++, k++) 1578 { 1579 if (degree (bufFactors[k], x) > 0) 1580 remainder= modNTL (E, bufFactors[k] [0]); 1581 else 1582 remainder= modNTL (E, bufFactors[k]); 1583 buf[k]= mulNTL (i.getItem(), remainder); 1584 if (degree (bufFactors[k], x) > 0) 1585 buf[k]= modNTL (buf[k], bufFactors[k] [0]); 1586 else 1587 buf[k]= modNTL (buf[k], bufFactors[k]); 1588 } 1589 1590 for (k= 0; k < factors.length(); k++) 1591 bufFactors[k] += xToJ*buf[k]; 1592 1593 // update Pi [0] 1594 int degBuf0= degree (bufFactors[0], x); 1595 int degBuf1= degree (bufFactors[1], x); 1596 if (degBuf0 > 0 && degBuf1 > 0) 1597 { 1598 M (j + 1, 1)= mulNTL (bufFactors[0] [j], bufFactors[1] [j]); 1599 if (j + 2 <= M.rows()) 1600 M (j + 2, 1)= mulNTL (bufFactors[0] [j + 1], bufFactors[1] [j + 1]); 1601 } 1602 CanonicalForm uIZeroJ; 1603 if (degBuf0 > 0 && degBuf1 > 0) 1604 uIZeroJ= mulNTL(bufFactors[0][0],buf[1])+mulNTL (bufFactors[1][0], buf[0]); 1605 else if (degBuf0 > 0) 1606 uIZeroJ= mulNTL (buf[0], bufFactors[1]); 1607 else if (degBuf1 > 0) 1608 uIZeroJ= mulNTL (bufFactors[0], buf [1]); 1609 else 1610 uIZeroJ= 0; 1611 Pi [0] += xToJ*uIZeroJ; 1612 1613 CFArray tmp= CFArray (factors.length() - 1); 1614 for (k= 0; k < factors.length() - 1; k++) 1615 tmp[k]= 0; 1616 CFIterator one, two; 1617 one= bufFactors [0]; 1618 two= bufFactors [1]; 1619 if (degBuf0 > 0 && degBuf1 > 0) 1620 { 1621 while (one.exp() > j) one++; 1622 while (two.exp() > j) two++; 1623 for (k= 1; k <= (int) ceil (j/2.0); k++) 1624 { 1625 if (k != j - k + 1) 1626 { 1627 if (one.exp() == j - k + 1 && two.exp() == j - k + 1) 1628 { 1629 tmp[0] += mulNTL ((bufFactors[0][k]+one.coeff()),(bufFactors[1][k] + 1630 two.coeff())) - M (k + 1, 1) - M (j - k + 2, 1); 1631 one++; 1632 two++; 1633 } 1634 else if (one.exp() == j - k + 1) 1635 { 1636 tmp[0] += mulNTL ((bufFactors[0][k]+one.coeff()), bufFactors[1] [k]) - 1637 M (k + 1, 1); 1638 one++; 1639 } 1640 else if (two.exp() == j - k + 1) 1641 { 1642 tmp[0] += mulNTL (bufFactors[0][k],(bufFactors[1][k] + two.coeff())) - 1643 M (k + 1, 1); 1644 two++; 1645 } 1646 } 1647 else 1648 tmp[0] += M (k + 1, 1); 1649 } 1650 1651 if (j + 2 <= M.rows()) 1652 { 1653 if (degBuf0 >= j + 1 && degBuf1 >= j + 1) 1654 tmp [0] += mulNTL ((bufFactors [0] [j + 1]+ bufFactors [0] [0]), 1655 (bufFactors [1] [j + 1] + bufFactors [1] [0])) 1656 - M(1,1) - M (j + 2,1); 1657 else if (degBuf0 >= j + 1) 1658 tmp[0] += mulNTL (bufFactors [0] [j+1], bufFactors [1] [0]); 1659 else if (degBuf1 >= j + 1) 1660 tmp[0] += mulNTL (bufFactors [0] [0], bufFactors [1] [j + 1]); 1661 } 1662 } 1663 Pi [0] += tmp[0]*xToJ*F.mvar(); 1664 1665 /*// update Pi [l] 1666 int degPi, degBuf; 1667 for (int l= 1; l < factors.length() - 1; l++) 1668 { 1669 degPi= degree (Pi [l - 1], x); 1670 degBuf= degree (bufFactors[l + 1], x); 1671 if (degPi > 0 && degBuf > 0) 1672 M (j + 1, l + 1)= mulNTL (Pi [l - 1] [j], bufFactors[l + 1] [j]); 1673 if (j == 1) 1674 { 1675 if (degPi > 0 && degBuf > 0) 1676 Pi [l] += xToJ*(mulNTL (Pi [l - 1] [0] + Pi [l - 1] [j], 1677 bufFactors[l + 1] [0] + buf[l + 1]) - M (j + 1, l +1) - 1678 M (1, l + 1)); 1679 else if (degPi > 0) 1680 Pi [l] += xToJ*(mulNTL (Pi [l - 1] [j], bufFactors[l + 1])); 1681 else if (degBuf > 0) 1682 Pi [l] += xToJ*(mulNTL (Pi [l - 1], buf[l + 1])); 1683 } 1684 else 1685 { 1686 if (degPi > 0 && degBuf > 0) 1687 { 1688 uIZeroJ= mulNTL (uIZeroJ, bufFactors [l + 1] [0]); 1689 uIZeroJ += mulNTL (Pi [l - 1] [0], buf [l + 1]); 1690 } 1691 else if (degPi > 0) 1692 uIZeroJ= mulNTL (uIZeroJ, bufFactors [l + 1]); 1693 else if (degBuf > 0) 1694 { 1695 uIZeroJ= mulNTL (uIZeroJ, bufFactors [l + 1] [0]); 1696 uIZeroJ += mulNTL (Pi [l - 1], buf[l + 1]); 1697 } 1698 Pi[l] += xToJ*uIZeroJ; 1699 } 1700 one= bufFactors [l + 1]; 1701 two= Pi [l - 1]; 1702 if (two.exp() == j + 1) 1703 { 1704 if (degBuf > 0 && degPi > 0) 1705 { 1706 tmp[l] += mulNTL (two.coeff(), bufFactors[l + 1][0]); 1707 two++; 1708 } 1709 else if (degPi > 0) 1710 { 1711 tmp[l] += mulNTL (two.coeff(), bufFactors[l + 1]); 1712 two++; 1713 } 1714 } 1715 if (degBuf > 0 && degPi > 0) 1716 { 1717 for (k= 1; k <= (int) ceil (j/2.0); k++) 1718 { 1719 if (k != j - k + 1) 1720 { 1721 if (one.exp() == j - k + 1 && two.exp() == j - k + 1) 1722 { 1723 tmp[l] += mulNTL ((bufFactors[l + 1][k]+one.coeff()),(Pi[l-1] [k] + 1724 two.coeff())) - M (k + 1, l + 1) - M (j - k + 2, l + 1); 1725 one++; 1726 two++; 1727 } 1728 else if (one.exp() == j - k + 1) 1729 { 1730 tmp[l] += mulNTL ((bufFactors[l+1][k]+one.coeff()),Pi[l - 1] [k]) - 1731 M (k + 1, l + 1); 1732 one++; 1733 } 1734 else if (two.exp() == j - k + 1) 1735 { 1736 tmp[l] += mulNTL (bufFactors[l+1][k],(Pi[l-1] [k] + two.coeff())) - 1737 M (k + 1, l + 1); 1738 two++; 1739 } 1740 } 1741 else 1742 tmp[l] += M (k + 1, l + 1); 1743 } 1744 } 1745 Pi[l] += tmp[l]*xToJ*F.mvar(); 1746 }*/ 1747 return; 1748 } 1749 1750 void 1751 henselLift122 (const CanonicalForm& F, CFList& factors, int l, CFArray& Pi, 1752 CFList& diophant, CFMatrix& M, const CFArray& LCs, bool sort) 1753 { 1754 if (sort) 1755 sortList (factors, Variable (1)); 1756 Pi= CFArray (factors.length() - 2); 1757 CFList bufFactors2= factors; 1758 bufFactors2.removeFirst(); 1759 diophant.removeFirst(); 1760 CFListIterator iter= diophant; 1761 CanonicalForm s,t; 1762 extgcd (bufFactors2.getFirst(), bufFactors2.getLast(), s, t); 1763 diophant= CFList(); 1764 diophant.append (t); 1765 diophant.append (s); 1766 DEBOUTLN (cerr, "diophant= " << diophant); 1767 1768 CFArray bufFactors= CFArray (bufFactors2.length()); 1769 int i= 0; 1770 for (CFListIterator k= bufFactors2; k.hasItem(); i++, k++) 1771 bufFactors[i]= replaceLc (k.getItem(), LCs [i]); 1772 1773 Variable x= F.mvar(); 1774 if (degree (bufFactors[0], x) > 0 && degree (bufFactors [1], x) > 0) 1775 { 1776 M (1, 1)= mulNTL (bufFactors [0] [0], bufFactors[1] [0]); 1777 Pi [0]= M (1, 1) + (mulNTL (bufFactors [0] [1], bufFactors[1] [0]) + 1778 mulNTL (bufFactors [0] [0], bufFactors [1] [1]))*x; 1779 } 1780 else if (degree (bufFactors[0], x) > 0) 1781 { 1782 M (1, 1)= mulNTL (bufFactors [0] [0], bufFactors[1]); 1783 Pi [0]= M (1, 1) + 1784 mulNTL (bufFactors [0] [1], bufFactors[1])*x; 1785 } 1786 else if (degree (bufFactors[1], x) > 0) 1787 { 1788 M (1, 1)= mulNTL (bufFactors [0], bufFactors[1] [0]); 1789 Pi [0]= M (1, 1) + 1790 mulNTL (bufFactors [0], bufFactors[1] [1])*x; 1791 } 1792 else 1793 { 1794 M (1, 1)= mulNTL (bufFactors [0], bufFactors[1]); 1795 Pi [0]= M (1, 1); 1796 } 1797 1798 for (i= 1; i < l; i++) 1799 henselStep122 (F, bufFactors2, bufFactors, diophant, M, Pi, i, LCs); 1800 1801 factors= CFList(); 1802 for (i= 0; i < bufFactors.size(); i++) 1803 factors.append (bufFactors[i]); 1804 return; 1805 } 1806 1807 /// solve \f$ E=sum_{i= 1}^{r}{\sigma_{i}prod_{j=1, j\neq i}^{r}{f_{i}}}\f$ 1808 /// mod M, products contains \f$ prod_{j=1, j\neq i}^{r}{f_{i}}} \f$ 1809 static inline 1810 CFList 1811 diophantine (const CFList& recResult, const CFList& factors, 1812 const CFList& products, const CFList& M, const CanonicalForm& E) 1813 { 1814 if (M.isEmpty()) 1815 { 1816 CFList result; 1817 CFListIterator j= factors; 1818 CanonicalForm buf; 1819 for (CFListIterator i= recResult; i.hasItem(); i++, j++) 1820 { 1821 ASSERT (E.isUnivariate() || E.inCoeffDomain(), 1822 "constant or univariate poly expected"); 1823 ASSERT (i.getItem().isUnivariate() || i.getItem().inCoeffDomain(), 1824 "constant or univariate poly expected"); 1825 ASSERT (j.getItem().isUnivariate() || j.getItem().inCoeffDomain(), 1826 "constant or univariate poly expected"); 1827 buf= mulNTL (E, i.getItem()); 1828 result.append (modNTL (buf, j.getItem())); 1829 } 1830 return result; 1831 } 1832 Variable y= M.getLast().mvar(); 1833 CFList bufFactors= factors; 1834 for (CFListIterator i= bufFactors; i.hasItem(); i++) 1835 i.getItem()= mod (i.getItem(), y); 1836 CFList bufProducts= products; 1837 for (CFListIterator i= bufProducts; i.hasItem(); i++) 1838 i.getItem()= mod (i.getItem(), y); 1839 CFList buf= M; 1840 buf.removeLast(); 1841 CanonicalForm bufE= mod (E, y); 1842 CFList recDiophantine= diophantine (recResult, bufFactors, bufProducts, buf, 1843 bufE); 1844 1845 CanonicalForm e= E; 1846 CFListIterator j= products; 1847 for (CFListIterator i= recDiophantine; i.hasItem(); i++, j++) 1848 e -= mulMod (i.getItem(), j.getItem(), M); 1849 1850 CFList result= recDiophantine; 1851 int d= degree (M.getLast()); 1852 CanonicalForm coeffE; 1853 for (int i= 1; i < d; i++) 1854 { 1855 if (degree (e, y) > 0) 1856 coeffE= e[i]; 1857 else 1858 coeffE= 0; 1859 if (!coeffE.isZero()) 1860 { 1861 CFListIterator k= result; 1862 recDiophantine= diophantine (recResult, bufFactors, bufProducts, buf, 1863 coeffE); 1864 CFListIterator l= products; 1865 for (j= recDiophantine; j.hasItem(); j++, k++, l++) 1866 { 1867 k.getItem() += j.getItem()*power (y, i); 1868 e -= mulMod (j.getItem()*power (y, i), l.getItem(), M); 1869 } 1870 } 1871 if (e.isZero()) 1872 break; 1873 } 1874 return result; 1875 } 1876 1877 // non monic case 1878 static inline 1879 CFList 1880 multiRecDiophantine2 (const CanonicalForm& F, const CFList& factors, 1881 const CFList& recResult, const CFList& M, const int d) 1882 { 1883 Variable y= F.mvar(); 1884 CFList result; 1885 CFListIterator i; 1886 CanonicalForm e= 1; 1887 CFListIterator j= factors; 1888 CFList p; 1889 CFArray bufFactors= CFArray (factors.length()); 1890 CanonicalForm yToD= power (y, d); 1891 int k= 0; 1892 for (CFListIterator i= factors; i.hasItem(); i++, k++) 1893 bufFactors [k]= i.getItem(); 1894 CanonicalForm b; 1895 CFList buf= M; 1896 buf.removeLast(); 1897 buf.append (yToD); 1898 for (k= 0; k < factors.length(); k++) //TODO compute b's faster 1899 { 1900 b= 1; 1901 if (fdivides (bufFactors[k], F)) 1902 b= F/bufFactors[k]; 1903 else 1904 { 1905 for (int l= 0; l < factors.length(); l++) 1906 { 1907 if (l == k) 1908 continue; 1909 else 1910 { 1911 b= mulMod (b, bufFactors[l], buf); 1912 } 1913 } 1914 } 1915 p.append (b); 1916 } 1917 j= p; 1918 for (CFListIterator i= recResult; i.hasItem(); i++, j++) 1919 e -= mulMod (i.getItem(), j.getItem(), M); 1920 if (e.isZero()) 1921 return recResult; 1922 CanonicalForm coeffE; 1923 result= recResult; 1924 CanonicalForm g; 1925 buf.removeLast(); 1926 for (int i= 1; i < d; i++) 1927 { 1928 if (degree (e, y) > 0) 1929 coeffE= e[i]; 1930 else 1931 coeffE= 0; 1932 if (!coeffE.isZero()) 1933 { 1934 CFListIterator k= result; 1935 CFListIterator l= p; 1936 j= recResult; 1937 int ii= 0; 1938 CanonicalForm dummy; 1939 CFList recDiophantine; 1940 CFList buf2, buf3; 1941 buf2= factors; 1942 buf3= p; 1943 for (CFListIterator iii= buf2; iii.hasItem(); iii++) 1944 iii.getItem()= mod (iii.getItem(), y); 1945 for (CFListIterator iii= buf3; iii.hasItem(); iii++) 1946 iii.getItem()= mod (iii.getItem(), y); 1947 recDiophantine= diophantine (recResult, buf2, buf3, buf, coeffE); 1948 CFListIterator iter= recDiophantine; 1949 for (; j.hasItem(); j++, k++, l++, ii++, iter++) 1950 { 1951 k.getItem() += iter.getItem()*power (y, i); 1952 e -= mulMod (iter.getItem()*power (y, i), l.getItem(), M); 1953 } 1954 } 1955 if (e.isZero()) 1956 break; 1957 } 1958 1959 #ifdef DEBUGOUTPUT 1960 CanonicalForm test= 0; 1961 j= p; 1962 for (CFListIterator i= result; i.hasItem(); i++, j++) 1963 test += mod (i.getItem()*j.getItem(), power (y, d)); 1964 DEBOUTLN (cerr, "test= " << test); 1965 #endif 1966 return result; 1967 } 1968 1969 // so far only tested for two! factor Hensel lifting 1970 static inline 1971 void 1972 henselStep2 (const CanonicalForm& F, const CFList& factors, CFArray& bufFactors, 1973 const CFList& diophant, CFMatrix& M, CFArray& Pi, 1974 const CFList& products, int j, const CFList& MOD) 1975 { 1976 CanonicalForm E; 1977 CanonicalForm xToJ= power (F.mvar(), j); 1978 Variable x= F.mvar(); 1979 1980 // compute the error 1981 #ifdef DEBUGOUTPUT 1982 CanonicalForm test= 1; 1983 for (int i= 0; i < factors.length(); i++) 1984 { 1985 if (i == 0) 1986 test *= mod (bufFactors [i], power (x, j)); 1987 else 1988 test *= bufFactors[i]; 1989 } 1990 test= mod (test, power (x, j)); 1991 test= mod (test, MOD); 1992 CanonicalForm test2= mod (F, power (x, j - 1)) - mod (test, power (x, j-1)); 1993 DEBOUTLN (cerr, "test= " << test2); 1994 #endif 1995 1996 if (degree (Pi [factors.length() - 2], x) > 0) 1997 E= F[j] - Pi [factors.length() - 2] [j]; 1998 else 1999 E= F[j]; 2000 2001 CFArray buf= CFArray (diophant.length()); 2002 2003 // actual lifting 2004 CFList diophantine2= diophantine (diophant, factors, products, MOD, E); 2005 2006 int k= 0; 2007 for (CFListIterator i= diophantine2; k < factors.length(); k++, i++) 2008 { 2009 buf[k]= i.getItem(); 2010 bufFactors[k] += xToJ*i.getItem(); 2011 } 2012 2013 // update Pi [0] 2014 int degBuf0= degree (bufFactors[0], x); 2015 int degBuf1= degree (bufFactors[1], x); 2016 if (degBuf0 > 0 && degBuf1 > 0) 2017 { 2018 M (j + 1, 1)= mulMod (bufFactors[0] [j], bufFactors[1] [j], MOD); 2019 if (j + 2 <= M.rows()) 2020 M (j + 2, 1)= mulMod (bufFactors[0] [j + 1], bufFactors[1] [j + 1], MOD); 2021 } 2022 CanonicalForm uIZeroJ; 2023 2024 if (degBuf0 > 0 && degBuf1 > 0) 2025 uIZeroJ= mulMod (bufFactors[0] [0], buf[1], MOD) + 2026 mulMod (bufFactors[1] [0], buf[0], MOD); 2027 else if (degBuf0 > 0) 2028 uIZeroJ= mulMod (buf[0], bufFactors[1], MOD); 2029 else if (degBuf1 > 0) 2030 uIZeroJ= mulMod (bufFactors[0], buf[1], MOD); 2031 else 2032 uIZeroJ= 0; 2033 Pi [0] += xToJ*uIZeroJ; 2034 2035 CFArray tmp= CFArray (factors.length() - 1); 2036 for (k= 0; k < factors.length() - 1; k++) 2037 tmp[k]= 0; 2038 CFIterator one, two; 2039 one= bufFactors [0]; 2040 two= bufFactors [1]; 2041 if (degBuf0 > 0 && degBuf1 > 0) 2042 { 2043 while (one.exp() > j) one++; 2044 while (two.exp() > j) two++; 2045 for (k= 1; k <= (int) ceil (j/2.0); k++) 2046 { 2047 if (k != j - k + 1) 2048 { 2049 if (one.exp() == j - k + 1 && two.exp() == j - k + 1) 2050 { 2051 tmp[0] += mulMod ((bufFactors[0] [k] + one.coeff()), 2052 (bufFactors[1] [k] + two.coeff()), MOD) - M (k + 1, 1) - 2053 M (j - k + 2, 1); 2054 one++; 2055 two++; 2056 } 2057 else if (one.exp() == j - k + 1) 2058 { 2059 tmp[0] += mulMod ((bufFactors[0] [k] + one.coeff()), 2060 bufFactors[1] [k], MOD) - M (k + 1, 1); 2061 one++; 2062 } 2063 else if (two.exp() == j - k + 1) 2064 { 2065 tmp[0] += mulMod (bufFactors[0] [k], (bufFactors[1] [k] + 2066 two.coeff()), MOD) - M (k + 1, 1); 2067 two++; 2068 } 2069 } 2070 else 2071 { 2072 tmp[0] += M (k + 1, 1); 2073 } 2074 } 2075 2076 if (j + 2 <= M.rows()) 2077 { 2078 if (degBuf0 >= j + 1 && degBuf1 >= j + 1) 2079 tmp [0] += mulMod ((bufFactors [0] [j + 1]+ bufFactors [0] [0]), 2080 (bufFactors [1] [j + 1] + bufFactors [1] [0]), MOD) 2081 - M(1,1) - M (j + 2,1); 2082 else if (degBuf0 >= j + 1) 2083 tmp[0] += mulMod (bufFactors [0] [j+1], bufFactors [1] [0], MOD); 2084 else if (degBuf1 >= j + 1) 2085 tmp[0] += mulMod (bufFactors [0] [0], bufFactors [1] [j + 1], MOD); 2086 } 2087 } 2088 Pi [0] += tmp[0]*xToJ*F.mvar(); 2089 2090 // update Pi [l] 2091 int degPi, degBuf; 2092 for (int l= 1; l < factors.length() - 1; l++) 2093 { 2094 degPi= degree (Pi [l - 1], x); 2095 degBuf= degree (bufFactors[l + 1], x); 2096 if (degPi > 0 && degBuf > 0) 2097 M (j + 1, l + 1)= mulMod (Pi [l - 1] [j], bufFactors[l + 1] [j], MOD); 2098 if (j == 1) 2099 { 2100 if (degPi > 0 && degBuf > 0) 2101 Pi [l] += xToJ*(mulMod ((Pi [l - 1] [0] + Pi [l - 1] [j]), 2102 (bufFactors[l + 1] [0] + buf[l + 1]), MOD) - M (j + 1, l +1)- 2103 M (1, l + 1)); 2104 else if (degPi > 0) 2105 Pi [l] += xToJ*(mulMod (Pi [l - 1] [j], bufFactors[l + 1], MOD)); 2106 else if (degBuf > 0) 2107 Pi [l] += xToJ*(mulMod (Pi [l - 1], buf[l + 1], MOD)); 2108 } 2109 else 2110 { 2111 if (degPi > 0 && degBuf > 0) 2112 { 2113 uIZeroJ= mulMod (uIZeroJ, bufFactors [l + 1] [0], MOD); 2114 uIZeroJ += mulMod (Pi [l - 1] [0], buf [l + 1], MOD); 2115 } 2116 else if (degPi > 0) 2117 uIZeroJ= mulMod (uIZeroJ, bufFactors [l + 1], MOD); 2118 else if (degBuf > 0) 2119 { 2120 uIZeroJ= mulMod (uIZeroJ, bufFactors [l + 1] [0], MOD); 2121 uIZeroJ += mulMod (Pi [l - 1], buf[l + 1], MOD); 2122 } 2123 Pi[l] += xToJ*uIZeroJ; 2124 } 2125 one= bufFactors [l + 1]; 2126 two= Pi [l - 1]; 2127 if (two.exp() == j + 1) 2128 { 2129 if (degBuf > 0 && degPi > 0) 2130 { 2131 tmp[l] += mulMod (two.coeff(), bufFactors[l + 1][0], MOD); 2132 two++; 2133 } 2134 else if (degPi > 0) 2135 { 2136 tmp[l] += mulMod (two.coeff(), bufFactors[l + 1], MOD); 2137 two++; 2138 } 2139 } 2140 if (degBuf > 0 && degPi > 0) 2141 { 2142 for (k= 1; k <= (int) ceil (j/2.0); k++) 2143 { 2144 if (k != j - k + 1) 2145 { 2146 if (one.exp() == j - k + 1 && two.exp() == j - k + 1) 2147 { 2148 tmp[l] += mulMod ((bufFactors[l + 1] [k] + one.coeff()), 2149 (Pi[l - 1] [k] + two.coeff()), MOD) - M (k + 1, l + 1) - 2150 M (j - k + 2, l + 1); 2151 one++; 2152 two++; 2153 } 2154 else if (one.exp() == j - k + 1) 2155 { 2156 tmp[l] += mulMod ((bufFactors[l + 1] [k] + one.coeff()), 2157 Pi[l - 1] [k], MOD) - M (k + 1, l + 1); 2158 one++; 2159 } 2160 else if (two.exp() == j - k + 1) 2161 { 2162 tmp[l] += mulMod (bufFactors[l + 1] [k], 2163 (Pi[l - 1] [k] + two.coeff()), MOD) - M (k + 1, l + 1); 2164 two++; 2165 } 2166 } 2167 else 2168 tmp[l] += M (k + 1, l + 1); 2169 } 2170 } 2171 Pi[l] += tmp[l]*xToJ*F.mvar(); 2172 } 2173 2174 return; 2175 } 2176 2177 // wrt. Variable (1) 2178 CanonicalForm replaceLC (const CanonicalForm& F, const CanonicalForm& c) 2179 { 2180 if (degree (F, 1) <= 0) 2181 return c; 2182 else 2183 { 2184 CanonicalForm result= swapvar (F, Variable (F.level() + 1), Variable (1)); 2185 result += (swapvar (c, Variable (F.level() + 1), Variable (1)) 2186 - LC (result))*power (result.mvar(), degree (result)); 2187 return swapvar (result, Variable (F.level() + 1), Variable (1)); 2188 } 2189 } 2190 2191 // so far only for two factor Hensel lifting 2192 CFList 2193 henselLift232 (const CFList& eval, const CFList& factors, int* l, CFList& 2194 diophant, CFArray& Pi, CFMatrix& M, const CFList& LCs1, 2195 const CFList& LCs2) 2196 { 2197 CFList buf= factors; 2198 int k= 0; 2199 int liftBoundBivar= l[k]; 2200 CFList bufbuf= factors; 2201 Variable v= Variable (2); 2202 2203 CFList MOD; 2204 MOD.append (power (Variable (2), liftBoundBivar)); 2205 CFArray bufFactors= CFArray (factors.length()); 2206 k= 0; 2207 CFListIterator j= eval; 2208 j++; 2209 CFListIterator iter1= LCs1; 2210 CFListIterator iter2= LCs2; 2211 iter1++; 2212 iter2++; 2213 bufFactors[0]= replaceLC (buf.getFirst(), iter1.getItem()); 2214 bufFactors[1]= replaceLC (buf.getLast(), iter2.getItem()); 2215 2216 CFListIterator i= buf; 2217 i++; 2218 Variable y= j.getItem().mvar(); 2219 if (y.level() != 3) 2220 y= Variable (3); 2221 2222 Pi[0]= mod (Pi[0], power (v, liftBoundBivar)); 2223 M (1, 1)= Pi[0]; 2224 if (degree (bufFactors[0], y) > 0 && degree (bufFactors [1], y) > 0) 2225 Pi [0] += (mulMod (bufFactors [0] [1], bufFactors[1] [0], MOD) + 2226 mulMod (bufFactors [0] [0], bufFactors [1] [1], MOD))*y; 2227 else if (degree (bufFactors[0], y) > 0) 2228 Pi [0] += mulMod (bufFactors [0] [1], bufFactors[1], MOD)*y; 2229 else if (degree (bufFactors[1], y) > 0) 2230 Pi [0] += mulMod (bufFactors [0], bufFactors[1] [1], MOD)*y; 2231 2232 CFList products; 2233 for (int i= 0; i < bufFactors.size(); i++) 2234 { 2235 if (degree (bufFactors[i], y) > 0) 2236 products.append (M (1, 1)/bufFactors[i] [0]); 2237 else 2238 products.append (M (1, 1)/bufFactors[i]); 2239 } 2240 2241 for (int d= 1; d < l[1]; d++) 2242 henselStep2 (j.getItem(), buf, bufFactors, diophant, M, Pi, products, d, MOD); 2243 CFList result; 2244 for (k= 0; k < factors.length(); k++) 2245 result.append (bufFactors[k]); 2246 return result; 2247 } 2248 2249 2250 CFList 2251 henselLift2 (const CFList& F, const CFList& factors, const CFList& MOD, CFList& 2252 diophant, CFArray& Pi, CFMatrix& M, const int lOld, int& 2253 lNew, const CFList& LCs1, const CFList& LCs2) 2254 { 2255 int k= 0; 2256 CFArray bufFactors= CFArray (factors.length()); 2257 bufFactors[0]= replaceLC (factors.getFirst(), LCs1.getLast()); 2258 bufFactors[1]= replaceLC (factors.getLast(), LCs2.getLast()); 2259 CFList buf= factors; 2260 Variable y= F.getLast().mvar(); 2261 Variable x= F.getFirst().mvar(); 2262 CanonicalForm xToLOld= power (x, lOld); 2263 Pi [0]= mod (Pi[0], xToLOld); 2264 M (1, 1)= Pi [0]; 2265 2266 if (degree (bufFactors[0], y) > 0 && degree (bufFactors [1], y) > 0) 2267 Pi [0] += (mulMod (bufFactors [0] [1], bufFactors[1] [0], MOD) + 2268 mulMod (bufFactors [0] [0], bufFactors [1] [1], MOD))*y; 2269 else if (degree (bufFactors[0], y) > 0) 2270 Pi [0] += mulMod (bufFactors [0] [1], bufFactors[1], MOD)*y; 2271 else if (degree (bufFactors[1], y) > 0) 2272 Pi [0] += mulMod (bufFactors [0], bufFactors[1] [1], MOD)*y; 2273 2274 CFList products; 2275 for (int i= 0; i < bufFactors.size(); i++) 2276 { 2277 if (degree (bufFactors[i], y) > 0) 2278 { 2279 ASSERT (fdivides (bufFactors[i][0], M (1, 1)), "expected exact division"); 2280 products.append (M (1, 1)/bufFactors[i] [0]); 2281 } 2282 else 2283 { 2284 ASSERT (fdivides (bufFactors[i], M (1, 1)), "expected exact division"); 2285 products.append (M (1, 1)/bufFactors[i]); 2286 } 2287 } 2288 2289 for (int d= 1; d < lNew; d++) 2290 henselStep2 (F.getLast(),buf,bufFactors, diophant, M, Pi, products, d, MOD); 2291 2292 CFList result; 2293 for (k= 0; k < factors.length(); k++) 2294 result.append (bufFactors[k]); 2295 return result; 2296 } 2297 2298 // so far only for two! factor Hensel lifting 2299 CFList 2300 henselLift2 (const CFList& eval, const CFList& factors, int* l, const int 2301 lLength, bool sort, const CFList& LCs1, const CFList& LCs2, 2302 const CFArray& Pi, const CFList& diophant) 2303 { 2304 CFList bufDiophant= diophant; 2305 CFList buf= factors; 2306 if (sort) 2307 sortList (buf, Variable (1)); 2308 CFArray bufPi= Pi; 2309 CFMatrix M= CFMatrix (l[1], factors.length()); 2310 CFList result= henselLift232(eval, buf, l, bufDiophant, bufPi, M, LCs1, LCs2); 2311 if (eval.length() == 2) 2312 return result; 2313 CFList MOD; 2314 for (int i= 0; i < 2; i++) 2315 MOD.append (power (Variable (i + 2), l[i])); 2316 CFListIterator j= eval; 2317 j++; 2318 CFList bufEval; 2319 bufEval.append (j.getItem()); 2320 j++; 2321 CFListIterator jj= LCs1; 2322 CFListIterator jjj= LCs2; 2323 CFList bufLCs1, bufLCs2; 2324 jj++, jjj++; 2325 bufLCs1.append (jj.getItem()); 2326 bufLCs2.append (jjj.getItem()); 2327 jj++, jjj++; 2328 2329 for (int i= 2; i <= lLength && j.hasItem(); i++, j++, jj++, jjj++) 2330 { 2331 bufEval.append (j.getItem()); 2332 bufLCs1.append (jj.getItem()); 2333 bufLCs2.append (jjj.getItem()); 2334 M= CFMatrix (l[i], factors.length()); 2335 result= henselLift2 (bufEval, result, MOD, bufDiophant, bufPi, M, l[i - 1], 2336 l[i], bufLCs1, bufLCs2); 2337 MOD.append (power (Variable (i + 2), l[i])); 2338 bufEval.removeFirst(); 2339 bufLCs1.removeFirst(); 2340 bufLCs2.removeFirst(); 2341 } 2342 return result; 2343 } 2344 1555 2345 #endif 1556 2346 /* HAVE_NTL */ -
factory/facHensel.h
rcde708 r08daea 364 364 ); 365 365 366 /// two factor Hensel lifting from univariate to bivariate, factors need not to 367 /// be monic 368 void 369 henselLift122 (const CanonicalForm& F,///< [in] a bivariate poly 370 CFList& factors, ///< [in, out] a list of univariate polys 371 ///< lifted factors 372 int l, ///< [in] lift bound 373 CFArray& Pi, ///< [in, out] stores intermediate results 374 CFList& diophant, ///< [in, out] result of diophantine 375 CFMatrix& M, ///< [in, out] stores intermediate results 376 const CFArray& LCs, ///< [in] leading coefficients 377 bool sort ///< [in] if true factors are sorted by 378 ///< their degree 379 ); 380 381 /// two factor Hensel lifting from bivariate to multivariate, factors need not 382 /// to be monic 383 /// 384 /// @return @a henselLift122 returns a list of lifted factors 385 CFList 386 henselLift2 (const CFList& eval, ///< [in] a list of polynomials the last 387 ///< element is a compressed multivariate 388 ///< poly, last but one element equals the 389 ///< last elements modulo its main variable 390 ///< and so on. The first element is a 391 ///< compressed bivariate poly. 392 const CFList& factors,///< [in] bivariate factors 393 int* l, ///< [in] lift bounds 394 const int lLength, ///< [in] length of l 395 bool sort, ///< [in] if true factors are sorted by 396 ///< their degree in Variable(1) 397 const CFList& LCs1, ///< [in] a list of evaluated LC of first 398 ///< factor 399 const CFList& LCs2, ///< [in] a list of evaluated LC of second 400 ///< factor 401 const CFArray& Pi, ///< [in] intermediate result 402 const CFList& diophant///< [in] result of diophantine 403 ); 404 366 405 #endif 367 406 /* FAC_HENSEL_H */ -
factory/ffreval.cc
rcde708 r08daea 59 59 } 60 60 61 /* ------------------------------------------------------------------------ */62 /* forward declarations: fin_ezgcd stuff*/63 static bool findeval_P( const CanonicalForm & F, const CanonicalForm & G, CanonicalForm & Fb, CanonicalForm & Gb, CanonicalForm & Db, REvaluation & b, int delta, int degF, int degG, int bound, int & counter );64 static void solveF_P ( const CFArray & P, const CFArray & Q, const CFArray & S, const CFArray & T, const CanonicalForm & C, int r, CFArray & a );65 static CanonicalForm derivAndEval_P ( const CanonicalForm & f, int n, const Variable & x, const CanonicalForm & a );66 //static CanonicalForm checkCombination_P ( const CanonicalForm & W, const Evaluation & a, const IteratedFor & e, int k );67 static CFArray findCorrCoeffs_P ( const CFArray & P, const CFArray & Q, const CFArray & P0, const CFArray & Q0, const CFArray & S, const CFArray & T, const CanonicalForm & C, const Evaluation & I, int r, int k, int h, int * n );68 static bool liftStep_P ( CFArray & P, int k, int r, int t, const Evaluation & A, const CFArray & lcG, const CanonicalForm & Uk, int * n, int h );69 static bool Hensel_P ( const CanonicalForm & U, CFArray & G, const CFArray & lcG, const Evaluation & A, const Variable & x );70 static bool hasFirstAlgVar( const CanonicalForm & f, Variable & a );71 72 CanonicalForm fin_ezgcd( const CanonicalForm & FF, const CanonicalForm & GG )73 {74 CanonicalForm F, G, f, g, d, Fb, Gb, Db, Fbt, Gbt, Dbt, B0, B, D0, lcF, lcG, lcD;75 CFArray DD( 1, 2 ), lcDD( 1, 2 );76 int degF, degG, delta, count, maxeval;77 maxeval = getCharacteristic(); // bound on the number of eval. to use78 count = 0; // number of eval. used79 REvaluation b, bt;80 bool gcdfound = false;81 Variable x = Variable(1);82 f = content( FF, x ); g = content( GG, x ); d = gcd( f, g );83 F = FF / f; G = GG / g;84 if( F.isUnivariate() && G.isUnivariate() )85 {86 if( F.mvar() == G.mvar() )87 d *= gcd( F, G );88 return d;89 }90 if( gcd_test_one( F, G, false ) )91 return d;92 93 lcF = LC( F, x ); lcG = LC( G, x );94 lcD = gcd( lcF, lcG );95 delta = 0;96 degF = degree( F, x ); degG = degree( G, x );97 Variable a,bv;98 if(hasFirstAlgVar(F,a))99 {100 if(hasFirstAlgVar(G,bv))101 {102 if(bv.level() > a.level())103 a = bv;104 }105 b = REvaluation( 2, tmax(F.level(), G.level()), AlgExtRandomF( a ) );106 }107 else // F not in extension108 {109 if(hasFirstAlgVar(G,a))110 b = REvaluation( 2, tmax(F.level(), G.level()), AlgExtRandomF( a ) );111 else // both not in extension112 b = REvaluation( 2, tmax(F.level(), G.level()), FFRandom() );113 }114 while( !gcdfound )115 {116 if( !findeval_P( F, G, Fb, Gb, Db, b, delta, degF, degG, maxeval, count ))117 { // too many eval. used --> try another method118 Off( SW_USE_EZGCD_P );119 d *= gcd( F, G );120 On( SW_USE_EZGCD_P );121 return d;122 }123 delta = degree( Db );124 if( delta == 0 )125 return d;126 while( true )127 {128 bt = b;129 if( !findeval_P( F, G, Fbt, Gbt, Dbt, bt, delta+1, degF, degG, maxeval, count ))130 { // too many eval. used --> try another method131 Off( SW_USE_EZGCD_P );132 d *= gcd( F, G );133 On( SW_USE_EZGCD_P );134 return d;135 }136 int dd = degree( Dbt );137 if( dd == 0 )138 return d;139 if( dd == delta )140 break;141 if( dd < delta )142 {143 delta = dd;144 b = bt;145 Db = Dbt; Fb = Fbt; Gb = Gbt;146 }147 }148 if( degF <= degG && delta == degF && fdivides( F, G ) )149 return d*F;150 if( degG < degF && delta == degG && fdivides( G, F ) )151 return d*G;152 if( delta != degF && delta != degG )153 {154 bool B_is_F;155 CanonicalForm xxx;156 DD[1] = Fb / Db;157 xxx = gcd( DD[1], Db );158 if( xxx.inCoeffDomain() )159 {160 B = F;161 DD[2] = Db;162 lcDD[1] = lcF;163 lcDD[2] = lcF;164 B *= lcF;165 B_is_F = true;166 }167 else168 {169 DD[1] = Gb / Db;170 xxx = gcd( DD[1], Db );171 if( xxx.inCoeffDomain() )172 {173 B = G;174 DD[2] = Db;175 lcDD[1] = lcG;176 lcDD[2] = lcG;177 B *= lcG;178 B_is_F = false;179 }180 else // special case handling181 {182 Off( SW_USE_EZGCD_P );183 d *= gcd( F, G ); // try another method184 On( SW_USE_EZGCD_P );185 return d;186 }187 }188 DD[2] = DD[2] * ( b( lcDD[2] ) / lc( DD[2] ) );189 DD[1] = DD[1] * ( b( lcDD[1] ) / lc( DD[1] ) );190 191 gcdfound = Hensel_P( B, DD, lcDD, b, x );192 193 if( gcdfound )194 {195 CanonicalForm cand = DD[2] / content( DD[2], Variable(1) );196 if( B_is_F )197 gcdfound = fdivides( cand, G );198 else199 gcdfound = fdivides( cand, F );200 }201 }202 delta++;203 }204 return d * DD[2] / content( DD[2],Variable(1) );205 }206 207 208 static bool hasFirstAlgVar( const CanonicalForm & f, Variable & a )209 {210 if( f.inBaseDomain() ) // f has NO alg. variable211 return false;212 if( f.level()<0 ) // f has only alg. vars, so take the first one213 {214 a = f.mvar();215 return true;216 }217 for(CFIterator i=f; i.hasTerms(); i++)218 if( hasFirstAlgVar( i.coeff(), a ))219 return true; // 'a' is already set220 return false;221 }222 223 224 static bool findeval_P( const CanonicalForm & F, const CanonicalForm & G, CanonicalForm & Fb, CanonicalForm & Gb, CanonicalForm & Db, REvaluation & b, int delta, int degF, int degG, int maxeval, int & count )225 {226 if( delta != 0 )227 {228 b.nextpoint();229 if( count++ > maxeval )230 return false; // too many eval. used231 }232 while( true )233 {234 Fb = b( F );235 if( degree( Fb ) == degF )236 {237 Gb = b( G );238 if( degree( Gb ) == degG )239 {240 Db = gcd( Fb, Gb );241 if( delta > 0 )242 {243 if( degree( Db ) < delta )244 return true;245 }246 else247 return true;248 }249 }250 b.nextpoint();251 if( count++ > maxeval ) // too many eval. used252 return false;253 }254 }255 256 257 static void solveF_P ( const CFArray & P, const CFArray & Q, const CFArray & S, const CFArray & T, const CanonicalForm & C, int r, CFArray & a )258 {259 CanonicalForm bb, b = C;260 for ( int j = 1; j < r; j++ )261 {262 divrem( S[j] * b, Q[j], a[j], bb );263 a[j] = T[j] * b + a[j] * P[j];264 b = bb;265 }266 a[r] = b;267 }268 269 270 static CanonicalForm derivAndEval_P ( const CanonicalForm & f, int n, const Variable & x, const CanonicalForm & a )271 {272 if ( n == 0 )273 return f( a, x );274 if ( f.degree( x ) < n )275 return 0;276 CFIterator i;277 CanonicalForm sum = 0, fact;278 int min, j;279 Variable v = Variable( f.level() + 1 );280 for ( i = swapvar( f, x, v); i.hasTerms() && i.exp() >= n; i++ )281 {282 fact = 1;283 min = i.exp() - n;284 for ( j = i.exp(); j > min; j-- )285 fact *= j;286 sum += fact * i.coeff() * power( v, min );287 }288 return sum( a, v );289 }290 291 292 static CFArray findCorrCoeffs_P ( const CFArray & P, const CFArray & Q, const CFArray & P0, const CFArray & Q0, const CFArray & S, const CFArray & T, const CanonicalForm & C, const Evaluation & I, int r, int k, int h, int * n )293 {294 bool what;295 int i, j, m;296 CFArray A(1,r), a(1,r);297 CanonicalForm C0, Dm, g, prodcomb;298 C0 = I( C, 2, k-1 );299 solveF_P( P0, Q0, S, T, 1, r, a );300 for ( i = 1; i <= r; i++ )301 A[i] = (a[i] * C0) % P0[i];302 for ( m = 0; m <= h && ( m == 0 || Dm != 0 ); m++ )303 {304 Dm = -C;305 prodcomb = 1;306 for ( i = 1; i <= r; i++ )307 {308 Dm += prodcomb * A[i] * Q[i];309 prodcomb *= P[i];310 }311 if ( Dm != 0 )312 {313 if ( k == 2 )314 {315 solveF_P( P0, Q0, S, T, Dm, r, a );316 for ( i = 1; i <= r; i++ )317 A[i] -= a[i];318 }319 else320 {321 IteratedFor e( 2, k-1, m+1 );322 while ( e.iterations_left() )323 {324 j = 0;325 what = true;326 for ( i = 2; i < k; i++ )327 {328 j += e[i];329 if ( e[i] > n[i] )330 {331 what = false;332 break;333 }334 }335 if ( what && j == m+1 )336 {337 g = Dm;338 for ( i = k-1; i >= 2 && ! g.isZero(); i-- )339 g = derivAndEval_P( g, e[i], Variable( i ), I[i] );340 if ( ! g.isZero() )341 {342 prodcomb = 1;343 for ( i = 2; i < k; i++ )344 for ( j = 2; j <= e[i]; j++ )345 prodcomb *= j;346 g /= prodcomb;347 if( ! (g.mvar() > Variable(1)) )348 {349 prodcomb = 1;350 for ( i = k-1; i > 1; i-- )351 prodcomb *= binomialpower( Variable(i), -I[i], e[i] );352 solveF_P( P0, Q0, S, T, g, r, a );353 for ( i = 1; i <= r; i++ )354 A[i] -= a[i] * prodcomb;355 }356 }357 }358 e++;359 }360 }361 }362 }363 return A;364 }365 366 367 static bool liftStep_P ( CFArray & P, int k, int r, int t, const Evaluation & A, const CFArray & lcG, const CanonicalForm & Uk, int * n, int h )368 {369 CFArray K( 1, r ), Q( 1, r ), Q0( 1, r ), P0( 1, r ), S( 1, r ), T( 1, r ), alpha( 1, r );370 CanonicalForm Rm, C, D, xa = Variable(k) - A[k];371 CanonicalForm xa1 = xa, xa2 = xa*xa;372 int i, m;373 for ( i = 1; i <= r; i++ )374 {375 Variable vm = Variable( t + 1 );376 Variable v1 = Variable(1);377 K[i] = swapvar( replaceLc( swapvar( P[i], v1, vm ), swapvar( A( lcG[i], k+1, t ), v1, vm ) ), v1, vm );378 P[i] = A( K[i], k, t );379 }380 Q[r] = 1;381 for ( i = r; i > 1; i-- )382 {383 Q[i-1] = Q[i] * P[i];384 P0[i] = A( P[i], 2, k-1 );385 Q0[i] = A( Q[i], 2, k-1 );386 (void) extgcd( P0[i], Q0[i], S[i], T[i] );387 }388 P0[1] = A( P[1], 2, k-1 );389 Q0[1] = A( Q[1], 2, k-1 );390 (void) extgcd( P0[1], Q0[1], S[1], T[1] );391 for ( m = 1; m <= n[k]+1; m++ )392 {393 Rm = prod( K ) - Uk;394 for ( i = 2; i < k; i++ )395 Rm.mod( binomialpower( Variable(i), -A[i], n[i]+1 ) );396 if ( mod( Rm, xa2 ) != 0 )397 {398 C = derivAndEval_P( Rm, m, Variable( k ), A[k] );399 D = 1;400 for ( i = 2; i <= m; i++ )401 D *= i;402 C /= D;403 alpha = findCorrCoeffs_P( P, Q, P0, Q0, S, T, C, A, r, k, h, n );404 for ( i = 1; i <= r; i++ )405 K[i] -= alpha[i] * xa1;406 }407 xa1 = xa2;408 xa2 *= xa;409 }410 for ( i = 1; i <= r; i++ )411 P[i] = K[i];412 return prod( K ) - Uk == 0;413 }414 415 416 static bool Hensel_P ( const CanonicalForm & U, CFArray & G, const CFArray & lcG, const Evaluation & A, const Variable & x )417 {418 int k, i, h, t = A.max();419 bool goodeval = true;420 CFArray Uk( A.min(), A.max() );421 int * n = new int[t+1];422 Uk[t] = U;423 for ( k = t-1; k > 1; k-- )424 {425 Uk[k] = Uk[k+1]( A[k+1], Variable( k+1 ) );426 n[k] = degree( Uk[k], Variable( k ) );427 }428 for ( k = A.min(); goodeval && (k <= t); k++ )429 {430 h = totaldegree( Uk[k], Variable(A.min()), Variable(k-1) );431 for ( i = A.min(); i <= k; i++ )432 n[i] = degree( Uk[k], Variable(i) );433 goodeval = liftStep_P( G, k, G.max(), t, A, lcG, Uk[k], n, h );434 }435 delete[] n;436 return goodeval;437 } -
factory/ffreval.h
rcde708 r08daea 5 5 6 6 #include "canonicalform.h" 7 #include "cf_eval.h" 8 7 #include "cf_reval.h" 9 8 10 9 class FFREvaluation : public REvaluation … … 17 16 { 18 17 for( int i=min; i<=max; i++ ) 19 values[i] = start[i] = gen->generate(); //generate random point 18 values[i] = start[i] = 0; // start with 0 19 20 nextpoint(); 21 } 22 FFREvaluation( int min, int max, const GFRandom & sample ) : REvaluation( min, max, sample ), start( min, max ) 23 { 24 for( int i=min; i<=max; i++ ) 25 values[i] = start[i] = 0; // start with 0 26 27 nextpoint(); 28 } 29 FFREvaluation( int min, int max, const AlgExtRandomF & sample ) : REvaluation( min, max, sample ), start( min, max ) 30 { 31 for( int i=min; i<=max; i++ ) 32 values[i] = start[i] = 0; // start with 0 20 33 21 34 nextpoint(); 22 35 } 23 36 FFREvaluation& operator= ( const FFREvaluation & e ); 37 24 38 void nextpoint(); 25 39 bool hasNext(); 26 40 }; 27 41 28 CanonicalForm fin_ezgcd ( const CanonicalForm & FF, const CanonicalForm & GG );29 30 42 #endif
Note: See TracChangeset
for help on using the changeset viewer.