001 /* 002 * $Id: MultiVarCoefficients.java 3444 2010-12-25 17:13:53Z kredel $ 003 */ 004 005 package edu.jas.ps; 006 007 008 import java.util.BitSet; 009 import java.util.HashMap; 010 import java.util.HashSet; 011 012 import edu.jas.poly.ExpVector; 013 import edu.jas.poly.GenPolynomial; 014 import edu.jas.poly.GenPolynomialRing; 015 import edu.jas.structure.RingElem; 016 017 018 /** 019 * Abstract class for generating functions for coefficients of multivariate 020 * power series. This class handles the caching itself. 021 * @param <C> ring element type 022 * @author Heinz Kredel 023 */ 024 025 public abstract class MultiVarCoefficients<C extends RingElem<C>> { 026 027 028 /** 029 * Ring factory for polynomials. 030 */ 031 public final GenPolynomialRing<C> pfac; 032 033 034 /** 035 * Cache for already computed coefficients. 036 */ 037 public final HashMap<Long, GenPolynomial<C>> coeffCache; 038 039 040 /** 041 * Indicator if all coefficients of a homogeneous degree have been 042 * constructed. 043 */ 044 public final BitSet homCheck; 045 046 047 /** 048 * Cache for known zero coefficients. Required because zero coefficients are 049 * not stored in the polynomials. 050 */ 051 public final HashSet<ExpVector> zeroCache; 052 053 054 /** 055 * Public constructor. 056 * @param pf multivariate power series ring factory. 057 */ 058 public MultiVarCoefficients(MultiVarPowerSeriesRing<C> pf) { 059 this(pf.polyRing(), new HashMap<Long, GenPolynomial<C>>(), new HashSet<ExpVector>()); 060 } 061 062 063 /** 064 * Public constructor with some pre-filled caches. 065 * @param pf multivariate power series ring factory. 066 * @param hc pre-filled homogeneous check bit-set. 067 */ 068 public MultiVarCoefficients(MultiVarPowerSeriesRing<C> pf, BitSet hc) { 069 this(pf.polyRing(), new HashMap<Long, GenPolynomial<C>>(), new HashSet<ExpVector>(), hc); 070 } 071 072 073 /** 074 * Public constructor. 075 * @param pf polynomial ring factory. 076 */ 077 public MultiVarCoefficients(GenPolynomialRing<C> pf) { 078 this(pf, new HashMap<Long, GenPolynomial<C>>(), new HashSet<ExpVector>()); 079 } 080 081 082 /** 083 * Public with pre-filled coefficient cache. 084 * @param pf polynomial ring factory. 085 * @param cache pre-filled coefficient cache. 086 */ 087 public MultiVarCoefficients(GenPolynomialRing<C> pf, HashMap<Long, GenPolynomial<C>> cache) { 088 this(pf, cache, new HashSet<ExpVector>()); 089 } 090 091 092 /** 093 * Public constructor with pre-filled caches. 094 * @param pf polynomial ring factory. 095 * @param cache pre-filled coefficient cache. 096 * @param zeros pre-filled zero coefficient cache. 097 */ 098 public MultiVarCoefficients(GenPolynomialRing<C> pf, HashMap<Long, GenPolynomial<C>> cache, 099 HashSet<ExpVector> zeros) { 100 this(pf, cache, zeros, new BitSet()); 101 } 102 103 104 /** 105 * Public constructor with pre-filled caches. 106 * @param pf polynomial ring factory. 107 * @param hc pre-filled homogeneous check bit-set. 108 */ 109 public MultiVarCoefficients(GenPolynomialRing<C> pf, BitSet hc) { 110 this(pf, new HashMap<Long, GenPolynomial<C>>(), new HashSet<ExpVector>(), hc); 111 } 112 113 114 /** 115 * Public constructor with pre-filled caches. 116 * @param pf polynomial ring factory. 117 * @param cache pre-filled coefficient cache. 118 * @param hc pre-filled homogeneous check bit-set. 119 */ 120 public MultiVarCoefficients(GenPolynomialRing<C> pf, HashMap<Long, GenPolynomial<C>> cache, BitSet hc) { 121 this(pf, cache, new HashSet<ExpVector>(), hc); 122 } 123 124 125 /** 126 * Public constructor with pre-filled caches. 127 * @param pf polynomial ring factory. 128 * @param cache pre-filled coefficient cache. 129 * @param zeros pre-filled zero coefficient cache. 130 * @param hc pre-filled homogeneous check bit-set. 131 */ 132 public MultiVarCoefficients(GenPolynomialRing<C> pf, HashMap<Long, GenPolynomial<C>> cache, 133 HashSet<ExpVector> zeros, BitSet hc) { 134 pfac = pf; 135 coeffCache = cache; 136 zeroCache = zeros; 137 homCheck = hc; 138 } 139 140 141 /** 142 * Get cached coefficient or generate coefficient. 143 * @param index of requested coefficient. 144 * @return coefficient at index. 145 */ 146 public C get(ExpVector index) { 147 //if (index.signum() < 0) { // better assert 148 // throw new IllegalArgumentException("negative signum not allowed " + index); 149 //} 150 //if (coeffCache == null) { // not possible 151 // return generate(index); 152 //} 153 long tdeg = index.totalDeg(); 154 GenPolynomial<C> p = coeffCache.get(tdeg); 155 if (p == null) { 156 p = pfac.getZERO().clone(); 157 coeffCache.put(tdeg, p); 158 } 159 C c = p.coefficient(index); 160 if (!c.isZERO()) { 161 return c; 162 } 163 if (homCheck.get((int) tdeg)) { // rely on p 164 return c; 165 } 166 if (zeroCache.contains(index)) { 167 return c; 168 } 169 C g = generate(index); 170 if (g.isZERO()) { 171 zeroCache.add(index); 172 } else { 173 p.doPutToMap(index, g); 174 } 175 return g; 176 } 177 178 179 /** 180 * Homogeneous part. 181 * @param tdeg requested degree. 182 * @return polynomial part of given degree. 183 */ 184 public GenPolynomial<C> getHomPart(long tdeg) { 185 if (coeffCache == null) { 186 throw new IllegalArgumentException("null cache not allowed"); 187 } 188 GenPolynomial<C> p = coeffCache.get(tdeg); 189 if (p == null) { 190 p = pfac.getZERO().clone(); 191 coeffCache.put(tdeg, p); 192 } 193 // trust contents? 194 if (homCheck.get((int) tdeg)) { 195 return p; 196 } 197 // check correct contents or generate coefficients 198 ExpVectorIterable eiter = new ExpVectorIterable(pfac.nvar, tdeg); 199 for (ExpVector e : eiter) { 200 if (zeroCache.contains(e)) { 201 if ( !zeroCache.remove(e) ) { // clean-up unused 202 System.out.println("not removed e = " + e); // cannot happen 203 } 204 continue; 205 } 206 if (!p.coefficient(e).isZERO()) { 207 continue; 208 } 209 C g = generate(e); 210 if (!g.isZERO()) { 211 p.doPutToMap(e, g); 212 } 213 } 214 homCheck.set((int) tdeg); 215 //System.out.println("homCheck = " + homCheck); 216 //System.out.println("coeffCache = " + coeffCache.keySet()); 217 return p; 218 } 219 220 221 /** 222 * Generate coefficient. 223 * @param index of requested coefficient. 224 * @return coefficient at index. 225 */ 226 protected abstract C generate(ExpVector index); 227 228 }