Changeset 3029

Show
Ignore:
Timestamp:
09/05/08 16:22:47 (3 months ago)
Author:
saunders
Message:

This upgraded test breaks solutions/minpoly.h when a small prime is used.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/linbox/tests/test-minpoly.C

    r2814 r3029  
    2424 
    2525#include "linbox/field/modular.h" 
     26#include "linbox/field/givaro-gfq.h" 
    2627#include "linbox/blackbox/sparse.h" 
    2728#include "linbox/util/commentator.h" 
     
    3334using namespace LinBox; 
    3435 
     36/* Test 0: Minimal polynomial of the zero matrix 
     37*/ 
     38template <class Field, class Meth> 
     39static bool testZeroMinpoly (Field &F, size_t n, bool symmetrizing, const Meth& M)  
     40{ 
     41        commentator.start ("Testing zero minpoly", "testZeroMinpoly"); 
     42        typedef vector <typename Field::Element> Polynomial; 
     43        Polynomial phi; 
     44        SparseMatrix<Field> A(F, n, n); 
     45        minpoly(phi, A, M); 
     46 
     47        ostream &report = commentator.report (Commentator::LEVEL_IMPORTANT, INTERNAL_DESCRIPTION); 
     48        report << "Minimal polynomial is: "; 
     49        printPolynomial<Field, Polynomial> (F, report, phi); 
     50 
     51        bool ret; 
     52        if (phi.size () == 2 && F.isZero (phi[0]) && F.isOne(phi[1]) )  
     53                ret = true; 
     54        else  
     55        { 
     56                commentator.report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR) 
     57                        << "ERROR: A = 0, should get x, got "; 
     58                printPolynomial<Field, Polynomial> (F, report, phi); 
     59                report << endl; 
     60                ret = false; 
     61        } 
     62        commentator.stop (MSG_STATUS (ret), (const char *) 0, "testZeroMinpoly"); 
     63        return ret; 
     64} 
     65template <class Field> 
     66static bool testZeroMinpoly (Field &F, size_t n)  
     67{ 
     68        return testZeroMinpoly(F, n, false, Method::Wiedemann()); 
     69} 
     70 
    3571/* Test 1: Minimal polynomial of the identity matrix 
    3672 * 
    3773 * Construct the identity matrix and compute its minimal polynomial. Confirm 
    38  * that the result is 1-x 
     74 * that the result is x-1 
    3975 * 
    4076 * F - Field over which to perform computations 
     
    5490        commentator.start ("Testing identity minpoly", "testIdentityMinpoly"); 
    5591 
    56         bool ret = true; 
    57  
    5892        typename Field::Element c0, c1; 
    5993 
     
    71105        printPolynomial<Field, Polynomial> (F, report, phi); 
    72106 
     107        bool ret; 
     108 
    73109        F.init (c0, -1); 
    74110        F.init (c1, 1); 
    75111 
    76         if (phi.size () != 2 || 
    77             !F.areEqual (phi[0], c0) || 
    78             !F.areEqual (phi[1], c1)) { 
     112        if (phi.size () == 2 && F.areEqual (phi[0], c0) && F.areEqual (phi[1], c1))  
     113                ret = true; 
     114        else { 
    79115                ret = false; 
    80116                commentator.report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR) 
    81                         << "ERROR: Minimal polynomial is incorrect" << endl; 
     117                        << "ERROR: A = I, should get x-1, got "; 
     118                printPolynomial<Field, Polynomial> (F, report, phi); 
    82119        } 
    83120 
     
    114151        commentator.start ("Testing nilpotent minpoly", "testNilpotentMinpoly"); 
    115152 
    116         bool ret = true; 
     153        bool ret; 
    117154        bool lowerTermsCorrect = true; 
    118155 
     
    136173                        lowerTermsCorrect = false; 
    137174 
    138         if (phi.size () != n + 1 || !F.isOne (phi[n]) || !lowerTermsCorrect) { 
     175        if (phi.size () == n + 1 && F.isOne (phi[n]) && lowerTermsCorrect) 
     176                ret = true; 
     177        else { 
    139178                ret = false; 
    140179                commentator.report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR) 
    141                         << "ERROR: Minimal polynomial is incorrect" << endl; 
     180                        << "ERROR: A^n = 0, should get x^" << n <<", got "; 
     181                printPolynomial (F, report, phi); 
    142182        } 
    143183 
     
    232272                if (!iter_passed) 
    233273                        commentator.report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR) 
    234                                 << "ERROR: Output vector was incorrect" << endl; 
     274                                << "ERROR: A = rand, purported-minpoly(A) is not zero." << endl; 
    235275                commentator.stop ("done"); 
    236276                commentator.progress (); 
     
    248288{ 
    249289    return testRandomMinpoly(F, iterations, A_stream, v_stream, Method::Wiedemann()); 
     290} 
     291 
     292/* Test 4: test gram matrix. 
     293     A test of behaviour with self-orthogonal rows and cols. 
     294 
     295         Gram matrix is 1's offdiagonal and 0's on diagonal.  Self orthogonality when characteristic | n-1. 
     296 
     297         Arg m is ignored.  
     298         if p := characteristic is small then size is p+1 and minpoly is x^2 + x 
     299         (because A^2 = (p-1)A). 
     300         if p is large, size is 2 and minpoly is x^2 -1. 
     301*/ 
     302template <class Field, class Meth> 
     303static bool testGramMinpoly (Field &F, size_t m, bool symmetrizing, const Meth& M)  
     304{ 
     305        commentator.start ("Testing gram minpoly", "testGramMinpoly"); 
     306        typedef vector <typename Field::Element> Polynomial; 
     307        integer n; 
     308        F.characteristic(n); n += 1; 
     309        if (n > 30) n = 2; 
     310        Polynomial phi; 
     311        typename Field::Element one, zero, neg1; F.init(one, 1); F.init(zero, 0); F.init(neg1); F.neg(neg1, one); 
     312        DenseMatrix<Field> A(F, n, n); 
     313        for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) A.setEntry(i, j, one); 
     314        for (int i = 0; i < n; ++i) A.setEntry(i, i, zero); 
     315        minpoly(phi, A, M); 
     316 
     317        ostream &report = commentator.report (Commentator::LEVEL_IMPORTANT, INTERNAL_DESCRIPTION); 
     318        report << "Minimal polynomial is: "; 
     319        printPolynomial<Field, Polynomial> (F, report, phi); 
     320 
     321        bool ret; 
     322        if (n == 2) 
     323                if ( phi.size() == 3 && F.areEqual(phi[0], neg1) && F.isZero(phi[1]) && F.isOne(phi[2])) 
     324                        ret = true; 
     325                else 
     326                { 
     327                        commentator.report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR) 
     328                                << "ERROR: A = gram, should get x^2 - x, got "; 
     329                        printPolynomial<Field, Polynomial> (F, report, phi); 
     330                        ret = false; 
     331                } 
     332        else  
     333                if (phi.size() == 3 && F.isZero(phi[0]) && F.isOne(phi[1]) && F.isOne(phi[2])) 
     334                        ret = true; 
     335                else 
     336                { 
     337                        commentator.report (Commentator::LEVEL_IMPORTANT, INTERNAL_ERROR) 
     338                                << "ERROR: A = gram, should get x^2 + x, got "; 
     339                        printPolynomial<Field, Polynomial> (F, report, phi); 
     340                        ret = false; 
     341                } 
     342                commentator.stop (MSG_STATUS (ret), (const char *) 0, "testGramMinpoly"); 
     343                return ret; 
     344} 
     345 
     346template <class Field> 
     347static bool testGramMinpoly (Field &F, size_t n)  
     348{ 
     349        return testGramMinpoly(F, n, false, Method::Wiedemann()); 
    250350} 
    251351 
     
    272372 
    273373        parseArguments (argc, argv, args); 
    274  
    275 // /////////////// finite field part ////////////////// 
    276         typedef Modular<LinBox::uint32> Field; 
    277         typedef vector<Field::Element> DenseVector; 
    278         typedef SparseMatrix<Field>::Row SparseVector; 
    279         //typedef pair<vector<size_t>, vector<Field::Element> > SparseVector; 
    280         Field F (q); 
    281         srand (time (NULL)); 
    282  
    283374        commentator.getMessageClass (TIMING_MEASURE).setMaxDepth (10); 
    284375        commentator.getMessageClass (INTERNAL_DESCRIPTION).setMaxDepth (10); 
    285376        commentator.getMessageClass (INTERNAL_DESCRIPTION).setMaxDetailLevel (Commentator::LEVEL_UNIMPORTANT); 
    286377 
     378// /////////////// finite field part ////////////////// 
     379        if (q > 5 && q % 2 != 0 && q % 3 != 0 && q % 5 != 0 ) 
     380        { 
     381        typedef Modular<LinBox::uint32> Field; 
     382        Field F (q); 
     383        srand (time (NULL)); 
     384 
    287385        commentator.start("Wiedemann prime field minpoly test suite", "Wminpoly"); 
    288         RandomDenseStream<Field, DenseVector, NonzeroRandIter<Field> > 
    289                 v_stream (F, NonzeroRandIter<Field> (F, Field::RandIter (F)), n, numVectors); 
    290         RandomSparseStream<Field, SparseVector, NonzeroRandIter<Field> > 
    291                 A_stream (F, NonzeroRandIter<Field> (F, Field::RandIter (F)), (double) k / (double) n, n, n); 
    292386 
    293387        //no symmetrizing 
     388        if (!testZeroMinpoly      (F, n)) pass = false; 
    294389        if (!testIdentityMinpoly  (F, n)) pass = false; 
    295390        if (!testNilpotentMinpoly (F, n)) pass = false; 
    296         if (!testRandomMinpoly    (F, iterations, A_stream, v_stream)) pass = false; 
     391        //if (!testRandomMinpoly    (F, n)) pass = false; 
     392        if (!testGramMinpoly      (F, n)) pass = false; 
    297393 
    298394        // symmetrizing 
     395        //if (!testZeroMinpoly            (F, n, true)) pass = false; 
    299396        if (!testIdentityMinpoly  (F, n, true)) pass = false; 
     397        //if (!testNilpotentMinpoly (F, n, true)) pass = false; 
     398        //if (!testRandomMinpoly    (F, n, true)) pass = false; 
     399        //if (!testGramMinpoly      (F, n, true)) pass = false; 
    300400        //need other tests... 
    301401 
    302402        commentator.stop("Wiedemann prime field minpoly test suite"); 
    303  
     403        }else{ 
     404 
     405        int p;   
     406        if (q % 2 == 0) p = 2; 
     407        if (q % 3 == 0) p = 3; 
     408        if (q % 5 == 0) p = 5; 
     409        int e = 0;  do {++e; q = q/p; } while (q > 1); 
     410        typedef GivaroGfq Field; 
     411        Field F (p, e); 
     412        srand (time (NULL)); 
     413 
     414        commentator.start("Wiedemann non-prime field minpoly test suite", "Wminpoly"); 
     415 
     416        //no symmetrizing 
     417        if (!testZeroMinpoly      (F, n)) pass = false; 
     418        if (!testIdentityMinpoly  (F, n)) pass = false; 
     419        if (!testNilpotentMinpoly (F, n)) pass = false; 
     420        //if (!testRandomMinpoly    (F, n)) pass = false; 
     421        if (!testGramMinpoly      (F, n)) pass = false; 
     422 
     423        // symmetrizing 
     424        //if (!testZeroMinpoly            (F, n, true)) pass = false; 
     425        if (!testIdentityMinpoly  (F, n, true)) pass = false; 
     426        //if (!testNilpotentMinpoly (F, n, true)) pass = false; 
     427        //if (!testRandomMinpoly    (F, n, true)) pass = false; 
     428        //if (!testGramMinpoly      (F, n, true)) pass = false; 
     429        //need other tests... 
     430 
     431        commentator.stop("Wiedemann non-prime field minpoly test suite"); 
     432        } 
     433 
     434#if 0 
    304435        commentator.start("Hybrid prime field minpoly test suite", "Hminpoly"); 
    305436        if (!testIdentityMinpoly  (F, n, false,  Method::Hybrid())) pass = false; 
     
    362493        commentator.stop("Elimination integer minpoly test suite"); 
    363494 
     495#endif 
    364496        return pass ? 0 : -1; 
    365497}