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