/symja_android_library/matheclipse-external/src/main/java/edu/jas/poly/PolyUtil.java

https://bitbucket.org/axelclk/symja_android_library · Java · 1285 lines · 718 code · 128 blank · 439 comment · 136 complexity · 71da9a1503a6aaec6fd82311a3b8b721 MD5 · raw file

  1. /*
  2. * $Id$
  3. */
  4. package edu.jas.poly;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7. import java.util.Map;
  8. import java.util.SortedMap;
  9. import java.util.TreeMap;
  10. import org.apache.logging.log4j.LogManager;
  11. import org.apache.logging.log4j.Logger;
  12. import edu.jas.arith.BigComplex;
  13. import edu.jas.arith.BigDecimal;
  14. import edu.jas.arith.BigDecimalComplex;
  15. import edu.jas.arith.BigInteger;
  16. import edu.jas.arith.BigRational;
  17. import edu.jas.arith.ModInteger;
  18. import edu.jas.arith.ModIntegerRing;
  19. import edu.jas.arith.Modular;
  20. import edu.jas.arith.ModularRingFactory;
  21. import edu.jas.arith.Product;
  22. import edu.jas.arith.ProductRing;
  23. import edu.jas.arith.Rational;
  24. import edu.jas.arith.Roots;
  25. import edu.jas.structure.Element;
  26. import edu.jas.structure.GcdRingElem;
  27. import edu.jas.structure.RingElem;
  28. import edu.jas.structure.RingFactory;
  29. import edu.jas.structure.StarRingElem;
  30. import edu.jas.structure.UnaryFunctor;
  31. import edu.jas.util.ListUtil;
  32. /**
  33. * Polynomial utilities, for example conversion between different
  34. * representations, evaluation and interpolation.
  35. * @author Heinz Kredel
  36. */
  37. public class PolyUtil {
  38. private static final Logger logger = LogManager.getLogger(PolyUtil.class);
  39. private static final boolean debug = logger.isDebugEnabled();
  40. /**
  41. * Recursive representation. Represent as polynomial in i variables with
  42. * coefficients in n-i variables. Works for arbitrary term orders.
  43. * @param <C> coefficient type.
  44. * @param rfac recursive polynomial ring factory.
  45. * @param A polynomial to be converted.
  46. * @return Recursive represenations of this in the ring rfac.
  47. */
  48. public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> recursive(
  49. GenPolynomialRing<GenPolynomial<C>> rfac, GenPolynomial<C> A) {
  50. GenPolynomial<GenPolynomial<C>> B = rfac.getZERO().copy();
  51. if (A.isZERO()) {
  52. return B;
  53. }
  54. int i = rfac.nvar;
  55. GenPolynomial<C> zero = rfac.getZEROCoefficient();
  56. Map<ExpVector, GenPolynomial<C>> Bv = B.val; //getMap();
  57. for (Map.Entry<ExpVector, C> y : A.getMap().entrySet()) {
  58. ExpVector e = y.getKey();
  59. C a = y.getValue();
  60. ExpVector f = e.contract(0, i);
  61. ExpVector g = e.contract(i, e.length() - i);
  62. GenPolynomial<C> p = Bv.get(f);
  63. if (p == null) {
  64. p = zero;
  65. }
  66. p = p.sum(a, g);
  67. Bv.put(f, p);
  68. }
  69. return B;
  70. }
  71. /**
  72. * Distribute a recursive polynomial to a generic polynomial. Works for
  73. * arbitrary term orders.
  74. * @param <C> coefficient type.
  75. * @param dfac combined polynomial ring factory of coefficients and this.
  76. * @param B polynomial to be converted.
  77. * @return distributed polynomial.
  78. */
  79. public static <C extends RingElem<C>> GenPolynomial<C> distribute(GenPolynomialRing<C> dfac,
  80. GenPolynomial<GenPolynomial<C>> B) {
  81. GenPolynomial<C> C = dfac.getZERO().copy();
  82. if (B.isZERO()) {
  83. return C;
  84. }
  85. Map<ExpVector, C> Cm = C.val; //getMap();
  86. for (Map.Entry<ExpVector, GenPolynomial<C>> y : B.getMap().entrySet()) {
  87. ExpVector e = y.getKey();
  88. GenPolynomial<C> A = y.getValue();
  89. for (Map.Entry<ExpVector, C> x : A.val.entrySet()) {
  90. ExpVector f = x.getKey();
  91. C b = x.getValue();
  92. ExpVector g = e.combine(f);
  93. assert (Cm.get(g) == null);
  94. Cm.put(g, b);
  95. }
  96. }
  97. return C;
  98. }
  99. /**
  100. * Recursive representation. Represent as polynomials in i variables with
  101. * coefficients in n-i variables. Works for arbitrary term orders.
  102. * @param <C> coefficient type.
  103. * @param rfac recursive polynomial ring factory.
  104. * @param L list of polynomials to be converted.
  105. * @return Recursive represenations of the list in the ring rfac.
  106. */
  107. public static <C extends RingElem<C>> List<GenPolynomial<GenPolynomial<C>>> recursive(
  108. GenPolynomialRing<GenPolynomial<C>> rfac, List<GenPolynomial<C>> L) {
  109. return ListUtil.<GenPolynomial<C>, GenPolynomial<GenPolynomial<C>>> map(L, new DistToRec<C>(rfac));
  110. }
  111. /**
  112. * Distribute a recursive polynomial list to a generic polynomial list.
  113. * Works for arbitrary term orders.
  114. * @param <C> coefficient type.
  115. * @param dfac combined polynomial ring factory of coefficients and this.
  116. * @param L list of polynomials to be converted.
  117. * @return distributed polynomial list.
  118. */
  119. public static <C extends RingElem<C>> List<GenPolynomial<C>> distribute(GenPolynomialRing<C> dfac,
  120. List<GenPolynomial<GenPolynomial<C>>> L) {
  121. return ListUtil.<GenPolynomial<GenPolynomial<C>>, GenPolynomial<C>> map(L, new RecToDist<C>(dfac));
  122. }
  123. /**
  124. * BigInteger from ModInteger coefficients, symmetric. Represent as
  125. * polynomial with BigInteger coefficients by removing the modules and
  126. * making coefficients symmetric to 0.
  127. * @param fac result polynomial factory.
  128. * @param A polynomial with ModInteger coefficients to be converted.
  129. * @return polynomial with BigInteger coefficients.
  130. */
  131. public static <C extends RingElem<C> & Modular> GenPolynomial<BigInteger> integerFromModularCoefficients(
  132. GenPolynomialRing<BigInteger> fac, GenPolynomial<C> A) {
  133. return PolyUtil.<C, BigInteger> map(fac, A, new ModSymToInt<C>());
  134. }
  135. /**
  136. * BigInteger from ModInteger coefficients, symmetric. Represent as
  137. * polynomial with BigInteger coefficients by removing the modules and
  138. * making coefficients symmetric to 0.
  139. * @param fac result polynomial factory.
  140. * @param L list of polynomials with ModInteger coefficients to be
  141. * converted.
  142. * @return list of polynomials with BigInteger coefficients.
  143. */
  144. public static <C extends RingElem<C> & Modular> List<GenPolynomial<BigInteger>> integerFromModularCoefficients(
  145. final GenPolynomialRing<BigInteger> fac, List<GenPolynomial<C>> L) {
  146. return ListUtil.<GenPolynomial<C>, GenPolynomial<BigInteger>> map(L,
  147. new UnaryFunctor<GenPolynomial<C>, GenPolynomial<BigInteger>>() {
  148. public GenPolynomial<BigInteger> eval(GenPolynomial<C> c) {
  149. return PolyUtil.<C> integerFromModularCoefficients(fac, c);
  150. }
  151. });
  152. }
  153. /**
  154. * BigInteger from ModInteger coefficients, positive. Represent as
  155. * polynomial with BigInteger coefficients by removing the modules.
  156. * @param fac result polynomial factory.
  157. * @param A polynomial with ModInteger coefficients to be converted.
  158. * @return polynomial with BigInteger coefficients.
  159. */
  160. public static <C extends RingElem<C> & Modular> GenPolynomial<BigInteger> integerFromModularCoefficientsPositive(
  161. GenPolynomialRing<BigInteger> fac, GenPolynomial<C> A) {
  162. return PolyUtil.<C, BigInteger> map(fac, A, new ModToInt<C>());
  163. }
  164. /**
  165. * BigInteger from BigRational coefficients. Represent as polynomial with
  166. * BigInteger coefficients by multiplication with the lcm of the numerators
  167. * of the BigRational coefficients.
  168. * @param fac result polynomial factory.
  169. * @param A polynomial with BigRational coefficients to be converted.
  170. * @return polynomial with BigInteger coefficients.
  171. */
  172. public static GenPolynomial<BigInteger> integerFromRationalCoefficients(GenPolynomialRing<BigInteger> fac,
  173. GenPolynomial<BigRational> A) {
  174. if (A == null || A.isZERO()) {
  175. return fac.getZERO();
  176. }
  177. java.math.BigInteger c = null;
  178. int s = 0;
  179. // lcm of denominators
  180. for (BigRational y : A.val.values()) {
  181. java.math.BigInteger x = y.denominator();
  182. // c = lcm(c,x)
  183. if (c == null) {
  184. c = x;
  185. s = x.signum();
  186. } else {
  187. java.math.BigInteger d = c.gcd(x);
  188. c = c.multiply(x.divide(d));
  189. }
  190. }
  191. if (s < 0) {
  192. c = c.negate();
  193. }
  194. return PolyUtil.<BigRational, BigInteger> map(fac, A, new RatToInt(c));
  195. }
  196. /**
  197. * BigInteger from BigRational coefficients. Represent as polynomial with
  198. * BigInteger coefficients by multiplication with the gcd of the numerators
  199. * and the lcm of the denominators of the BigRational coefficients. <br />
  200. * <b>Author:</b> Axel Kramer
  201. * @param fac result polynomial factory.
  202. * @param A polynomial with BigRational coefficients to be converted.
  203. * @return Object[] with 3 entries: [0]=gcd [1]=lcm and [2]=polynomial with
  204. * BigInteger coefficients.
  205. */
  206. public static Object[] integerFromRationalCoefficientsFactor(GenPolynomialRing<BigInteger> fac,
  207. GenPolynomial<BigRational> A) {
  208. Object[] result = new Object[3];
  209. if (A == null || A.isZERO()) {
  210. result[0] = java.math.BigInteger.ONE;
  211. result[1] = java.math.BigInteger.ZERO;
  212. result[2] = fac.getZERO();
  213. return result;
  214. }
  215. java.math.BigInteger gcd = null;
  216. java.math.BigInteger lcm = null;
  217. int sLCM = 0;
  218. int sGCD = 0;
  219. // lcm of denominators
  220. for (BigRational y : A.val.values()) {
  221. java.math.BigInteger numerator = y.numerator();
  222. java.math.BigInteger denominator = y.denominator();
  223. // lcm = lcm(lcm,x)
  224. if (lcm == null) {
  225. lcm = denominator;
  226. sLCM = denominator.signum();
  227. } else {
  228. java.math.BigInteger d = lcm.gcd(denominator);
  229. lcm = lcm.multiply(denominator.divide(d));
  230. }
  231. // gcd = gcd(gcd,x)
  232. if (gcd == null) {
  233. gcd = numerator;
  234. sGCD = numerator.signum();
  235. } else {
  236. gcd = gcd.gcd(numerator);
  237. }
  238. }
  239. if (sLCM < 0) {
  240. lcm = lcm.negate();
  241. }
  242. if (sGCD < 0) {
  243. gcd = gcd.negate();
  244. }
  245. //System.out.println("gcd* = " + gcd + ", lcm = " + lcm);
  246. result[0] = gcd;
  247. result[1] = lcm;
  248. result[2] = PolyUtil.<BigRational, BigInteger> map(fac, A, new RatToIntFactor(gcd, lcm));
  249. return result;
  250. }
  251. /**
  252. * BigInteger from BigRational coefficients. Represent as polynomial with
  253. * BigInteger coefficients by multiplication with the gcd of the numerators
  254. * and the lcm of the denominators of the BigRational coefficients. <br />
  255. * @param fac result polynomial factory.
  256. * @param gcd of rational coefficient numerators.
  257. * @param lcm of rational coefficient denominators.
  258. * @param A polynomial with BigRational coefficients to be converted.
  259. * @return polynomial with BigInteger coefficients.
  260. */
  261. public static GenPolynomial<BigInteger> integerFromRationalCoefficients(GenPolynomialRing<BigInteger> fac,
  262. java.math.BigInteger gcd, java.math.BigInteger lcm, GenPolynomial<BigRational> A) {
  263. //System.out.println("gcd = " + gcd + ", lcm = " + lcm);
  264. GenPolynomial<BigInteger> Ai = PolyUtil.<BigRational, BigInteger> map(fac, A,
  265. new RatToIntFactor(gcd, lcm));
  266. return Ai;
  267. }
  268. /**
  269. * BigInteger from BigRational coefficients. Represent as list of
  270. * polynomials with BigInteger coefficients by multiplication with the lcm
  271. * of the numerators of the BigRational coefficients of each polynomial.
  272. * @param fac result polynomial factory.
  273. * @param L list of polynomials with BigRational coefficients to be
  274. * converted.
  275. * @return polynomial list with BigInteger coefficients.
  276. */
  277. public static List<GenPolynomial<BigInteger>> integerFromRationalCoefficients(
  278. GenPolynomialRing<BigInteger> fac, List<GenPolynomial<BigRational>> L) {
  279. return ListUtil.<GenPolynomial<BigRational>, GenPolynomial<BigInteger>> map(L, new RatToIntPoly(fac));
  280. }
  281. /**
  282. * From BigInteger coefficients. Represent as polynomial with type C
  283. * coefficients, e.g. ModInteger or BigRational.
  284. * @param <C> coefficient type.
  285. * @param fac result polynomial factory.
  286. * @param A polynomial with BigInteger coefficients to be converted.
  287. * @return polynomial with type C coefficients.
  288. */
  289. public static <C extends RingElem<C>> GenPolynomial<C> fromIntegerCoefficients(GenPolynomialRing<C> fac,
  290. GenPolynomial<BigInteger> A) {
  291. return PolyUtil.<BigInteger, C> map(fac, A, new FromInteger<C>(fac.coFac));
  292. }
  293. /**
  294. * From BigInteger coefficients. Represent as list of polynomials with type
  295. * C coefficients, e.g. ModInteger or BigRational.
  296. * @param <C> coefficient type.
  297. * @param fac result polynomial factory.
  298. * @param L list of polynomials with BigInteger coefficients to be
  299. * converted.
  300. * @return list of polynomials with type C coefficients.
  301. */
  302. public static <C extends RingElem<C>> List<GenPolynomial<C>> fromIntegerCoefficients(
  303. GenPolynomialRing<C> fac, List<GenPolynomial<BigInteger>> L) {
  304. return ListUtil.<GenPolynomial<BigInteger>, GenPolynomial<C>> map(L, new FromIntegerPoly<C>(fac));
  305. }
  306. /**
  307. * Convert to decimal coefficients.
  308. * @param fac result polynomial factory.
  309. * @param A polynomial with Rational coefficients to be converted.
  310. * @return polynomial with BigDecimal coefficients.
  311. */
  312. public static <C extends RingElem<C> & Rational> GenPolynomial<BigDecimal> decimalFromRational(
  313. GenPolynomialRing<BigDecimal> fac, GenPolynomial<C> A) {
  314. return PolyUtil.<C, BigDecimal> map(fac, A, new RatToDec<C>());
  315. }
  316. /**
  317. * Convert to complex decimal coefficients.
  318. * @param fac result polynomial factory.
  319. * @param A polynomial with complex Rational coefficients to be converted.
  320. * @return polynomial with Complex BigDecimal coefficients.
  321. */
  322. public static <C extends RingElem<C> & Rational> GenPolynomial<Complex<BigDecimal>> complexDecimalFromRational(
  323. GenPolynomialRing<Complex<BigDecimal>> fac, GenPolynomial<Complex<C>> A) {
  324. return PolyUtil.<Complex<C>, Complex<BigDecimal>> map(fac, A, new CompRatToDec<C>(fac.coFac));
  325. }
  326. /**
  327. * Real part.
  328. * @param fac result polynomial factory.
  329. * @param A polynomial with BigComplex coefficients to be converted.
  330. * @return polynomial with real part of the coefficients.
  331. */
  332. public static GenPolynomial<BigRational> realPart(GenPolynomialRing<BigRational> fac,
  333. GenPolynomial<BigComplex> A) {
  334. return PolyUtil.<BigComplex, BigRational> map(fac, A, new RealPart());
  335. }
  336. /**
  337. * Imaginary part.
  338. * @param fac result polynomial factory.
  339. * @param A polynomial with BigComplex coefficients to be converted.
  340. * @return polynomial with imaginary part of coefficients.
  341. */
  342. public static GenPolynomial<BigRational> imaginaryPart(GenPolynomialRing<BigRational> fac,
  343. GenPolynomial<BigComplex> A) {
  344. return PolyUtil.<BigComplex, BigRational> map(fac, A, new ImagPart());
  345. }
  346. /**
  347. * Real part.
  348. * @param fac result polynomial factory.
  349. * @param A polynomial with BigComplex coefficients to be converted.
  350. * @return polynomial with real part of the coefficients.
  351. */
  352. public static <C extends RingElem<C>> GenPolynomial<C> realPartFromComplex(GenPolynomialRing<C> fac,
  353. GenPolynomial<Complex<C>> A) {
  354. return PolyUtil.<Complex<C>, C> map(fac, A, new RealPartComplex<C>());
  355. }
  356. /**
  357. * Imaginary part.
  358. * @param fac result polynomial factory.
  359. * @param A polynomial with BigComplex coefficients to be converted.
  360. * @return polynomial with imaginary part of coefficients.
  361. */
  362. public static <C extends RingElem<C>> GenPolynomial<C> imaginaryPartFromComplex(GenPolynomialRing<C> fac,
  363. GenPolynomial<Complex<C>> A) {
  364. return PolyUtil.<Complex<C>, C> map(fac, A, new ImagPartComplex<C>());
  365. }
  366. /**
  367. * Complex from real polynomial.
  368. * @param fac result polynomial factory.
  369. * @param A polynomial with C coefficients to be converted.
  370. * @return polynomial with Complex<C> coefficients.
  371. */
  372. public static <C extends RingElem<C>> GenPolynomial<Complex<C>> toComplex(
  373. GenPolynomialRing<Complex<C>> fac, GenPolynomial<C> A) {
  374. return PolyUtil.<C, Complex<C>> map(fac, A, new ToComplex<C>(fac.coFac));
  375. }
  376. /**
  377. * Complex from rational coefficients.
  378. * @param fac result polynomial factory.
  379. * @param A polynomial with BigRational coefficients to be converted.
  380. * @return polynomial with BigComplex coefficients.
  381. */
  382. public static GenPolynomial<BigComplex> complexFromRational(GenPolynomialRing<BigComplex> fac,
  383. GenPolynomial<BigRational> A) {
  384. return PolyUtil.<BigRational, BigComplex> map(fac, A, new RatToCompl());
  385. }
  386. /**
  387. * Complex from ring element coefficients.
  388. * @param fac result polynomial factory.
  389. * @param A polynomial with RingElem coefficients to be converted.
  390. * @return polynomial with Complex coefficients.
  391. */
  392. public static <C extends GcdRingElem<C>> GenPolynomial<Complex<C>> complexFromAny(
  393. GenPolynomialRing<Complex<C>> fac, GenPolynomial<C> A) {
  394. ComplexRing<C> cr = (ComplexRing<C>) fac.coFac;
  395. return PolyUtil.<C, Complex<C>> map(fac, A, new AnyToComplex<C>(cr));
  396. }
  397. /**
  398. * From AlgebraicNumber coefficients. Represent as polynomial with type
  399. * GenPolynomial&lt;C&gt; coefficients, e.g. ModInteger or BigRational.
  400. * @param rfac result polynomial factory.
  401. * @param A polynomial with AlgebraicNumber coefficients to be converted.
  402. * @return polynomial with type GenPolynomial&lt;C&gt; coefficients.
  403. */
  404. public static <C extends GcdRingElem<C>> GenPolynomial<GenPolynomial<C>> fromAlgebraicCoefficients(
  405. GenPolynomialRing<GenPolynomial<C>> rfac, GenPolynomial<AlgebraicNumber<C>> A) {
  406. return PolyUtil.<AlgebraicNumber<C>, GenPolynomial<C>> map(rfac, A, new AlgToPoly<C>());
  407. }
  408. /**
  409. * Convert to AlgebraicNumber coefficients. Represent as polynomial with
  410. * AlgebraicNumber<C> coefficients, C is e.g. ModInteger or BigRational.
  411. * @param pfac result polynomial factory.
  412. * @param A polynomial with C coefficients to be converted.
  413. * @return polynomial with AlgebraicNumber&lt;C&gt; coefficients.
  414. */
  415. public static <C extends GcdRingElem<C>> GenPolynomial<AlgebraicNumber<C>> convertToAlgebraicCoefficients(
  416. GenPolynomialRing<AlgebraicNumber<C>> pfac, GenPolynomial<C> A) {
  417. AlgebraicNumberRing<C> afac = (AlgebraicNumberRing<C>) pfac.coFac;
  418. return PolyUtil.<C, AlgebraicNumber<C>> map(pfac, A, new CoeffToAlg<C>(afac));
  419. }
  420. /**
  421. * Convert to recursive AlgebraicNumber coefficients. Represent as
  422. * polynomial with recursive AlgebraicNumber<C> coefficients, C is e.g.
  423. * ModInteger or BigRational.
  424. * @param depth recursion depth of AlgebraicNumber coefficients.
  425. * @param pfac result polynomial factory.
  426. * @param A polynomial with C coefficients to be converted.
  427. * @return polynomial with AlgebraicNumber&lt;C&gt; coefficients.
  428. */
  429. public static <C extends GcdRingElem<C>> GenPolynomial<AlgebraicNumber<C>> convertToRecAlgebraicCoefficients(
  430. int depth, GenPolynomialRing<AlgebraicNumber<C>> pfac, GenPolynomial<C> A) {
  431. AlgebraicNumberRing<C> afac = (AlgebraicNumberRing<C>) pfac.coFac;
  432. return PolyUtil.<C, AlgebraicNumber<C>> map(pfac, A, new CoeffToRecAlg<C>(depth, afac));
  433. }
  434. /**
  435. * Convert to AlgebraicNumber coefficients. Represent as polynomial with
  436. * AlgebraicNumber<C> coefficients, C is e.g. ModInteger or BigRational.
  437. * @param pfac result polynomial factory.
  438. * @param A recursive polynomial with GenPolynomial&lt;BigInteger&gt;
  439. * coefficients to be converted.
  440. * @return polynomial with AlgebraicNumber&lt;C&gt; coefficients.
  441. */
  442. public static <C extends GcdRingElem<C>> GenPolynomial<AlgebraicNumber<C>> convertRecursiveToAlgebraicCoefficients(
  443. GenPolynomialRing<AlgebraicNumber<C>> pfac, GenPolynomial<GenPolynomial<C>> A) {
  444. AlgebraicNumberRing<C> afac = (AlgebraicNumberRing<C>) pfac.coFac;
  445. return PolyUtil.<GenPolynomial<C>, AlgebraicNumber<C>> map(pfac, A, new PolyToAlg<C>(afac));
  446. }
  447. /**
  448. * Complex from algebraic coefficients.
  449. * @param fac result polynomial factory.
  450. * @param A polynomial with AlgebraicNumber coefficients Q(i) to be
  451. * converted.
  452. * @return polynomial with Complex coefficients.
  453. */
  454. public static <C extends GcdRingElem<C>> GenPolynomial<Complex<C>> complexFromAlgebraic(
  455. GenPolynomialRing<Complex<C>> fac, GenPolynomial<AlgebraicNumber<C>> A) {
  456. ComplexRing<C> cfac = (ComplexRing<C>) fac.coFac;
  457. return PolyUtil.<AlgebraicNumber<C>, Complex<C>> map(fac, A, new AlgebToCompl<C>(cfac));
  458. }
  459. /**
  460. * AlgebraicNumber from complex coefficients.
  461. * @param fac result polynomial factory over Q(i).
  462. * @param A polynomial with Complex coefficients to be converted.
  463. * @return polynomial with AlgebraicNumber coefficients.
  464. */
  465. public static <C extends GcdRingElem<C>> GenPolynomial<AlgebraicNumber<C>> algebraicFromComplex(
  466. GenPolynomialRing<AlgebraicNumber<C>> fac, GenPolynomial<Complex<C>> A) {
  467. AlgebraicNumberRing<C> afac = (AlgebraicNumberRing<C>) fac.coFac;
  468. return PolyUtil.<Complex<C>, AlgebraicNumber<C>> map(fac, A, new ComplToAlgeb<C>(afac));
  469. }
  470. /**
  471. * ModInteger chinese remainder algorithm on coefficients.
  472. * @param fac GenPolynomial&lt;ModInteger&gt; result factory with
  473. * A.coFac.modul*B.coFac.modul = C.coFac.modul.
  474. * @param A GenPolynomial&lt;ModInteger&gt;.
  475. * @param B other GenPolynomial&lt;ModInteger&gt;.
  476. * @param mi inverse of A.coFac.modul in ring B.coFac.
  477. * @return S = cra(A,B), with S mod A.coFac.modul == A and S mod
  478. * B.coFac.modul == B.
  479. */
  480. public static <C extends RingElem<C> & Modular> GenPolynomial<C> chineseRemainder(
  481. GenPolynomialRing<C> fac, GenPolynomial<C> A, C mi, GenPolynomial<C> B) {
  482. ModularRingFactory<C> cfac = (ModularRingFactory<C>) fac.coFac; // get RingFactory
  483. GenPolynomial<C> S = fac.getZERO().copy();
  484. GenPolynomial<C> Ap = A.copy();
  485. SortedMap<ExpVector, C> av = Ap.val; //getMap();
  486. SortedMap<ExpVector, C> bv = B.getMap();
  487. SortedMap<ExpVector, C> sv = S.val; //getMap();
  488. C c = null;
  489. for (Map.Entry<ExpVector, C> me : bv.entrySet()) {
  490. ExpVector e = me.getKey();
  491. C y = me.getValue(); //bv.get(e); // assert y != null
  492. C x = av.get(e);
  493. if (x != null) {
  494. av.remove(e);
  495. c = cfac.chineseRemainder(x, mi, y);
  496. if (!c.isZERO()) { // 0 cannot happen
  497. sv.put(e, c);
  498. }
  499. } else {
  500. //c = cfac.fromInteger( y.getVal() );
  501. c = cfac.chineseRemainder(A.ring.coFac.getZERO(), mi, y);
  502. if (!c.isZERO()) { // 0 cannot happen
  503. sv.put(e, c); // c != null
  504. }
  505. }
  506. }
  507. // assert bv is empty = done
  508. for (Map.Entry<ExpVector, C> me : av.entrySet()) { // rest of av
  509. ExpVector e = me.getKey();
  510. C x = me.getValue(); // av.get(e); // assert x != null
  511. //c = cfac.fromInteger( x.getVal() );
  512. c = cfac.chineseRemainder(x, mi, B.ring.coFac.getZERO());
  513. if (!c.isZERO()) { // 0 cannot happen
  514. sv.put(e, c); // c != null
  515. }
  516. }
  517. return S;
  518. }
  519. /**
  520. * GenPolynomial monic, i.e. leadingBaseCoefficient == 1. If
  521. * leadingBaseCoefficient is not invertible returns this unmodified.
  522. * @param <C> coefficient type.
  523. * @param p recursive GenPolynomial&lt;GenPolynomial<C>&gt;.
  524. * @return monic(p).
  525. */
  526. public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> monic(
  527. GenPolynomial<GenPolynomial<C>> p) {
  528. if (p == null || p.isZERO()) {
  529. return p;
  530. }
  531. C lc = p.leadingBaseCoefficient().leadingBaseCoefficient();
  532. if (!lc.isUnit()) {
  533. return p;
  534. }
  535. C lm = lc.inverse();
  536. GenPolynomial<C> L = p.ring.coFac.getONE();
  537. L = L.multiply(lm);
  538. return p.multiplyLeft(L);
  539. }
  540. /**
  541. * GenSolvablePolynomial monic, i.e. leadingBaseCoefficient == 1. If
  542. * leadingBaseCoefficient is not invertible returns this unmodified.
  543. * @param <C> coefficient type.
  544. * @param p recursive GenSolvablePolynomial&lt;GenPolynomial<C>&gt;.
  545. * @return monic(p).
  546. */
  547. public static <C extends RingElem<C>> GenSolvablePolynomial<GenPolynomial<C>> monic(
  548. GenSolvablePolynomial<GenPolynomial<C>> p) {
  549. if (p == null || p.isZERO()) {
  550. return p;
  551. }
  552. C lc = p.leadingBaseCoefficient().leadingBaseCoefficient();
  553. if (!lc.isUnit()) {
  554. return p;
  555. }
  556. C lm = lc.inverse();
  557. GenPolynomial<C> L = p.ring.coFac.getONE();
  558. L = L.multiply(lm);
  559. return p.multiplyLeft(L);
  560. }
  561. /**
  562. * Polynomial list monic.
  563. * @param <C> coefficient type.
  564. * @param L list of polynomials with field coefficients.
  565. * @return list of polynomials with leading coefficient 1.
  566. */
  567. public static <C extends RingElem<C>> List<GenPolynomial<C>> monic(List<GenPolynomial<C>> L) {
  568. return ListUtil.<GenPolynomial<C>, GenPolynomial<C>> map(L,
  569. new UnaryFunctor<GenPolynomial<C>, GenPolynomial<C>>() {
  570. public GenPolynomial<C> eval(GenPolynomial<C> c) {
  571. if (c == null) {
  572. return null;
  573. }
  574. return c.monic();
  575. }
  576. });
  577. }
  578. /**
  579. * Word polynomial list monic.
  580. * @param <C> coefficient type.
  581. * @param L list of word polynomials with field coefficients.
  582. * @return list of word polynomials with leading coefficient 1.
  583. */
  584. public static <C extends RingElem<C>> List<GenWordPolynomial<C>> wordMonic(List<GenWordPolynomial<C>> L) {
  585. return ListUtil.<GenWordPolynomial<C>, GenWordPolynomial<C>> map(L,
  586. new UnaryFunctor<GenWordPolynomial<C>, GenWordPolynomial<C>>() {
  587. public GenWordPolynomial<C> eval(GenWordPolynomial<C> c) {
  588. if (c == null) {
  589. return null;
  590. }
  591. return c.monic();
  592. }
  593. });
  594. }
  595. /**
  596. * Recursive polynomial list monic.
  597. * @param <C> coefficient type.
  598. * @param L list of recursive polynomials with field coefficients.
  599. * @return list of polynomials with leading base coefficient 1.
  600. */
  601. public static <C extends RingElem<C>> List<GenPolynomial<GenPolynomial<C>>> monicRec(
  602. List<GenPolynomial<GenPolynomial<C>>> L) {
  603. return ListUtil.<GenPolynomial<GenPolynomial<C>>, GenPolynomial<GenPolynomial<C>>> map(L,
  604. new UnaryFunctor<GenPolynomial<GenPolynomial<C>>, GenPolynomial<GenPolynomial<C>>>() {
  605. public GenPolynomial<GenPolynomial<C>> eval(GenPolynomial<GenPolynomial<C>> c) {
  606. if (c == null) {
  607. return null;
  608. }
  609. return PolyUtil.<C> monic(c);
  610. }
  611. });
  612. }
  613. /**
  614. * Polynomial list leading exponent vectors.
  615. * @param <C> coefficient type.
  616. * @param L list of polynomials.
  617. * @return list of leading exponent vectors.
  618. */
  619. public static <C extends RingElem<C>> List<ExpVector> leadingExpVector(List<GenPolynomial<C>> L) {
  620. return ListUtil.<GenPolynomial<C>, ExpVector> map(L, new UnaryFunctor<GenPolynomial<C>, ExpVector>() {
  621. public ExpVector eval(GenPolynomial<C> c) {
  622. if (c == null) {
  623. return null;
  624. }
  625. return c.leadingExpVector();
  626. }
  627. });
  628. }
  629. /**
  630. * Extend coefficient variables. Extend all coefficient ExpVectors by i
  631. * elements and multiply by x_j^k.
  632. * @param pfac extended polynomial ring factory (by i variables in the
  633. * coefficients).
  634. * @param j index of variable to be used for multiplication.
  635. * @param k exponent for x_j.
  636. * @return extended polynomial.
  637. */
  638. public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> extendCoefficients(
  639. GenPolynomialRing<GenPolynomial<C>> pfac, GenPolynomial<GenPolynomial<C>> A, int j,
  640. long k) {
  641. GenPolynomial<GenPolynomial<C>> Cp = pfac.getZERO().copy();
  642. if (A.isZERO()) {
  643. return Cp;
  644. }
  645. GenPolynomialRing<C> cfac = (GenPolynomialRing<C>) pfac.coFac;
  646. //GenPolynomialRing<C> acfac = (GenPolynomialRing<C>) A.ring.coFac;
  647. //int i = cfac.nvar - acfac.nvar;
  648. Map<ExpVector, GenPolynomial<C>> CC = Cp.val; //getMap();
  649. for (Map.Entry<ExpVector, GenPolynomial<C>> y : A.val.entrySet()) {
  650. ExpVector e = y.getKey();
  651. GenPolynomial<C> a = y.getValue();
  652. GenPolynomial<C> f = a.extend(cfac, j, k);
  653. CC.put(e, f);
  654. }
  655. return Cp;
  656. }
  657. /**
  658. * Extend coefficient variables. Extend all coefficient ExpVectors by i
  659. * elements and multiply by x_j^k.
  660. * @param pfac extended polynomial ring factory (by i variables in the
  661. * coefficients).
  662. * @param j index of variable to be used for multiplication.
  663. * @param k exponent for x_j.
  664. * @return extended polynomial.
  665. */
  666. public static <C extends RingElem<C>> GenSolvablePolynomial<GenPolynomial<C>> extendCoefficients(
  667. GenSolvablePolynomialRing<GenPolynomial<C>> pfac,
  668. GenSolvablePolynomial<GenPolynomial<C>> A, int j, long k) {
  669. GenSolvablePolynomial<GenPolynomial<C>> Cp = pfac.getZERO().copy();
  670. if (A.isZERO()) {
  671. return Cp;
  672. }
  673. GenPolynomialRing<C> cfac = (GenPolynomialRing<C>) pfac.coFac;
  674. //GenPolynomialRing<C> acfac = (GenPolynomialRing<C>) A.ring.coFac;
  675. //int i = cfac.nvar - acfac.nvar;
  676. Map<ExpVector, GenPolynomial<C>> CC = Cp.val; //getMap();
  677. for (Map.Entry<ExpVector, GenPolynomial<C>> y : A.val.entrySet()) {
  678. ExpVector e = y.getKey();
  679. GenPolynomial<C> a = y.getValue();
  680. GenPolynomial<C> f = a.extend(cfac, j, k);
  681. CC.put(e, f);
  682. }
  683. return Cp;
  684. }
  685. /**
  686. * To recursive representation. Represent as polynomial in i+r variables
  687. * with coefficients in i variables. Works for arbitrary term orders.
  688. * @param <C> coefficient type.
  689. * @param rfac recursive polynomial ring factory.
  690. * @param A polynomial to be converted.
  691. * @return Recursive represenations of A in the ring rfac.
  692. */
  693. public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> toRecursive(
  694. GenPolynomialRing<GenPolynomial<C>> rfac, GenPolynomial<C> A) {
  695. GenPolynomial<GenPolynomial<C>> B = rfac.getZERO().copy();
  696. if (A.isZERO()) {
  697. return B;
  698. }
  699. //int i = rfac.nvar;
  700. //GenPolynomial<C> zero = rfac.getZEROCoefficient();
  701. GenPolynomial<C> one = rfac.getONECoefficient();
  702. Map<ExpVector, GenPolynomial<C>> Bv = B.val; //getMap();
  703. for (Monomial<C> m : A) {
  704. ExpVector e = m.e;
  705. C a = m.c;
  706. GenPolynomial<C> p = one.multiply(a);
  707. Bv.put(e, p);
  708. }
  709. return B;
  710. }
  711. /**
  712. * To recursive representation. Represent as solvable polynomial in i+r
  713. * variables with coefficients in i variables. Works for arbitrary term
  714. * orders.
  715. * @param <C> coefficient type.
  716. * @param rfac recursive solvable polynomial ring factory.
  717. * @param A solvable polynomial to be converted.
  718. * @return Recursive represenations of A in the ring rfac.
  719. */
  720. public static <C extends RingElem<C>> GenSolvablePolynomial<GenPolynomial<C>> toRecursive(
  721. GenSolvablePolynomialRing<GenPolynomial<C>> rfac, GenSolvablePolynomial<C> A) {
  722. GenSolvablePolynomial<GenPolynomial<C>> B = rfac.getZERO().copy();
  723. if (A.isZERO()) {
  724. return B;
  725. }
  726. //int i = rfac.nvar;
  727. //GenPolynomial<C> zero = rfac.getZEROCoefficient();
  728. GenPolynomial<C> one = rfac.getONECoefficient();
  729. Map<ExpVector, GenPolynomial<C>> Bv = B.val; //getMap();
  730. for (Monomial<C> m : A) {
  731. ExpVector e = m.e;
  732. C a = m.c;
  733. GenPolynomial<C> p = one.multiply(a);
  734. Bv.put(e, p);
  735. }
  736. return B;
  737. }
  738. /**
  739. * GenPolynomial coefficient wise remainder.
  740. * @param <C> coefficient type.
  741. * @param P GenPolynomial.
  742. * @param s nonzero coefficient.
  743. * @return coefficient wise remainder.
  744. * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
  745. */
  746. public static <C extends RingElem<C>> GenPolynomial<C> baseRemainderPoly(GenPolynomial<C> P, C s) {
  747. if (s == null || s.isZERO()) {
  748. throw new ArithmeticException(P + " division by zero " + s);
  749. }
  750. GenPolynomial<C> h = P.ring.getZERO().copy();
  751. Map<ExpVector, C> hm = h.val; //getMap();
  752. for (Map.Entry<ExpVector, C> m : P.getMap().entrySet()) {
  753. ExpVector f = m.getKey();
  754. C a = m.getValue();
  755. C x = a.remainder(s);
  756. hm.put(f, x);
  757. }
  758. return h;
  759. }
  760. /**
  761. * GenPolynomial sparse pseudo remainder. For univariate polynomials.
  762. * @param <C> coefficient type.
  763. * @param P GenPolynomial.
  764. * @param S nonzero GenPolynomial.
  765. * @return remainder with ldcf(S)<sup>m'</sup> P = quotient * S + remainder.
  766. * m' &le; deg(P)-deg(S)
  767. * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
  768. * @deprecated(forRemoval=true) Use
  769. * {@link #baseSparsePseudoRemainder(edu.jas.poly.GenPolynomial,edu.jas.poly.GenPolynomial)}
  770. * instead
  771. */
  772. @Deprecated
  773. public static <C extends RingElem<C>> GenPolynomial<C> basePseudoRemainder(GenPolynomial<C> P,
  774. GenPolynomial<C> S) {
  775. return baseSparsePseudoRemainder(P, S);
  776. }
  777. /**
  778. * GenPolynomial sparse pseudo remainder. For univariate polynomials.
  779. * @param <C> coefficient type.
  780. * @param P GenPolynomial.
  781. * @param S nonzero GenPolynomial.
  782. * @return remainder with ldcf(S)<sup>m'</sup> P = quotient * S + remainder.
  783. * m' &le; deg(P)-deg(S)
  784. * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
  785. */
  786. public static <C extends RingElem<C>> GenPolynomial<C> baseSparsePseudoRemainder(GenPolynomial<C> P,
  787. GenPolynomial<C> S) {
  788. if (S == null || S.isZERO()) {
  789. throw new ArithmeticException(P.toString() + " division by zero " + S);
  790. }
  791. if (P.isZERO()) {
  792. return P;
  793. }
  794. if (S.isConstant()) {
  795. return P.ring.getZERO();
  796. }
  797. C c = S.leadingBaseCoefficient();
  798. ExpVector e = S.leadingExpVector();
  799. GenPolynomial<C> h;
  800. GenPolynomial<C> r = P;
  801. while (!r.isZERO()) {
  802. ExpVector f = r.leadingExpVector();
  803. if (f.multipleOf(e)) {
  804. C a = r.leadingBaseCoefficient();
  805. ExpVector fe = f.subtract(e);
  806. C x = a.remainder(c);
  807. if (x.isZERO()) {
  808. C y = a.divide(c);
  809. h = S.multiply(y, fe); // coeff a
  810. } else {
  811. r = r.multiply(c); // coeff ac
  812. h = S.multiply(a, fe); // coeff ac
  813. }
  814. r = r.subtract(h);
  815. } else {
  816. break;
  817. }
  818. }
  819. return r;
  820. }
  821. /**
  822. * GenPolynomial dense pseudo remainder. For univariate polynomials.
  823. * @param P GenPolynomial.
  824. * @param S nonzero GenPolynomial.
  825. * @return remainder with ldcf(S)<sup>m</sup> P = quotient * S + remainder.
  826. * m == deg(P)-deg(S)
  827. * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
  828. */
  829. public static <C extends RingElem<C>> GenPolynomial<C> baseDensePseudoRemainder(GenPolynomial<C> P,
  830. GenPolynomial<C> S) {
  831. if (S == null || S.isZERO()) {
  832. throw new ArithmeticException(P + " division by zero " + S);
  833. }
  834. if (P.isZERO()) {
  835. return P;
  836. }
  837. if (S.isConstant()) {
  838. return P.ring.getZERO();
  839. }
  840. long m = P.degree(0);
  841. long n = S.degree(0);
  842. C c = S.leadingBaseCoefficient();
  843. ExpVector e = S.leadingExpVector();
  844. GenPolynomial<C> h;
  845. GenPolynomial<C> r = P;
  846. for (long i = m; i >= n; i--) {
  847. if (r.isZERO()) {
  848. return r;
  849. }
  850. long k = r.degree(0);
  851. if (i == k) {
  852. ExpVector f = r.leadingExpVector();
  853. C a = r.leadingBaseCoefficient();
  854. f = f.subtract(e); // EVDIF( f, e );
  855. //System.out.println("red div = " + f);
  856. r = r.multiply(c); // coeff ac
  857. h = S.multiply(a, f); // coeff ac
  858. r = r.subtract(h);
  859. } else {
  860. r = r.multiply(c);
  861. }
  862. }
  863. return r;
  864. }
  865. /**
  866. * GenPolynomial dense pseudo quotient. For univariate polynomials.
  867. * @param P GenPolynomial.
  868. * @param S nonzero GenPolynomial.
  869. * @return quotient with ldcf(S)<sup>m</sup> P = quotient * S + remainder. m
  870. * == deg(P)-deg(S)
  871. * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
  872. */
  873. public static <C extends RingElem<C>> GenPolynomial<C> baseDensePseudoQuotient(GenPolynomial<C> P,
  874. GenPolynomial<C> S) {
  875. if (S == null || S.isZERO()) {
  876. throw new ArithmeticException(P + " division by zero " + S);
  877. }
  878. if (P.isZERO()) {
  879. return P;
  880. }
  881. //if (S.degree() <= 0) {
  882. // return l^n P; //P.ring.getZERO();
  883. //}
  884. long m = P.degree(0);
  885. long n = S.degree(0);
  886. C c = S.leadingBaseCoefficient();
  887. ExpVector e = S.leadingExpVector();
  888. GenPolynomial<C> q = P.ring.getZERO();
  889. GenPolynomial<C> h;
  890. GenPolynomial<C> r = P;
  891. for (long i = m; i >= n; i--) {
  892. if (r.isZERO()) {
  893. return q;
  894. }
  895. long k = r.degree(0);
  896. if (i == k) {
  897. ExpVector f = r.leadingExpVector();
  898. C a = r.leadingBaseCoefficient();
  899. f = f.subtract(e); // EVDIF( f, e );
  900. //System.out.println("red div = " + f);
  901. r = r.multiply(c); // coeff ac
  902. h = S.multiply(a, f); // coeff ac
  903. r = r.subtract(h);
  904. q = q.multiply(c);
  905. q = q.sum(a, f);
  906. } else {
  907. q = q.multiply(c);
  908. r = r.multiply(c);
  909. }
  910. }
  911. return q;
  912. }
  913. /**
  914. * GenPolynomial sparse pseudo divide. For univariate polynomials or exact
  915. * division.
  916. * @param <C> coefficient type.
  917. * @param P GenPolynomial.
  918. * @param S nonzero GenPolynomial.
  919. * @return quotient with ldcf(S)<sup>m'</sup> P = quotient * S + remainder.
  920. * m' &le; deg(P)-deg(S)
  921. * @see edu.jas.poly.GenPolynomial#divide(edu.jas.poly.GenPolynomial).
  922. */
  923. public static <C extends RingElem<C>> GenPolynomial<C> basePseudoDivide(GenPolynomial<C> P,
  924. GenPolynomial<C> S) {
  925. if (S == null || S.isZERO()) {
  926. throw new ArithmeticException(P.toString() + " division by zero " + S);
  927. }
  928. //if (S.ring.nvar != 1) {
  929. // ok if exact division
  930. // throw new RuntimeException(this.getClass().getName()
  931. // + " univariate polynomials only");
  932. //}
  933. if (P.isZERO() || S.isONE()) {
  934. return P;
  935. }
  936. C c = S.leadingBaseCoefficient();
  937. ExpVector e = S.leadingExpVector();
  938. GenPolynomial<C> h;
  939. GenPolynomial<C> r = P;
  940. GenPolynomial<C> q = S.ring.getZERO().copy();
  941. while (!r.isZERO()) {
  942. ExpVector f = r.leadingExpVector();
  943. if (f.multipleOf(e)) {
  944. C a = r.leadingBaseCoefficient();
  945. f = f.subtract(e);
  946. C x = a.remainder(c);
  947. if (x.isZERO()) {
  948. C y = a.divide(c);
  949. q = q.sum(y, f);
  950. h = S.multiply(y, f); // coeff a
  951. } else {
  952. q = q.multiply(c);
  953. q = q.sum(a, f);
  954. r = r.multiply(c); // coeff ac
  955. h = S.multiply(a, f); // coeff ac
  956. }
  957. r = r.subtract(h);
  958. } else {
  959. break;
  960. }
  961. }
  962. return q;
  963. }
  964. /**
  965. * GenPolynomial sparse pseudo quotient and remainder. For univariate
  966. * polynomials or exact division.
  967. * @param <C> coefficient type.
  968. * @param P GenPolynomial.
  969. * @param S nonzero GenPolynomial.
  970. * @return [ quotient, remainder ] with ldcf(S)<sup>m'</sup> P = quotient *
  971. * S + remainder. m' &le; deg(P)-deg(S)
  972. * @see edu.jas.poly.GenPolynomial#divide(edu.jas.poly.GenPolynomial).
  973. */
  974. @SuppressWarnings("unchecked")
  975. public static <C extends RingElem<C>> GenPolynomial<C>[] basePseudoQuotientRemainder(GenPolynomial<C> P,
  976. GenPolynomial<C> S) {
  977. if (S == null || S.isZERO()) {
  978. throw new ArithmeticException(P.toString() + " division by zero " + S);
  979. }
  980. //if (S.ring.nvar != 1) {
  981. // ok if exact division
  982. // throw new RuntimeException(this.getClass().getName()
  983. // + " univariate polynomials only");
  984. //}
  985. GenPolynomial<C>[] ret = new GenPolynomial[2];
  986. ret[0] = null;
  987. ret[1] = null;
  988. if (P.isZERO() || S.isONE()) {
  989. ret[0] = P;
  990. ret[1] = S.ring.getZERO();
  991. return ret;
  992. }
  993. C c = S.leadingBaseCoefficient();
  994. ExpVector e = S.leadingExpVector();
  995. GenPolynomial<C> h;
  996. GenPolynomial<C> r = P;
  997. GenPolynomial<C> q = S.ring.getZERO().copy();
  998. while (!r.isZERO()) {
  999. ExpVector f = r.leadingExpVector();
  1000. if (f.multipleOf(e)) {
  1001. C a = r.leadingBaseCoefficient();
  1002. f = f.subtract(e);
  1003. C x = a.remainder(c);
  1004. if (x.isZERO()) {
  1005. C y = a.divide(c);
  1006. q = q.sum(y, f);
  1007. h = S.multiply(y, f); // coeff a
  1008. } else {
  1009. q = q.multiply(c);
  1010. q = q.sum(a, f);
  1011. r = r.multiply(c); // coeff a c
  1012. h = S.multiply(a, f); // coeff c a
  1013. }
  1014. r = r.subtract(h);
  1015. } else {
  1016. break;
  1017. }
  1018. }
  1019. //GenPolynomial<C> rhs = q.multiply(S).sum(r);
  1020. //GenPolynomial<C> lhs = P;
  1021. ret[0] = q;
  1022. ret[1] = r;
  1023. return ret;
  1024. }
  1025. /**
  1026. * Is GenPolynomial pseudo quotient and remainder. For univariate
  1027. * polynomials.
  1028. * @param <C> coefficient type.
  1029. * @param P base GenPolynomial.
  1030. * @param S nonzero base GenPolynomial.
  1031. * @return true, if P = q * S + r, else false.
  1032. * @see edu.jas.poly.GenPolynomial#remainder(edu.jas.poly.GenPolynomial).
  1033. * <b>Note:</b> not always meaningful and working
  1034. */
  1035. public static <C extends RingElem<C>> boolean isBasePseudoQuotientRemainder(GenPolynomial<C> P,
  1036. GenPolynomial<C> S, GenPolynomial<C> q, GenPolynomial<C> r) {
  1037. GenPolynomial<C> rhs = q.multiply(S).sum(r);
  1038. //System.out.println("rhs,1 = " + rhs);
  1039. GenPolynomial<C> lhs = P;
  1040. C ldcf = S.leadingBaseCoefficient();
  1041. long d = P.degree(0) - S.degree(0) + 1;
  1042. d = (d > 0 ? d : -d + 2);
  1043. for (long i = 0; i <= d; i++) {
  1044. //System.out.println("lhs-rhs = " + lhs.subtract(rhs));
  1045. if (lhs.equals(rhs) || lhs.negate().equals(rhs)) {
  1046. //System.out.println("lhs,1 = " + lhs);
  1047. return true;
  1048. }
  1049. lhs = lhs.multiply(ldcf);
  1050. }
  1051. GenPolynomial<C> Pp = P;
  1052. rhs = q.multiply(S);
  1053. //System.out.println("rhs,2 = " + rhs);
  1054. for (long i = 0; i <= d; i++) {
  1055. lhs = Pp.subtract(r);
  1056. //System.out.println("lhs-rhs = " + lhs.subtract(rhs));
  1057. if (lhs.equals(rhs) || lhs.negate().equals(rhs)) {
  1058. //System.out.println("lhs,2 = " + lhs);
  1059. return true;
  1060. }
  1061. Pp = Pp.multiply(ldcf);
  1062. }
  1063. C a = P.leadingBaseCoefficient();
  1064. rhs = q.multiply(S).sum(r);
  1065. C b = rhs.leadingBaseCoefficient();
  1066. C gcd = a.gcd(b);
  1067. C p = a.multiply(b);
  1068. C lcm = p.divide(gcd);
  1069. C ap = lcm.divide(a);
  1070. C bp = lcm.divide(b);
  1071. if (P.multiply(ap).equals(rhs.multiply(bp))) {
  1072. return true;
  1073. }
  1074. return false;
  1075. }
  1076. /**
  1077. * GenPolynomial divide. For recursive polynomials. Division by coefficient
  1078. * ring element.
  1079. * @param <C> coefficient type.
  1080. * @param P recursive GenPolynomial.
  1081. * @param s GenPolynomial.
  1082. * @return this/s.
  1083. */
  1084. public static <C extends RingElem<C>> GenPolynomial<GenPolynomial<C>> recursiveDivide(
  1085. GenPolynomial<GenPolynomial<C>> P, GenPolynomial<C> s) {
  1086. if (s == null || s.isZERO()) {
  1087. throw new ArithmeticException("division by zero " + P + ", " + s);
  1088. }
  1089. if (P.isZERO()) {
  1090. return P;
  1091. }
  1092. if (s.isONE()) {
  1093. return P;
  1094. }
  1095. GenPolynomial<GenPolynomial<C>> p = P.ring.getZERO().copy();
  1096. SortedMap<ExpVector, GenPolynomial<C>> pv = p.val; //getMap();
  1097. for (Map.Entry<ExpVector, GenPolynomial<C>> m1 : P.getMap().entrySet()) {
  1098. GenPolynomial<C> c1 = m1.getValue();
  1099. ExpVector e1 = m1.getKey();
  1100. GenPolynomial<C> c = PolyUtil.<C> basePseudoDivide(c1, s);
  1101. if (!c.isZERO()) {
  1102. pv.put(e1, c); // or m1.setValue( c )
  1103. } else {
  1104. logger.warn("rDiv, P = " + P);
  1105. logger.warn("rDiv, c1 = " + c1);
  1106. logger.warn("rDiv, s = " + s);
  1107. logger.warn("rDiv, c = " + c);
  1108. throw new RuntimeException("something is wrong");
  1109. }
  1110. }
  1111. return p;
  1112. }
  1113. /**
  1114. * GenPolynomial divide. For recursive polynomials. Division by coefficient
  1115. * ring element.
  1116. * @param <C> coefficient type.
  1117. * @param P recursive GenPolynomial.
  1118. * @param s GenPolynomial.
  1119. * @return this/s.
  1120. */
  1121. public static <C extends RingElem<C>> GenWordPolynomial<GenPolynomial<C>> recursiveDivide(
  1122. GenWordPolynomial<GenPolynomial<C>> P, GenPolynomial<C> s) {
  1123. if (s == null || s.isZERO()) {
  1124. throw new ArithmeticException("division by zero " + P + ", " + s);
  1125. }
  1126. if (P.isZERO()) {
  1127. return P;
  1128. }
  1129. if (s.isONE()) {
  1130. return P;
  1131. }
  1132. GenWordPolynomial<GenPolynomial<C>> p = P.ring.getZERO().copy();
  1133. SortedMap<Word, GenPolynomial<C>> pv = p.val; //getMap();
  1134. for (Map.Entry<Word, GenPolynomial<C>> m1 : P.getMap().entrySet()) {
  1135. GenPolynomial<C> c1 = m1.getValue();
  1136. Word e1 = m1.getKey();
  1137. GenPolynomial<C> c = PolyUtil.<C> basePseudoDivide(c1, s);
  1138. if (!c.isZERO()) {
  1139. pv.put(e1, c); // or m1.setValue( c )
  1140. } else {
  1141. logger.warn("rDiv, P = " + P);
  1142. logger.warn("rDiv, c1 = " + c1);
  1143. logger.warn("rDiv, s = " + s);
  1144. logger.warn("rDiv, c = " + c);
  1145. throw new RuntimeException("something is wrong");
  1146. }
  1147. }
  1148. return p;
  1149. }
  1150. /**
  1151. * GenPolynomial base divide. For recursive polynomials. Division by
  1152. * coefficient ring element.
  1153. * @param <C> coefficient type.
  1154. * @param P recursive GenPolynomial.
  1155. * @param s coefficient.
  1156. * @return this/s.
  1157. */