001/* 002 * $Id: LogIntegral.java 5999 2020-03-17 15:44:50Z 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) < 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 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}