001/*
002 * $Id: ExtensionFieldBuilderTest.java 4071 2012-07-27 19:59:38Z kredel $
003 */
004
005package edu.jas.application;
006
007
008import java.util.List;
009
010import junit.framework.Test;
011import junit.framework.TestCase;
012import junit.framework.TestSuite;
013
014import org.apache.log4j.BasicConfigurator;
015
016import edu.jas.arith.BigRational;
017import edu.jas.arith.ModLongRing;
018import edu.jas.kern.ComputerThreads;
019import edu.jas.poly.AlgebraicNumber;
020import edu.jas.poly.AlgebraicNumberRing;
021import edu.jas.poly.ComplexRing;
022import edu.jas.poly.GenPolynomial;
023import edu.jas.poly.GenPolynomialRing;
024import edu.jas.root.RealAlgebraicNumber;
025import edu.jas.root.RootFactory;
026import edu.jas.structure.Power;
027import edu.jas.structure.RingElem;
028import edu.jas.structure.RingFactory;
029import edu.jas.ufd.Quotient;
030import edu.jas.ufd.QuotientRing;
031
032
033/**
034 * ExtensionFieldBuilder tests with JUnit.
035 * @author Heinz Kredel.
036 */
037
038public class ExtensionFieldBuilderTest extends TestCase {
039
040
041    /**
042     * main.
043     */
044    public static void main(String[] args) {
045        BasicConfigurator.configure();
046        junit.textui.TestRunner.run(suite());
047    }
048
049
050    /**
051     * Constructs a <CODE>ExtensionFieldBuilderTest</CODE> object.
052     * @param name String.
053     */
054    public ExtensionFieldBuilderTest(String name) {
055        super(name);
056    }
057
058
059    /**
060     * suite.
061     */
062    public static Test suite() {
063        TestSuite suite = new TestSuite(ExtensionFieldBuilderTest.class);
064        return suite;
065    }
066
067
068    ExtensionFieldBuilder builder;
069
070
071    @Override
072    protected void setUp() {
073        builder = null;
074    }
075
076
077    @Override
078    protected void tearDown() {
079        builder = null;
080        ComputerThreads.terminate();
081    }
082
083
084    /**
085     * Test construction Q(sqrt(2))(x)(sqrt(x)) by hand.
086     */
087    public void testConstructionF0() {
088        BigRational bf = new BigRational(1);
089        GenPolynomialRing<BigRational> pf = new GenPolynomialRing<BigRational>(bf, new String[] { "w2" });
090        GenPolynomial<BigRational> a = pf.parse("w2^2 - 2");
091        AlgebraicNumberRing<BigRational> af = new AlgebraicNumberRing<BigRational>(a);
092        GenPolynomialRing<AlgebraicNumber<BigRational>> tf = new GenPolynomialRing<AlgebraicNumber<BigRational>>(
093                        af, new String[] { "x" });
094        QuotientRing<AlgebraicNumber<BigRational>> qf = new QuotientRing<AlgebraicNumber<BigRational>>(tf);
095        GenPolynomialRing<Quotient<AlgebraicNumber<BigRational>>> qaf = new GenPolynomialRing<Quotient<AlgebraicNumber<BigRational>>>(
096                        qf, new String[] { "wx" });
097        GenPolynomial<Quotient<AlgebraicNumber<BigRational>>> b = qaf.parse("wx^2 - x");
098        AlgebraicNumberRing<Quotient<AlgebraicNumber<BigRational>>> fac = new AlgebraicNumberRing<Quotient<AlgebraicNumber<BigRational>>>(
099                        b);
100        //System.out.println("fac = " + fac.toScript());
101
102        List<AlgebraicNumber<Quotient<AlgebraicNumber<BigRational>>>> gens = fac.generators();
103        int s = gens.size();
104        //System.out.println("gens    = " + gens);
105        assertTrue("#gens == 4 " + s, s == 4);
106
107        AlgebraicNumber<Quotient<AlgebraicNumber<BigRational>>> elem = fac.random(2);
108        if (elem.isZERO() || elem.isONE()) {
109            elem = gens.get(s - 1).sum(gens.get(s - 2));
110            //elem = (RingElem)gens.get(s-1).multiply(gens.get(s-2));
111            elem = elem.multiply(elem);
112        }
113        //System.out.println("elem     = " + elem.toScript());
114        //System.out.println("elem    = " + elem);
115
116        AlgebraicNumber<Quotient<AlgebraicNumber<BigRational>>> inv = elem.inverse();
117        //System.out.println("inv      = " + inv.toScript());
118        //System.out.println("inv     = " + inv);
119
120        AlgebraicNumber<Quotient<AlgebraicNumber<BigRational>>> e = elem.multiply(inv);
121        assertTrue("e / e == 1 " + e, e.isONE());
122    }
123
124
125    /**
126     * Test construction Q(sqrt(2))(x)(sqrt(x)) by extension field builder.
127     */
128    public void testConstructionF1() {
129        builder = ExtensionFieldBuilder.baseField(new BigRational(1));
130        //System.out.println("builder = " + builder.toString());
131
132        RingFactory fac = builder.build();
133        //System.out.println("fac     = " + fac.toScript());
134
135        builder = builder.algebraicExtension("w2", "w2^2 - 2");
136        //System.out.println("builder = " + builder.toString());
137
138        fac = builder.build();
139        //System.out.println("fac     = " + fac.toScript());
140
141        builder = builder.transcendentExtension("x");
142        //System.out.println("builder = " + builder.toString());
143
144        fac = builder.build();
145        //System.out.println("fac     = " + fac.toScript());
146
147        builder = builder.algebraicExtension("wx", "wx^2 - x"); // number of { } resolved
148        //System.out.println("builder = " + builder.toString());
149
150        fac = builder.build();
151        //System.out.println("fac     = " + fac.toScript());
152
153        List<RingElem> gens = fac.generators();
154        int s = gens.size();
155        //System.out.println("gens    = " + gens);
156        assertTrue("#gens == 4 " + s, s == 4);
157
158        RingElem elem = (RingElem) fac.random(2);
159        if (elem.isZERO() || elem.isONE()) {
160            elem = (RingElem) gens.get(s - 1).sum(gens.get(s - 2));
161            //elem = (RingElem)gens.get(s-1).multiply(gens.get(s-2));
162            elem = (RingElem) elem.multiply(elem);
163        }
164        //System.out.println("elem     = " + elem.toScript());
165        //System.out.println("elem    = " + elem);
166
167        RingElem inv = (RingElem) elem.inverse();
168        //System.out.println("inv      = " + inv.toScript());
169        //System.out.println("inv     = " + inv);
170
171        RingElem a = (RingElem) elem.multiply(inv);
172        assertTrue("e / e == 1 " + a, a.isONE());
173    }
174
175
176    /**
177     * Test construction Q(x)(sqrt(2))(sqrt(x)) by extension field builder.
178     */
179    public void testConstructionF2() {
180        builder = ExtensionFieldBuilder.baseField(new BigRational(1));
181        //System.out.println("builder = " + builder.toString());
182
183        RingFactory fac = builder.build();
184        //System.out.println("fac     = " + fac.toScript());
185
186        builder = builder.transcendentExtension("x");
187        //System.out.println("builder = " + builder.toString());
188
189        fac = builder.build();
190        //System.out.println("fac     = " + fac.toScript());
191        builder = builder.algebraicExtension("w2", "w2^2 - 2");
192        //System.out.println("builder = " + builder.toString());
193
194        fac = builder.build();
195        //System.out.println("fac     = " + fac.toScript());
196
197        builder = builder.algebraicExtension("wx", "wx^2 - x"); // number of { } resolved
198        //System.out.println("builder = " + builder.toString());
199
200        fac = builder.build();
201        //System.out.println("fac     = " + fac.toScript());
202
203        List<RingElem> gens = fac.generators();
204        int s = gens.size();
205        //System.out.println("gens    = " + gens);
206        assertTrue("#gens == 4 " + s, s == 4);
207
208        RingElem elem = (RingElem) fac.random(1);
209        if (elem.isZERO() || elem.isONE()) {
210            elem = (RingElem) gens.get(s - 1).sum(gens.get(s - 2));
211            //elem = (RingElem)gens.get(s-1).multiply(gens.get(s-2));
212            elem = (RingElem) elem.multiply(elem);
213        }
214        //System.out.println("elem     = " + elem.toScript());
215        //System.out.println("elem    = " + elem);
216
217        RingElem inv = (RingElem) elem.inverse();
218        //System.out.println("inv      = " + inv.toScript());
219        //System.out.println("inv     = " + inv);
220
221        RingElem a = (RingElem) elem.multiply(inv);
222        assertTrue("e / e == 1 " + a, a.isONE());
223    }
224
225
226    /**
227     * Test construction Z_p(sqrt(2))(x)(sqrt(x)) by extension field builder.
228     */
229    public void testConstructionF3() {
230        RingFactory fac = ExtensionFieldBuilder.baseField(new ModLongRing(7))
231                        .algebraicExtension("w2", "w2^2 - 3").transcendentExtension("x")
232                        .algebraicExtension("wx", "wx^7 - x").build();
233        //System.out.println("fac = " + fac.toScript());
234
235        List<RingElem> gens = fac.generators();
236        int s = gens.size();
237        //System.out.println("gens    = " + gens);
238        assertTrue("#gens == 4 " + s, s == 4);
239
240        RingElem elem = (RingElem) fac.random(2);
241        if (elem.isZERO() || elem.isONE()) {
242            elem = (RingElem) gens.get(s - 1).sum(gens.get(s - 2));
243            //elem = (RingElem)gens.get(s-1).multiply(gens.get(s-2));
244            elem = (RingElem) elem.multiply(elem);
245        }
246        //System.out.println("elem     = " + elem.toScript());
247        //System.out.println("elem    = " + elem);
248
249        RingElem inv = (RingElem) elem.inverse();
250        //System.out.println("inv      = " + inv.toScript());
251        //System.out.println("inv     = " + inv);
252
253        RingElem a = (RingElem) elem.multiply(inv);
254        assertTrue("e / e == 1 " + a, a.isONE());
255    }
256
257
258    /**
259     * Test construction Q(+3rt(3))(+sqrt(+3rt(3)))(+5rt(2)) by extension field
260     * builder.
261     */
262    public void testConstructionR1() {
263        RingFactory fac = ExtensionFieldBuilder.baseField(new BigRational(1))
264                        .realAlgebraicExtension("q", "q^3 - 3", "[1,2]")
265                        .realAlgebraicExtension("w", "w^2 - q", "[1,2]")
266                        .realAlgebraicExtension("s", "s^5 - 2", "[1,2]").build();
267        //System.out.println("fac = " + fac.toScript());
268
269        List<RingElem> gens = fac.generators();
270        int s = gens.size();
271        //System.out.println("gens    = " + gens);
272        assertTrue("#gens == 4 " + s, s == 4);
273
274        RingElem elem = (RingElem) fac.random(2);
275        if (elem.isZERO() || elem.isONE()) {
276            elem = (RingElem) gens.get(s - 1).sum(gens.get(s - 2));
277            //elem = (RingElem)gens.get(s-1).multiply(gens.get(s-2));
278            elem = (RingElem) elem.multiply(elem);
279        }
280        //elem = (RingElem)elem.negate();
281        //System.out.println("elem     = " + elem.toScript());
282        //System.out.println("elem    = " + elem);
283        //BigDecimal ed = new BigDecimal(((Rational)elem).getRational());
284        //System.out.println("        ~ " + ed);
285
286        RingElem inv = (RingElem) elem.inverse();
287        //System.out.println("inv      = " + inv.toScript());
288        //System.out.println("inv     = " + inv);
289        //BigDecimal id = new BigDecimal(((Rational)inv).getRational());
290        //System.out.println("        ~ " + id);
291
292        RingElem a = (RingElem) elem.multiply(inv);
293        //System.out.println("a       = " + a);
294        //System.out.println("        ~ " + ed.multiply(id));
295        assertTrue("e / e == 1 " + a, a.isONE());
296    }
297
298
299    /**
300     * Test construction Q(sqrt(-1))(+3rt(i)) by extension field builder.
301     */
302    public void testConstructionC1() {
303        ComplexRing<BigRational> cf = new ComplexRing<BigRational>(new BigRational(1));
304        //System.out.println("cf = " + cf.toScript());
305        RingFactory fac = ExtensionFieldBuilder.baseField(cf)
306                        .complexAlgebraicExtension("w2", "w2^2 + 2", "[-1i0,1i2]")
307                        //.complexAlgebraicExtension("q3", "q3^3 + { w2 }","[-1i0,1i2]") // not possible, TODO
308                        .build();
309        //System.out.println("fac = " + fac.toScript());
310
311        List<RingElem> gens = fac.generators();
312        int s = gens.size();
313        //System.out.println("gens    = " + gens);
314        assertTrue("#gens == 3 " + s, s == 3);
315
316        RingElem elem = (RingElem) fac.random(2);
317        if (elem.isZERO() || elem.isONE()) {
318            elem = (RingElem) gens.get(s - 1).sum(gens.get(s - 2));
319            //elem = (RingElem)gens.get(s-1).multiply(gens.get(s-2));
320            elem = (RingElem) elem.multiply(elem);
321        }
322        //System.out.println("elem     = " + elem.toScript());
323        //System.out.println("elem    = " + elem);
324
325        RingElem inv = (RingElem) elem.inverse();
326        //System.out.println("inv      = " + inv.toScript());
327        //System.out.println("inv     = " + inv);
328
329        RingElem a = (RingElem) elem.multiply(inv);
330        //System.out.println("a       = " + a);
331        assertTrue("e / e == 1 " + a, a.isONE());
332    }
333
334
335    /**
336     * Test construction Q(+3rt(3))(+sqrt(+3rt(3)))(+5rt(2))[y] by extension
337     * field builder and real root calculation.
338     */
339    public void testConstructionR2factory() {
340        RingFactory fac = ExtensionFieldBuilder.baseField(new BigRational(1))
341                        .realAlgebraicExtension("q", "q^3 - 3", "[1,2]")
342                        .realAlgebraicExtension("w", "w^2 - q", "[1,2]")
343                        .realAlgebraicExtension("s", "s^5 - 2", "[1,2]").build();
344        //System.out.println("fac = " + fac.toScript());
345
346        List<RingElem> gens = fac.generators();
347        int s = gens.size();
348        //System.out.println("gens    = " + gens);
349        assertTrue("#gens == 4 " + s, s == 4);
350
351        GenPolynomialRing pfac = new GenPolynomialRing(fac, new String[] { "y" });
352        GenPolynomial elem = pfac.parse("y^2 - w s");
353        //elem = (RingElem)elem.negate();
354        //System.out.println("elem    = " + elem.toScript());
355        //System.out.println("elem    = " + elem);
356
357        List<RealAlgebraicNumber<BigRational>> roots = RootFactory
358                        .realAlgebraicNumbers((GenPolynomial<BigRational>) elem);
359        //System.out.println("roots   = " + roots);
360        assertTrue("#roots == 2 " + roots, roots.size() == 2);
361        for (RealAlgebraicNumber root : roots) {
362            //BigDecimal id = new BigDecimal(root.getRational());
363            //System.out.println("root    = " + root);
364            //System.out.println("        ~ " + id);
365            RealAlgebraicNumber inv = root.inverse();
366            //System.out.println("inv     = " + inv);
367            //BigDecimal ivd = new BigDecimal(inv.getRational());
368            //System.out.println("        ~ " + ivd);
369
370            RealAlgebraicNumber a = root.multiply(inv);
371            //System.out.println("a       = " + a);
372            //System.out.println("        ~ " + id.multiply(ivd));
373            assertTrue("y / y == 1 " + a, a.isONE());
374        }
375    }
376
377
378    /**
379     * Test construction by extension field builder and multiple algebraic
380     * extension.
381     */
382    public void testConstructionM1() {
383        RingFactory fac = ExtensionFieldBuilder.baseField(new BigRational(1))
384                        .algebraicExtension("q,w,s", "( q^3 - 3, w^2 - q, s^5 - 2)").build();
385        //System.out.println("fac = " + fac.toScript());
386
387        List<RingElem> gens = fac.generators();
388        int s = gens.size();
389        //System.out.println("gens    = " + gens);
390        assertTrue("#gens == 4 " + s, s == 4);
391
392        GenPolynomialRing pfac = (GenPolynomialRing) ExtensionFieldBuilder.baseField(fac)
393                        .polynomialExtension("y").build();
394        GenPolynomial elem = pfac.parse("y^2 - w s");
395        //System.out.println("elem    = " + elem.toScript());
396        //System.out.println("elem    = " + elem);
397
398        RingElem r = elem.trailingBaseCoefficient();
399        RingElem t = (RingElem) r.inverse();
400        RingElem u = (RingElem) r.multiply(t);
401        //System.out.println("r       = " + r);
402        //System.out.println("t       = " + t);
403        //System.out.println("r*t     = " + u);
404        assertTrue("r*t == 1: ", u.isONE());
405
406        elem = elem.multiply(elem.negate());
407        //System.out.println("elem    = " + elem);
408        elem = Power.positivePower(elem, 3);
409        //System.out.println("elem    = " + elem);
410        assertFalse("elem == 0 " + elem, elem.isZERO());
411    }
412
413
414    /**
415     * Test construction by extension field builder and multiple transcendent
416     * extension.
417     */
418    public void testConstructionM2() {
419        RingFactory fac = ExtensionFieldBuilder.baseField(new BigRational(1)).algebraicExtension("q,w,s", "")
420                        .build();
421        //System.out.println("fac = " + fac.toScript());
422
423        List<RingElem> gens = fac.generators();
424        int s = gens.size();
425        //System.out.println("gens    = " + gens);
426        assertTrue("#gens == 4 " + s, s == 4);
427
428        GenPolynomialRing pfac = (GenPolynomialRing) ExtensionFieldBuilder.baseField(fac)
429                        .polynomialExtension("y").build();
430        GenPolynomial elem = pfac.parse("y^2 - w s");
431        //System.out.println("elem    = " + elem.toScript());
432        //System.out.println("elem    = " + elem);
433
434        RingElem r = elem.trailingBaseCoefficient();
435        RingElem t = (RingElem) r.inverse();
436        RingElem u = (RingElem) r.multiply(t);
437        //System.out.println("r       = " + r);
438        //System.out.println("t       = " + t);
439        //System.out.println("r*t     = " + u);
440        assertTrue("r*t == 1: ", u.isONE());
441
442        elem = elem.multiply(elem.negate());
443        //System.out.println("elem    = " + elem);
444        elem = Power.positivePower(elem, 3);
445        //System.out.println("elem    = " + elem);
446        assertFalse("elem == 0 " + elem, elem.isZERO());
447    }
448
449}