001/* 002 * $Id$ 003 */ 004 005package edu.jas.application; 006 007 008import java.io.IOException; 009import java.io.Serializable; 010import java.io.StringReader; 011import java.util.List; 012 013import edu.jas.arith.Rational; 014import edu.jas.arith.PrimeInteger; 015import edu.jas.poly.AlgebraicNumberRing; 016import edu.jas.poly.Complex; 017import edu.jas.poly.GenPolynomial; 018import edu.jas.poly.GenPolynomialRing; 019import edu.jas.poly.GenPolynomialTokenizer; 020import edu.jas.poly.TermOrder; 021import edu.jas.root.ComplexAlgebraicRing; 022import edu.jas.root.Interval; 023import edu.jas.root.RealAlgebraicRing; 024import edu.jas.root.Rectangle; 025import edu.jas.root.RootUtil; 026import edu.jas.structure.RingElem; 027import edu.jas.structure.RingFactory; 028import edu.jas.ufd.QuotientRing; 029import edu.jas.ufd.PolyUfdUtil; 030import edu.jas.vector.GenMatrixRing; 031 032 033/** 034 * Builder for extension field towers. 035 * @author Heinz Kredel 036 */ 037public class ExtensionFieldBuilder implements Serializable { 038 039 040 /** 041 * The current factory. 042 */ 043 public final RingFactory factory; // must be a raw type 044 045 046 /** 047 * Constructor not for use. 048 */ 049 protected ExtensionFieldBuilder() { 050 throw new IllegalArgumentException("do not use this constructor"); 051 } 052 053 054 /** 055 * Constructor. 056 * @param base the base field. 057 */ 058 public ExtensionFieldBuilder(RingFactory base) { 059 factory = base; 060 } 061 062 063 /** 064 * Build the field tower. TODO: optimize field tower for faster 065 * computation. 066 */ 067 public RingFactory build() { 068 return factory; 069 } 070 071 072 /** 073 * Set base field. 074 * @param base the base field for the extensions. 075 */ 076 public static ExtensionFieldBuilder baseField(RingFactory base) { 077 return new ExtensionFieldBuilder(base); 078 } 079 080 081 /** 082 * Transcendent field extension. 083 * @param vars names for the transcendent generators. 084 */ 085 @SuppressWarnings("unchecked") 086 public ExtensionFieldBuilder transcendentExtension(String vars) { 087 String[] variables = GenPolynomialTokenizer.variableList(vars); 088 GenPolynomialRing pfac = new GenPolynomialRing(factory, variables); 089 QuotientRing qfac = new QuotientRing(pfac); 090 RingFactory base = (RingFactory) qfac; 091 return new ExtensionFieldBuilder(base); 092 } 093 094 095 /** 096 * Polynomial ring extension. 097 * @param vars names for the polynomial ring generators. 098 */ 099 @SuppressWarnings("unchecked") 100 public ExtensionFieldBuilder polynomialExtension(String vars) { 101 String[] variables = GenPolynomialTokenizer.variableList(vars); 102 GenPolynomialRing pfac = new GenPolynomialRing(factory, variables); 103 RingFactory base = (RingFactory) pfac; 104 return new ExtensionFieldBuilder(base); 105 } 106 107 108 /** 109 * Matrix ring extension. 110 * @param n dimension of n x n matrix. 111 */ 112 @SuppressWarnings("unchecked") 113 public ExtensionFieldBuilder matrixExtension(int n) { 114 GenMatrixRing mfac = new GenMatrixRing(factory, n, n); 115 RingFactory base = (RingFactory) mfac; 116 return new ExtensionFieldBuilder(base); 117 } 118 119 120 /** 121 * Finite field extension. 122 * Construct a finite field with q = p**n elements, where 123 * p is the characteristic of the base field. 124 * @param n exponent. 125 */ 126 @SuppressWarnings("unchecked") 127 public ExtensionFieldBuilder finiteFieldExtension(int n) { 128 java.math.BigInteger p = factory.characteristic(); 129 if (p.signum() != 1) { 130 throw new IllegalArgumentException("characteristic not finite"); 131 } 132 if (!PrimeInteger.isPrime(p)) { //?? 133 throw new IllegalArgumentException("characteristic not prime"); 134 } 135 RingFactory base = (RingFactory) PolyUfdUtil.algebraicNumberField(factory,n); 136 return new ExtensionFieldBuilder(base); 137 } 138 139 140 /** 141 * Algebraic field extension. 142 * @param var name(s) for the algebraic generator(s). 143 * @param expr generating expression, a univariate or multivariate polynomial 144 * in vars. 145 */ 146 @SuppressWarnings("unchecked") 147 public ExtensionFieldBuilder algebraicExtension(String var, String expr) { 148 String[] variables = GenPolynomialTokenizer.variableList(var); 149 if (variables.length < 1) { 150 variables = GenPolynomialTokenizer.expressionVariables(expr); 151 if (variables.length < 1) { 152 throw new IllegalArgumentException("no variables in '" + var + "' and '" + expr + "'"); 153 } 154 } 155 GenPolynomialRing pfac = new GenPolynomialRing(factory, variables); 156 if (variables.length == 1) { // simple extension 157 GenPolynomial gen = pfac.parse(expr); 158 AlgebraicNumberRing afac = new AlgebraicNumberRing(gen); 159 RingFactory base = (RingFactory) afac; 160 return new ExtensionFieldBuilder(base); 161 } 162 GenPolynomialTokenizer pt = new GenPolynomialTokenizer(pfac, new StringReader(expr)); 163 List<GenPolynomial> gen = null; 164 try { 165 gen = pt.nextPolynomialList(); 166 } catch (IOException e) { // should not happen 167 throw new IllegalArgumentException(e); 168 } 169 Ideal agen = new Ideal(pfac, gen); 170 if (agen.isONE()) { 171 throw new IllegalArgumentException("ideal is 1: " + expr); 172 } 173 if (agen.isZERO()) { // transcendent extension 174 QuotientRing qfac = new QuotientRing(pfac); 175 RingFactory base = (RingFactory) qfac; 176 return new ExtensionFieldBuilder(base); 177 } 178 // check if agen is prime? 179 ResidueRing afac = new ResidueRing(agen); 180 RingFactory base = (RingFactory) afac; 181 return new ExtensionFieldBuilder(base); 182 } 183 184 185 /** 186 * Real algebraic field extension. 187 * @param var name for the algebraic generator. 188 * @param expr generating expression, a univariate polynomial in var. 189 * @param root isolating interval for a real root. 190 */ 191 @SuppressWarnings("unchecked") 192 public ExtensionFieldBuilder realAlgebraicExtension(String var, String expr, String root) { 193 String[] variables = new String[] { var }; 194 RingElem one = (RingElem) factory.getONE(); 195 if (!(one instanceof Rational)) { 196 throw new IllegalArgumentException("base field not instance of Rational"); 197 } 198 TermOrder to = new TermOrder(TermOrder.INVLEX); 199 GenPolynomialRing pfac = new GenPolynomialRing(factory, to, variables); 200 GenPolynomial gen = pfac.parse(expr); 201 RingFactory cf = pfac.coFac; 202 Interval iv = RootUtil.parseInterval(cf, root); 203 //System.out.println("iv = " + iv); 204 RealAlgebraicRing rfac = new RealAlgebraicRing(gen, iv); 205 RingFactory base = (RingFactory) rfac; 206 return new ExtensionFieldBuilder(base); 207 } 208 209 210 /** 211 * Complex algebraic field extension. 212 * @param var name for the algebraic generator. 213 * @param expr generating expression, a univariate polynomial in var. 214 * @param root isolating rectangle for a complex root. 215 */ 216 @SuppressWarnings("unchecked") 217 public ExtensionFieldBuilder complexAlgebraicExtension(String var, String expr, String root) { 218 String[] variables = new String[] { var }; 219 RingElem one = (RingElem) factory.getONE(); 220 if (!(one instanceof Complex)) { 221 throw new IllegalArgumentException("base field not instance of Complex"); 222 } 223 GenPolynomialRing pfac = new GenPolynomialRing(factory, variables); 224 //System.out.println("pfac = " + pfac); 225 GenPolynomial gen = pfac.parse(expr); 226 //System.out.println("gen = " + gen); 227 RingFactory cf = pfac.coFac; 228 Rectangle rt = RootUtil.parseRectangle(cf, root); 229 //System.out.println("rt = " + rt); 230 ComplexAlgebraicRing rfac = new ComplexAlgebraicRing(gen, rt); 231 RingFactory base = (RingFactory) rfac; 232 return new ExtensionFieldBuilder(base); 233 } 234 235 236 /** 237 * String representation of the ideal. 238 * @see java.lang.Object#toString() 239 */ 240 @Override 241 public String toString() { 242 StringBuffer s = new StringBuffer(" "); 243 s.append(factory.toString()); 244 s.append(" "); 245 return s.toString(); 246 } 247 248 249 /** 250 * Get a scripting compatible string representation. 251 * @return script compatible representation for this Element. 252 * @see edu.jas.structure.Element#toScript() 253 */ 254 public String toScript() { 255 // Python case 256 StringBuffer s = new StringBuffer(" "); 257 s.append(factory.toScript()); 258 s.append(" "); 259 return s.toString(); 260 } 261 262}