001/*
002 * $Id$
003 */
004
005package edu.jas.poly;
006
007
008import java.util.HashSet;
009import java.util.Set;
010
011import edu.jas.arith.BigRational;
012// import edu.jas.structure.RingElem;
013import edu.jas.structure.NotInvertibleException;
014
015import junit.framework.Test;
016import junit.framework.TestCase;
017import junit.framework.TestSuite;
018
019
020/**
021 * AlgebraicNumber Test using JUnit.
022 * @author Heinz Kredel
023 */
024
025public class AlgebraicNumberTest extends TestCase {
026
027
028    /**
029     * main.
030     */
031    public static void main(String[] args) {
032        junit.textui.TestRunner.run(suite());
033    }
034
035
036    /**
037     * Constructs a <CODE>AlgebraicNumberTest</CODE> object.
038     * @param name String.
039     */
040    public AlgebraicNumberTest(String name) {
041        super(name);
042    }
043
044
045    /**
046     * suite.
047     */
048    public static Test suite() {
049        TestSuite suite = new TestSuite(AlgebraicNumberTest.class);
050        return suite;
051    }
052
053
054    //private final static int bitlen = 100;
055
056    AlgebraicNumberRing<BigRational> fac;
057
058
059    GenPolynomialRing<BigRational> mfac;
060
061
062    AlgebraicNumber<BigRational> a, b, c, d, e;
063
064
065    int rl = 1;
066
067
068    int kl = 10;
069
070
071    int ll = 7;
072
073
074    int el = ll;
075
076
077    float q = 0.4f;
078
079
080    @Override
081    protected void setUp() {
082        a = b = c = d = e = null;
083        BigRational bi = new BigRational(1);
084        //bi.setAllIterator();
085        bi.setNoDuplicatesIterator();
086        mfac = new GenPolynomialRing<BigRational>(bi, rl);
087        GenPolynomial<BigRational> mo = mfac.random(kl, ll, 7, q);
088        while (mo.isConstant()) {
089            mo = mfac.random(kl, ll, 5, q);
090        }
091        fac = new AlgebraicNumberRing<BigRational>(mo.monic());
092    }
093
094
095    @Override
096    protected void tearDown() {
097        a = b = c = d = e = null;
098        fac = null;
099    }
100
101
102    /**
103     * Test constructor and toString.
104     */
105    public void testConstruction() {
106        c = fac.getONE();
107        //System.out.println("c = " + c);
108        //System.out.println("c.getVal() = " + c.getVal());
109        assertTrue("length( c ) = 1", c.getVal().length() == 1);
110        assertTrue("isZERO( c )", !c.isZERO());
111        assertTrue("isONE( c )", c.isONE());
112
113        d = fac.getZERO();
114        //System.out.println("d = " + d);
115        //System.out.println("d.getVal() = " + d.getVal());
116        assertTrue("length( d ) = 0", d.getVal().length() == 0);
117        assertTrue("isZERO( d )", d.isZERO());
118        assertTrue("isONE( d )", !d.isONE());
119    }
120
121
122    /**
123     * Test random polynomial.
124     */
125    public void testRandom() {
126        for (int i = 0; i < 7; i++) {
127            a = fac.random(el);
128            //System.out.println("a = " + a);
129            if (a.isZERO() || a.isONE()) {
130                continue;
131            }
132            //fac.random(kl*(i+1), ll+2*i, el+i, q );
133            assertTrue("length( a" + i + " ) <> 0", a.getVal().length() >= 0);
134            assertTrue(" not isZERO( a" + i + " )", !a.isZERO());
135            assertTrue(" not isONE( a" + i + " )", !a.isONE());
136        }
137    }
138
139
140    /**
141     * Test addition.
142     */
143    public void testAddition() {
144        a = fac.random(ll);
145        b = fac.random(ll);
146
147        c = a.sum(b);
148        d = c.subtract(b);
149        assertEquals("a+b-b = a", a, d);
150
151        c = a.sum(b);
152        d = b.sum(a);
153        assertEquals("a+b = b+a", c, d);
154
155        c = fac.random(ll);
156        d = c.sum(a.sum(b));
157        e = c.sum(a).sum(b);
158        assertEquals("c+(a+b) = (c+a)+b", d, e);
159
160
161        c = a.sum(fac.getZERO());
162        d = a.subtract(fac.getZERO());
163        assertEquals("a+0 = a-0", c, d);
164
165        c = fac.getZERO().sum(a);
166        d = fac.getZERO().subtract(a.negate());
167        assertEquals("0+a = 0-(-a)", c, d);
168    }
169
170
171    /**
172     * Test object multiplication.
173     */
174    @SuppressWarnings({ "unchecked", "cast" })
175    public void testMultiplication() {
176        a = fac.random(ll);
177        assertTrue("not isZERO( a )", !a.isZERO());
178
179        b = fac.random(ll);
180        assertTrue("not isZERO( b )", !b.isZERO());
181
182        c = b.multiply(a);
183        d = a.multiply(b);
184        assertTrue("not isZERO( c )", !c.isZERO());
185        assertTrue("not isZERO( d )", !d.isZERO());
186
187        //System.out.println("a = " + a);
188        //System.out.println("b = " + b);
189        e = d.subtract(c);
190        assertTrue("isZERO( a*b-b*a ) " + e, e.isZERO());
191
192        assertTrue("a*b = b*a", c.equals(d));
193        assertEquals("a*b = b*a", c, d);
194
195        c = fac.random(ll);
196        //System.out.println("c = " + c);
197        d = a.multiply(b.multiply(c));
198        e = (a.multiply(b)).multiply(c);
199
200        //System.out.println("d = " + d);
201        //System.out.println("e = " + e);
202        //System.out.println("d-e = " + d.subtract(c) );
203
204        assertEquals("a(bc) = (ab)c", d, e);
205        assertTrue("a(bc) = (ab)c", d.equals(e));
206
207        c = a.multiply(fac.getONE());
208        d = fac.getONE().multiply(a);
209        assertEquals("a*1 = 1*a", c, d);
210
211        c = a.inverse();
212        d = c.multiply(a);
213        //System.out.println("a = " + a);
214        //System.out.println("c = " + c);
215        //System.out.println("d = " + d);
216        assertEquals("a*1/a = 1", fac.getONE(), d);
217
218        try {
219            d = fac.getZERO().inverse();
220            fail("0 invertible");
221        } catch (NotInvertibleException expected) {
222            // ok
223        }
224
225        GenPolynomial<BigRational> dp = fac.modul;
226        GenPolynomial<BigRational> cp = fac.modul.multiply(a.val.monic());
227        //System.out.println("dp = " + dp);
228        //System.out.println("cp = " + cp);
229        fac = new AlgebraicNumberRing<BigRational>(cp);
230        a = new AlgebraicNumber<BigRational>(fac, a.val.monic());
231        assertFalse("a !unit mod m*a: " + a, a.isUnit() && !a.isONE());
232
233        try {
234            b = a.inverse();
235            if (!a.isONE()) {
236                fail("invertible " + a);
237            }
238        } catch (AlgebraicNotInvertibleException expected) {
239            //ok
240            //expected.printStackTrace();
241            //System.out.println("expected = " + expected);
242            GenPolynomial<BigRational> f1 = (GenPolynomial<BigRational>) expected.f1;
243            GenPolynomial<BigRational> f2 = (GenPolynomial<BigRational>) expected.f2;
244            assertTrue("f  = " + cp, expected.f.equals(cp));
245            assertTrue("f1 = " + a.val, f1.equals(a.val));
246            assertTrue("f2 = " + dp, f2.equals(dp));
247            assertTrue("f  =  f1*f2 ", expected.f.equals(f1.multiply(f2)));
248        } catch (NotInvertibleException e) {
249            //e.printStackTrace();
250            fail("wrong exception " + e);
251        }
252    }
253
254
255    /**
256     * Test distributive law.
257     */
258    public void testDistributive() {
259        a = fac.random(ll);
260        b = fac.random(ll);
261        c = fac.random(ll);
262
263        d = a.multiply(b.sum(c));
264        e = a.multiply(b).sum(a.multiply(c));
265
266        assertEquals("a(b+c) = ab+ac", d, e);
267    }
268
269
270    /**
271     * Test example.
272     */
273    public void testExample() {
274        BigRational cofac = new BigRational(1);
275        GenPolynomialRing<BigRational> mfac = new GenPolynomialRing<BigRational>(cofac,
276                        new String[] { "w35" });
277
278        // w35**2 - 35: w35 == sqrt(35)
279        GenPolynomial<BigRational> mo = mfac.univariate(0);
280        mo = mo.power(2).subtract(mfac.fromInteger(35));
281        //System.out.println("mo = " + mo);
282        AlgebraicNumberRing<BigRational> fac = new AlgebraicNumberRing<BigRational>(mo);
283        //System.out.println("fac = " + fac);
284
285        // (5+sqrt(35))**(-1) == 1/10 w35 - 1/2
286        AlgebraicNumber<BigRational> w35 = fac.getGenerator();
287        AlgebraicNumber<BigRational> rr = fac.fromInteger(5).sum(w35).inverse();
288        //System.out.println("rr = " + rr);
289        assertFalse("rr != 0: ", rr.isZERO());
290        assertTrue("deg(rr.val) == 1: ", rr.val.degree() == 1);
291    }
292
293
294    /**
295     * Test enumerator.
296     */
297    public void testEnumerator() {
298        //System.out.println("fac = " + fac);
299        long s = 0L;
300        long t = 0L;
301        Set<AlgebraicNumber<BigRational>> elems = new HashSet<AlgebraicNumber<BigRational>>(49);
302        //Iterator<AlgebraicNumber<BigRational>> iter = fac.iterator();
303        for (AlgebraicNumber<BigRational> an : fac) {
304            t++;
305            if (elems.contains(an)) {
306                //System.out.println("dup(an) = " + an);
307                s++;
308            } else {
309                //System.out.println("an = " + an);
310                elems.add(an);
311            }
312            if (t >= 100) {
313                break;
314            }
315        }
316        //System.out.println("elems = " + elems);
317        assertTrue("#elems " + t + ", t = " + elems.size(), t == elems.size());
318        assertTrue("#elems " + t + ", t = " + elems.size(), s == 0L);
319    }
320
321}