001/*
002 * $Id$
003 */
004
005package edu.jas.vector;
006
007
008import java.util.ArrayList;
009import java.util.List;
010
011import edu.jas.arith.BigRational;
012import edu.jas.arith.ModLong;
013import edu.jas.arith.ModLongRing;
014
015import junit.framework.Test;
016import junit.framework.TestCase;
017import junit.framework.TestSuite;
018
019
020/**
021 * GenMatrix tests with JUnit.
022 * @author Heinz Kredel
023 */
024
025public class GenMatrixTest 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>GenMatrixTest</CODE> object.
038     * @param name String.
039     */
040    public GenMatrixTest(String name) {
041        super(name);
042    }
043
044
045    /**
046     */
047    public static Test suite() {
048        TestSuite suite = new TestSuite(GenMatrixTest.class);
049        return suite;
050    }
051
052
053    int rl = 5;
054
055
056    int kl = 10;
057
058
059    int ll = 10;
060
061
062    float q = 0.5f;
063
064
065    int rows = 3 + 20;
066
067
068    int cols = 3 + 20;
069
070
071    @Override
072    protected void setUp() {
073    }
074
075
076    @Override
077    protected void tearDown() {
078    }
079
080
081    /**
082     * Test constructor and toString.
083     */
084    public void testConstruction() {
085        BigRational cfac = new BigRational(1);
086        GenMatrixRing<BigRational> mfac = new GenMatrixRing<BigRational>(cfac, rows, cols);
087
088        assertTrue("#rows = " + rows, mfac.rows == rows);
089        assertTrue("#columns = " + cols, mfac.cols == cols);
090        assertTrue("cfac == coFac ", cfac == mfac.coFac);
091
092        GenMatrix<BigRational> a;
093        a = mfac.getZERO();
094        //System.out.println("a = " + a);
095        assertTrue("isZERO( a )", a.isZERO());
096
097        GenMatrix<BigRational> b = new GenMatrix<BigRational>(mfac);
098        //System.out.println("b = " + b);
099        assertTrue("isZERO( b )", b.isZERO());
100
101        assertTrue("a == b ", a.equals(b));
102
103        GenMatrix<BigRational> c = b.copy();
104        //System.out.println("c = " + c);
105        assertTrue("isZERO( c )", c.isZERO());
106        assertTrue("a == c ", a.equals(c));
107
108        GenMatrix<BigRational> d = mfac.copy(b);
109        //System.out.println("d = " + d);
110        assertTrue("isZERO( d )", d.isZERO());
111        assertTrue("a == d ", a.equals(d));
112
113        a = mfac.getONE();
114        //System.out.println("a = " + a);
115        assertTrue("isONE( a )", a.isONE());
116
117        List<ArrayList<BigRational>> m = a.matrix;
118        List<List<BigRational>> ml = new ArrayList<List<BigRational>>(m.size());
119        for (ArrayList<BigRational> r : m) {
120            ml.add(r);
121        }
122        b = mfac.fromList(ml);
123        assertEquals("a == fromList(a.matrix)", a, b);
124
125        GenMatrix<BigRational> e = mfac.generate((i, j) -> cfac.getZERO());
126        //System.out.println("e = " + e);
127        assertTrue("e == 0: ", e.isZERO());
128
129        e = mfac.generate((i, j) -> i == j ? cfac.getONE() : cfac.getZERO());
130        //System.out.println("e = " + e);
131        assertTrue("e == 1: ", e.isONE());
132
133        e = mfac.generate((i, j) -> i == j + 1 ? cfac.getONE() : cfac.getZERO());
134        //System.out.println("e = " + e);
135        assertTrue("e**" + mfac.cols + " == 0: ", e.power(mfac.cols).isZERO());
136    }
137
138
139    /**
140     * Test random matrix.
141     */
142    public void testRandom() {
143        BigRational cfac = new BigRational(1);
144        GenMatrixRing<BigRational> mfac = new GenMatrixRing<BigRational>(cfac, rows, cols);
145        GenMatrixRing<BigRational> tfac = mfac.transpose();
146
147        if (rows == cols) {
148            assertTrue(" mfac = tfac ", mfac.equals(tfac));
149        }
150
151        GenMatrix<BigRational> a, b, c;
152
153        for (int i = 0; i < 5; i++) {
154            a = mfac.random(kl, q);
155            //System.out.println("a = " + a);
156            if (a.isZERO()) {
157                continue;
158            }
159            assertTrue(" not isZERO( a" + i + " )", !a.isZERO());
160            b = a.transpose(tfac);
161            //System.out.println("b = " + b);
162            assertTrue(" not isZERO( b" + i + " )", !b.isZERO());
163            c = b.transpose(mfac);
164            //System.out.println("c = " + c);
165            assertEquals(" a^r^r == a ", a, c);
166        }
167
168        for (int i = 0; i < 3; i++) {
169            a = mfac.randomUpper(kl, q);
170            //System.out.println("a = " + a);
171            if (a.isZERO()) {
172                continue;
173            }
174            assertTrue(" not isZERO( a" + i + " )", !a.isZERO());
175            b = a.transpose(tfac);
176            //System.out.println("b = " + b);
177            assertTrue(" not isZERO( b" + i + " )", !b.isZERO());
178            c = b.transpose(mfac);
179            //System.out.println("c = " + c);
180            assertEquals(" a^r^r == a ", a, c);
181        }
182
183        for (int i = 0; i < 3; i++) {
184            a = mfac.randomLower(kl, q);
185            //System.out.println("a = " + a);
186            if (a.isZERO()) {
187                continue;
188            }
189            assertTrue(" not isZERO( a" + i + " )", !a.isZERO());
190            b = a.transpose(tfac);
191            //System.out.println("b = " + b);
192            assertTrue(" not isZERO( b" + i + " )", !b.isZERO());
193            c = b.transpose(mfac);
194            //System.out.println("c = " + c);
195            assertEquals(" a^r^r == a ", a, c);
196        }
197    }
198
199
200    /**
201     * Test addition.
202     */
203    public void testAddition() {
204        BigRational cfac = new BigRational(1);
205        GenMatrixRing<BigRational> mfac = new GenMatrixRing<BigRational>(cfac, rows, cols);
206        GenMatrix<BigRational> a, b, c, d, e;
207
208        a = mfac.random(kl, q);
209        b = mfac.random(kl, q);
210        //System.out.println("a = " + a);
211        //System.out.println("b = " + b);
212
213        c = a.sum(b);
214        d = c.subtract(b);
215        //System.out.println("c = " + c);
216        //System.out.println("d = " + d);
217        assertEquals("a+b-b = a", a, d);
218
219        c = a.sum(b);
220        d = c.sum(b.negate());
221        //System.out.println("c = " + c);
222        //System.out.println("d = " + d);
223        assertEquals("a+b+(-b) = a", a, d);
224
225        c = a.sum(b);
226        d = b.sum(a);
227        //System.out.println("c = " + c);
228        //System.out.println("d = " + d);
229        assertEquals("a+b = b+a", c, d);
230
231        c = mfac.random(kl, q);
232        d = a.sum(b).sum(c);
233        e = a.sum(b.sum(c));
234        //System.out.println("d = " + d);
235        //System.out.println("e = " + e);
236        assertEquals("a+(b+c) = (a+b)+c", d, e);
237    }
238
239
240    /**
241     * Test scalar multiplication.
242     */
243    public void testScalarMultiplication() {
244        BigRational cfac = new BigRational(1);
245        GenMatrixRing<BigRational> mfac = new GenMatrixRing<BigRational>(cfac, rows, cols);
246        BigRational r, s, t;
247        GenMatrix<BigRational> a, b, c, d;
248
249        r = cfac.random(kl);
250        //System.out.println("r = " + r);
251        s = r.inverse();
252        //System.out.println("s = " + s);
253
254        a = mfac.random(kl, q);
255        //System.out.println("a = " + a);
256
257        c = a.scalarMultiply(r);
258        d = c.scalarMultiply(s);
259        //System.out.println("c = " + c);
260        //System.out.println("d = " + d);
261        assertEquals("a*b*(1/b) = a", a, d);
262
263        b = mfac.random(kl, q);
264        //System.out.println("b = " + b);
265
266        t = cfac.getONE();
267        //System.out.println("t = " + t);
268        c = a.linearCombination(b, t);
269        d = b.linearCombination(a, t);
270        //System.out.println("c = " + c);
271        //System.out.println("d = " + d);
272        assertEquals("a+1*b = b+1*a", c, d);
273
274        c = a.linearCombination(b, t);
275        d = a.sum(b);
276        //System.out.println("c = " + c);
277        //System.out.println("d = " + d);
278        assertEquals("a+1*b = b+1*a", c, d);
279
280        s = t.negate();
281        //System.out.println("s = " + s);
282        c = a.linearCombination(b, t);
283        d = c.linearCombination(b, s);
284        //System.out.println("c = " + c);
285        //System.out.println("d = " + d);
286        assertEquals("a+1*b+(-1)*b = a", a, d);
287
288        c = a.linearCombination(t, b, t);
289        d = c.linearCombination(t, b, s);
290        //System.out.println("c = " + c);
291        //System.out.println("d = " + d);
292        assertEquals("a*1+b*1+b*(-1) = a", a, d);
293
294        t = cfac.getZERO();
295        //System.out.println("t = " + t);
296        c = a.linearCombination(b, t);
297        //System.out.println("c = " + c);
298        assertEquals("a+0*b = a", a, c);
299
300        d = a.linearCombination(t, b, t);
301        //System.out.println("d = " + d);
302        assertEquals("0*a+0*b = 0", mfac.getZERO(), d);
303    }
304
305
306    /**
307     * Test (simple) multiplication.
308     */
309    public void testSimpleMultiplication() {
310        BigRational cfac = new BigRational(1);
311        GenMatrixRing<BigRational> mfac = new GenMatrixRing<BigRational>(cfac, rows, cols);
312        GenMatrix<BigRational> a, b, c, d, e, f;
313
314        a = mfac.getZERO();
315        b = mfac.getZERO();
316        c = a.multiplySimple(b);
317        //System.out.println("a = " + a);
318        //System.out.println("b = " + b);
319        //System.out.println("c = " + c);
320        assertTrue("0*0 = 0 ", c.isZERO());
321
322        a = mfac.getONE();
323        b = mfac.getONE();
324        c = a.multiplySimple(b);
325        //System.out.println("a = " + a);
326        //System.out.println("b = " + b);
327        //System.out.println("c = " + c);
328        assertTrue("1*1 = 1 ", c.isONE());
329
330        a = mfac.random(kl, q);
331        b = mfac.getONE();
332        c = a.multiplySimple(b);
333        d = a.multiply(b);
334        //System.out.println("a = " + a);
335        //System.out.println("b = " + b);
336        //System.out.println("c = " + c);
337        //System.out.println("d = " + d);
338        assertEquals("a*1 = a ", a, c);
339        assertEquals("a*1 = a*1 ", c, d);
340
341        c = b.multiplySimple(a);
342        d = a.multiply(b);
343        //System.out.println("a = " + a);
344        //System.out.println("b = " + b);
345        //System.out.println("c = " + c);
346        //System.out.println("d = " + d);
347        assertEquals("1*a = a ", a, c);
348        assertEquals("a*1 = a*1 ", c, d);
349
350        b = mfac.random(kl, q);
351        long s, t;
352        s = System.currentTimeMillis();
353        c = a.multiplySimple(b);
354        s = System.currentTimeMillis() - s;
355        assertTrue("nonsense " + s, s >= 0L);
356        d = b.multiplySimple(a);
357        t = System.currentTimeMillis();
358        e = a.multiply(b);
359        t = System.currentTimeMillis() - t;
360        assertTrue("nonsense " + t, t >= 0L);
361        f = b.multiply(a);
362        //System.out.println("a = " + a);
363        //System.out.println("b = " + b);
364        //System.out.println("c = " + c);
365        //System.out.println("d = " + d);
366        //System.out.println("e = " + e);
367        //System.out.println("f = " + e);
368        //System.out.println("e = " + e);
369        assertTrue("a*b != b*a ", !c.equals(d));
370        assertEquals("a*1 = a*1 ", c, e);
371        assertEquals("a*1 = a*1 ", d, f);
372        //System.out.println("time: s = " + s + ", t = " + t);
373
374        if (!mfac.isAssociative()) {
375            return;
376        }
377        c = mfac.random(kl, q);
378
379        d = a.multiply(b.sum(c));
380        e = (a.multiply(b)).sum(a.multiply(c));
381        assertEquals("a*(b+c) = a*b+a*c", d, e);
382
383        d = a.multiply(b.multiply(c));
384        e = (a.multiply(b)).multiply(c);
385        assertEquals("a*(b*c) = (a*b)*c", d, e);
386    }
387
388
389    /**
390     * Test parse matrix.
391     */
392    public void testParse() {
393        BigRational cfac = new BigRational(1);
394        GenMatrixRing<BigRational> mfac = new GenMatrixRing<BigRational>(cfac, rows, cols);
395
396        GenMatrix<BigRational> a, c;
397
398        a = mfac.random(kl, q);
399        //System.out.println("a = " + a);
400        if (!a.isZERO()) {
401            //return;
402            assertTrue(" not isZERO( a )", !a.isZERO());
403        }
404        String s = a.toString();
405        //System.out.println("s = " + s);
406        c = mfac.parse(s);
407        //System.out.println("c = " + c);
408        assertEquals("parse(toStirng(a) == a ", a, c);
409    }
410
411
412    /**
413     * Test LU decomposition.
414     */
415    public void testLUdecomp() {
416        BigRational cfac = new BigRational(1);
417        int n = 10;
418        GenMatrixRing<BigRational> mfac = new GenMatrixRing<BigRational>(cfac, n, n);//rows, cols);
419        GenVectorModul<BigRational> vfac = new GenVectorModul<BigRational>(cfac, n);//rows);
420
421        GenMatrix<BigRational> A, Ap, iA, AiA;
422        //A = mfac.getONE().negate(); //.sum(mfac.getONE());
423        A = mfac.random(kl, 0.7f);
424        //A = mfac.parse("[ [3,4], [1,2] ]");
425        //System.out.println("A = " + A);
426        if (A.isZERO()) {
427            return;
428        }
429        assertTrue(" not isZERO( A )", !A.isZERO());
430        Ap = A.copy();
431
432        LinAlg<BigRational> lu = new LinAlg<BigRational>();
433        BasicLinAlg<BigRational> blas = new BasicLinAlg<BigRational>();
434
435        List<Integer> P = lu.decompositionLU(A);
436        //System.out.println("P = " + P);
437        //System.out.println("A = " + A);
438        if (P.size() == 0) {
439            System.out.println("undecomposable");
440            return;
441        }
442
443        GenVector<BigRational> s;
444        //b = vfac.random(kl);
445        //b = vfac.parse("[5,5]");
446        //s = vfac.parse("[1,1]");
447        s = vfac.random(kl);
448        //System.out.println("s = " + s);
449        GenVector<BigRational> b = blas.rightProduct(s, Ap);
450        //System.out.println("b = " + b);
451
452        GenVector<BigRational> x = lu.solveLU(A, P, b);
453        //System.out.println("x = " + x);
454        assertEquals("s == x: ", s, x);
455
456        GenVector<BigRational> r = blas.rightProduct(x, Ap);
457        //System.out.println("r = " + r);
458
459        //System.out.println("b == r: " + b.equals(r));
460        assertEquals("b == r: ", b, r);
461
462        BigRational det = lu.determinantLU(A, P);
463        //System.out.println("det = " + det + " ~= " + det.getDecimal());
464        assertFalse("det(A) != 0: ", det.isZERO());
465
466        // test inverse and divide
467        iA = lu.inverseLU(A, P);
468        //System.out.println("iA = " + iA);
469        AiA = Ap.multiply(iA);
470        //System.out.println("AiA = " + AiA);
471        assertTrue("A*iA == 1: ", AiA.isONE());
472
473        GenMatrix<BigRational> I = Ap.inverse();
474        GenMatrix<BigRational> CI = Ap.multiply(I);
475        //System.out.println("C*I:   " + CI.toScript());
476        assertTrue("Ap*I == 1: ", CI.isONE());
477
478        GenMatrix<BigRational> C = mfac.random(3, 0.5f);
479        GenMatrix<BigRational> CA = C.divide(Ap);
480        GenMatrix<BigRational> AC = C.divideLeft(Ap);
481        //System.out.println("C/A :    " + CA);
482        //System.out.println("A\\C :   " + AC);
483        assertFalse("C/A != A\\C: ", CA.equals(AC));
484
485        GenMatrix<BigRational> B = CA.multiply(Ap);
486        assertEquals("C == C/A*A: ", B, C);
487        B = Ap.multiply(AC);
488        assertEquals("C == A*A\\C: ", B, C);
489
490        // test upper / lower matrix
491        B = Ap.getUpper();
492        //System.out.println("b = " + B);
493        C = Ap.getLower();
494        //System.out.println("c = " + C);
495        GenMatrix<BigRational> bc = C.sum(B);
496        //System.out.println("bc = " + bc);
497
498        GenMatrix<BigRational> abc = Ap.subtract(bc);
499        //System.out.println("Ap = " + Ap);
500        //System.out.println("abc = " + abc);
501
502        assertTrue("abc is diagonal: ", abc.isDiagonal());
503        GenVector<BigRational> ad = abc.getDiagonal();
504        //System.out.println("ad = " + ad);
505        assertFalse("diag(abc) != 0: ", ad.isZERO());
506    }
507
508
509    /**
510     * Test Null Space basis, modular coeffs.
511     */
512    public void testNullSpaceMod() {
513        ModLongRing cfac = new ModLongRing(11); //11, 32003
514        int n = 100;
515        GenMatrixRing<ModLong> mfac = new GenMatrixRing<ModLong>(cfac, n, n);//rows, cols);
516        //System.out.println("mfac = " + mfac.toScript());
517        //GenVectorModul<ModLong> vfac = new GenVectorModul<ModLong>(cfac, n);//rows);
518        GenMatrixRing<ModLong> tfac = mfac.transpose();
519
520        GenMatrix<ModLong> A, Ap, B, T;
521        //A = mfac.getONE(); //.negate(); //.sum(mfac.getONE());
522        A = mfac.random(kl, 0.5f / n);
523        //A = mfac.parse("[ [3,4,5], [1,2,3], [2,4,6] ]");
524        //A = mfac.parse("[ [1,0,0,0,0], [3,0,0,0,0], [0,0,1,0,0], [2,0,4,0,0], [0,0,0,0,1] ]");
525        //A = mfac.parse("[ [0,0,0,0,0,0], [3,4,-3,-3,5,5], [3,-5,5,1,-1,0], [-2,4,-1,2,-4,-2], [-4,-3,-1,0,-1,-3], [-3,-1,-4,-3,-1,-4] ]");
526        //A = A.sum( mfac.getONE() );
527        if (n < 50)
528            System.out.println("A = " + A);
529        if (A.isZERO()) {
530            return;
531        }
532        assertTrue(" not isZERO( A )", !A.isZERO());
533        Ap = A.copy();
534        T = A.transpose(tfac);
535        if (n < 10)
536            System.out.println("At = " + T);
537
538        LinAlg<ModLong> lu = new LinAlg<ModLong>();
539        BasicLinAlg<ModLong> blas = new BasicLinAlg<ModLong>();
540
541        List<GenVector<ModLong>> NSB = lu.nullSpaceBasis(A);
542        //System.out.println("NS basis = " + NSB.size());
543        if (NSB.size() == 0) {
544            System.out.println("no null space basis");
545            return;
546        }
547        if (n < 10)
548            System.out.println("mod A-I = " + A);
549        for (GenVector<ModLong> v : NSB) {
550            GenVector<ModLong> z = blas.leftProduct(v, T);
551            //System.out.println("z == 0: " + z.isZERO());
552            assertTrue("z == 0: " + z, z.isZERO());
553        }
554        // test idempotent
555        Ap = A.sum(mfac.getONE());
556        B = Ap.multiply(Ap);
557        if (!Ap.equals(B)) {
558            System.out.println("Ap = " + Ap);
559            System.out.println("B = " + B);
560        }
561        assertEquals("A*A == B: ", Ap, B);
562    }
563
564
565    /**
566     * Test Null Space basis.
567     */
568    public void testNullSpace() {
569        BigRational cfac = new BigRational(11);
570        int n = 100;
571        GenMatrixRing<BigRational> mfac = new GenMatrixRing<BigRational>(cfac, n, n);//rows, cols);
572        //System.out.println("mfac = " + mfac.toScript());
573        //GenVectorModul<BigRational> vfac = new GenVectorModul<BigRational>(cfac, n);//rows);
574        GenMatrixRing<BigRational> tfac = mfac.transpose();
575
576        GenMatrix<BigRational> A, Ap, B, T;
577        //A = mfac.getZERO(); //.negate(); //.sum(mfac.getONE());
578        //A.setMutate(4,1, cfac.parse("44") );
579        //A.setMutate(5,2, cfac.parse("22") );
580        //A.setMutate(5,3, cfac.parse("33") );
581        A = mfac.random(kl, 0.5f / n);
582        //A = mfac.parse("[ [3,4,5], [1,2,3], [2,4,6] ]");
583        //A = mfac.parse("[ [1,0,0,0,0], [3,0,0,0,0], [0,0,1,0,0], [2,0,4,0,0], [0,0,0,0,1] ]");
584        //A = mfac.parse("[ [0,0,0,0,0,0], [3,4,-3,-3,5,5], [3,-5,5,1,-1,0], [-2,4,-1,2,-4,-2], [-4,-3,-1,0,-1,-3], [-3,-1,-4,-3,-1,-4] ]");
585        //A = A.sum( mfac.getONE() ); // subtract
586        if (n < 10)
587            System.out.println("A = " + A);
588        if (A.isZERO()) {
589            return;
590        }
591        assertTrue(" not isZERO( A )", !A.isZERO());
592        Ap = A.copy();
593        T = A.transpose(tfac);
594
595        LinAlg<BigRational> lu = new LinAlg<BigRational>();
596        BasicLinAlg<BigRational> blas = new BasicLinAlg<BigRational>();
597
598        List<GenVector<BigRational>> NSB = lu.nullSpaceBasis(A);
599        //System.out.println("NS basis = " + NSB.size());
600        if (NSB.size() == 0) {
601            System.out.println("no null space basis");
602            return;
603        }
604        if (n < 10)
605            System.out.println("mod A-I = " + A);
606        if (n < 10)
607            System.out.println("T = " + T);
608        for (GenVector<BigRational> v : NSB) {
609            //System.out.println("v = " + v);
610            GenVector<BigRational> z = blas.leftProduct(v, T);
611            //System.out.println("z == 0: " + z.isZERO());
612            assertTrue("z == 0: " + z, z.isZERO());
613        }
614        // test idempotent
615        Ap = A.sum(mfac.getONE());
616        B = Ap.multiply(Ap);
617        if (!Ap.equals(B)) {
618            System.out.println("Ap = " + Ap);
619            System.out.println("B = " + B);
620        }
621        assertEquals("A*A == B: ", Ap, B);
622    }
623
624
625    /**
626     * Test Null Space basis for cokernel and kernel.
627     */
628    public void testNullSpaceKernels() {
629        BigRational cfac = new BigRational(11);
630        int n = 10;
631        GenMatrixRing<BigRational> mfac = new GenMatrixRing<BigRational>(cfac, n, n);//rows, cols);
632        //System.out.println("mfac = " + mfac.toScript());
633        GenMatrixRing<BigRational> tfac = mfac.transpose();
634
635        GenMatrix<BigRational> A, Ap, T, Tp;
636        A = mfac.random(kl, 0.7f / n);
637        if (n < 10)
638            System.out.println("A = " + A);
639        if (A.isZERO()) {
640            return;
641        }
642        assertTrue(" not isZERO( A )", !A.isZERO());
643        Ap = A.copy();
644        T = Ap.transpose(tfac);
645        Tp = T.copy();
646        if (n < 10)
647            System.out.println("T = " + T);
648
649        LinAlg<BigRational> lu = new LinAlg<BigRational>();
650        BasicLinAlg<BigRational> blas = new BasicLinAlg<BigRational>();
651
652        List<GenVector<BigRational>> cokern = lu.nullSpaceBasis(A);
653        //System.out.println("cokern basis = " + cokern);
654        if (cokern.size() == 0) {
655            System.out.println("no cokern null space basis");
656            //return;
657        }
658        for (GenVector<BigRational> v : cokern) {
659            //System.out.println("v = " + v);
660            GenVector<BigRational> z = blas.leftProduct(v, Tp);
661            //System.out.println("z == 0: " + z.isZERO());
662            assertTrue("z == 0: " + z, z.isZERO());
663        }
664
665        List<GenVector<BigRational>> kern = lu.nullSpaceBasis(T);
666        //System.out.println("kern basis = " + kern);
667        if (kern.size() == 0) {
668            System.out.println("no kern null space basis");
669            //return;
670        }
671        for (GenVector<BigRational> v : kern) {
672            //System.out.println("v = " + v);
673            GenVector<BigRational> z = blas.rightProduct(v, Ap);
674            //System.out.println("z == 0: " + z.isZERO());
675            assertTrue("z == 0: " + z, z.isZERO());
676        }
677
678        // test ranks
679        long r1, r2, k, c;
680        //System.out.println("diag(Ap): " + Ap.getDiagonal());
681        //System.out.println("Ap: " + Ap);
682        r1 = lu.rankNS(Ap);
683        c = cokern.size();
684        assertTrue("0 <= rank < n: ", 0 <= r1 && r1 <= n);
685        assertTrue("rank + dim coker == n ", r1 + c == n);
686
687        //System.out.println("diag(Tp): " + Tp.getDiagonal());
688        //System.out.println("Tp: " + Tp);
689        r2 = lu.rankNS(Tp);
690        k = kern.size();
691        //System.out.println("rank A = " + r1 + ", c = " + c + ", n = " + n);
692        //System.out.println("rank T = " + r2 + ", k = " + k);
693        assertTrue("0 <= rank < n: ", 0 <= r2 && r2 <= n);
694        assertTrue("rank + dim ker == n ", r2 + k == n);
695    }
696
697
698    /**
699     * Test row echelon form and rank.
700     */
701    public void testRowEchelonForm() {
702        BigRational cfac = new BigRational(11);
703        int n = 50;
704        GenMatrixRing<BigRational> mfac = new GenMatrixRing<BigRational>(cfac, n, n);//rows, cols);
705        //System.out.println("mfac = " + mfac.toScript());
706        GenMatrixRing<BigRational> tfac = mfac.transpose();
707
708        GenMatrix<BigRational> A, Ap, App, B, T, Tpp;
709        A = mfac.random(kl, 2.0f / n);
710        //A = mfac.getONE();
711        //A = mfac.getZERO(); A.setMutate(3,4, cfac.parse("2")); A.setMutate(5,4, cfac.parse("3"));
712        if (n < 10)
713            System.out.println("A = " + A);
714        if (A.isZERO()) {
715            return;
716        }
717        assertTrue(" not isZERO( A )", !A.isZERO());
718        Ap = A.copy();
719        T = Ap.transpose(tfac);
720        //Tp = T.copy();
721        if (n < 10)
722            System.out.println("T = " + T.ring.rows);
723
724        LinAlg<BigRational> lu = new LinAlg<BigRational>();
725        //BasicLinAlg<BigRational> blas = new BasicLinAlg<BigRational>();
726
727        // test ranks
728        long r1 = 0, r2 = 0;
729        App = lu.rowEchelonForm(A);
730        //System.out.println("A:   " + Ap);
731        //System.out.println("App: " + App);
732        r1 = lu.rankRE(App);
733        //System.out.println("rank A = " + r1 + ", c = " + c + ", n = " + n);
734        assertTrue("0 <= rank < n: ", 0 <= r1 && r1 <= n);
735
736        Tpp = lu.rowEchelonForm(T);
737        //System.out.println("T:   " + T);
738        //System.out.println("Tpp: " + Tpp);
739        r2 = lu.rankRE(Tpp);
740        //System.out.println("rank A = " + r1 + ", c = " + c + ", n = " + n);
741        //System.out.println("rank T = " + r2 + ", k = " + k);
742        assertTrue("0 <= rank < n: ", 0 <= r2 && r2 <= n);
743        //assertTrue("rank == rank^t: ", r1 == r2);
744
745        // reduce upper triagonal part
746        //System.out.println("App: " + App);
747        B = lu.rowEchelonFormSparse(App);
748        //System.out.println("B:   " + B);
749        //System.out.println("B^2: " + B.power(2));
750        r2 = lu.rankRE(B);
751        assertTrue("rank1 == rank2: ", r1 == r2);
752    }
753
754}