001/*
002 * $Id: ExtensionFieldBuilder.java 3655 2011-06-02 18:20:54Z 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    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}