Changeset 08daea in git for factory/facHensel.cc
- Timestamp:
- Nov 22, 2010, 11:12:46 AM (13 years ago)
- Branches:
- (u'spielwiese', 'fe61d9c35bf7c61f2b6cbf1b56e25e2f08d536cc')
- Children:
- fb8ba2756f35787214f1a0b5702e31e4b853de97
- Parents:
- cde7084dc141670809afd29cafbd9c571bd9fc3a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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 */
Note: See TracChangeset
for help on using the changeset viewer.