001/* 002 * $Id$ 003 */ 004 005package edu.jas.integrate; 006 007 008import java.util.ArrayList; 009import java.util.Collections; 010import java.util.List; 011 012import org.apache.logging.log4j.LogManager; 013import org.apache.logging.log4j.Logger; 014 015import edu.jas.gb.GroebnerBaseAbstract; 016import edu.jas.gbufd.GBFactory; 017import edu.jas.poly.AlgebraicNumber; 018import edu.jas.poly.AlgebraicNumberRing; 019import edu.jas.poly.GenPolynomial; 020import edu.jas.poly.GenPolynomialRing; 021import edu.jas.poly.PolyUtil; 022import edu.jas.structure.GcdRingElem; 023import edu.jas.structure.RingFactory; 024import edu.jas.ufd.PolyUfdUtil; 025 026 027/** 028 * Method related to elementary integration. Czichowski integration based on 029 * Groebner bases for the logarithmic part. 030 * 031 * @author Youssef Elbarbary 032 * @param <C> coefficient type 033 */ 034 035public class ElementaryIntegrationCzichowski<C extends GcdRingElem<C>> extends ElementaryIntegration<C> { 036 037 038 private static final Logger logger = LogManager.getLogger(ElementaryIntegrationCzichowski.class); 039 040 041 /** 042 * Engine for Groebner basis. 043 */ 044 public final GroebnerBaseAbstract<C> red; 045 046 047 /** 048 * Constructor. 049 */ 050 public ElementaryIntegrationCzichowski(RingFactory<C> br) { 051 super(br); 052 red = GBFactory.<C> getImplementation(br); 053 } 054 055 056 /** 057 * Univariate GenPolynomial integration of the logarithmic part, Czichowski 058 * 059 * @param A univariate GenPolynomial, deg(A) < deg(P). 060 * @param P univariate irreducible GenPolynomial. // gcd(A,P) == 1 automatic 061 * @return logarithmic part container. 062 */ 063 @Override 064 public LogIntegral<C> integrateLogPart(GenPolynomial<C> A, GenPolynomial<C> P) { 065 if (P == null || P.isZERO()) { 066 throw new IllegalArgumentException("P == null or P == 0"); 067 } 068 // System.out.println("\nP_base_algeb_part = " + P); 069 GenPolynomialRing<C> pfac = P.ring; // K[x] 070 if (pfac.nvar > 1) { 071 throw new IllegalArgumentException("only for univariate polynomials " + pfac); 072 } 073 if (!pfac.coFac.isField()) { 074 throw new IllegalArgumentException("only for field coefficients " + pfac); 075 } 076 List<C> cfactors = new ArrayList<C>(); 077 List<GenPolynomial<C>> cdenom = new ArrayList<GenPolynomial<C>>(); 078 List<AlgebraicNumber<C>> afactors = new ArrayList<AlgebraicNumber<C>>(); 079 List<GenPolynomial<AlgebraicNumber<C>>> adenom = new ArrayList<GenPolynomial<AlgebraicNumber<C>>>(); 080 081 // P linear 082 if (P.degree(0) <= 1) { 083 cfactors.add(A.leadingBaseCoefficient()); 084 cdenom.add(P); 085 return new LogIntegral<C>(A, P, cfactors, cdenom, afactors, adenom); 086 } 087 088 // derivative 089 GenPolynomial<C> Pp = PolyUtil.<C> baseDerivative(P); 090 // no: Pp = Pp.monic(); 091 // System.out.println("Pp = " + Pp); 092 093 // Q[t] 094 String[] vars = new String[] { "t" }; 095 GenPolynomialRing<C> cfac = new GenPolynomialRing<C>(pfac.coFac, 1, pfac.tord, vars); 096 GenPolynomial<C> t = cfac.univariate(0); 097 098 // Q[x][t] 099 GenPolynomialRing<GenPolynomial<C>> rfac = new GenPolynomialRing<GenPolynomial<C>>(pfac, cfac); // sic 100 // System.out.println("rfac = " + rfac.toScript()); 101 102 // transform polynomials to bi-variate polynomial 103 GenPolynomial<GenPolynomial<C>> Ac = PolyUfdUtil.<C> introduceLowerVariable(rfac, A); 104 // System.out.println("Ac = " + Ac); 105 GenPolynomial<GenPolynomial<C>> Pc = PolyUfdUtil.<C> introduceLowerVariable(rfac, P); 106 // System.out.println("Pc = " + Pc); 107 GenPolynomial<GenPolynomial<C>> Pcp = PolyUfdUtil.<C> introduceLowerVariable(rfac, Pp); 108 // System.out.println("Pcp = " + Pcp); 109 110 // Q[t][x] 111 GenPolynomialRing<GenPolynomial<C>> rfac1 = Pc.ring; 112 // System.out.println("rfac1 = " + rfac1.toScript()); 113 114 // A - t P' 115 GenPolynomial<GenPolynomial<C>> tc = rfac1.getONE().multiply(t); 116 // System.out.println("tc = " + tc); 117 GenPolynomial<GenPolynomial<C>> At = Ac.subtract(tc.multiply(Pcp)); 118 // System.out.println("At = " + At); 119 120 // Q[t][x] to Q[t,x] 121 GenPolynomialRing<C> dfac = pfac.distribute(); 122 GenPolynomial<C> Atd = PolyUtil.distribute(dfac, At); 123 GenPolynomial<C> Pcd = PolyUtil.distribute(dfac, Pc); 124 125 // Groebner Basis 126 List<GenPolynomial<C>> myList = new ArrayList<GenPolynomial<C>>(); 127 myList.add(Atd); 128 myList.add(Pcd); 129 List<GenPolynomial<C>> mGB = red.GB(myList); 130 Collections.sort(mGB); // OrderedPolynomialList 131 132 // Q[t,x] to Q[t][x] 133 List<GenPolynomial<GenPolynomial<C>>> gbList = PolyUtil.recursive(rfac1, mGB); 134 135 // Content & Primitive Part 136 int counter = 1; 137 for (GenPolynomial<GenPolynomial<C>> tmGB : gbList) { 138 if (counter == gbList.size()) { 139 continue; 140 } 141 GenPolynomial<C> content = ufd.recursiveContent(tmGB); 142 143 // Content of GB i+1 144 GenPolynomial<C> c = ufd.recursiveContent(gbList.get(counter)); 145 GenPolynomial<C> Q = content.divide(c); 146 147 // Primitive Part of GB i+1 148 GenPolynomial<GenPolynomial<C>> ppS = ufd.baseRecursivePrimitivePart(gbList.get(counter)); 149 // System.out.println("pp(S) = " + ppS); 150 counter++; 151 152 // vars = new String[] { "z_" + Math.abs(r.hashCode() % 1000) }; 153 vars = pfac.newVars("z_"); 154 pfac = pfac.copy(); 155 @SuppressWarnings("unused") 156 String[] unused = pfac.setVars(vars); 157 if (Q.degreeMin() == 1) { 158 Q = Q.divide(t); 159 } 160 Q = pfac.copy(Q); // hack to exchange the variables 161 AlgebraicNumberRing<C> afac = new AlgebraicNumberRing<C>(Q); 162 logger.debug("afac = {}", afac); //.toScript() 163 AlgebraicNumber<C> a = afac.getGenerator(); 164 // no: a = a.negate(); 165 // System.out.println("a = " + a); 166 167 168 // K(alpha)[x] 169 GenPolynomialRing<AlgebraicNumber<C>> pafac = new GenPolynomialRing<AlgebraicNumber<C>>(afac, 170 ppS.ring); 171 // System.out.println("pafac = " + pafac.toScript()); 172 173 // convert to K(alpha)[x] 174 GenPolynomial<AlgebraicNumber<C>> Sa = PolyUtil.convertRecursiveToAlgebraicCoefficients(pafac, 175 ppS); 176 // System.out.println("Sa = " + Sa); 177 178 afactors.add(a); 179 adenom.add(Sa); 180 // adenom.add(Sa.monic()); 181 } 182 return new LogIntegral<C>(A, P, cfactors, cdenom, afactors, adenom); 183 } 184 185}