1547
1547
return m.slice(rk,nc);
1550
// The following function computes the upper-triangular echelon form of m modulo the prime pr.
1550
// Possible FLINT_LEVEL values are as follows.
1552
// 0: no FLINT support (or a version <2.3)
1553
// 1: support for 64-bit nmod_mat (standard from version 2.3)
1554
// 2: support for 32-bit hmod_mat (non-standard, from version 2.3)
1556
// The configure script should have detected whether the functions
1557
// nmod_mat_rref and/or hmod_mat_rref are available to be used here.
1560
//#define TRACE_FLINT_RREF
1561
#include "flint/fmpz.h"
1562
#if (SCALAR_OPTION==1)&&(FLINT_LEVEL==2)
1563
#include "flint/hmod_mat.h"
1567
#undef mod_mat_clear
1568
#undef mod_mat_entry
1570
#define uscalar hlimb_t // unsigned int
1571
#define mod_mat hmod_mat_t // uses unsigned ints
1572
#define mod_mat_init hmod_mat_init
1573
#define mod_mat_clear hmod_mat_clear
1574
#define mod_mat_entry hmod_mat_entry
1575
#define mod_mat_rref hmod_mat_rref
1577
#include "flint/nmod_mat.h"
1581
#undef mod_mat_clear
1582
#undef mod_mat_entry
1584
#define uscalar mp_limb_t // unsigned long
1585
#define mod_mat nmod_mat_t // uses unsigned longs
1586
#define mod_mat_init nmod_mat_init
1587
#define mod_mat_clear nmod_mat_clear
1588
#define mod_mat_entry nmod_mat_entry
1589
#define mod_mat_rref nmod_mat_rref
1591
#include "flint/profiler.h"
1593
// FLINT has two types for modular matrices: standard in FLINT-2.3 has
1594
// nmod_mat_t with entries of type mp_limb_t (unsigned long);
1595
// non-standard (in an optional branch) is hmod_mat_t, with entries
1596
// hlimb_t (unsigned int). We use the former when scalar=long and the
1597
// latter when scalar=int, provided that the optional functions are
1598
// present, which should have been determined by the configure script.
1599
// The unsigned scalar types are #define'd as uscalar.
1601
mat ref_via_flint(const mat& M, scalar pr)
1603
long nr=nrows(M), nc=ncols(M);
1604
long i, j, n=max(nr,nc);
1606
// copy of the modulus for FLINT
1607
uscalar mod = (uscalar)pr;
1609
// create flint matrix copy of M:
1611
mod_mat_init(A, nr, nc, mod);
1614
mod_mat_entry(A,i,j) = M(i+1,j+1);
1616
// reduce A to rref:
1617
#ifdef TRACE_FLINT_RREF
1620
cerr<<"(nr,nc)=("<<nr<<","<<nc<<"): "<<flush;
1622
long rank = mod_mat_rref(A);
1623
#ifdef TRACE_FLINT_RREF
1625
cerr<<" cpu = "<<(t->cpu)<<" ms, wall = "<<(t->wall)<<" ms"<<endl;
1628
// copy back to a new matrix for return:
1632
ans(i+1,j+1) = mod_mat_entry(A,i,j);
1638
// The following function computes the reduced echelon form
1639
// of M modulo the prime pr, calling FLINT's nmod_mat_rref function.
1641
mat ref_via_flint(const mat& M, vec& pcols, vec& npcols,
1642
long& rk, long& ny, scalar pr)
1644
long nr=nrows(M), nc=ncols(M);
1645
long i, j, k, n=max(nr,nc);
1647
#ifdef TRACE_FLINT_RREF
1648
#if (SCALAR_OPTION==1)
1649
cout << "In ref_via_flint(M) with M having "<<nr<<" rows and "<<nc<<" columns, using hmod_mat and modulus "<<pr<<"."<<endl;
1651
cout << "In ref_via_flint(M) with M having "<<nr<<" rows and "<<nc<<" columns, using nmod_mat and modulus "<<pr<<"."<<endl;
1653
// cout << "Size of scalar = "<<8*sizeof(scalar)<<" bits"<<endl;
1654
// cout << "Size of uscalar = "<<8*sizeof(uscalar)<<" bits"<<endl;
1657
// copy of the modulus
1658
uscalar mod = (uscalar)pr;
1660
// create flint matrix copy of M:
1662
mod_mat_init(A, nr, nc, mod);
1665
mod_mat_entry(A,i,j) = (uscalar)posmod(M(i+1,j+1),pr);
1667
#ifdef TRACE_FLINT_RREF
1670
cerr<<"(nr,nc)=("<<nr<<","<<nc<<"): "<<flush;
1673
// reduce A to rref:
1674
rk = mod_mat_rref(A);
1675
#ifdef TRACE_FLINT_RREF
1677
cerr<<"rank = "<<rk<<". cpu = "<<(t->cpu)<<" ms, wall = "<<(t->wall)<<" ms"<<endl;
1680
// construct vectors of pivotal and non-pivotal columns
1684
for (i = j = k = 0; i < rk; i++)
1686
while (mod_mat_entry(A, i, j) == 0UL)
1702
// copy back to a new matrix for return:
1706
ans(i+1,j+1) = mod_mat_entry(A,i,j);
1711
#endif // FLINT_LEVEL
1713
// The following function computes the upper-triangular echelon form
1714
// of m modulo the prime pr.
1552
1716
mat echmodp_uptri(const mat& entries, vec& pcols, vec& npcols,
1553
1717
long& rk, long& ny, scalar pr)
1555
// cout << "In echmodp_uptri with entries = " << entries;
1719
// cout << "In echmodp_uptri with matrix = " << entries;
1556
1720
long nc,nr,r,c,r2,r3,rmin;
1557
1721
scalar min, mr2c;
1558
1722
nr=entries.nro, nc=entries.nco;