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