001/*
002 * $Id: LogIntegral.java 3295 2010-08-26 17:01:10Z kredel $
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 the String representation.
138     * @see java.lang.Object#toString()
139     */
140    //@Override
141    public String toStringX() {
142        StringBuffer sb = new StringBuffer();
143        sb.append("(" + num.toString() + ")");
144        sb.append(" / ");
145        sb.append("(" + den.toString() + ")");
146        sb.append(" =\n");
147        boolean first = true;
148        for (C cp : cfactors) {
149            if (first) {
150                first = false;
151            } else {
152                sb.append(", ");
153            }
154            sb.append(cp.toString());
155        }
156        if (!first) {
157            sb.append(" linear denominators: ");
158        }
159        first = true;
160        for (GenPolynomial<C> cp : cdenom) {
161            if (first) {
162                first = false;
163            } else {
164                sb.append(", ");
165            }
166            sb.append(cp.toString());
167        }
168        if (!first) {
169            sb.append("; ");
170        }
171        first = true;
172        for (AlgebraicNumber<C> ap : afactors) {
173            if (first) {
174                first = false;
175            } else {
176                //sb.append(", ");
177            }
178            sb.append(ap.toString());
179            sb.append(" ## over " + ap.factory() + "\n");
180        }
181        if (!first) {
182            sb.append(" denominators: ");
183        }
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.toString());
192        }
193        return sb.toString();
194    }
195
196
197    /**
198     * Get a scripting compatible string representation.
199     * @return script compatible representation for this container.
200     * @see edu.jas.structure.ElemFactory#toScript()
201     */
202    public String toScript() {
203        // Python case
204        StringBuffer sb = new StringBuffer();
205
206        sb.append(num.toScript());
207        sb.append(" / ");
208        sb.append(den.toScript());
209        sb.append(" = ");
210        boolean first = true;
211        for (C cp : cfactors) {
212            if (first) {
213                first = false;
214            } else {
215                sb.append(", ");
216            }
217            sb.append(cp.toScript());
218        }
219        if (!first) {
220            sb.append(" linear denominators: ");
221        }
222        first = true;
223        for (GenPolynomial<C> cp : cdenom) {
224            if (first) {
225                first = false;
226            } else {
227                sb.append(", ");
228            }
229            sb.append(cp.toScript());
230        }
231        if (!first) {
232            sb.append(", ");
233        }
234        first = true;
235        for (AlgebraicNumber<C> ap : afactors) {
236            if (first) {
237                first = false;
238            } else {
239                //sb.append(", ");
240            }
241            sb.append(ap.toScript());
242            sb.append(" ## over " + ap.toScriptFactory() + "\n");
243        }
244        sb.append(" denominators: ");
245        first = true;
246        for (GenPolynomial<AlgebraicNumber<C>> ap : adenom) {
247            if (first) {
248                first = false;
249            } else {
250                sb.append(", ");
251            }
252            sb.append(ap.toScript());
253        }
254        return sb.toString();
255    }
256
257
258    /**
259     * Hash code for this Factors.
260     * @see java.lang.Object#hashCode()
261     */
262    @Override
263    public int hashCode() {
264        int h = num.hashCode();
265        h = h * 37 + den.hashCode();
266        h = h * 37 + cfactors.hashCode();
267        h = h * 37 + cdenom.hashCode();
268        h = h * 37 + afactors.hashCode();
269        h = h * 37 + adenom.hashCode();
270        return h;
271    }
272
273
274    /**
275     * Comparison with any other object.
276     * @see java.lang.Object#equals(java.lang.Object)
277     */
278    @Override
279    @SuppressWarnings("unchecked")
280    public boolean equals(Object B) {
281        if (!(B instanceof LogIntegral)) {
282            return false;
283        }
284        LogIntegral<C> a = null;
285        try {
286            a = (LogIntegral<C>) B;
287        } catch (ClassCastException ignored) {
288        }
289        if (a == null) {
290            return false;
291        }
292        boolean t = num.equals(a.num) && den.equals(a.den);
293        if (!t) {
294            return t;
295        }
296        t = cfactors.equals(a.cfactors);
297        if (!t) {
298            return t;
299        }
300        t = cdenom.equals(a.cdenom);
301        if (!t) {
302            return t;
303        }
304        t = afactors.equals(a.afactors);
305        if (!t) {
306            return t;
307        }
308        t = adenom.equals(a.adenom);
309        return t;
310    }
311
312}