001/*
002 * $Id$
003 */
004
005package edu.jas.integrate;
006
007
008import java.io.Serializable;
009import java.util.List;
010
011import edu.jas.poly.AlgebraicNumber;
012import edu.jas.poly.AlgebraicNumberRing;
013import edu.jas.poly.GenPolynomial;
014import edu.jas.structure.GcdRingElem;
015
016
017/**
018 * Container for the logarithmic part of a rational function integral. num/den =
019 * sum( a_i ( der(d_i) / d_i ) ) integrate(num/den) = sum( a_i log ( d_i ) )
020 * @author Heinz Kredel
021 * @param <C> coefficient type
022 */
023
024public class LogIntegral<C extends GcdRingElem<C>> implements Serializable {
025
026
027    /**
028     * Original numerator polynomial with coefficients from C and deg(num) &lt;
029     * deg(den).
030     */
031    public final GenPolynomial<C> num;
032
033
034    /**
035     * Original (irreducible) denominator polynomial with coefficients from C.
036     */
037    public final GenPolynomial<C> den;
038
039
040    /**
041     * List of numbers from C.
042     */
043    public final List<C> cfactors;
044
045
046    /**
047     * List of linear factors of the denominator with coefficients from C.
048     */
049    public final List<GenPolynomial<C>> cdenom;
050
051
052    /**
053     * List of algebraic numbers of an algebraic field extension over C.
054     */
055    public final List<AlgebraicNumber<C>> afactors;
056
057
058    /**
059     * List of factors of the denominator with coefficients from an
060     * AlgebraicNumberRing&lt;C&gt;.
061     */
062    public final List<GenPolynomial<AlgebraicNumber<C>>> adenom;
063
064
065    /**
066     * Constructor.
067     * @param n numerator GenPolynomial over C.
068     * @param d irreducible denominator GenPolynomial over C.
069     * @param cf list of elements a_i.
070     * @param cd list of linear factors d_i of d.
071     * @param af list of algebraic elements a_i.
072     * @param ad list of irreducible factors d_i of d with algebraic
073     *            coefficients. n/d = sum( a_i ( der(d_i) / d_i ) )
074     */
075    public LogIntegral(GenPolynomial<C> n, GenPolynomial<C> d, List<C> cf, List<GenPolynomial<C>> cd,
076                    List<AlgebraicNumber<C>> af, List<GenPolynomial<AlgebraicNumber<C>>> ad) {
077        num = n;
078        den = d;
079        cfactors = cf;
080        cdenom = cd;
081        afactors = af;
082        adenom = ad;
083    }
084
085
086    /**
087     * Get the String representation.
088     * @see java.lang.Object#toString()
089     */
090    @Override
091    public String toString() {
092        StringBuffer sb = new StringBuffer();
093        //         sb.append("(" + num.toString() + ")");
094        //         sb.append(" / ");
095        //         sb.append("(" + den.toString() + ")");
096        //         sb.append(" =\n");
097        boolean first = true;
098        for (int i = 0; i < cfactors.size(); i++) {
099            C cp = cfactors.get(i);
100            if (first) {
101                first = false;
102            } else {
103                sb.append(" + ");
104            }
105            sb.append("(" + cp.toString() + ")");
106            GenPolynomial<C> p = cdenom.get(i);
107            sb.append(" log( " + p.toString() + ")");
108        }
109        if (!first && afactors.size() > 0) {
110            sb.append(" + ");
111        }
112        first = true;
113        for (int i = 0; i < afactors.size(); i++) {
114            if (first) {
115                first = false;
116            } else {
117                sb.append(" + ");
118            }
119            AlgebraicNumber<C> ap = afactors.get(i);
120            AlgebraicNumberRing<C> ar = ap.factory();
121            //sb.append(" ## over " + ap.factory() + "\n");
122            GenPolynomial<AlgebraicNumber<C>> p = adenom.get(i);
123            if (p.degree(0) < ar.modul.degree(0) && ar.modul.degree(0) > 2) {
124                sb.append("sum_(" + ar.getGenerator() + " in ");
125                sb.append("rootOf(" + ar.modul + ") ) ");
126            } else {
127                //sb.append("sum_("+ar+") ");
128            }
129            sb.append("(" + ap.toString() + ")");
130            sb.append(" log( " + p.toString() + ")");
131        }
132        return sb.toString();
133    }
134
135
136    /**
137     * Get a scripting compatible string representation.
138     * @return script compatible representation for this container.
139     * @see edu.jas.structure.ElemFactory#toScript()
140     */
141    public String toScript() {
142        // Python case
143        StringBuffer sb = new StringBuffer();
144
145        sb.append(num.toScript());
146        sb.append(" / ");
147        sb.append(den.toScript());
148        sb.append(" = ");
149        boolean first = true;
150        for (C cp : cfactors) {
151            if (first) {
152                first = false;
153            } else {
154                sb.append(", ");
155            }
156            sb.append(cp.toScript());
157        }
158        if (!first) {
159            sb.append(" linear denominators: ");
160        }
161        first = true;
162        for (GenPolynomial<C> cp : cdenom) {
163            if (first) {
164                first = false;
165            } else {
166                sb.append(", ");
167            }
168            sb.append(cp.toScript());
169        }
170        if (!first) {
171            sb.append(", ");
172        }
173        first = true;
174        for (AlgebraicNumber<C> ap : afactors) {
175            if (first) {
176                first = false;
177            } else {
178                //sb.append(", ");
179            }
180            sb.append(ap.toScript());
181            sb.append(" ## over " + ap.toScriptFactory() + "\n");
182        }
183        sb.append(" denominators: ");
184        first = true;
185        for (GenPolynomial<AlgebraicNumber<C>> ap : adenom) {
186            if (first) {
187                first = false;
188            } else {
189                sb.append(", ");
190            }
191            sb.append(ap.toScript());
192        }
193        return sb.toString();
194    }
195
196
197    /**
198     * Hash code for this Factors.
199     * @see java.lang.Object#hashCode()
200     */
201    @Override
202    public int hashCode() {
203        int h = num.hashCode();
204        h = h * 37 + den.hashCode();
205        h = h * 37 + cfactors.hashCode();
206        h = h * 37 + cdenom.hashCode();
207        h = h * 37 + afactors.hashCode();
208        h = h * 37 + adenom.hashCode();
209        return h;
210    }
211
212
213    /**
214     * Comparison with any other object.
215     * @see java.lang.Object#equals(java.lang.Object)
216     */
217    @Override
218    @SuppressWarnings("unchecked")
219    public boolean equals(Object B) {
220        if (B == null) {
221            return false;
222        }
223        if (!(B instanceof LogIntegral)) {
224            return false;
225        }
226        LogIntegral<C> a = (LogIntegral<C>) B;
227        boolean t = num.equals(a.num) && den.equals(a.den);
228        if (!t) {
229            return t;
230        }
231        t = cfactors.equals(a.cfactors);
232        if (!t) {
233            return t;
234        }
235        t = cdenom.equals(a.cdenom);
236        if (!t) {
237            return t;
238        }
239        t = afactors.equals(a.afactors);
240        if (!t) {
241            return t;
242        }
243        t = adenom.equals(a.adenom);
244        return t;
245    }
246
247}