001    /*
002     * $Id: ExtensionFieldBuilderTest.java 3591 2011-04-01 20:29:49Z kredel $
003     */
004    
005    package edu.jas.application;
006    
007    
008    import java.util.List;
009    
010    import junit.framework.Test;
011    import junit.framework.TestCase;
012    import junit.framework.TestSuite;
013    
014    import org.apache.log4j.BasicConfigurator;
015    
016    import edu.jas.arith.BigRational;
017    import edu.jas.arith.ModLongRing;
018    import edu.jas.kern.ComputerThreads;
019    import edu.jas.poly.AlgebraicNumber;
020    import edu.jas.poly.AlgebraicNumberRing;
021    import edu.jas.poly.ComplexRing;
022    import edu.jas.poly.GenPolynomial;
023    import edu.jas.poly.GenPolynomialRing;
024    import edu.jas.root.RealAlgebraicNumber;
025    import edu.jas.root.RootFactory;
026    import edu.jas.structure.Power;
027    import edu.jas.structure.RingElem;
028    import edu.jas.structure.RingFactory;
029    import edu.jas.ufd.Quotient;
030    import edu.jas.ufd.QuotientRing;
031    
032    
033    /**
034     * ExtensionFieldBuilder tests with JUnit.
035     * @author Heinz Kredel.
036     */
037    
038    public 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 = (RingElem) 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        }
411    
412    
413        /**
414         * Test construction by extension field builder and multiple transcendent
415         * extension.
416         */
417        public void testConstructionM2() {
418            RingFactory fac = ExtensionFieldBuilder.baseField(new BigRational(1)).algebraicExtension("q,w,s", "")
419                            .build();
420            //System.out.println("fac = " + fac.toScript());
421    
422            List<RingElem> gens = fac.generators();
423            int s = gens.size();
424            //System.out.println("gens    = " + gens);
425            assertTrue("#gens == 4 " + s, s == 4);
426    
427            GenPolynomialRing pfac = (GenPolynomialRing) ExtensionFieldBuilder.baseField(fac)
428                            .polynomialExtension("y").build();
429            GenPolynomial elem = pfac.parse("y^2 - w s");
430            //System.out.println("elem    = " + elem.toScript());
431            //System.out.println("elem    = " + elem);
432    
433            RingElem r = (RingElem) elem.trailingBaseCoefficient();
434            RingElem t = (RingElem) r.inverse();
435            RingElem u = (RingElem) r.multiply(t);
436            //System.out.println("r       = " + r);
437            //System.out.println("t       = " + t);
438            //System.out.println("r*t     = " + u);
439            assertTrue("r*t == 1: ", u.isONE());
440    
441            elem = elem.multiply(elem.negate());
442            //System.out.println("elem    = " + elem);
443            elem = Power.positivePower(elem, 3);
444            //System.out.println("elem    = " + elem);
445        }
446    
447    }