001 /* 002 * $Id: PartialFraction.java 3295 2010-08-26 17:01:10Z kredel $ 003 */ 004 005 package edu.jas.ufd; 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 partial fraction decomposition of a squarefree denominator. 019 * num/den = sum( a_i ( der(d_i) / d_i ) ) 020 * @author Heinz Kredel 021 * @param <C> coefficient type 022 */ 023 024 public class PartialFraction<C extends GcdRingElem<C>> implements Serializable { 025 026 027 /** 028 * Original numerator polynomial coefficients from C and deg(num) < 029 * deg(den). 030 */ 031 public final GenPolynomial<C> num; 032 033 034 /** 035 * Original (irreducible) denominator polynomial 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 PartialFraction(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 PartialFraction)) { 282 return false; 283 } 284 PartialFraction<C> a = null; 285 try { 286 a = (PartialFraction<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 }