001 /* 002 * $Id: GenSolvablePolynomial.java 3440 2010-12-25 14:21:08Z kredel $ 003 */ 004 005 package edu.jas.poly; 006 007 import java.util.Set; 008 import java.util.Map; 009 import java.util.SortedMap; 010 011 import org.apache.log4j.Logger; 012 013 import edu.jas.structure.RingElem; 014 import edu.jas.structure.RingFactory; 015 016 017 /** 018 * GenSolvablePolynomial generic solvable polynomials implementing RingElem. 019 * n-variate ordered solvable polynomials over C. 020 * Objects of this class are intended to be immutable. 021 * The implementation is based on TreeMap respectively SortedMap 022 * from exponents to coefficients by extension of GenPolybomial. 023 * Only the coefficients are modeled with generic types, 024 * the exponents are fixed to ExpVector with long entries 025 * (this will eventually be changed in the future). 026 * @param <C> coefficient type 027 * @author Heinz Kredel 028 */ 029 030 public class GenSolvablePolynomial<C extends RingElem<C>> 031 extends GenPolynomial<C> { 032 //not possible: implements RingElem< GenSolvablePolynomial<C> > { 033 034 035 /** The factory for the solvable polynomial ring. 036 * Hides super.ring. 037 */ 038 public final GenSolvablePolynomialRing< C > ring; 039 040 041 private static final Logger logger = Logger.getLogger(GenSolvablePolynomial.class); 042 private final boolean debug = false; //logger.isDebugEnabled(); 043 044 045 /** 046 * Constructor for zero GenSolvablePolynomial. 047 * @param r solvable polynomial ring factory. 048 */ 049 public GenSolvablePolynomial(GenSolvablePolynomialRing< C > r) { 050 super(r); 051 ring = r; 052 } 053 054 055 /** 056 * Constructor for zero GenSolvablePolynomial. 057 * @param r solvable polynomial ring factory. 058 * @param c coefficient. 059 * @param e exponent. 060 */ 061 public GenSolvablePolynomial(GenSolvablePolynomialRing< C > r, 062 C c, ExpVector e) { 063 this(r); 064 if ( c != null && ! c.isZERO() ) { 065 val.put(e,c); 066 } 067 } 068 069 070 /** 071 * Constructor for zero GenSolvablePolynomial. 072 * @param r solvable polynomial ring factory. 073 * @param v the SortedMap of some other (solvable) polynomial. 074 */ 075 protected GenSolvablePolynomial(GenSolvablePolynomialRing< C > r, 076 SortedMap<ExpVector,C> v) { 077 this(r); 078 val.putAll( v ); // assume no zero coefficients 079 } 080 081 082 /** 083 * Get the corresponding element factory. 084 * @return factory for this Element. 085 * @see edu.jas.structure.Element#factory() 086 */ 087 public GenSolvablePolynomialRing<C> factory() { 088 return ring; 089 } 090 091 092 /** 093 * Clone this GenSolvablePolynomial. 094 * @see java.lang.Object#clone() 095 */ 096 @Override 097 public GenSolvablePolynomial<C> clone() { 098 //return ring.copy(this); 099 return new GenSolvablePolynomial<C>(ring,this.val); 100 } 101 102 103 /** 104 * GenSolvablePolynomial multiplication. 105 * @param Bp GenSolvablePolynomial. 106 * @return this*Bp, where * denotes solvable multiplication. 107 */ 108 public GenSolvablePolynomial<C> multiply(GenSolvablePolynomial<C> Bp) { 109 if ( Bp == null || Bp.isZERO() ) { 110 return ring.getZERO(); 111 } 112 if ( this.isZERO() ) { 113 return this; 114 } 115 assert (ring.nvar == Bp.ring.nvar); 116 if ( debug ) { 117 logger.debug("ring = " + ring); 118 } 119 ExpVector Z = ring.evzero; 120 GenSolvablePolynomial<C> Cp = ring.getZERO().clone(); 121 GenSolvablePolynomial<C> zero = ring.getZERO().clone(); 122 C one = ring.getONECoefficient(); 123 124 GenSolvablePolynomial<C> C1 = null; 125 GenSolvablePolynomial<C> C2 = null; 126 Map<ExpVector,C> A = val; 127 Map<ExpVector,C> B = Bp.val; 128 Set<Map.Entry<ExpVector,C>> Bk = B.entrySet(); 129 for ( Map.Entry<ExpVector,C> y: A.entrySet() ) { 130 C a = y.getValue(); 131 ExpVector e = y.getKey(); 132 if ( debug ) logger.debug("e = " + e); 133 int[] ep = e.dependencyOnVariables(); 134 int el1 = ring.nvar + 1; 135 if ( ep.length > 0 ) { 136 el1 = ep[0]; 137 } 138 int el1s = ring.nvar + 1 - el1; 139 for ( Map.Entry<ExpVector,C> x: Bk ) { 140 C b = x.getValue(); 141 ExpVector f = x.getKey(); 142 if ( debug ) logger.debug("f = " + f); 143 int[] fp = f.dependencyOnVariables(); 144 int fl1 = 0; 145 if ( fp.length > 0 ) { 146 fl1 = fp[fp.length-1]; 147 } 148 int fl1s = ring.nvar + 1 - fl1; 149 if ( debug ) { 150 logger.debug("el1s = " + el1s + " fl1s = " + fl1s); 151 } 152 GenSolvablePolynomial<C> Cs = null; 153 if ( el1s <= fl1s ) { // symmetric 154 ExpVector g = e.sum(f); 155 //if ( debug ) logger.debug("g = " + g); 156 Cs = (GenSolvablePolynomial<C>)zero.sum( one, g ); // symmetric! 157 //Cs = new GenSolvablePolynomial<C>(ring,one,g); // symmetric! 158 } else { // unsymmetric 159 // split e = e1 * e2, f = f1 * f2 160 ExpVector e1 = e.subst(el1,0); 161 ExpVector e2 = Z.subst(el1,e.getVal(el1)); 162 ExpVector e4; 163 ExpVector f1 = f.subst(fl1,0); 164 ExpVector f2 = Z.subst(fl1,f.getVal(fl1)); 165 //if ( debug ) logger.debug("e1 = " + e1 + " e2 = " + e2); 166 //if ( debug ) logger.debug("f1 = " + f1 + " f2 = " + f2); 167 TableRelation<C> rel = ring.table.lookup(e2,f2); 168 //logger.info("relation = " + rel); 169 Cs = rel.p; //ring.copy( rel.p ); // do not clone() 170 if ( rel.f != null ) { 171 C2 = (GenSolvablePolynomial<C>)zero.sum( one, rel.f ); 172 Cs = Cs.multiply( C2 ); 173 if ( rel.e == null ) { 174 e4 = e2; 175 } else { 176 e4 = e2.subtract( rel.e ); 177 } 178 ring.table.update(e4,f2,Cs); 179 } 180 if ( rel.e != null ) { 181 C1 = (GenSolvablePolynomial<C>)zero.sum( one, rel.e ); 182 Cs = C1.multiply( Cs ); 183 ring.table.update(e2,f2,Cs); 184 } 185 if ( !f1.isZERO() ) { 186 C2 = (GenSolvablePolynomial<C>)zero.sum( one, f1 ); 187 Cs = Cs.multiply( C2 ); 188 //ring.table.update(?,f1,Cs) 189 } 190 if ( !e1.isZERO() ) { 191 C1 = (GenSolvablePolynomial<C>)zero.sum( one, e1 ); 192 Cs = C1.multiply( Cs ); 193 //ring.table.update(e1,?,Cs) 194 } 195 } 196 C c = a.multiply(b); 197 //logger.debug("c = " + c); 198 Cs = Cs.multiply( c ); // symmetric! 199 //if ( debug ) logger.debug("Cs = " + Cs); 200 Cp = (GenSolvablePolynomial<C>)Cp.sum( Cs ); 201 } 202 } 203 return Cp; 204 } 205 206 207 208 /** 209 * GenSolvablePolynomial multiplication. 210 * Product with coefficient ring element. 211 * @param b coefficient. 212 * @return this*b, where * is usual multiplication. 213 */ 214 @Override 215 public GenSolvablePolynomial<C> multiply(C b) { 216 GenSolvablePolynomial<C> Cp = ring.getZERO().clone(); 217 if ( b == null || b.isZERO() ) { 218 return Cp; 219 } 220 Map<ExpVector,C> Cm = Cp.val; //getMap(); 221 Map<ExpVector,C> Am = val; 222 for ( Map.Entry<ExpVector,C> y: Am.entrySet() ) { 223 ExpVector e = y.getKey(); 224 C a = y.getValue(); 225 C c = a.multiply(b); 226 Cm.put( e, c ); 227 } 228 return Cp; 229 } 230 231 232 /** 233 * GenSolvablePolynomial multiplication. 234 * Product with exponent vector. 235 * @param e exponent. 236 * @return this * x<sup>e</sup>, 237 * where * denotes solvable multiplication. 238 */ 239 @Override 240 public GenSolvablePolynomial<C> multiply(ExpVector e) { 241 GenSolvablePolynomial<C> Cp = ring.getZERO().clone(); 242 if ( e == null || e.isZERO() ) { 243 return this; 244 } 245 C b = ring.getONECoefficient(); 246 Cp = new GenSolvablePolynomial<C>(ring,b,e); 247 return multiply(Cp); 248 } 249 250 251 /** 252 * GenSolvablePolynomial multiplication. 253 * Product with ring element and exponent vector. 254 * @param b coefficient. 255 * @param e exponent. 256 * @return this * b x<sup>e</sup>, 257 * where * denotes solvable multiplication. 258 */ 259 @Override 260 public GenSolvablePolynomial<C> multiply(C b, ExpVector e) { 261 GenSolvablePolynomial<C> Cp = ring.getZERO().clone(); 262 if ( b == null || b.isZERO() ) { 263 return Cp; 264 } 265 //Cp = (GenSolvablePolynomial<C>)Cp.add(b,e); 266 Cp = new GenSolvablePolynomial<C>(ring,b,e); 267 return multiply(Cp); 268 } 269 270 271 /** 272 * GenSolvablePolynomial multiplication. 273 * Left product with ring element and exponent vector. 274 * @param b coefficient. 275 * @param e exponent. 276 * @return b x<sup>e</sup> * this, 277 * where * denotes solvable multiplication. 278 */ 279 public GenSolvablePolynomial<C> multiplyLeft(C b, ExpVector e) { 280 GenSolvablePolynomial<C> Cp = ring.getZERO().clone(); 281 if ( b == null || b.isZERO() ) { 282 return Cp; 283 } 284 Cp = new GenSolvablePolynomial<C>(ring,b,e); 285 Cp = Cp.multiply(this); 286 return Cp; 287 } 288 289 290 /** 291 * GenSolvablePolynomial multiplication. 292 * Left product with exponent vector. 293 * @param e exponent. 294 * @return x<sup>e</sup> * this, 295 * where * denotes solvable multiplication. 296 */ 297 public GenSolvablePolynomial<C> multiplyLeft(ExpVector e) { 298 GenSolvablePolynomial<C> Cp = ring.getZERO().clone(); 299 if ( e == null || e.isZERO() ) { 300 return this; 301 } 302 C b = ring.getONECoefficient(); 303 Cp = new GenSolvablePolynomial<C>(ring,b,e); 304 return Cp.multiply(this); 305 } 306 307 308 /** 309 * GenSolvablePolynomial multiplication. 310 * Left product with coefficient ring element. 311 * @param b coefficient. 312 * @return b*this, where * is usual multiplication. 313 */ 314 public GenSolvablePolynomial<C> multiplyLeft(C b) { 315 GenSolvablePolynomial<C> Cp = ring.getZERO().clone(); 316 if ( b == null || b.isZERO() ) { 317 return Cp; 318 } 319 Map<ExpVector,C> Cm = Cp.val; //getMap(); 320 Map<ExpVector,C> Am = val; 321 for ( Map.Entry<ExpVector,C> y: Am.entrySet() ) { 322 ExpVector e = y.getKey(); 323 C a = y.getValue(); 324 C c = b.multiply(a); 325 Cm.put( e, c ); 326 } 327 return Cp; 328 } 329 330 331 /** 332 * GenSolvablePolynomial multiplication. 333 * Left product with 'monimial'. 334 * @param m 'monoial'. 335 * @return m * this, 336 * where * denotes solvable multiplication. 337 */ 338 public GenSolvablePolynomial<C> multiplyLeft(Map.Entry<ExpVector,C> m) { 339 if ( m == null ) { 340 return ring.getZERO(); 341 } 342 return multiplyLeft( m.getValue(), m.getKey() ); 343 } 344 345 }