001/*
002 * $Id: ExtensionFieldBuilder.java 4960 2014-10-17 18:46:22Z kredel $
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.poly.AlgebraicNumberRing;
015import edu.jas.poly.Complex;
016import edu.jas.poly.GenPolynomial;
017import edu.jas.poly.GenPolynomialRing;
018import edu.jas.poly.GenPolynomialTokenizer;
019import edu.jas.poly.TermOrder;
020import edu.jas.root.ComplexAlgebraicRing;
021import edu.jas.root.Interval;
022import edu.jas.root.RealAlgebraicRing;
023import edu.jas.root.Rectangle;
024import edu.jas.root.RootUtil;
025import edu.jas.structure.RingElem;
026import edu.jas.structure.RingFactory;
027import edu.jas.ufd.QuotientRing;
028
029
030/**
031 * Builder for extension field towers.
032 * @author Heinz Kredel
033 */
034public 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    @SuppressWarnings("cast")
083    public ExtensionFieldBuilder transcendentExtension(String vars) {
084        String[] variables = GenPolynomialTokenizer.variableList(vars);
085        GenPolynomialRing pfac = new GenPolynomialRing(factory, variables);
086        QuotientRing qfac = new QuotientRing(pfac);
087        RingFactory base = (RingFactory) qfac;
088        return new ExtensionFieldBuilder(base);
089    }
090
091
092    /**
093     * Polynomial ring extension.
094     * @param vars names for the polynomial ring generators.
095     */
096    @SuppressWarnings("cast")
097    public ExtensionFieldBuilder polynomialExtension(String vars) {
098        String[] variables = GenPolynomialTokenizer.variableList(vars);
099        GenPolynomialRing pfac = new GenPolynomialRing(factory, variables);
100        RingFactory base = (RingFactory) pfac;
101        return new ExtensionFieldBuilder(base);
102    }
103
104
105    /**
106     * Algebraic field extension.
107     * @param var name(s) for the algebraic generator(s).
108     * @param expr generating expresion, a univariate or multivariate polynomial
109     *            in vars.
110     */
111    @SuppressWarnings("cast")
112    public ExtensionFieldBuilder algebraicExtension(String var, String expr) {
113        String[] variables = GenPolynomialTokenizer.variableList(var);
114        if (variables.length < 1) {
115            variables = GenPolynomialTokenizer.expressionVariables(expr);
116            if (variables.length < 1) {
117                throw new IllegalArgumentException("no variables in '" + var + "' and '" + expr + "'");
118            }
119        }
120        GenPolynomialRing pfac = new GenPolynomialRing(factory, variables);
121        if (variables.length == 1) { // simple extension
122            GenPolynomial gen = pfac.parse(expr);
123            AlgebraicNumberRing afac = new AlgebraicNumberRing(gen);
124            RingFactory base = (RingFactory) afac;
125            return new ExtensionFieldBuilder(base);
126        }
127        GenPolynomialTokenizer pt = new GenPolynomialTokenizer(pfac, new StringReader(expr));
128        List<GenPolynomial> gen = null;
129        try {
130            gen = pt.nextPolynomialList();
131        } catch (IOException e) { // should not happen
132            throw new IllegalArgumentException(e);
133        }
134        Ideal agen = new Ideal(pfac, gen);
135        if (agen.isONE()) {
136            throw new IllegalArgumentException("ideal is 1: " + expr);
137        }
138        if (agen.isZERO()) { // transcendent extension
139            QuotientRing qfac = new QuotientRing(pfac);
140            RingFactory base = (RingFactory) qfac;
141            return new ExtensionFieldBuilder(base);
142        }
143        // check if agen is prime?
144        ResidueRing afac = new ResidueRing(agen);
145        RingFactory base = (RingFactory) afac;
146        return new ExtensionFieldBuilder(base);
147    }
148
149
150    /**
151     * Real algebraic field extension.
152     * @param var name for the algebraic generator.
153     * @param expr generating expresion, a univariate polynomial in var.
154     * @param root isolating interval for a real root.
155     */
156    @SuppressWarnings("cast")
157    public ExtensionFieldBuilder realAlgebraicExtension(String var, String expr, String root) {
158        String[] variables = new String[] { var };
159        RingElem one = (RingElem) factory.getONE();
160        if (!(one instanceof Rational)) {
161            throw new IllegalArgumentException("base field not instance of Rational");
162        }
163        TermOrder to = new TermOrder(TermOrder.INVLEX);
164        GenPolynomialRing pfac = new GenPolynomialRing(factory, to, variables);
165        GenPolynomial gen = pfac.parse(expr);
166        RingFactory cf = pfac.coFac;
167        Interval iv = RootUtil.parseInterval(cf, root);
168        //System.out.println("iv = " + iv);
169        RealAlgebraicRing rfac = new RealAlgebraicRing(gen, iv);
170        RingFactory base = (RingFactory) rfac;
171        return new ExtensionFieldBuilder(base);
172    }
173
174
175    /**
176     * Complex algebraic field extension.
177     * @param var name for the algebraic generator.
178     * @param expr generating expresion, a univariate polynomial in var.
179     * @param root isolating rectangle for a complex root.
180     */
181    @SuppressWarnings("cast")
182    public ExtensionFieldBuilder complexAlgebraicExtension(String var, String expr, String root) {
183        String[] variables = new String[] { var };
184        RingElem one = (RingElem) factory.getONE();
185        if (!(one instanceof Complex)) {
186            throw new IllegalArgumentException("base field not instance of Complex");
187        }
188        GenPolynomialRing pfac = new GenPolynomialRing(factory, variables);
189        //System.out.println("pfac = " + pfac);
190        GenPolynomial gen = pfac.parse(expr);
191        //System.out.println("gen  = " + gen);
192        RingFactory cf = pfac.coFac;
193        Rectangle rt = RootUtil.parseRectangle(cf, root);
194        //System.out.println("rt = " + rt);
195        ComplexAlgebraicRing rfac = new ComplexAlgebraicRing(gen, rt);
196        RingFactory base = (RingFactory) rfac;
197        return new ExtensionFieldBuilder(base);
198    }
199
200
201    /**
202     * String representation of the ideal.
203     * @see java.lang.Object#toString()
204     */
205    @Override
206    public String toString() {
207        StringBuffer s = new StringBuffer(" ");
208        s.append(factory.toString());
209        s.append(" ");
210        return s.toString();
211    }
212
213
214    /**
215     * Get a scripting compatible string representation.
216     * @return script compatible representation for this Element.
217     * @see edu.jas.structure.Element#toScript()
218     */
219    public String toScript() {
220        // Python case
221        StringBuffer s = new StringBuffer(" ");
222        s.append(factory.toScript());
223        s.append(" ");
224        return s.toString();
225    }
226
227}