001 /*
002 * $Id: LogIntegral.java 3295 2010-08-26 17:01:10Z kredel $
003 */
004
005 package edu.jas.integrate;
006
007
008 import java.io.Serializable;
009 import java.util.List;
010
011 import edu.jas.poly.AlgebraicNumber;
012 import edu.jas.poly.AlgebraicNumberRing;
013 import edu.jas.poly.GenPolynomial;
014 import 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
024 public class LogIntegral<C extends GcdRingElem<C>> implements Serializable {
025
026
027 /**
028 * Original numerator polynomial with coefficients from C and deg(num) <
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<C>.
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 }