ALL: Add flint

This commit is contained in:
2014-05-19 00:03:37 +02:00
parent a15ef46ea6
commit d51d8e3652
3752 changed files with 446416 additions and 0 deletions

59
external/flint-2.4.3/fmpz_mat/CRT_ui.c vendored Normal file
View File

@@ -0,0 +1,59 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_CRT_ui(fmpz_mat_t res, const fmpz_mat_t mat1,
const fmpz_t m1, const nmod_mat_t mat2, int sign)
{
slong i, j;
mp_limb_t c;
mp_limb_t m2 = mat2->mod.n;
mp_limb_t m2inv = mat2->mod.ninv;
fmpz_t m1m2;
c = fmpz_fdiv_ui(m1, m2);
c = n_invmod(c, m2);
if (c == 0)
{
flint_printf("Exception (fmpz_mat_CRT_ui). m1 not invertible modulo m2.\n");
abort();
}
fmpz_init(m1m2);
fmpz_mul_ui(m1m2, m1, m2);
for (i = 0; i < mat1->r; i++)
{
for (j = 0; j < mat1->c; j++)
_fmpz_CRT_ui_precomp(fmpz_mat_entry(res, i, j),
fmpz_mat_entry(mat1, i, j), m1,
nmod_mat_entry(mat2, i, j), m2, m2inv, m1m2, c, sign);
}
fmpz_clear(m1m2);
}

38
external/flint-2.4.3/fmpz_mat/add.c vendored Normal file
View File

@@ -0,0 +1,38 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_add(fmpz_mat_t res, const fmpz_mat_t mat1, const fmpz_mat_t mat2)
{
slong i;
if (res->c < 1)
return;
for (i = 0; i < res->r; i++)
_fmpz_vec_add(res->rows[i], mat1->rows[i], mat2->rows[i], res->c);
}

124
external/flint-2.4.3/fmpz_mat/charpoly.c vendored Normal file
View File

@@ -0,0 +1,124 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2012 Sebastian Pancratz
******************************************************************************/
#include "fmpz_mat.h"
/*
Assumes that \code{mat} is an $n \times n$ matrix and sets \code{(cp,n+1)}
to its characteristic polynomial.
Employs a division-free algorithm using $O(n^4)$ ring operations.
*/
void _fmpz_mat_charpoly(fmpz *cp, const fmpz_mat_t mat)
{
const slong n = mat->r;
if (n == 0)
{
fmpz_one(cp);
}
else if (n == 1)
{
fmpz_neg(cp + 0, fmpz_mat_entry(mat, 0, 0));
fmpz_one(cp + 1);
}
else
{
slong i, j, k, t;
fmpz *a, *A, *s;
a = _fmpz_vec_init(n * n);
A = a + (n - 1) * n;
_fmpz_vec_zero(cp, n + 1);
fmpz_neg(cp + 0, fmpz_mat_entry(mat, 0, 0));
for (t = 1; t < n; t++)
{
for (i = 0; i <= t; i++)
{
fmpz_set(a + 0 * n + i, fmpz_mat_entry(mat, i, t));
}
fmpz_set(A + 0, fmpz_mat_entry(mat, t, t));
for (k = 1; k < t; k++)
{
for (i = 0; i <= t; i++)
{
s = a + k * n + i;
fmpz_zero(s);
for (j = 0; j <= t; j++)
{
fmpz_addmul(s, fmpz_mat_entry(mat, i, j), a + (k - 1) * n + j);
}
}
fmpz_set(A + k, a + k * n + t);
}
fmpz_zero(A + t);
for (j = 0; j <= t; j++)
{
fmpz_addmul(A + t, fmpz_mat_entry(mat, t, j), a + (t - 1) * n + j);
}
for (k = 0; k <= t; k++)
{
for (j = 0; j < k; j++)
{
fmpz_submul(cp + k, A + j, cp + (k - j - 1));
}
fmpz_sub(cp + k, cp + k, A + k);
}
}
/* Shift all coefficients up by one */
for (i = n; i > 0; i--)
{
fmpz_swap(cp + i, cp + (i - 1));
}
fmpz_one(cp + 0);
_fmpz_poly_reverse(cp, cp, n + 1, n + 1);
_fmpz_vec_clear(a, n * n);
}
}
void fmpz_mat_charpoly(fmpz_poly_t cp, const fmpz_mat_t mat)
{
if (mat->r != mat->c)
{
flint_printf("Exception (fmpz_mat_charpoly). Non-square matrix.\n");
abort();
}
fmpz_poly_fit_length(cp, mat->r + 1);
_fmpz_poly_set_length(cp, mat->r + 1);
_fmpz_mat_charpoly(cp->coeffs, mat);
}

39
external/flint-2.4.3/fmpz_mat/clear.c vendored Normal file
View File

@@ -0,0 +1,39 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 William Hart
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_clear(fmpz_mat_t mat)
{
if (mat->entries)
{
slong i;
for (i = 0; i < mat->r * mat->c; i++)
fmpz_clear(mat->entries + i); /* Clear all coefficients */
flint_free(mat->entries); /* Clean up array of entries */
flint_free(mat->rows); /* Clean up row array */
}
}

54
external/flint-2.4.3/fmpz_mat/det.c vendored Normal file
View File

@@ -0,0 +1,54 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010,2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_det(fmpz_t det, const fmpz_mat_t A)
{
slong dim = A->r;
if (dim != A->c)
{
flint_printf("Exception (fmpz_mat_det). Non-square matrix.\n");
abort();
}
if (dim < 5)
fmpz_mat_det_cofactor(det, A);
else if (dim < 25)
fmpz_mat_det_bareiss(det, A);
else if (dim < 60)
fmpz_mat_det_modular(det, A, 1);
else
{
slong bits = fmpz_mat_max_bits(A);
if (dim < FLINT_ABS(bits))
fmpz_mat_det_modular(det, A, 1);
else
fmpz_mat_det_modular_accelerated(det, A, 1);
}
}

View File

@@ -0,0 +1,57 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010,2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
#include "perm.h"
void
_fmpz_mat_det_bareiss(fmpz_t det, fmpz_mat_t tmp)
{
slong *perm, n = fmpz_mat_nrows(tmp);
perm = _perm_init(n);
fmpz_mat_fflu(tmp, det, perm, tmp, 1);
if (_perm_parity(perm, n) == 1)
fmpz_neg(det, det);
_perm_clear(perm);
}
void
fmpz_mat_det_bareiss(fmpz_t det, const fmpz_mat_t A)
{
fmpz_mat_t tmp;
if (A->r < 1)
{
fmpz_one(det);
return;
}
fmpz_mat_init_set(tmp, A);
_fmpz_mat_det_bareiss(det, tmp);
fmpz_mat_clear(tmp);
}

View File

@@ -0,0 +1,57 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_det_bound(fmpz_t bound, const fmpz_mat_t A)
{
fmpz_t p, s, t;
slong i, j;
fmpz_init(p);
fmpz_init(s);
fmpz_init(t);
fmpz_one(p);
for (i = 0; i < A->r; i++)
{
fmpz_zero(s);
for (j = 0; j < A->c; j++)
fmpz_addmul(s, A->rows[i] + j, A->rows[i] + j);
fmpz_sqrtrem(s, t, s);
if (!fmpz_is_zero(t))
fmpz_add_ui(s, s, UWORD(1));
fmpz_mul(p, p, s);
}
fmpz_set(bound, p);
fmpz_clear(p);
fmpz_clear(s);
fmpz_clear(t);
}

View File

@@ -0,0 +1,136 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010,2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
_fmpz_mat_det_cofactor_2x2(fmpz_t det, fmpz ** const x)
{
fmpz_t t;
fmpz_init(t);
fmpz_mul (t, &x[0][0], &x[1][1]);
fmpz_submul(t, &x[0][1], &x[1][0]);
fmpz_set(det, t);
fmpz_clear(t);
}
void
_fmpz_mat_det_cofactor_3x3(fmpz_t det, fmpz ** const x)
{
fmpz_t a, t;
fmpz_init(a);
fmpz_init(t);
fmpz_mul (a, &x[1][0], &x[2][1]);
fmpz_submul(a, &x[1][1], &x[2][0]);
fmpz_mul (t, a, &x[0][2]);
fmpz_mul (a, &x[1][2], &x[2][0]);
fmpz_submul(a, &x[1][0], &x[2][2]);
fmpz_addmul(t, a, &x[0][1]);
fmpz_mul (a, &x[1][1], &x[2][2]);
fmpz_submul(a, &x[1][2], &x[2][1]);
fmpz_addmul(t, a, &x[0][0]);
fmpz_set(det, t);
fmpz_clear(a);
fmpz_clear(t);
}
void
_fmpz_mat_det_cofactor_4x4(fmpz_t det, fmpz ** const x)
{
fmpz_t a, b, t;
fmpz_init(a);
fmpz_init(b);
fmpz_init(t);
fmpz_mul (a, &x[0][3], &x[1][2]);
fmpz_submul(a, &x[0][2], &x[1][3]);
fmpz_mul (b, &x[2][1], &x[3][0]);
fmpz_submul(b, &x[2][0], &x[3][1]);
fmpz_mul(t, a, b);
fmpz_mul (a, &x[0][1], &x[1][3]);
fmpz_submul(a, &x[0][3], &x[1][1]);
fmpz_mul (b, &x[2][2], &x[3][0]);
fmpz_submul(b, &x[2][0], &x[3][2]);
fmpz_addmul(t, a, b);
fmpz_mul (a, &x[0][2], &x[1][1]);
fmpz_submul(a, &x[0][1], &x[1][2]);
fmpz_mul (b, &x[2][3], &x[3][0]);
fmpz_submul(b, &x[2][0], &x[3][3]);
fmpz_addmul(t, a, b);
fmpz_mul (a, &x[0][3], &x[1][0]);
fmpz_submul(a, &x[0][0], &x[1][3]);
fmpz_mul (b, &x[2][2], &x[3][1]);
fmpz_submul(b, &x[2][1], &x[3][2]);
fmpz_addmul(t, a, b);
fmpz_mul (a, &x[0][0], &x[1][2]);
fmpz_submul(a, &x[0][2], &x[1][0]);
fmpz_mul (b, &x[2][3], &x[3][1]);
fmpz_submul(b, &x[2][1], &x[3][3]);
fmpz_addmul(t, a, b);
fmpz_mul (a, &x[0][1], &x[1][0]);
fmpz_submul(a, &x[0][0], &x[1][1]);
fmpz_mul (b, &x[2][3], &x[3][2]);
fmpz_submul(b, &x[2][2], &x[3][3]);
fmpz_addmul(t, a, b);
fmpz_set(det, t);
fmpz_clear(a);
fmpz_clear(b);
fmpz_clear(t);
}
void
fmpz_mat_det_cofactor(fmpz_t det, const fmpz_mat_t A)
{
slong dim = A->r;
switch (dim)
{
case 0: fmpz_one(det); break;
case 1: fmpz_set(det, A->rows[0]); break;
case 2: _fmpz_mat_det_cofactor_2x2(det, A->rows); break;
case 3: _fmpz_mat_det_cofactor_3x3(det, A->rows); break;
case 4: _fmpz_mat_det_cofactor_4x4(det, A->rows); break;
default:
flint_printf("Exception (fmpz_mat_det_cofactor). dim > 4 not implemented.");
abort();
}
}

View File

@@ -0,0 +1,82 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
#include "fmpq.h"
void
fmpz_mat_det_divisor(fmpz_t d, const fmpz_mat_t A)
{
fmpz_mat_t X, B;
fmpz_t t, u, v, mod;
slong i, n;
int success;
n = A->r;
fmpz_mat_init(B, n, 1);
fmpz_mat_init(X, n, 1);
fmpz_init(t);
fmpz_init(u);
fmpz_init(v);
fmpz_init(mod);
/* Create a "random" vector */
for (i = 0; i < n; i++)
{
fmpz_set_si(fmpz_mat_entry(B, i, 0), 2*(i % 2) - 1);
}
success = fmpz_mat_solve_dixon(X, mod, A, B);
if (success)
{
fmpz_one(d);
for (i = 0; i < n; i++)
{
fmpz_mul(t, d, fmpz_mat_entry(X, i, 0));
fmpz_fdiv_qr(u, t, t, mod);
if (!_fmpq_reconstruct_fmpz(u, v, t, mod))
{
flint_printf("Exception (fmpz_mat_det_divisor): "
"Rational reconstruction failed.\n");
abort();
}
fmpz_mul(d, v, d);
}
}
else
{
fmpz_zero(d);
}
fmpz_mat_clear(B);
fmpz_mat_clear(X);
fmpz_clear(t);
fmpz_clear(u);
fmpz_clear(v);
fmpz_clear(mod);
}

View File

@@ -0,0 +1,36 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_det_modular(fmpz_t det, const fmpz_mat_t A, int proved)
{
fmpz_t d;
fmpz_init(d);
fmpz_one(d);
fmpz_mat_det_modular_given_divisor(det, A, d, proved);
fmpz_clear(d);
}

View File

@@ -0,0 +1,36 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_det_modular_accelerated(fmpz_t det, const fmpz_mat_t A, int proved)
{
fmpz_t d;
fmpz_init(d);
fmpz_mat_det_divisor(d, A);
fmpz_mat_det_modular_given_divisor(det, A, d, proved);
fmpz_clear(d);
}

View File

@@ -0,0 +1,127 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
/* Enable to exercise corner cases */
#define DEBUG_USE_SMALL_PRIMES 0
static mp_limb_t
next_good_prime(const fmpz_t d, mp_limb_t p)
{
mp_limb_t r = 0;
while (r == 0)
{
p = n_nextprime(p, 0);
r = fmpz_fdiv_ui(d, p);
}
return p;
}
void
fmpz_mat_det_modular_given_divisor(fmpz_t det, const fmpz_mat_t A,
const fmpz_t d, int proved)
{
fmpz_t bound, prod, stable_prod, x, xnew;
mp_limb_t p, xmod;
nmod_mat_t Amod;
slong n = A->r;
if (n == 0)
{
fmpz_one(det);
return;
}
if (fmpz_is_zero(d))
{
fmpz_zero(det);
return;
}
fmpz_init(bound);
fmpz_init(prod);
fmpz_init(stable_prod);
fmpz_init(x);
fmpz_init(xnew);
/* Bound x = det(A) / d */
fmpz_mat_det_bound(bound, A);
fmpz_mul_ui(bound, bound, UWORD(2)); /* accomodate sign */
fmpz_cdiv_q(bound, bound, d);
nmod_mat_init(Amod, n, n, 2);
fmpz_zero(x);
fmpz_one(prod);
#if DEBUG_USE_SMALL_PRIMES
p = UWORD(1);
#else
p = UWORD(1) << NMOD_MAT_OPTIMAL_MODULUS_BITS;
#endif
/* Compute x = det(A) / d */
while (fmpz_cmp(prod, bound) <= 0)
{
p = next_good_prime(d, p);
_nmod_mat_set_mod(Amod, p);
fmpz_mat_get_nmod_mat(Amod, A);
/* Compute x = det(A) / d mod p */
xmod = _nmod_mat_det(Amod);
xmod = n_mulmod2_preinv(xmod,
n_invmod(fmpz_fdiv_ui(d, p), p), Amod->mod.n, Amod->mod.ninv);
fmpz_CRT_ui(xnew, x, prod, xmod, p, 1);
if (fmpz_equal(xnew, x))
{
fmpz_mul_ui(stable_prod, stable_prod, p);
if (!proved && fmpz_bits(stable_prod) > 100)
break;
}
else
{
fmpz_set_ui(stable_prod, p);
}
fmpz_mul_ui(prod, prod, p);
fmpz_set(x, xnew);
}
/* det(A) = x * d */
fmpz_mul(det, x, d);
nmod_mat_clear(Amod);
fmpz_clear(bound);
fmpz_clear(prod);
fmpz_clear(stable_prod);
fmpz_clear(x);
fmpz_clear(xnew);
}

View File

@@ -0,0 +1,860 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 William Hart
Copyright (C) 2010-2011 Andy Novocin
Copyright (C) 2010-2011 Fredrik Johansson
******************************************************************************/
*******************************************************************************
Memory management
*******************************************************************************
void fmpz_mat_init(fmpz_mat_t mat, slong rows, slong cols)
Initialises a matrix with the given number of rows and columns for use.
void fmpz_mat_clear(fmpz_mat_t mat)
Clears the given matrix.
*******************************************************************************
Basic assignment and manipulation
*******************************************************************************
void fmpz_mat_set(fmpz_mat_t mat1, const fmpz_mat_t mat2)
Sets \code{mat1} to a copy of \code{mat2}. The dimensions of
\code{mat1} and \code{mat2} must be the same.
void fmpz_mat_init_set(fmpz_mat_t mat, const fmpz_mat_t src)
Initialises the matrix \code{mat} to the same size as \code{src} and
sets it to a copy of \code{src}.
void fmpz_mat_swap(fmpz_mat_t mat1, fmpz_mat_t mat2)
Swaps two matrices. The dimensions of \code{mat1} and \code{mat2}
are allowed to be different.
fmpz * fmpz_mat_entry(fmpz_mat_t mat, slong i, slong j)
Returns a reference to the entry of \code{mat} at row $i$ and column $j$.
This reference can be passed as an input or output variable to any
function in the \code{fmpz} module for direct manipulation.
Both $i$ and $j$ must not exceed the dimensions of the matrix.
This function is implemented as a macro.
void fmpz_mat_zero(fmpz_mat_t mat)
Sets all entries of \code{mat} to 0.
void fmpz_mat_one(fmpz_mat_t mat)
Sets \code{mat} to the unit matrix, having ones on the main diagonal
and zeroes elsewhere. If \code{mat} is nonsquare, it is set to the
truncation of a unit matrix.
*******************************************************************************
Random matrix generation
*******************************************************************************
void fmpz_mat_randbits(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits)
Sets the entries of \code{mat} to random signed integers whose absolute
values have the given number of binary bits.
void fmpz_mat_randtest(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits)
Sets the entries of \code{mat} to random signed integers whose
absolute values have a random number of bits up to the given number
of bits inclusive.
void fmpz_mat_randintrel(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits)
Sets \code{mat} to be a random \emph{integer relations} matrix, with
signed entries up to the given number of bits.
The number of columns of \code{mat} must be equal to one more than
the number of rows. The format of the matrix is a set of random integers
in the left hand column and an identity matrix in the remaining square
submatrix.
void fmpz_mat_randsimdioph(fmpz_mat_t mat, flint_rand_t state,
mp_bitcnt_t bits, mp_bitcnt_t bits2)
Sets \code{mat} to a random \emph{simultaneous diophantine} matrix.
The matrix must be square. The top left entry is set to \code{2^bits2}.
The remainder of that row is then set to signed random integers of the
given number of binary bits. The remainder of the first column is zero.
Running down the rest of the diagonal are the values \code{2^bits} with
all remaining entries zero.
void fmpz_mat_randntrulike(fmpz_mat_t mat, flint_rand_t state,
mp_bitcnt_t bits, ulong q)
Sets a square matrix \code{mat} of even dimension to a random
\emph{NTRU like} matrix.
The matrix is broken into four square submatrices. The top left submatrix
is set to the identity. The bottom left submatrix is set to the zero
matrix. The bottom right submatrix is set to $q$ times the identity matrix.
Finally the top right submatrix has the following format. A random vector
$h$ of length $r/2$ is created, with random signed entries of the given
number of bits. Then entry $(i, j)$ of the submatrix is set to
$h[i + j \bmod{r/2}]$.
void fmpz_mat_randntrulike2(fmpz_mat_t mat, flint_rand_t state,
mp_bitcnt_t bits, ulong q)
Sets a square matrix \code{mat} of even dimension to a random
\emph{NTRU like} matrix.
The matrix is broken into four square submatrices. The top left submatrix
is set to $q$ times the identity matrix. The top right submatrix is set to
the zero matrix. The bottom right submatrix is set to the identity matrix.
Finally the bottom left submatrix has the following format. A random vector
$h$ of length $r/2$ is created, with random signed entries of the given
number of bits. Then entry $(i, j)$ of the submatrix is set to
$h[i + j \bmod{r/2}]$.
void fmpz_mat_randajtai(fmpz_mat_t mat, flint_rand_t state, double alpha)
Sets a square matrix \code{mat} to a random \emph{ajtai} matrix.
The diagonal entries $(i, i)$ are set to a random entry in the range
$[1, 2^{b-1}]$ inclusive where $b = \floor{(2 r - i)^\alpha}$ for some
double parameter~$\alpha$. The entries below the diagonal in column~$i$
are set to a random entry in the range $(-2^b + 1, 2^b - 1)$ whilst the
entries to the right of the diagonal in row~$i$ are set to zero.
int fmpz_mat_randpermdiag(fmpz_mat_t mat, flint_rand_t state,
const fmpz * diag, slong n)
Sets \code{mat} to a random permutation of the rows and columns of a
given diagonal matrix. The diagonal matrix is specified in the form of
an array of the $n$ initial entries on the main diagonal.
The return value is $0$ or $1$ depending on whether the permutation is
even or odd.
void fmpz_mat_randrank(fmpz_mat_t mat, flint_rand_t state, slong rank,
mp_bitcnt_t bits)
Sets \code{mat} to a random sparse matrix with the given rank,
having exactly as many non-zero elements as the rank, with the
nonzero elements being random integers of the given bit size.
The matrix can be transformed into a dense matrix with unchanged
rank by subsequently calling \code{fmpz_mat_randops()}.
void fmpz_mat_randdet(fmpz_mat_t mat, flint_rand_t state, const fmpz_t det)
Sets \code{mat} to a random sparse matrix with minimal number of
nonzero entries such that its determinant has the given value.
Note that the matrix will be zero if \code{det} is zero.
In order to generate a non-zero singular matrix, the function
\code{fmpz_mat_randrank()} can be used.
The matrix can be transformed into a dense matrix with unchanged
determinant by subsequently calling \code{fmpz_mat_randops()}.
void fmpz_mat_randops(fmpz_mat_t mat, flint_rand_t state, slong count)
Randomises \code{mat} by performing elementary row or column operations.
More precisely, at most \code{count} random additions or subtractions of
distinct rows and columns will be performed. This leaves the rank
(and for square matrices, the determinant) unchanged.
*******************************************************************************
Input and output
*******************************************************************************
int fmpz_mat_fprint(FILE * file, const fmpz_mat_t mat)
Prints the given matrix to the stream \code{file}. The format is
the number of rows, a space, the number of columns, two spaces, then
a space separated list of coefficients, one row after the other.
In case of success, returns a positive value; otherwise, returns
a non-positive value.
int fmpz_mat_fprint_pretty(FILE * file, const fmpz_mat_t mat)
Prints the given matrix to the stream \code{file}. The format is an
opening square bracket then on each line a row of the matrix, followed
by a closing square bracket. Each row is written as an opening square
bracket followed by a space separated list of coefficients followed
by a closing square bracket.
In case of success, returns a positive value; otherwise, returns
a non-positive value.
int fmpz_mat_print(const fmpz_mat_t mat)
Prints the given matrix to the stream \code{stdout}. For further
details, see \code{fmpz_mat_fprint()}.
int fmpz_mat_print_pretty(const fmpz_mat_t mat)
Prints the given matrix to \code{stdout}. For further details,
see \code{fmpz_mat_fprint_pretty()}.
int fmpz_mat_fread(FILE* file, fmpz_mat_t mat)
Reads a matrix from the stream \code{file}, storing the result
in \code{mat}. The expected format is the number of rows, a
space, the number of columns, two spaces, then a space separated
list of coefficients, one row after the other.
In case of success, returns a positive number. In case of failure,
returns a non-positive value.
int fmpz_mat_read(fmpz_mat_t mat)
Reads a matrix from \code{stdin}, storing the result
in \code{mat}.
In case of success, returns a positive number. In case of failure,
returns a non-positive value.
*******************************************************************************
Comparison
*******************************************************************************
int fmpz_mat_equal(const fmpz_mat_t mat1, const fmpz_mat_t mat2)
Returns a non-zero value if \code{mat1} and \code{mat2} have
the same dimensions and entries, and zero otherwise.
int fmpz_mat_is_zero(const fmpz_mat_t mat)
Returns a non-zero value if all entries \code{mat} are zero, and
otherwise returns zero.
int fmpz_mat_is_empty(const fmpz_mat_t mat)
Returns a non-zero value if the number of rows or the number of
columns in \code{mat} is zero, and otherwise returns
zero.
int fmpz_mat_is_square(const fmpz_mat_t mat)
Returns a non-zero value if the number of rows is equal to the
number of columns in \code{mat}, and otherwise returns zero.
*******************************************************************************
Transpose
*******************************************************************************
void fmpz_mat_transpose(fmpz_mat_t B, const fmpz_mat_t A)
Sets $B$ to $A^T$, the transpose of $A$. Dimensions must be compatible.
$A$ and $B$ are allowed to be the same object if $A$ is a square matrix.
*******************************************************************************
Modular reduction and reconstruction
*******************************************************************************
void fmpz_mat_get_nmod_mat(nmod_mat_t Amod, const fmpz_mat_t A)
Sets the entries of \code{Amod} to the entries of \code{A} reduced
by the modulus of \code{Amod}.
void fmpz_mat_set_nmod_mat(fmpz_mat_t A, const nmod_mat_t Amod)
Sets the entries of \code{Amod} to the residues in \code{Amod},
normalised to the interval $-m/2 <= r < m/2$ where $m$ is the modulus.
void fmpz_mat_set_nmod_mat_unsigned(fmpz_mat_t A, const nmod_mat_t Amod)
Sets the entries of \code{Amod} to the residues in \code{Amod},
normalised to the interval $0 <= r < m$ where $m$ is the modulus.
void fmpz_mat_CRT_ui(fmpz_mat_t res, const fmpz_mat_t mat1,
const fmpz_t m1, const nmod_mat_t mat2, int sign)
Given \code{mat1} with entries modulo \code{m} and \code{mat2}
with modulus $n$, sets \code{res} to the CRT reconstruction modulo $mn$
with entries satisfying $-mn/2 <= c < mn/2$ (if sign = 1)
or $0 <= c < mn$ (if sign = 0).
void fmpz_mat_multi_mod_ui_precomp(nmod_mat_t * residues, slong nres,
const fmpz_mat_t mat, fmpz_comb_t comb, fmpz_comb_temp_t temp)
Sets each of the \code{nres} matrices in \code{residues} to \code{mat}
reduced modulo the modulus of the respective matrix, given
precomputed \code{comb} and \code{comb_temp} structures.
void fmpz_mat_multi_mod_ui(nmod_mat_t * residues, slong nres,
const fmpz_mat_t mat)
Sets each of the \code{nres} matrices in \code{residues} to \code{mat}
reduced modulo the modulus of the respective matrix.
This function is provided for convenience purposes.
For reducing or reconstructing multiple integer matrices over the same
set of moduli, it is faster to use\\ \code{fmpz_mat_multi_mod_precomp}.
void fmpz_mat_multi_CRT_ui_precomp(fmpz_mat_t mat, nmod_mat_t * const residues,
slong nres, fmpz_comb_t comb, fmpz_comb_temp_t temp, int sign)
Reconstructs \code{mat} from its images modulo the \code{nres} matrices
in \code{residues}, given precomputed \code{comb} and \code{comb_temp}
structures.
void fmpz_mat_multi_CRT_ui(fmpz_mat_t mat, nmod_mat_t * const residues,
slong nres, int sign)
Reconstructs \code{mat} from its images modulo the \code{nres} matrices
in \code{residues}.
This function is provided for convenience purposes.
For reducing or reconstructing multiple integer matrices over the same
set of moduli, it is faster to use\\ \code{fmpz_mat_multi_CRT_ui_precomp}.
*******************************************************************************
Addition and subtraction
*******************************************************************************
void fmpz_mat_add(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B)
Sets \code{C} to the elementwise sum $A + B$. All inputs must
be of the same size. Aliasing is allowed.
void fmpz_mat_sub(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B)
Sets \code{C} to the elementwise difference $A - B$. All inputs must
be of the same size. Aliasing is allowed.
void fmpz_mat_neg(fmpz_mat_t B, const fmpz_mat_t A)
Sets \code{B} to the elementwise negation of \code{A}. Both inputs
must be of the same size. Aliasing is allowed.
*******************************************************************************
Matrix-scalar arithmetic
*******************************************************************************
void fmpz_mat_scalar_mul_si(fmpz_mat_t B, const fmpz_mat_t A, slong c)
void fmpz_mat_scalar_mul_ui(fmpz_mat_t B, const fmpz_mat_t A, ulong c)
void fmpz_mat_scalar_mul_fmpz(fmpz_mat_t B, const fmpz_mat_t A, const fmpz_t c)
Set \code{A = B*c} where \code{B} is an \code{fmpz_mat_t} and \code{c}
is a scalar respectively of type \code{slong}, \code{ulong},
or \code{fmpz_t}. The dimensions of \code{A} and \code{B} must
be compatible.
void fmpz_mat_scalar_addmul_si(fmpz_mat_t B, const fmpz_mat_t A, slong c)
void fmpz_mat_scalar_addmul_ui(fmpz_mat_t B, const fmpz_mat_t A, ulong c)
void fmpz_mat_scalar_addmul_fmpz(fmpz_mat_t B, const fmpz_mat_t A,
const fmpz_t c)
Set \code{A = A + B*c} where \code{B} is an \code{fmpz_mat_t} and \code{c}
is a scalar respectively of type \code{slong}, \code{ulong},
or \code{fmpz_t}. The dimensions of \code{A} and \code{B} must
be compatible.
void fmpz_mat_scalar_submul_si(fmpz_mat_t B, const fmpz_mat_t A, slong c)
void fmpz_mat_scalar_submul_ui(fmpz_mat_t B, const fmpz_mat_t A, ulong c)
void fmpz_mat_scalar_submul_fmpz(fmpz_mat_t B, const fmpz_mat_t A,
const fmpz_t c)
Set \code{A = A - B*c} where \code{B} is an \code{fmpz_mat_t} and \code{c}
is a scalar respectively of type \code{slong}, \code{ulong},
or \code{fmpz_t}. The dimensions of \code{A} and \code{B} must
be compatible.
void fmpz_mat_scalar_addmul_nmod_mat_ui(fmpz_mat_t B, const nmod_mat_t A,
ulong c)
void fmpz_mat_scalar_addmul_nmod_mat_fmpz(fmpz_mat_t B, const nmod_mat_t A,
const fmpz_t c)
Set \code{A = A + B*c} where \code{B} is an \code{nmod_mat_t} and \code{c}
is a scalar respectively of type \code{ulong} or \code{fmpz_t}.
The dimensions of \code{A} and \code{B} must be compatible.
void fmpz_mat_scalar_divexact_si(fmpz_mat_t B, const fmpz_mat_t A, slong c)
void fmpz_mat_scalar_divexact_ui(fmpz_mat_t B, const fmpz_mat_t A, ulong c)
void fmpz_mat_scalar_divexact_fmpz(fmpz_mat_t B, const fmpz_mat_t A,
const fmpz_t c)
Set \code{A = B / c}, where \code{B} is an \code{fmpz_mat_t} and \code{c}
is a scalar respectively of type \code{slong}, \code{ulong},
or \code{fmpz_t}, which is assumed to divide all elements of
\code{B} exactly.
*******************************************************************************
Matrix multiplication
*******************************************************************************
void fmpz_mat_mul(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B)
Sets \code{C} to the matrix product $C = A B$. The matrices must have
compatible dimensions for matrix multiplication. Aliasing
is allowed.
This function automatically switches between classical and
multimodular multiplication, based on a heuristic comparison of
the dimensions and entry sizes.
void fmpz_mat_mul_classical(fmpz_mat_t C,
const fmpz_mat_t A, const fmpz_mat_t B)
Sets \code{C} to the matrix product $C = A B$ computed using
classical matrix algorithm.
The matrices must have compatible dimensions for matrix multiplication.
No aliasing is allowed.
void _fmpz_mat_mul_multi_mod(fmpz_mat_t C,
const fmpz_mat_t A, const fmpz_mat_t B, mp_bitcnt_t bits)
void fmpz_mat_mul_multi_mod(fmpz_mat_t C,
const fmpz_mat_t A, const fmpz_mat_t B)
Sets \code{C} to the matrix product $C = AB$ computed using a multimodular
algorithm. $C$ is computed modulo several small prime numbers
and reconstructed using the Chinese Remainder Theorem. This generally
becomes more efficient than classical multiplication for large matrices.
The \code{bits} parameter is a bound for the bit size of largest
element of $C$, or twice the absolute value of the largest element
if any elements of $C$ are negative. The function
\code{fmpz_mat_mul_multi_mod} calculates a rigorous bound automatically.
If the default bound is too pessimistic, \code{_fmpz_mat_mul_multi_mod}
can be used with a custom bound.
The matrices must have compatible dimensions for matrix multiplication.
No aliasing is allowed.
void fmpz_mat_sqr(fmpz_mat_t B, const fmpz_mat_t A)
Sets \code{B} to the square of the matrix \code{A}, which must be
a square matrix. Aliasing is allowed.
void fmpz_mat_pow(fmpz_mat_t B, const fmpz_mat_t A, ulong e)
Sets \code{B} to the matrix \code{A} raised to the power \code{e},
where \code{A} must be a square matrix. Aliasing is allowed.
*******************************************************************************
Inverse
*******************************************************************************
int fmpz_mat_inv(fmpz_mat_t Ainv, fmpz_t den, const fmpz_mat_t A)
Sets (\code{Ainv}, \code{den}) to the inverse matrix of \code{A}.
Returns 1 if \code{A} is nonsingular and 0 if \code{A} is singular.
Aliasing of \code{Ainv} and \code{A} is allowed.
The denominator is not guaranteed to be minimal, but is guaranteed
to be a divisor of the determinant of \code{A}.
This function uses a direct formula for matrices of size two or less,
and otherwise solves for the identity matrix using
fraction-free LU decomposition.
*******************************************************************************
Trace
*******************************************************************************
void fmpz_mat_trace(fmpz_t trace, const fmpz_mat_t mat)
Computes the trace of the matrix, i.e. the sum of the entries on
the main diagonal. The matrix is required to be square.
*******************************************************************************
Determinant
*******************************************************************************
void fmpz_mat_det(fmpz_t det, const fmpz_mat_t A)
Sets \code{det} to the determinant of the square matrix $A$.
The matrix of dimension $0 \times 0$ is defined to have determinant 1.
This function automatically chooses between \code{fmpz_mat_det_cofactor},\\
\code{fmpz_mat_det_bareiss}, \code{fmpz_mat_det_modular} and\\
\code{fmpz_mat_det_modular_accelerated}
(with \code{proved} = 1), depending on the size of the matrix
and its entries.
void fmpz_mat_det_cofactor(fmpz_t det, const fmpz_mat_t A)
Sets \code{det} to the determinant of the square matrix $A$
computed using direct cofactor expansion. This function only
supports matrices up to size $4 \times 4$.
void fmpz_mat_det_bareiss(fmpz_t det, const fmpz_mat_t A)
Sets \code{det} to the determinant of the square matrix $A$
computed using the Bareiss algorithm. A copy of the input matrix is
row reduced using fraction-free Gaussian elimination, and the
determinant is read off from the last element on the main
diagonal.
void fmpz_mat_det_modular(fmpz_t det, const fmpz_mat_t A, int proved)
Sets \code{det} to the determinant of the square matrix $A$
(if \code{proved} = 1), or a probabilistic value for the
determinant (\code{proved} = 0), computed using a multimodular
algorithm.
The determinant is computed modulo several small primes and
reconstructed using the Chinese Remainder Theorem.
With \code{proved} = 1, sufficiently many primes are chosen
to satisfy the bound computed by \code{fmpz_mat_det_bound}.
With \code{proved} = 0, the determinant is considered determined
if it remains unchanged modulo several consecutive primes
(currently if their product exceeds $2^{100}$).
void fmpz_mat_det_modular_accelerated(fmpz_t det,
const fmpz_mat_t A, int proved)
Sets \code{det} to the determinant of the square matrix $A$
(if \code{proved} = 1), or a probabilistic value for the
determinant (\code{proved} = 0), computed using a multimodular
algorithm.
This function uses the same basic algorithm as \code{fmpz_mat_det_modular},
but instead of computing $\det(A)$ directly, it generates a divisor $d$
of $\det(A)$ and then computes $x = \det(A) / d$ modulo several
small primes not dividing $d$. This typically accelerates the
computation by requiring fewer primes for large matrices, since $d$
with high probability will be nearly as large as the determinant.
This trick is described in \citep{AbbottBronsteinMulders1999}.
void fmpz_mat_det_modular_given_divisor(fmpz_t det, const fmpz_mat_t A,
const fmpz_t d, int proved)
Given a positive divisor $d$ of $\det(A)$, sets \code{det} to the
determinant of the square matrix $A$ (if \code{proved} = 1), or a
probabilistic value for the determinant (\code{proved} = 0), computed
using a multimodular algorithm.
void fmpz_mat_det_bound(fmpz_t bound, const fmpz_mat_t A)
Sets \code{bound} to a nonnegative integer $B$ such that
$|\det(A)| \le B$. Assumes $A$ to be a square matrix.
The bound is computed from the Hadamard inequality
$|\det(A)| \le \prod \|a_i\|_2$ where the product is taken
over the rows $a_i$ of $A$.
void fmpz_mat_det_divisor(fmpz_t d, const fmpz_mat_t A)
Sets $d$ to some positive divisor of the determinant of the given
square matrix $A$, if the determinant is nonzero. If $|\det(A)| = 0$,
$d$ will always be set to zero.
A divisor is obtained by solving $Ax = b$ for an arbitrarily chosen
right-hand side $b$ using Dixon's algorithm and computing the least
common multiple of the denominators in $x$. This yields a divisor $d$
such that $|\det(A)| / d$ is tiny with very high probability.
*******************************************************************************
Charactersitic polynomial
*******************************************************************************
void _fmpz_mat_charpoly(fmpz * cp, const fmpz_mat_t mat)
Sets \code{(cp, n+1)} to the characteristic polynomial of
an $n \times n$ square matrix.
void fmpz_mat_charpoly(fmpz_poly_t cp, const fmpz_mat_t mat)
Computes the characteristic polynomial of length $n + 1$ of
an $n \times n$ square matrix.
*******************************************************************************
Rank
*******************************************************************************
slong fmpz_mat_rank(const fmpz_mat_t A)
Returns the rank, that is, the number of linearly independent columns
(equivalently, rows), of $A$. The rank is computed by row reducing
a copy of $A$.
*******************************************************************************
Nonsingular solving
The following functions allow solving matrix-matrix equations $AX = B$
where the system matrix $A$ is square and has full rank. The solving
is implicitly done over the field of rational numbers: except
where otherwise noted, an integer matrix $\hat X$ and a separate
denominator $d$ (\code{den}) are computed such that $A(\hat X/d) = b$,
equivalently such that $A\hat X = bd$ holds over the integers.
No guarantee is made that the numerators and denominator
are reduced to lowest terms, but the denominator is always guaranteed
to be a divisor of the determinant of $A$. If $A$ is singular,
\code{den} will be set to zero and the elements of the solution
vector or matrix will have undefined values. No aliasing is
allowed between arguments.
*******************************************************************************
int fmpz_mat_solve(fmpz_mat_t X, fmpz_t den,
const fmpz_mat_t A, const fmpz_mat_t B)
Solves the equation $AX = B$ for nonsingular $A$. More precisely, computes
(\code{X}, \code{den}) such that $AX = B \times \operatorname{den}$.
Returns 1 if $A$ is nonsingular and 0 if $A$ is singular.
The computed denominator will not generally be minimal.
This function uses Cramer's rule for small systems and
fraction-free LU decomposition followed by fraction-free forward
and back substitution for larger systems.
Note that for very large systems, it is faster to compute a modular
solution using \code{fmpz_mat_solve_dixon}.
int fmpz_mat_solve_fflu(fmpz_mat_t X, fmpz_t den,
const fmpz_mat_t A, const fmpz_mat_t B)
Solves the equation $AX = B$ for nonsingular $A$. More precisely, computes
(\code{X}, \code{den}) such that $AX = B \times \operatorname{den}$.
Returns 1 if $A$ is nonsingular and 0 if $A$ is singular.
The computed denominator will not generally be minimal.
Uses fraction-free LU decomposition followed by fraction-free
forward and back substitution.
void fmpz_mat_solve_fflu_precomp(fmpz_mat_t X,
const slong * perm,
const fmpz_mat_t FFLU, const fmpz_mat_t B)
Performs fraction-free forward and back substitution given a precomputed
fraction-free LU decomposition and corresponding permutation.
int fmpz_mat_solve_cramer(fmpz_mat_t X, fmpz_t den,
const fmpz_mat_t A, const fmpz_mat_t B)
Solves the equation $AX = B$ for nonsingular $A$. More precisely, computes
(\code{X}, \code{den}) such that $AX = B \times \operatorname{den}$.
Returns 1 if $A$ is nonsingular and 0 if $A$ is singular.
Uses Cramer's rule. Only systems of size up to $3 \times 3$ are allowed.
void fmpz_mat_solve_bound(fmpz_t N, fmpz_t D, const fmpz_mat_t A,
const fmpz_mat_t B)
Assuming that $A$ is nonsingular, computes integers $N$ and $D$
such that the reduced numerators and denominators $n/d$ in
$A^{-1} B$ satisfy the bounds $0 \le |n| \le N$ and $0 \le d \le D$.
int fmpz_mat_solve_dixon(fmpz_mat_t X, fmpz_t M, const fmpz_mat_t A,
const fmpz_mat_t B)
Solves $AX = B$ given a nonsingular square matrix $A$ and a matrix $B$ of
compatible dimensions, using a modular algorithm. In particular,
Dixon's p-adic lifting algorithm is used (currently a non-adaptive version).
This is generally the preferred method for large dimensions.
More precisely, this function computes an integer $M$ and an integer
matrix $X$ such that $AX = B \bmod M$ and such that all the reduced
numerators and denominators of the elements $x = p/q$ in the full
solution satisfy $2|p|q < B$. As such, the explicit rational solution
matrix can be recovered uniquely by passing the output of this
function to \code{fmpq_mat_set_fmpz_mat_mod}.
A nonzero value is returned if $A$ is nonsingular. If $A$ is singular,
zero is returned and the values of the output variables will be
undefined.
Aliasing between input and output matrices is allowed.
*******************************************************************************
Row reduction
*******************************************************************************
slong fmpz_mat_find_pivot_any(const fmpz_mat_t mat,
slong start_row, slong end_row, slong c)
Attempts to find a pivot entry for row reduction.
Returns a row index $r$ between \code{start_row} (inclusive) and
\code{stop_row} (exclusive) such that column $c$ in \code{mat} has
a nonzero entry on row $r$, or returns -1 if no such entry exists.
This implementation simply chooses the first nonzero entry from
it encounters. This is likely to be a nearly optimal choice if all
entries in the matrix have roughly the same size, but can lead to
unnecessary coefficient growth if the entries vary in size.
slong fmpz_mat_fflu(fmpz_mat_t B, fmpz_poly_t den, slong * perm,
const fmpz_mat_t A, int rank_check)
Uses fraction-free Gaussian elimination to set (\code{B}, \code{den}) to a
fraction-free LU decomposition of \code{A} and returns the
rank of \code{A}. Aliasing of \code{A} and \code{B} is allowed.
Pivot elements are chosen with \code{fmpz_mat_find_pivot_any}.
If \code{perm} is non-\code{NULL}, the permutation of
rows in the matrix will also be applied to \code{perm}.
If \code{rank_check} is set, the function aborts and returns 0 if the
matrix is detected not to have full rank without completing the
elimination.
The denominator \code{den} is set to $\pm \operatorname{det}(S)$ where
$S$ is an appropriate submatrix of $A$ ($S = A$ if $A$ is square)
and the sign is decided by the parity of the permutation. Note that the
determinant is not generally the minimal denominator.
The fraction-free LU decomposition is defined in \citep{NakTurWil1997}.
slong fmpz_mat_rref(fmpz_mat_t B, fmpz_t den, const fmpz_mat_t A)
Sets (\code{B}, \code{den}) to the reduced row echelon form of \code{A}
and returns the rank of \code{A}. Aliasing of \code{A} and \code{B}
is allowed.
The algorithm proceeds by first computing a row echelon form using
\code{fmpz_mat_fflu}. Letting the upper part of this matrix be
$(U | V) P$ where $U$ is full rank upper triangular and $P$ is a
permutation matrix, we obtain the rref by setting $V$ to $U^{-1} V$
using back substitution. Scaling each completed row in the back
substitution to the denominator \code{den}, we avoid introducing
new fractions. This strategy is equivalent to the fraction-free
Gauss-Jordan elimination in \citep{NakTurWil1997}, but faster since
only the part $V$ corresponding to the null space has to be updated.
The denominator \code{den} is set to $\pm \operatorname{det}(S)$ where
$S$ is an appropriate submatrix of $A$ ($S = A$ if $A$ is square).
Note that the determinant is not generally the minimal denominator.
*******************************************************************************
Modular gaussian elimination
*******************************************************************************
slong fmpz_mat_rref_mod(slong * perm, fmpz_mat_t A, const fmpz_t p)
Uses fraction-free Gauss-Jordan elimination to set \code{A}
to its reduced row echelon form and returns the rank of \code{A}.
All computations are done modulo p.
Pivot elements are chosen with \code{fmpz_mat_find_pivot_any}.
If \code{perm} is non-\code{NULL}, the permutation of
rows in the matrix will also be applied to \code{perm}.
*******************************************************************************
Nullspace
*******************************************************************************
slong fmpz_mat_nullspace(fmpz_mat_t B, const fmpz_mat_t A)
Computes a basis for the right rational nullspace of $A$ and returns
the dimension of the nullspace (or nullity). $B$ is set to a matrix with
linearly independent columns and maximal rank such that $AB = 0$
(i.e. $Ab = 0$ for each column $b$ in $B$), and the rank of $B$ is
returned.
In general, the entries in $B$ will not be minimal: in particular,
the pivot entries in $B$ will generally differ from unity.
$B$ must be allocated with sufficient space to represent the result
(at most $n \times n$ where $n$ is the number of column of $A$).
*******************************************************************************
Echelon form
*******************************************************************************
slong fmpz_mat_rref_fraction_free(slong * perm, fmpz_mat_t B, fmpz_t den,
const fmpz_mat_t A)
Computes an integer matrix \code{B} and an integer \code{den} such that
\code{B / den} is the unique row reduced echelon form (RREF) of \code{A}
and returns the rank, i.e. the number of nonzero rows in \code{B}.
Aliasing of \code{B} and \code{A} is allowed, with an in-place
computation being more efficient. The size of \code{B} must be
the same as that of \code{A}.
The permutation order will be written to \code{perm} unless this
argument is \code{NULL}. That is, row \code{i} of the output matrix will
correspond to row \code{perm[i]} of the input matrix.
The denominator will always be a divisor of the determinant of (some
submatrix of) $A$, but is not guaranteed to be minimal or canonical in
any other sense.

49
external/flint-2.4.3/fmpz_mat/equal.c vendored Normal file
View File

@@ -0,0 +1,49 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
int fmpz_mat_equal(const fmpz_mat_t mat1, const fmpz_mat_t mat2)
{
slong j;
if (mat1->r != mat2->r || mat1->c != mat2->c)
{
return 0;
}
if (mat1->r == 0 || mat1->c == 0)
return 1;
for (j = 0; j < mat1->r; j++)
{
if (!_fmpz_vec_equal(mat1->rows[j], mat2->rows[j], mat1->c))
{
return 0;
}
}
return 1;
}

92
external/flint-2.4.3/fmpz_mat/fflu.c vendored Normal file
View File

@@ -0,0 +1,92 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
#include "perm.h"
#define E(j,k) fmpz_mat_entry(B,j,k)
slong
fmpz_mat_fflu(fmpz_mat_t B, fmpz_t den, slong * perm,
const fmpz_mat_t A, int rank_check)
{
fmpz_t t;
slong m, n, j, k, rank, r, pivot_row, pivot_col;
if (fmpz_mat_is_empty(A))
{
fmpz_one(den);
return 0;
}
fmpz_mat_set(B, A);
m = B->r;
n = B->c;
rank = pivot_row = pivot_col = 0;
fmpz_init(t);
while (pivot_row < m && pivot_col < n)
{
r = fmpz_mat_find_pivot_any(B, pivot_row, m, pivot_col);
if (r == -1)
{
if (rank_check)
{
fmpz_zero(den);
rank = 0;
break;
}
pivot_col++;
continue;
}
else if (r != pivot_row)
fmpz_mat_swap_rows(B, perm, pivot_row, r);
rank++;
for (j = pivot_row + 1; j < m; j++)
{
for (k = pivot_col + 1; k < n; k++)
{
/* todo: use submul */
fmpz_mul(E(j, k), E(j, k), E(pivot_row, pivot_col));
fmpz_mul(t, E(j, pivot_col), E(pivot_row, k));
fmpz_sub(E(j, k), E(j, k), t);
if (pivot_row > 0)
fmpz_divexact(E(j, k), E(j, k), den);
}
}
fmpz_set(den, E(pivot_row, pivot_col));
pivot_row++;
pivot_col++;
}
fmpz_clear(t);
return rank;
}

View File

@@ -0,0 +1,41 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
slong
fmpz_mat_find_pivot_any(const fmpz_mat_t mat,
slong start_row, slong end_row, slong c)
{
slong r;
for (r = start_row; r < end_row; r++)
{
if (!fmpz_is_zero(fmpz_mat_entry(mat, r, c)))
return r;
}
return -1;
}

111
external/flint-2.4.3/fmpz_mat/fprint.c vendored Normal file
View File

@@ -0,0 +1,111 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 William Hart
******************************************************************************/
#include "fmpz_mat.h"
/*
The macros xxx_putc, xxx_flint_printf, and xxx_fmpz_print are provided
as wrappers to handle return values and error conditions. While
this is not exactly pretty, it improves the readability of the
functions fmpz_mat_fprint and fmpz_mat_fprint_pretty. Moreover,
if we later want to improve the handling of returns values, e.g.
to return the number of characters printed, this will be easier.
The macros are undef'd at the end of the file.
*/
#define xxx_putc(c) \
do { \
z = fputc((c), file); \
if (z <= 0) \
return z; \
} while (0)
#define xxx_flint_printf() \
do { \
z = flint_fprintf(file, "%li %li ", r, c); \
if (z <= 0) \
return z; \
} while (0)
#define xxx_fmpz_print(f) \
do { \
z = fmpz_fprint(file, (f)); \
if (z <= 0) \
return z; \
} while(0)
int fmpz_mat_fprint(FILE * file, const fmpz_mat_t mat)
{
int z;
slong i, j;
slong r = mat->r;
slong c = mat->c;
xxx_flint_printf();
for (i = 0; (i < r); i++)
{
for (j = 0; j < c; j++)
{
xxx_fmpz_print(mat->rows[i] + j);
if (j != c - 1)
xxx_putc(' ');
}
if (i != r - 1)
xxx_putc(' ');
}
return z;
}
int fmpz_mat_fprint_pretty(FILE * file, const fmpz_mat_t mat)
{
int z;
slong i, j;
slong r = mat->r;
slong c = mat->c;
xxx_putc('[');
for (i = 0; i < r; i++)
{
xxx_putc('[');
for (j = 0; j < c; j++)
{
xxx_fmpz_print(mat->rows[i] + j);
if (j != c - 1)
xxx_putc(' ');
}
xxx_putc(']');
xxx_putc('\n');
}
xxx_putc(']');
return z;
}
#undef xxx_putc
#undef xxx_flint_printf
#undef xxx_fmpz_print

95
external/flint-2.4.3/fmpz_mat/fread.c vendored Normal file
View File

@@ -0,0 +1,95 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Andy Novocin
******************************************************************************/
#include "fmpz_mat.h"
int
fmpz_mat_fread(FILE* file, fmpz_mat_t mat)
{
slong r, c, i, j;
int byte_count;
mpz_t t;
/* first number in file should be row dimension */
mpz_init(t);
byte_count = mpz_inp_str(t, file, 10);
if (byte_count == 0)
{
mpz_clear(t);
return 0;
}
if (!mpz_fits_slong_p(t))
{
flint_printf("Exception (fmpz_mat_fread). "
"Number of rows does not fit into a slong.\n");
abort();
}
r = flint_mpz_get_si(t);
/* second number in file should be column dimension */
byte_count = mpz_inp_str(t, file, 10);
if (byte_count == 0)
{
mpz_clear(t);
return 0;
}
if (!mpz_fits_slong_p(t))
{
flint_printf("Exception (fmpz_mat_fread). "
"Number of columns does not fit into a slong.\n");
abort();
}
c = flint_mpz_get_si(t);
mpz_clear(t);
/* if the input is 0 by 0 then set the dimensions to r and c */
if (mat->r == 0 && mat->c == 0)
{
fmpz_mat_clear(mat);
fmpz_mat_init(mat,r,c);
}
else if (mat->r == 0 && mat->c == 0)
{
flint_printf("Exception (fmpz_mat_fread). \n"
"Dimensions are non-zero and do not match input dimensions.\n");
abort();
}
for (i = 0; i < r; i++)
{
for (j = 0; j < c; j++)
{
if (!fmpz_fread(file, fmpz_mat_entry(mat, i, j)))
return 0;
}
}
/* a return value of 0 means a problem with
the file stream a value of 1 means success*/
return 1;
}

View File

@@ -0,0 +1,37 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_get_nmod_mat(nmod_mat_t Amod, const fmpz_mat_t A)
{
slong i, j;
mp_limb_t m = Amod->mod.n;
for (i = 0; i < A->r; i++)
for (j = 0; j < A->c; j++)
Amod->rows[i][j] = fmpz_fdiv_ui(A->rows[i]+j, m);
}

45
external/flint-2.4.3/fmpz_mat/init.c vendored Normal file
View File

@@ -0,0 +1,45 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 William Hart
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_init(fmpz_mat_t mat, slong rows, slong cols)
{
if ((rows) && (cols)) /* Allocate space for r*c small entries */
{
slong i;
mat->entries = (fmpz *) flint_calloc(rows * cols, sizeof(fmpz));
mat->rows = (fmpz **) flint_malloc(rows * sizeof(fmpz *)); /* Initialise rows */
for (i = 0; i < rows; i++)
mat->rows[i] = mat->entries + i * cols;
}
else
mat->entries = NULL;
mat->r = rows;
mat->c = cols;
}

View File

@@ -0,0 +1,34 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 William Hart
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_init_set(fmpz_mat_t mat, const fmpz_mat_t src)
{
fmpz_mat_init(mat, src->r, src->c);
fmpz_mat_set(mat, src);
}

79
external/flint-2.4.3/fmpz_mat/inv.c vendored Normal file
View File

@@ -0,0 +1,79 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010-2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
_fmpz_mat_inv_2x2(fmpz ** b, fmpz_t den, fmpz ** const a)
{
fmpz_t tmp;
_fmpz_mat_det_cofactor_2x2(den, a);
fmpz_neg(&b[0][1], &a[0][1]);
fmpz_neg(&b[1][0], &a[1][0]);
fmpz_init(tmp);
fmpz_set(tmp, &a[0][0]);
fmpz_set(&b[0][0], &a[1][1]);
fmpz_set(&b[1][1], tmp);
fmpz_clear(tmp);
}
int
fmpz_mat_inv(fmpz_mat_t B, fmpz_t den, const fmpz_mat_t A)
{
slong dim = A->r;
if (dim == 0)
{
fmpz_one(den);
return 1;
}
else if (dim == 1)
{
fmpz_set(den, A->entries);
fmpz_one(B->entries);
return !fmpz_is_zero(den);
}
else if (dim == 2)
{
_fmpz_mat_inv_2x2(B->rows, den, A->rows);
return !fmpz_is_zero(den);
}
else
{
fmpz_mat_t I;
slong i;
int success;
fmpz_mat_init(I, dim, dim);
for (i = 0; i < dim; i++)
fmpz_one(fmpz_mat_entry(I, i, i));
success = fmpz_mat_solve_fflu(B, den, A, I);
fmpz_mat_clear(I);
return success;
}
}

43
external/flint-2.4.3/fmpz_mat/is_zero.c vendored Normal file
View File

@@ -0,0 +1,43 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
int
fmpz_mat_is_zero(const fmpz_mat_t mat)
{
slong j;
if (mat->r == 0 || mat->c == 0)
return 1;
for (j = 0; j < mat->r; j++)
{
if (!_fmpz_vec_is_zero(mat->rows[j], mat->c))
return 0;
}
return 1;
}

View File

@@ -0,0 +1,52 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
slong
fmpz_mat_max_bits(const fmpz_mat_t mat)
{
slong i;
slong bits, row_bits, sign;
sign = 1;
bits = 0;
if (mat->r == 0 || mat->c == 0)
return 0;
for (i = 0; i < mat->r; i++)
{
row_bits = _fmpz_vec_max_bits(mat->rows[i], mat->c);
if (row_bits < 0)
{
row_bits = -row_bits;
sign = -1;
}
bits = FLINT_MAX(bits, row_bits);
}
return bits * sign;
}

78
external/flint-2.4.3/fmpz_mat/mul.c vendored Normal file
View File

@@ -0,0 +1,78 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010,2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_mul(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B)
{
slong dim, m, n, k;
m = A->r;
n = A->c;
k = B->c;
if (C == A || C == B)
{
fmpz_mat_t t;
fmpz_mat_init(t, m, k);
fmpz_mat_mul(t, A, B);
fmpz_mat_swap(C, t);
fmpz_mat_clear(t);
return;
}
dim = FLINT_MIN(FLINT_MIN(m, n), k);
if (dim < 12)
{
/* The inline version only benefits from large n */
if (n <= 2)
fmpz_mat_mul_classical(C, A, B);
else
fmpz_mat_mul_classical_inline(C, A, B);
}
else
{
slong ab, bb, bits;
ab = fmpz_mat_max_bits(A);
bb = fmpz_mat_max_bits(B);
ab = FLINT_ABS(ab);
bb = FLINT_ABS(bb);
bits = ab + bb + FLINT_BIT_COUNT(n) + 1;
if (5*(ab + bb) > dim * dim || (bits > FLINT_BITS - 3 && dim < 60))
{
fmpz_mat_mul_classical_inline(C, A, B);
}
else
{
_fmpz_mat_mul_multi_mod(C, A, B, bits);
}
}
}

View File

@@ -0,0 +1,60 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010,2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_mul_classical(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B)
{
slong ar, bc, br;
slong i, j, k;
ar = A->r;
br = B->r;
bc = B->c;
if (br == 0)
{
fmpz_mat_zero(C);
return;
}
for (i = 0; i < ar; i++)
{
for (j = 0; j < bc; j++)
{
fmpz_mul(fmpz_mat_entry(C, i, j),
fmpz_mat_entry(A, i, 0),
fmpz_mat_entry(B, 0, j));
for (k = 1; k < br; k++)
{
fmpz_addmul(fmpz_mat_entry(C, i, j),
fmpz_mat_entry(A, i, k),
fmpz_mat_entry(B, k, j));
}
}
}
}

View File

@@ -0,0 +1,131 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
#include "longlong.h"
void
fmpz_mat_mul_classical_inline(fmpz_mat_t C, const fmpz_mat_t A,
const fmpz_mat_t B)
{
slong ar, bc, br;
slong i, j, k;
fmpz a, b;
mpz_t t;
mp_limb_t au, bu;
mp_limb_t pos[3];
mp_limb_t neg[3];
ar = A->r;
br = B->r;
bc = B->c;
mpz_init(t);
for (i = 0; i < ar; i++)
{
for (j = 0; j < bc; j++)
{
flint_mpz_set_ui(t, UWORD(0));
pos[2] = pos[1] = pos[0] = neg[2] = neg[1] = neg[0] = UWORD(0);
for (k = 0; k < br; k++)
{
a = A->rows[i][k];
b = B->rows[k][j];
if (a == 0 || b == 0)
continue;
if (!COEFF_IS_MPZ(a)) /* a is small */
{
if (!COEFF_IS_MPZ(b)) /* both are small */
{
au = FLINT_ABS(a);
bu = FLINT_ABS(b);
umul_ppmm(au, bu, au, bu);
if ((a ^ b) >= WORD(0))
add_sssaaaaaa(pos[2], pos[1], pos[0],
pos[2], pos[1], pos[0], 0, au, bu);
else
add_sssaaaaaa(neg[2], neg[1], neg[0],
neg[2], neg[1], neg[0], 0, au, bu);
}
else
{
if (a >= 0)
flint_mpz_addmul_ui(t, COEFF_TO_PTR(b), a);
else
flint_mpz_submul_ui(t, COEFF_TO_PTR(b), -a);
}
}
else if (!COEFF_IS_MPZ(b)) /* b is small */
{
if (b >= 0)
flint_mpz_addmul_ui(t, COEFF_TO_PTR(a), b);
else
flint_mpz_submul_ui(t, COEFF_TO_PTR(a), -b);
}
else
{
mpz_addmul(t, COEFF_TO_PTR(a), COEFF_TO_PTR(b));
}
}
if (mpz_sgn(t) != 0 || pos[2] || neg[2] || pos[1] || neg[1])
{
__mpz_struct r;
r._mp_size = pos[2] ? 3 : (pos[1] ? 2 : pos[0] != 0);
r._mp_alloc = r._mp_size;
r._mp_d = pos;
mpz_add(t, t, &r);
r._mp_size = neg[2] ? 3 : (neg[1] ? 2 : neg[0] != 0);
r._mp_alloc = r._mp_size;
r._mp_d = neg;
mpz_sub(t, t, &r);
fmpz_set_mpz(fmpz_mat_entry(C, i, j), t);
}
else
{
if (neg[0] > pos[0])
fmpz_neg_ui(fmpz_mat_entry(C, i, j), neg[0] - pos[0]);
else
fmpz_set_ui(fmpz_mat_entry(C, i, j), pos[0] - neg[0]);
}
}
}
mpz_clear(t);
}

View File

@@ -0,0 +1,140 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
_fmpz_mat_mul_multi_mod(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B,
mp_bitcnt_t bits)
{
slong i, j;
fmpz_comb_t comb;
fmpz_comb_temp_t comb_temp;
slong num_primes;
mp_bitcnt_t primes_bits;
mp_limb_t * primes;
mp_limb_t * residues;
nmod_mat_t * mod_C;
nmod_mat_t * mod_A;
nmod_mat_t * mod_B;
primes_bits = NMOD_MAT_OPTIMAL_MODULUS_BITS;
if (bits < primes_bits)
{
primes_bits = bits;
num_primes = 1;
}
else
{
/* Round up in the division */
num_primes = (bits + primes_bits - 1) / primes_bits;
}
/* Initialize */
primes = flint_malloc(sizeof(mp_limb_t) * num_primes);
primes[0] = n_nextprime(UWORD(1) << primes_bits, 0);
for (i = 1; i < num_primes; i++)
primes[i] = n_nextprime(primes[i-1], 0);
residues = flint_malloc(sizeof(mp_limb_t) * num_primes);
mod_A = flint_malloc(sizeof(nmod_mat_t) * num_primes);
mod_B = flint_malloc(sizeof(nmod_mat_t) * num_primes);
mod_C = flint_malloc(sizeof(nmod_mat_t) * num_primes);
for (i = 0; i < num_primes; i++)
{
nmod_mat_init(mod_A[i], A->r, A->c, primes[i]);
nmod_mat_init(mod_B[i], B->r, B->c, primes[i]);
nmod_mat_init(mod_C[i], C->r, C->c, primes[i]);
}
fmpz_comb_init(comb, primes, num_primes);
fmpz_comb_temp_init(comb_temp, comb);
/* Calculate residues of A */
for (i = 0; i < A->r * A->c; i++)
{
fmpz_multi_mod_ui(residues, &A->entries[i], comb, comb_temp);
for (j = 0; j < num_primes; j++)
mod_A[j]->entries[i] = residues[j];
}
/* Calculate residues of B */
for (i = 0; i < B->r * B->c; i++)
{
fmpz_multi_mod_ui(residues, &B->entries[i], comb, comb_temp);
for (j = 0; j < num_primes; j++)
mod_B[j]->entries[i] = residues[j];
}
/* Multiply */
for (i = 0; i < num_primes; i++)
{
nmod_mat_mul(mod_C[i], mod_A[i], mod_B[i]);
}
/* Chinese remaindering */
for (i = 0; i < C->r * C->c; i++)
{
for (j = 0; j < num_primes; j++)
residues[j] = mod_C[j]->entries[i];
fmpz_multi_CRT_ui(&C->entries[i], residues, comb, comb_temp, 1);
}
/* Cleanup */
for (i = 0; i < num_primes; i++)
{
nmod_mat_clear(mod_A[i]);
nmod_mat_clear(mod_B[i]);
nmod_mat_clear(mod_C[i]);
}
flint_free(mod_A);
flint_free(mod_B);
flint_free(mod_C);
fmpz_comb_temp_clear(comb_temp);
fmpz_comb_clear(comb);
flint_free(residues);
flint_free(primes);
}
void
fmpz_mat_mul_multi_mod(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B)
{
slong A_bits;
slong B_bits;
A_bits = fmpz_mat_max_bits(A);
B_bits = fmpz_mat_max_bits(B);
_fmpz_mat_mul_multi_mod(C, A, B, FLINT_ABS(A_bits) + FLINT_ABS(B_bits) \
+ FLINT_BIT_COUNT(A->c) + 1);
}

View File

@@ -0,0 +1,72 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_multi_CRT_ui_precomp(fmpz_mat_t mat,
nmod_mat_t * const residues, slong nres,
const fmpz_comb_t comb, fmpz_comb_temp_t temp, int sign)
{
slong i, j, k;
mp_ptr r;
r = _nmod_vec_init(nres);
for (i = 0; i < fmpz_mat_nrows(mat); i++)
{
for (j = 0; j < fmpz_mat_ncols(mat); j++)
{
for (k = 0; k < nres; k++)
r[k] = nmod_mat_entry(residues[k], i, j);
fmpz_multi_CRT_ui(fmpz_mat_entry(mat, i, j), r, comb, temp, sign);
}
}
_nmod_vec_clear(r);
}
void
fmpz_mat_multi_CRT_ui(fmpz_mat_t mat, nmod_mat_t * const residues,
slong nres, int sign)
{
fmpz_comb_t comb;
fmpz_comb_temp_t temp;
mp_ptr primes;
slong i;
primes = _nmod_vec_init(nres);
for (i = 0; i < nres; i++)
primes[i] = residues[i]->mod.n;
fmpz_comb_init(comb, primes, nres);
fmpz_comb_temp_init(temp, comb);
fmpz_mat_multi_CRT_ui_precomp(mat, residues, nres, comb, temp, sign);
fmpz_comb_clear(comb);
fmpz_comb_temp_clear(temp);
_nmod_vec_clear(primes);
}

View File

@@ -0,0 +1,69 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_multi_mod_ui_precomp(nmod_mat_t * residues, slong nres,
const fmpz_mat_t mat, const fmpz_comb_t comb, fmpz_comb_temp_t temp)
{
slong i, j, k;
mp_ptr r;
r = _nmod_vec_init(nres);
for (i = 0; i < fmpz_mat_nrows(mat); i++)
{
for (j = 0; j < fmpz_mat_ncols(mat); j++)
{
fmpz_multi_mod_ui(r, fmpz_mat_entry(mat, i, j), comb, temp);
for (k = 0; k < nres; k++)
nmod_mat_entry(residues[k], i, j) = r[k];
}
}
_nmod_vec_clear(r);
}
void
fmpz_mat_multi_mod_ui(nmod_mat_t * residues, slong nres, const fmpz_mat_t mat)
{
fmpz_comb_t comb;
fmpz_comb_temp_t temp;
mp_ptr primes;
slong i;
primes = _nmod_vec_init(nres);
for (i = 0; i < nres; i++)
primes[i] = residues[i]->mod.n;
fmpz_comb_init(comb, primes, nres);
fmpz_comb_temp_init(temp, comb);
fmpz_mat_multi_mod_ui_precomp(residues, nres, mat, comb, temp);
fmpz_comb_clear(comb);
fmpz_comb_temp_clear(temp);
_nmod_vec_clear(primes);
}

38
external/flint-2.4.3/fmpz_mat/neg.c vendored Normal file
View File

@@ -0,0 +1,38 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_neg(fmpz_mat_t res, const fmpz_mat_t mat)
{
slong i;
if (res->c < 1)
return;
for (i = 0; i < res->r; i++)
_fmpz_vec_neg(res->rows[i], mat->rows[i], res->c);
}

View File

@@ -0,0 +1,91 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
slong
fmpz_mat_nullspace(fmpz_mat_t res, const fmpz_mat_t mat)
{
slong i, j, k, n, rank, nullity;
slong * pivots;
slong * nonpivots;
fmpz_mat_t tmp;
fmpz_t den;
n = mat->c;
fmpz_mat_init_set(tmp, mat);
fmpz_init(den);
rank = fmpz_mat_rref(tmp, den, mat);
nullity = n - rank;
fmpz_mat_zero(res);
if (rank == 0)
{
for (i = 0; i < nullity; i++)
fmpz_one(res->rows[i] + i);
}
else if (nullity)
{
pivots = flint_malloc(rank * sizeof(slong));
nonpivots = flint_malloc(nullity * sizeof(slong));
for (i = j = k = 0; i < rank; i++)
{
while (fmpz_is_zero(tmp->rows[i] + j))
{
nonpivots[k] = j;
k++;
j++;
}
pivots[i] = j;
j++;
}
while (k < nullity)
{
nonpivots[k] = j;
k++;
j++;
}
fmpz_set(den, tmp->rows[0] + pivots[0]);
for (i = 0; i < nullity; i++)
{
for (j = 0; j < rank; j++)
fmpz_set(res->rows[pivots[j]] + i, tmp->rows[j] + nonpivots[i]);
fmpz_neg(res->rows[nonpivots[i]] + i, den);
}
flint_free(pivots);
flint_free(nonpivots);
}
fmpz_clear(den);
fmpz_mat_clear(tmp);
return nullity;
}

38
external/flint-2.4.3/fmpz_mat/one.c vendored Normal file
View File

@@ -0,0 +1,38 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_one(fmpz_mat_t mat)
{
slong i, n;
fmpz_mat_zero(mat);
n = FLINT_MIN(mat->r, mat->c);
for (i = 0; i < n; i++)
fmpz_one(fmpz_mat_entry(mat, i, i));
}

75
external/flint-2.4.3/fmpz_mat/pow.c vendored Normal file
View File

@@ -0,0 +1,75 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2012 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_pow(fmpz_mat_t B, const fmpz_mat_t A, ulong exp)
{
slong d = fmpz_mat_nrows(A);
if (exp <= 2 || d <= 1)
{
if (exp == 0 || d == 0)
{
fmpz_mat_one(B);
}
else if (d == 1)
{
fmpz_pow_ui(fmpz_mat_entry(B, 0, 0),
fmpz_mat_entry(A, 0, 0), exp);
}
else if (exp == 1)
{
fmpz_mat_set(B, A);
}
else if (exp == 2)
{
fmpz_mat_sqr(B, A);
}
}
else
{
fmpz_mat_t T, U;
slong i;
fmpz_mat_init_set(T, A);
fmpz_mat_init(U, d, d);
for (i = ((slong) FLINT_BIT_COUNT(exp)) - 2; i >= 0; i--)
{
fmpz_mat_sqr(U, T);
if (exp & (WORD(1) << i))
fmpz_mat_mul(T, U, A);
else
fmpz_mat_swap(T, U);
}
fmpz_mat_swap(B, T);
fmpz_mat_clear(T);
fmpz_mat_clear(U);
}
}

View File

@@ -0,0 +1,116 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright 2009 William Hart
Copyright 2010,2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "profiler.h"
#include "flint.h"
#include "fmpz_mat.h"
#include "fmpz.h"
#include "ulong_extras.h"
typedef struct
{
ulong dim;
int algorithm;
slong bits;
} mat_mul_t;
void sample(void * arg, ulong count)
{
mat_mul_t * params = (mat_mul_t *) arg;
ulong i, dim = params->dim;
slong bits = params->bits;
int algorithm = params->algorithm;
flint_rand_t rnd;
fmpz_mat_t A;
fmpz_t d;
FLINT_TEST_INIT(state);
fmpz_mat_init(A, dim, dim);
fmpz_init(d);
fmpz_mat_randtest(A, state, bits);
prof_start();
if (algorithm == 0)
for (i = 0; i < count; i++)
fmpz_mat_det_bareiss(d, A);
else if (algorithm == 1)
for (i = 0; i < count; i++)
fmpz_mat_det_modular(d, A, 1);
else if (algorithm == 2)
for (i = 0; i < count; i++)
fmpz_mat_det_modular_accelerated(d, A, 1);
prof_stop();
fmpz_mat_clear(A);
fmpz_clear(d);
flint_randclear(state);
}
int main(void)
{
double min_default, min_classical, min_modular, min_modular_2, max;
mat_mul_t params;
slong dim, bits;
params.bits = 200;
for (bits = 2; bits <= 4096; bits *= 2)
{
params.bits = bits;
flint_printf("fmpz_mat_det (bits = %wd):\n", params.bits);
for (dim = 2; dim <= 512; dim = (slong) ((double) dim * 1.1) + 1)
{
params.dim = dim;
params.algorithm = 0;
prof_repeat(&min_classical, &max, sample, &params);
params.algorithm = 1;
prof_repeat(&min_modular, &max, sample, &params);
params.algorithm = 2;
prof_repeat(&min_modular_2, &max, sample, &params);
flint_printf("dim = %wd classical/modular/acc. %.2f %.2f %.2f (us)\n",
dim, min_classical, min_modular, min_modular_2);
if (min_modular > 1.1*min_modular_2)
break;
}
}
return 0;
}

View File

@@ -0,0 +1,133 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright 2009 William Hart
Copyright 2010,2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "profiler.h"
#include "flint.h"
#include "fmpz_mat.h"
#include "fmpz.h"
#include "ulong_extras.h"
typedef struct
{
slong m;
slong n;
slong k;
int algorithm;
slong bits;
} mat_mul_t;
void sample(void * arg, ulong count)
{
mat_mul_t * params = (mat_mul_t *) arg;
slong i, m = params->m, n = params->n, k = params->k;
slong bits = params->bits;
int algorithm = params->algorithm;
flint_rand_t rnd;
fmpz_mat_t A, B, C;
FLINT_TEST_INIT(state);
fmpz_mat_init(A, m, n);
fmpz_mat_init(B, n, k);
fmpz_mat_init(C, m, k);
fmpz_mat_randbits(A, state, bits);
fmpz_mat_randbits(B, state, bits);
prof_start();
if (algorithm == 0)
for (i = 0; i < count; i++)
fmpz_mat_mul(C, A, B);
else if (algorithm == 1)
for (i = 0; i < count; i++)
fmpz_mat_mul_classical(C, A, B);
else if (algorithm == 2)
for (i = 0; i < count; i++)
fmpz_mat_mul_classical_inline(C, A, B);
else if (algorithm == 3)
for (i = 0; i < count; i++)
fmpz_mat_mul_multi_mod(C, A, B);
prof_stop();
fmpz_mat_clear(A);
fmpz_mat_clear(B);
fmpz_mat_clear(C);
flint_randclear(state);
}
int main(void)
{
double min_default, min_classical, min_inline, min_multi_mod, max;
mat_mul_t params;
slong bits, dim;
for (bits = 1; bits <= 2000; bits = (slong) ((double) bits * 1.3) + 1)
{
params.bits = bits;
flint_printf("fmpz_mat_mul (bits = %wd):\n", params.bits);
for (dim = 1; dim <= 512; dim = (slong) ((double) dim * 1.3) + 1)
{
params.m = dim;
params.n = dim;
params.k = dim;
params.algorithm = 0;
prof_repeat(&min_default, &max, sample, &params);
params.algorithm = 1;
prof_repeat(&min_classical, &max, sample, &params);
params.algorithm = 2;
prof_repeat(&min_inline, &max, sample, &params);
params.algorithm = 3;
prof_repeat(&min_multi_mod, &max, sample, &params);
flint_printf("dim = %wd default/classical/inline/multi_mod %.2f %.2f %.2f %.2f (us)\n",
dim, min_default, min_classical, min_inline, min_multi_mod);
if (min_multi_mod < 0.6*min_default)
flint_printf("BAD!\n");
if (min_inline < 0.6*min_default)
flint_printf("BAD!\n");
if (min_multi_mod < 0.7*min_inline)
break;
}
}
return 0;
}

View File

@@ -0,0 +1,68 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2005-2009 Damien Stehle
Copyright (C) 2007 David Cade
Copyright (C) 2010 William Hart
******************************************************************************/
#include <math.h>
#include "fmpz_mat.h"
void
fmpz_mat_randajtai(fmpz_mat_t mat, flint_rand_t state, double alpha)
{
const slong c = mat->c, r = mat->r, d = r;
slong i, j;
fmpz_t tmp;
if (c != r)
{
flint_printf("Exception (fmpz_mat_ajtai): Non-square matrix.\n");
abort();
}
fmpz_init(tmp);
for (i = 0; i < d; i++)
{
mp_bitcnt_t bits = (mp_bitcnt_t) pow((double) (2 * d - i), alpha);
fmpz_one(tmp);
fmpz_mul_2exp(tmp, tmp, bits);
fmpz_sub_ui(tmp, tmp, 1);
fmpz_randm(mat->rows[i] + i, state, tmp);
fmpz_add_ui(mat->rows[i] + i, mat->rows[i] + i, 2);
fmpz_fdiv_q_2exp(mat->rows[i] + i, mat->rows[i] + i, 1);
for (j = i + 1; j <= d; j++)
{
fmpz_randm(mat->rows[j] + i, state, tmp);
if (n_randint(state, 2))
fmpz_neg(mat->rows[j] + i, mat->rows[j] + i);
fmpz_zero(mat->rows[i] + j);
}
}
fmpz_clear(tmp);
}

View File

@@ -0,0 +1,39 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 William Hart
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_randbits(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits)
{
slong r, c, i, j;
r = mat->r;
c = mat->c;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
fmpz_randbits(mat->rows[i] + j, state, bits);
}

101
external/flint-2.4.3/fmpz_mat/randdet.c vendored Normal file
View File

@@ -0,0 +1,101 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
#include "fmpz.h"
void
fmpz_mat_randdet(fmpz_mat_t mat, flint_rand_t state, const fmpz_t det)
{
slong i, j, k, n;
int parity;
fmpz * diag;
fmpz_factor_t factor;
n = mat->r;
if (n != mat->c)
{
flint_printf("Exception (fmpz_mat_randdet). Non-square matrix.\n");
abort();
}
if (n < 1)
return;
/* Start with the zero matrix */
fmpz_mat_zero(mat);
if (*det == WORD(0))
return;
fmpz_factor_init(factor);
fmpz_factor(factor, det);
diag = _fmpz_vec_init(n);
for (i = 0; i < n; i++)
fmpz_one(&diag[i]);
/* Form diagonal entries that multiply to the determinant */
for (i = 0; i < factor->num; i++)
{
for (j = 0; j < factor->exp[i]; j++)
{
k = n_randint(state, n);
fmpz_mul(&diag[k], &diag[k], &factor->p[i]);
}
}
/* Reverse signs an even number of times */
for (i = 0; i < 2*n; i++)
{
k = n_randint(state, n);
fmpz_neg(&diag[k], &diag[k]);
}
if (factor->sign == -1)
fmpz_neg(&diag[0], &diag[0]);
parity = fmpz_mat_randpermdiag(mat, state, diag, n);
/* Need another reversal if the permutation was odd */
if (parity)
{
for (i = 0; i < mat->r; i++)
{
for (j = 0; j < mat->c; j++)
{
if (!fmpz_is_zero(mat->rows[i] + j))
{
fmpz_neg(mat->rows[i] + j, mat->rows[i] + j);
goto end;
}
}
}
}
end:
_fmpz_vec_clear(diag, n);
fmpz_factor_clear(factor);
}

View File

@@ -0,0 +1,52 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2005-2009 Damien Stehle
Copyright (C) 2007 David Cade
Copyright (C) 2010 William Hart
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_randintrel(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits)
{
const slong c = mat->c, r = mat->r;
slong i, j;
if (c != r + 1)
{
flint_printf("Exception (fmpz_mat_randintrel). c != r + 1.\n");
abort();
}
for (i = 0; i < r; i++)
{
fmpz_randbits(mat->rows[i], state, bits);
for (j = 1; j <= i; j++)
fmpz_zero(mat->rows[i] + j);
fmpz_one(mat->rows[i] + i + 1);
for (j = i + 2; j < c; j++)
fmpz_zero(mat->rows[i] + j);
}
}

View File

@@ -0,0 +1,83 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2005-2009 Damien Stehle
Copyright (C) 2007 David Cade
Copyright (C) 2010 William Hart
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_randntrulike(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits, ulong q)
{
const slong c = mat->c, r = mat->r, d = r / 2;
slong i, j, k;
fmpz *h;
if ((c != r) || (c != 2 * d))
{
flint_printf("Exception (fmpz_mat_randntrulike). Ill-formed matrix.\n");
abort();
}
h = _fmpz_vec_init(d);
for (i = 0; i < d; i++)
fmpz_randbits(h + i, state, bits);
for (i = 0; i < d; i++)
{
for (j = 0; j < i; j++)
fmpz_zero(mat->rows[i] + j);
fmpz_one(mat->rows[i] + i);
for (j = i + 1; j < d; j++)
fmpz_zero(mat->rows[i] + j);
}
for (i = d; i < r; i++)
for (j = 0; j < d; j++)
fmpz_zero(mat->rows[i] + j);
for (i = d; i < r; i++)
{
for (j = d; j < i; j++)
fmpz_zero(mat->rows[i] + j);
fmpz_set_ui(mat->rows[i] + i, q);
for (j = i + 1; j < c; j++)
fmpz_zero(mat->rows[i] + j);
}
for (i = 0; i < d; i++)
{
for (j = d; j < c; j++)
{
k = j + i;
while (k >= d)
k -= d;
fmpz_set(mat->rows[i] + j, h + k);
}
}
_fmpz_vec_clear(h, d);
}

View File

@@ -0,0 +1,83 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2005-2009 Damien Stehle
Copyright (C) 2007 David Cade
Copyright (C) 2010 William Hart
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_randntrulike2(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits, ulong q)
{
const slong c = mat->c, r = mat->r, d = r / 2;
slong i, j, k;
fmpz *h;
if ((c != r) || (c != 2 * d))
{
flint_printf("Exception (fmpz_mat_randntrulike2). Ill-formed matrix.\n");
abort();
}
h = _fmpz_vec_init(d);
for (i = 0; i < d; i++)
fmpz_randbits(h + i, state, bits);
for (i = 0; i < d; i++)
{
for (j = 0; j < i; j++)
fmpz_zero(mat->rows[i] + j);
fmpz_set_ui(mat->rows[i] + i, q);
for (j = i + 1; j < d; j++)
fmpz_zero(mat->rows[i] + j);
}
for (i = 0; i < d; i++)
for (j = d; j < c; j++)
fmpz_zero(mat->rows[i] + j);
for (i = d; i < c; i++)
{
for (j = d; j < i; j++)
fmpz_zero(mat->rows[i] + j);
fmpz_one(mat->rows[i] + i);
for (j = i + 1; j < c; j++)
fmpz_zero(mat->rows[i] + j);
}
for (i = d; i < r; i++)
{
for (j = 0; j < d; j++)
{
k = j + i;
while (k >= d)
k -= d;
fmpz_set(mat->rows[i] + j, h + k);
}
}
_fmpz_vec_clear(h, d);
}

67
external/flint-2.4.3/fmpz_mat/randops.c vendored Normal file
View File

@@ -0,0 +1,67 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_randops(fmpz_mat_t mat, flint_rand_t state, slong count)
{
slong c, i, j, k;
slong m = mat->r;
slong n = mat->c;
if (mat->r == 0 || mat->c == 0)
return;
for (c = 0; c < count; c++)
{
if (n_randint(state, 2))
{
if ((i = n_randint(state, m)) == (j = n_randint(state, m)))
continue;
if (n_randint(state, 2))
for (k = 0; k < n; k++)
fmpz_add(&mat->rows[j][k], &mat->rows[j][k],
&mat->rows[i][k]);
else
for (k = 0; k < n; k++)
fmpz_sub(&mat->rows[j][k], &mat->rows[j][k],
&mat->rows[i][k]);
}
else
{
if ((i = n_randint(state, n)) == (j = n_randint(state, n)))
continue;
if (n_randint(state, 2))
for (k = 0; k < m; k++)
fmpz_add(&mat->rows[k][j], &mat->rows[k][j],
&mat->rows[k][i]);
else
for (k = 0; k < m; k++)
fmpz_sub(&mat->rows[k][j], &mat->rows[k][j],
&mat->rows[k][i]);
}
}
}

View File

@@ -0,0 +1,52 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010,2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
#include "perm.h"
int
fmpz_mat_randpermdiag(fmpz_mat_t mat, flint_rand_t state,
const fmpz * diag, slong n)
{
int parity;
slong i;
slong * rows;
slong * cols;
rows = _perm_init(mat->r);
cols = _perm_init(mat->c);
parity = _perm_randtest(rows, mat->r, state);
parity ^= _perm_randtest(cols, mat->c, state);
fmpz_mat_zero(mat);
for (i = 0; i < n; i++)
fmpz_set(fmpz_mat_entry(mat, rows[i], cols[i]), diag + i);
_perm_clear(rows);
_perm_clear(cols);
return parity;
}

View File

@@ -0,0 +1,48 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_randrank(fmpz_mat_t mat, flint_rand_t state, slong rank,
mp_bitcnt_t bits)
{
slong i;
fmpz * diag;
if (rank < 0 || rank > mat->r || rank > mat->c)
{
flint_printf("Exception (fmpz_mat_randrank). Impossible rank.\n");
abort();
}
diag = _fmpz_vec_init(rank);
for (i = 0; i < rank; i++)
fmpz_randtest_not_zero(&diag[i], state, bits);
fmpz_mat_randpermdiag(mat, state, diag, rank);
_fmpz_vec_clear(diag, rank);
}

View File

@@ -0,0 +1,56 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2005-2009 Damien Stehle
Copyright (C) 2007 David Cade
Copyright (C) 2010 William Hart
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_randsimdioph(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits, mp_bitcnt_t bits2)
{
const slong c = mat->c, r = mat->r;
slong i, j;
if (c != r)
{
flint_printf("Exception (fmpz_mat_randsimdioph). Ill-formed matrix.\n");
abort();
}
fmpz_one(mat->rows[0]);
fmpz_mul_2exp(mat->rows[0], mat->rows[0], bits2);
for (j = 1; j < c; j++)
fmpz_randbits(mat->rows[0] + j, state, bits);
for (i = 1; i < r; i++)
{
for (j = 0; j < i; j++)
fmpz_zero(mat->rows[i] + j);
fmpz_one(mat->rows[i] + i);
fmpz_mul_2exp(mat->rows[i] + i, mat->rows[i] + i, bits);
for (j = i + 1; j < c; j++)
fmpz_zero(mat->rows[i] + j);
}
}

View File

@@ -0,0 +1,39 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 William Hart
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_randtest(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits)
{
slong r, c, i, j;
r = mat->r;
c = mat->c;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
fmpz_randtest(mat->rows[i] + j, state, bits);
}

View File

@@ -0,0 +1,39 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 William Hart
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_randtest_unsigned(fmpz_mat_t mat, flint_rand_t state, mp_bitcnt_t bits)
{
slong r, c, i, j;
r = mat->r;
c = mat->c;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
fmpz_randtest_unsigned(mat->rows[i] + j, state, bits);
}

47
external/flint-2.4.3/fmpz_mat/rank.c vendored Normal file
View File

@@ -0,0 +1,47 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
slong
fmpz_mat_rank(const fmpz_mat_t A)
{
fmpz_mat_t tmp;
fmpz_t den;
slong rank;
if (fmpz_mat_is_empty(A))
return 0;
fmpz_mat_init_set(tmp, A);
fmpz_init(den);
rank = fmpz_mat_fflu(tmp, den, NULL, tmp, 0);
fmpz_mat_clear(tmp);
fmpz_clear(den);
return rank;
}

105
external/flint-2.4.3/fmpz_mat/rref.c vendored Normal file
View File

@@ -0,0 +1,105 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011-2012 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
slong
fmpz_mat_rref(fmpz_mat_t R, fmpz_t den, const fmpz_mat_t A)
{
slong i, j, k, m, n, rank;
slong *pivots, *nonpivots;
rank = fmpz_mat_fflu(R, den, NULL, A, 0);
m = fmpz_mat_nrows(R);
n = fmpz_mat_ncols(R);
/* clear bottom */
for (i = rank; i < m; i++)
for (j = 0; j < n; j++)
fmpz_zero(fmpz_mat_entry(R, i, j));
/* Convert row echelon form to reduced row echelon form */
if (rank > 1)
{
fmpz_t tmp;
fmpz_init(tmp);
pivots = flint_malloc(sizeof(slong) * n);
nonpivots = pivots + rank;
for (i = j = k = 0; i < rank; i++)
{
while (fmpz_is_zero(fmpz_mat_entry(R, i, j)))
{
nonpivots[k] = j;
k++;
j++;
}
pivots[i] = j;
j++;
}
while (k < n - rank)
{
nonpivots[k] = j;
k++;
j++;
}
for (k = 0; k < n - rank; k++)
{
for (i = rank - 2; i >= 0; i--)
{
fmpz_mul(tmp, den, fmpz_mat_entry(R, i, nonpivots[k]));
for (j = i + 1; j < rank; j++)
{
fmpz_submul(tmp, fmpz_mat_entry(R, i, pivots[j]),
fmpz_mat_entry(R, j, nonpivots[k]));
}
fmpz_divexact(fmpz_mat_entry(R, i, nonpivots[k]),
tmp, fmpz_mat_entry(R, i, pivots[i]));
}
}
/* clear pivot columns */
for (i = 0; i < rank; i++)
{
for (j = 0; j < rank; j++)
{
if (i == j)
fmpz_set(fmpz_mat_entry(R, j, pivots[i]), den);
else
fmpz_zero(fmpz_mat_entry(R, j, pivots[i]));
}
}
flint_free(pivots);
fmpz_clear(tmp);
}
return rank;
}

View File

@@ -0,0 +1,98 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
Copyright (C) 2012 Lina Kulakova
******************************************************************************/
#include "fmpz_mat.h"
#define E(j,k) fmpz_mat_entry(A,j,k)
slong
fmpz_mat_rref_mod(slong * perm, fmpz_mat_t A, const fmpz_t p)
{
fmpz_t t, inv;
slong m, n, j, k, rank, r, pivot_row, pivot_col;
if (fmpz_mat_is_empty(A))
{
return 0;
}
m = A->r;
n = A->c;
rank = pivot_row = pivot_col = 0;
fmpz_init(t);
fmpz_init(inv);
while (pivot_row < m && pivot_col < n)
{
r = fmpz_mat_find_pivot_any(A, pivot_row, m, pivot_col);
if (r == -1)
{
pivot_col++;
continue;
}
else if (r != pivot_row)
{
fmpz_mat_swap_rows(A, perm, pivot_row, r);
}
rank++;
fmpz_invmod(inv, E(pivot_row, pivot_col), p);
/* pivot row */
for (k = pivot_col + 1; k < n; k++)
{
fmpz_mul(E(pivot_row, k), E(pivot_row, k), inv);
fmpz_mod(E(pivot_row, k), E(pivot_row, k), p);
}
fmpz_one(E(pivot_row, pivot_col));
/* other rows */
for (j = 0; j < m; j++)
{
if (j == pivot_row)
continue;
for (k = pivot_col + 1; k < n; k++)
{
fmpz_mul(t, E(j, pivot_col), E(pivot_row, k));
fmpz_sub(E(j, k), E(j, k), t);
fmpz_mod(E(j, k), E(j, k), p);
}
fmpz_zero(E(j, pivot_col));
}
pivot_row++;
pivot_col++;
}
fmpz_clear(inv);
fmpz_clear(t);
return rank;
}

View File

@@ -0,0 +1,36 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_scalar_addmul_fmpz(fmpz_mat_t B, const fmpz_mat_t A, const fmpz_t c)
{
slong i, j;
for (i = 0; i < A->r; i++)
for (j = 0; j < A->c; j++)
fmpz_addmul(fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), c);
}

View File

@@ -0,0 +1,37 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_scalar_addmul_nmod_mat_fmpz(fmpz_mat_t B,
const nmod_mat_t A, const fmpz_t c)
{
slong i, j;
for (i = 0; i < A->r; i++)
for (j = 0; j < A->c; j++)
fmpz_addmul_ui(fmpz_mat_entry(B,i,j), c, nmod_mat_entry(A,i,j));
}

View File

@@ -0,0 +1,37 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_scalar_addmul_nmod_mat_ui(fmpz_mat_t B,
const nmod_mat_t A, ulong c)
{
fmpz_t t;
fmpz_init(t);
fmpz_set_ui(t, c);
fmpz_mat_scalar_addmul_nmod_mat_fmpz(B, A, t);
fmpz_clear(t);
}

View File

@@ -0,0 +1,35 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_scalar_addmul_si(fmpz_mat_t B, const fmpz_mat_t A, slong c)
{
if (c > 0)
fmpz_mat_scalar_addmul_ui(B, A, c);
else
fmpz_mat_scalar_submul_ui(B, A, -c);
}

View File

@@ -0,0 +1,36 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_scalar_addmul_ui(fmpz_mat_t B, const fmpz_mat_t A, ulong c)
{
slong i, j;
for (i = 0; i < A->r; i++)
for (j = 0; j < A->c; j++)
fmpz_addmul_ui(fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), c);
}

View File

@@ -0,0 +1,36 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_scalar_divexact_fmpz(fmpz_mat_t B, const fmpz_mat_t A, const fmpz_t c)
{
slong i, j;
for (i = 0; i < A->r; i++)
for (j = 0; j < A->c; j++)
fmpz_divexact(fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), c);
}

View File

@@ -0,0 +1,36 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_scalar_divexact_si(fmpz_mat_t B, const fmpz_mat_t A, slong c)
{
slong i, j;
for (i = 0; i < A->r; i++)
for (j = 0; j < A->c; j++)
fmpz_divexact_si(fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), c);
}

View File

@@ -0,0 +1,36 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_scalar_divexact_ui(fmpz_mat_t B, const fmpz_mat_t A, ulong c)
{
slong i, j;
for (i = 0; i < A->r; i++)
for (j = 0; j < A->c; j++)
fmpz_divexact_ui(fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), c);
}

View File

@@ -0,0 +1,40 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_scalar_mod_fmpz(fmpz_mat_t B, const fmpz_mat_t A, const fmpz_t m)
{
slong i, j;
fmpz_t t;
fmpz_init(t);
for (i = 0; i < A->r; i++)
for (j = 0; j < A->c; j++)
fmpz_fdiv_qr(t, fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), m);
fmpz_clear(t);
}

View File

@@ -0,0 +1,36 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_scalar_mul_fmpz(fmpz_mat_t B, const fmpz_mat_t A, const fmpz_t c)
{
slong i, j;
for (i = 0; i < A->r; i++)
for (j = 0; j < A->c; j++)
fmpz_mul(fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), c);
}

View File

@@ -0,0 +1,36 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_scalar_mul_si(fmpz_mat_t B, const fmpz_mat_t A, slong c)
{
slong i, j;
for (i = 0; i < A->r; i++)
for (j = 0; j < A->c; j++)
fmpz_mul_si(fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), c);
}

View File

@@ -0,0 +1,36 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_scalar_mul_ui(fmpz_mat_t B, const fmpz_mat_t A, ulong c)
{
slong i, j;
for (i = 0; i < A->r; i++)
for (j = 0; j < A->c; j++)
fmpz_mul_ui(fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), c);
}

View File

@@ -0,0 +1,36 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_scalar_submul_fmpz(fmpz_mat_t B, const fmpz_mat_t A, const fmpz_t c)
{
slong i, j;
for (i = 0; i < A->r; i++)
for (j = 0; j < A->c; j++)
fmpz_submul(fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), c);
}

View File

@@ -0,0 +1,35 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_scalar_submul_si(fmpz_mat_t B, const fmpz_mat_t A, slong c)
{
if (c > 0)
fmpz_mat_scalar_submul_ui(B, A, c);
else
fmpz_mat_scalar_addmul_ui(B, A, -c);
}

View File

@@ -0,0 +1,36 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_scalar_submul_ui(fmpz_mat_t B, const fmpz_mat_t A, ulong c)
{
slong i, j;
for (i = 0; i < A->r; i++)
for (j = 0; j < A->c; j++)
fmpz_submul_ui(fmpz_mat_entry(B,i,j), fmpz_mat_entry(A,i,j), c);
}

40
external/flint-2.4.3/fmpz_mat/set.c vendored Normal file
View File

@@ -0,0 +1,40 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2008-2009 William Hart
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_set(fmpz_mat_t mat1, const fmpz_mat_t mat2)
{
if (mat1 != mat2)
{
slong i;
if (mat2->r && mat2->c)
for (i = 0; i < mat2->r; i++)
_fmpz_vec_set(mat1->rows[i], mat2->rows[i], mat2->c);
}
}

View File

@@ -0,0 +1,37 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_set_nmod_mat(fmpz_mat_t A, const nmod_mat_t Amod)
{
slong i, j;
for (i = 0; i < Amod->r; i++)
for (j = 0; j < Amod->c; j++)
fmpz_set_ui_smod(fmpz_mat_entry(A, i, j),
nmod_mat_entry(Amod, i, j), Amod->mod.n);
}

View File

@@ -0,0 +1,36 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_set_nmod_mat_unsigned(fmpz_mat_t A, const nmod_mat_t Amod)
{
slong i, j;
for (i = 0; i < Amod->r; i++)
for (j = 0; j < Amod->c; j++)
fmpz_set_ui(fmpz_mat_entry(A, i, j), nmod_mat_entry(Amod, i, j));
}

37
external/flint-2.4.3/fmpz_mat/solve.c vendored Normal file
View File

@@ -0,0 +1,37 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
#include "perm.h"
int
fmpz_mat_solve(fmpz_mat_t X, fmpz_t den,
const fmpz_mat_t A, const fmpz_mat_t B)
{
if (fmpz_mat_nrows(A) <= 3)
return fmpz_mat_solve_cramer(X, den, A, B);
else
return fmpz_mat_solve_fflu(X, den, A, B);
}

View File

@@ -0,0 +1,63 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_solve_bound(fmpz_t N, fmpz_t D,
const fmpz_mat_t A, const fmpz_mat_t B)
{
slong i, j, m, n;
fmpz_t t, u;
m = B->r;
n = B->c;
fmpz_mat_det_bound(D, A);
fmpz_init(t);
fmpz_init(u);
fmpz_zero(t);
/* Largest column norm of B */
for (j = 0; j < n; j++)
{
fmpz_zero(u);
for (i = 0; i < m; i++)
fmpz_addmul(u, fmpz_mat_entry(B, i, j), fmpz_mat_entry(B, i, j));
if (fmpz_cmp(t, u) < 0)
fmpz_set(t, u);
}
fmpz_sqrtrem(t, u, t);
if (!fmpz_is_zero(u))
fmpz_add_ui(t, t, UWORD(1));
fmpz_mul(N, D, t);
fmpz_clear(t);
fmpz_clear(u);
}

View File

@@ -0,0 +1,172 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
#define AA(i,j) fmpz_mat_entry(A, i, j)
#define BB(i,j) fmpz_mat_entry(B, i, j)
#define XX(i,j) fmpz_mat_entry(X, i, j)
int
_fmpz_mat_solve_cramer_3x3(fmpz_mat_t X, fmpz_t den,
const fmpz_mat_t A, const fmpz_mat_t B)
{
fmpz_t t15, t16, t17;
int success;
fmpz_init(t15);
fmpz_init(t16);
fmpz_init(t17);
fmpz_mul(t17, AA(1,0), AA(2,1));
fmpz_submul(t17, AA(1,1), AA(2,0));
fmpz_mul(t16, AA(1,2), AA(2,0));
fmpz_submul(t16, AA(1,0), AA(2,2));
fmpz_mul(t15, AA(1,1), AA(2,2));
fmpz_submul(t15, AA(1,2), AA(2,1));
fmpz_mul (den, t15, AA(0,0));
fmpz_addmul(den, t16, AA(0,1));
fmpz_addmul(den, t17, AA(0,2));
success = !fmpz_is_zero(den);
if (success)
{
fmpz_t t12, t13, t14, x0, x1, x2;
slong i, n = fmpz_mat_ncols(B);
fmpz_init(t12);
fmpz_init(t13);
fmpz_init(t14);
fmpz_init(x0);
fmpz_init(x1);
fmpz_init(x2);
for (i = 0; i < n; i++)
{
fmpz_mul(t14, AA(2,0), BB(1,i));
fmpz_submul(t14, AA(1,0), BB(2,i));
fmpz_mul(t13, AA(2,1), BB(1,i));
fmpz_submul(t13, AA(1,1), BB(2,i));
fmpz_mul(t12, AA(2,2), BB(1,i));
fmpz_submul(t12, AA(1,2), BB(2,i));
fmpz_mul (x0, t15, BB(0,i));
fmpz_addmul(x0, t13, AA(0,2));
fmpz_submul(x0, t12, AA(0,1));
fmpz_mul (x1, t16, BB(0,i));
fmpz_addmul(x1, t12, AA(0,0));
fmpz_submul(x1, t14, AA(0,2));
fmpz_mul (x2, t17, BB(0,i));
fmpz_addmul(x2, t14, AA(0,1));
fmpz_submul(x2, t13, AA(0,0));
fmpz_swap(XX(0,i), x0);
fmpz_swap(XX(1,i), x1);
fmpz_swap(XX(2,i), x2);
}
fmpz_clear(t12);
fmpz_clear(t13);
fmpz_clear(t14);
fmpz_clear(x0);
fmpz_clear(x1);
fmpz_clear(x2);
}
fmpz_clear(t15);
fmpz_clear(t16);
fmpz_clear(t17);
return success;
}
int
fmpz_mat_solve_cramer(fmpz_mat_t X, fmpz_t den,
const fmpz_mat_t A, const fmpz_mat_t B)
{
slong i, dim = fmpz_mat_nrows(A);
if (dim == 0 || fmpz_mat_ncols(B) == 0)
{
fmpz_one(den);
return 1;
}
else if (dim == 1)
{
fmpz_set(den, fmpz_mat_entry(A, 0, 0));
if (fmpz_is_zero(den))
return 0;
if (!fmpz_mat_is_empty(B))
_fmpz_vec_set(X->rows[0], B->rows[0], fmpz_mat_ncols(B));
return 1;
}
else if (dim == 2)
{
fmpz_t t, u;
_fmpz_mat_det_cofactor_2x2(den, A->rows);
if (fmpz_is_zero(den))
return 0;
fmpz_init(t);
fmpz_init(u);
for (i = 0; i < fmpz_mat_ncols(B); i++)
{
fmpz_mul (t, fmpz_mat_entry(A, 1, 1), fmpz_mat_entry(B, 0, i));
fmpz_submul(t, fmpz_mat_entry(A, 0, 1), fmpz_mat_entry(B, 1, i));
fmpz_mul (u, fmpz_mat_entry(A, 0, 0), fmpz_mat_entry(B, 1, i));
fmpz_submul(u, fmpz_mat_entry(A, 1, 0), fmpz_mat_entry(B, 0, i));
fmpz_swap(fmpz_mat_entry(X, 0, i), t);
fmpz_swap(fmpz_mat_entry(X, 1, i), u);
}
fmpz_clear(t);
fmpz_clear(u);
return 1;
}
else if (dim == 3)
{
return _fmpz_mat_solve_cramer_3x3(X, den, A, B);
}
else
{
flint_printf("Exception (fmpz_mat_solve_cramer). dim > 3 not implemented.");
abort();
}
}

View File

@@ -0,0 +1,251 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
static mp_limb_t
find_good_prime_and_invert(nmod_mat_t Ainv,
const fmpz_mat_t A, const fmpz_t det_bound)
{
mp_limb_t p;
fmpz_t tested;
p = UWORD(1) << NMOD_MAT_OPTIMAL_MODULUS_BITS;
fmpz_init(tested);
fmpz_one(tested);
while (1)
{
p = n_nextprime(p, 0);
_nmod_mat_set_mod(Ainv, p);
fmpz_mat_get_nmod_mat(Ainv, A);
if (nmod_mat_inv(Ainv, Ainv))
break;
fmpz_mul_ui(tested, tested, p);
if (fmpz_cmp(tested, det_bound) > 0)
{
p = 0;
break;
}
}
fmpz_clear(tested);
return p;
}
/* We need to perform several matrix-vector products Ay, and speed them
up by using modular multiplication (this is only faster if we
precompute the modular matrices). Note: we assume that all
primes are >= p. This allows reusing y_mod as the right-hand
side without reducing it. */
#define USE_SLOW_MULTIPLICATION 0
mp_limb_t * get_crt_primes(slong * num_primes, const fmpz_mat_t A, mp_limb_t p)
{
fmpz_t bound, prod;
mp_limb_t * primes;
slong i, j;
fmpz_init(bound);
fmpz_init(prod);
for (i = 0; i < A->r; i++)
for (j = 0; j < A->c; j++)
if (fmpz_cmpabs(bound, fmpz_mat_entry(A, i, j)) < 0)
fmpz_abs(bound, fmpz_mat_entry(A, i, j));
fmpz_mul_ui(bound, bound, p - UWORD(1));
fmpz_mul_ui(bound, bound, A->r);
fmpz_mul_ui(bound, bound, UWORD(2)); /* signs */
primes = flint_malloc(sizeof(mp_limb_t) * (fmpz_bits(bound) /
(FLINT_BIT_COUNT(p) - 1) + 2));
primes[0] = p;
fmpz_set_ui(prod, p);
*num_primes = 1;
while (fmpz_cmp(prod, bound) <= 0)
{
primes[*num_primes] = p = n_nextprime(p, 0);
*num_primes += 1;
fmpz_mul_ui(prod, prod, p);
}
fmpz_clear(bound);
fmpz_clear(prod);
return primes;
}
static void
_fmpz_mat_solve_dixon(fmpz_mat_t X, fmpz_t mod,
const fmpz_mat_t A, const fmpz_mat_t B,
const nmod_mat_t Ainv, mp_limb_t p,
const fmpz_t N, const fmpz_t D)
{
fmpz_t bound, ppow;
fmpz_mat_t x, d, y, Ay;
fmpz_t prod;
mp_limb_t * crt_primes;
nmod_mat_t * A_mod;
nmod_mat_t Ay_mod, d_mod, y_mod;
slong i, n, cols, num_primes;
n = A->r;
cols = B->c;
fmpz_init(bound);
fmpz_init(ppow);
fmpz_init(prod);
fmpz_mat_init(x, n, cols);
fmpz_mat_init(y, n, cols);
fmpz_mat_init(Ay, n, cols);
fmpz_mat_init_set(d, B);
/* Compute bound for the needed modulus. TODO: if one of N and D
is much smaller than the other, we could use a tighter bound (i.e. 2ND).
This would require the ability to forward N and D to the
rational reconstruction routine.
*/
if (fmpz_cmpabs(N, D) < 0)
fmpz_mul(bound, D, D);
else
fmpz_mul(bound, N, N);
fmpz_mul_ui(bound, bound, UWORD(2)); /* signs */
crt_primes = get_crt_primes(&num_primes, A, p);
A_mod = flint_malloc(sizeof(nmod_mat_t) * num_primes);
for (i = 0; i < num_primes; i++)
{
nmod_mat_init(A_mod[i], n, n, crt_primes[i]);
fmpz_mat_get_nmod_mat(A_mod[i], A);
}
nmod_mat_init(Ay_mod, n, cols, UWORD(1));
nmod_mat_init(d_mod, n, cols, p);
nmod_mat_init(y_mod, n, cols, p);
fmpz_one(ppow);
while (fmpz_cmp(ppow, bound) <= 0)
{
/* y = A^(-1) * d (mod p) */
fmpz_mat_get_nmod_mat(d_mod, d);
nmod_mat_mul(y_mod, Ainv, d_mod);
/* x = x + y * p^i [= A^(-1) * b mod p^(i+1)] */
fmpz_mat_scalar_addmul_nmod_mat_fmpz(x, y_mod, ppow);
/* ppow = p^(i+1) */
fmpz_mul_ui(ppow, ppow, p);
if (fmpz_cmp(ppow, bound) > 0)
break;
/* d = (d - Ay) / p */
#if USE_SLOW_MULTIPLICATION
fmpz_mat_set_nmod_mat_unsigned(y, y_mod);
fmpz_mat_mul(Ay, A, y);
#else
for (i = 0; i < num_primes; i++)
{
_nmod_mat_set_mod(y_mod, crt_primes[i]);
_nmod_mat_set_mod(Ay_mod, crt_primes[i]);
nmod_mat_mul(Ay_mod, A_mod[i], y_mod);
if (i == 0)
{
fmpz_mat_set_nmod_mat(Ay, Ay_mod);
fmpz_set_ui(prod, crt_primes[0]);
}
else
{
fmpz_mat_CRT_ui(Ay, Ay, prod, Ay_mod, 1);
fmpz_mul_ui(prod, prod, crt_primes[i]);
}
}
#endif
_nmod_mat_set_mod(y_mod, p);
fmpz_mat_sub(d, d, Ay);
fmpz_mat_scalar_divexact_ui(d, d, p);
}
fmpz_set(mod, ppow);
fmpz_mat_set(X, x);
nmod_mat_clear(y_mod);
nmod_mat_clear(d_mod);
nmod_mat_clear(Ay_mod);
for (i = 0; i < num_primes; i++)
nmod_mat_clear(A_mod[i]);
flint_free(A_mod);
flint_free(crt_primes);
fmpz_clear(bound);
fmpz_clear(ppow);
fmpz_clear(prod);
fmpz_mat_clear(x);
fmpz_mat_clear(y);
fmpz_mat_clear(d);
fmpz_mat_clear(Ay);
}
int
fmpz_mat_solve_dixon(fmpz_mat_t X, fmpz_t mod,
const fmpz_mat_t A, const fmpz_mat_t B)
{
nmod_mat_t Ainv;
fmpz_t N, D;
mp_limb_t p;
if (!fmpz_mat_is_square(A))
{
flint_printf("Exception (fmpz_mat_solve_dixon). Non-square system matrix.\n");
abort();
}
if (fmpz_mat_is_empty(A) || fmpz_mat_is_empty(B))
return 1;
fmpz_init(N);
fmpz_init(D);
fmpz_mat_solve_bound(N, D, A, B);
nmod_mat_init(Ainv, A->r, A->r, 1);
p = find_good_prime_and_invert(Ainv, A, D);
if (p != 0)
_fmpz_mat_solve_dixon(X, mod, A, B, Ainv, p, N, D);
nmod_mat_clear(Ainv);
fmpz_clear(N);
fmpz_clear(D);
return p != 0;
}

View File

@@ -0,0 +1,56 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
#include "perm.h"
int
fmpz_mat_solve_fflu(fmpz_mat_t X, fmpz_t den,
const fmpz_mat_t A, const fmpz_mat_t B)
{
fmpz_mat_t LU;
slong dim, *perm;
int result;
if (fmpz_mat_is_empty(A) || fmpz_mat_is_empty(B))
{
fmpz_one(den);
return 1;
}
dim = fmpz_mat_nrows(A);
perm = _perm_init(dim);
fmpz_mat_init_set(LU, A);
result = (fmpz_mat_fflu(LU, den, perm, LU, 1) == dim);
if (result)
fmpz_mat_solve_fflu_precomp(X, perm, LU, B);
else
fmpz_zero(den);
_perm_clear(perm);
fmpz_mat_clear(LU);
return result;
}

View File

@@ -0,0 +1,97 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
#define XX(ii,jj) fmpz_mat_entry(X,(ii),(jj))
#define BB(ii,jj) fmpz_mat_entry(B,(ii),(jj))
#define LU(ii,jj) fmpz_mat_entry(FFLU,(ii),(jj))
void
fmpz_mat_set_perm(fmpz_mat_t X, const slong * perm, const fmpz_mat_t B)
{
if (X == B)
{
/* Not implemented */
abort();
}
else
{
slong i, j;
if (perm == NULL)
abort();
for (i = 0; i < fmpz_mat_nrows(B); i++)
for (j = 0; j < fmpz_mat_ncols(B); j++)
fmpz_set(fmpz_mat_entry(X, i, j),
fmpz_mat_entry(B, perm[i], j));
}
}
void
fmpz_mat_solve_fflu_precomp(fmpz_mat_t X,
const slong * perm,
const fmpz_mat_t FFLU, const fmpz_mat_t B)
{
fmpz_t T;
slong i, j, k, m, n;
n = X->r;
m = X->c;
fmpz_init(T);
fmpz_mat_set_perm(X, perm, B);
for (k = 0; k < m; k++)
{
/* Fraction-free forward substitution */
for (i = 0; i < n - 1; i++)
{
for (j = i + 1; j < n; j++)
{
fmpz_mul(XX(j, k), XX(j, k), LU(i, i));
fmpz_mul(T, LU(j, i), XX(i, k));
fmpz_sub(XX(j, k), XX(j, k), T);
if (i > 0)
fmpz_divexact(XX(j, k), XX(j, k), LU(i-1, i-1));
}
}
/* Fraction-free back substitution */
for (i = n - 2; i >= 0; i--)
{
fmpz_mul(XX(i, k), XX(i, k), LU(n-1, n-1));
for (j = i + 1; j < n; j++)
{
fmpz_mul(T, XX(j, k), LU(i, j));
fmpz_sub(XX(i, k), XX(i, k), T);
}
fmpz_divexact(XX(i, k), XX(i, k), LU(i, i));
}
}
fmpz_clear(T);
}

69
external/flint-2.4.3/fmpz_mat/sqr.c vendored Normal file
View File

@@ -0,0 +1,69 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2012 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
#define E fmpz_mat_entry
void
fmpz_mat_sqr(fmpz_mat_t B, const fmpz_mat_t A)
{
slong n = A->r;
if (n == 0)
{
return;
}
else if (n == 1)
{
fmpz_mul(E(B, 0, 0), E(A, 0, 0), E(A, 0, 0));
}
else if (n == 2)
{
fmpz_t t, u;
fmpz_init(t);
fmpz_init(u);
fmpz_add(t, E(A, 0, 0), E(A, 1, 1));
fmpz_mul(u, E(A, 0, 1), E(A, 1, 0));
fmpz_mul(E(B, 0, 0), E(A, 0, 0), E(A, 0, 0));
fmpz_add(E(B, 0, 0), E(B, 0, 0), u);
fmpz_mul(E(B, 1, 1), E(A, 1, 1), E(A, 1, 1));
fmpz_add(E(B, 1, 1), E(B, 1, 1), u);
fmpz_mul(E(B, 0, 1), E(A, 0, 1), t);
fmpz_mul(E(B, 1, 0), E(A, 1, 0), t);
fmpz_clear(t);
fmpz_clear(u);
}
else
{
fmpz_mat_mul(B, A, A);
}
}

38
external/flint-2.4.3/fmpz_mat/sub.c vendored Normal file
View File

@@ -0,0 +1,38 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_sub(fmpz_mat_t res, const fmpz_mat_t mat1, const fmpz_mat_t mat2)
{
slong i;
if (res->c < 1)
return;
for (i = 0; i < res->r; i++)
_fmpz_vec_sub(res->rows[i], mat1->rows[i], mat2->rows[i], res->c);
}

39
external/flint-2.4.3/fmpz_mat/swap.c vendored Normal file
View File

@@ -0,0 +1,39 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include "fmpz_mat.h"
void
fmpz_mat_swap(fmpz_mat_t mat1, fmpz_mat_t mat2)
{
if (mat1 != mat2)
{
fmpz_mat_struct tmp;
tmp = *mat1;
*mat1 = *mat2;
*mat2 = tmp;
}
}

View File

@@ -0,0 +1,119 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2007 William Hart and David Harvey
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_mat.h"
#include "nmod_mat.h"
int
main(void)
{
int i;
FLINT_TEST_INIT(state);
flint_printf("CRT_ui....");
fflush(stdout);
for (i = 0; i < 1000 * flint_test_multiplier(); i++)
{
slong bits, prime_bits, rows, cols, num_primes, j;
fmpz_t mod;
fmpz_mat_t A, B, C;
nmod_mat_t Amod;
mp_limb_t primes[1000];
bits = n_randint(state, 500) + 1;
rows = n_randint(state, 10);
cols = n_randint(state, 10);
prime_bits = 1 + n_randint(state, FLINT_BITS - 1);
fmpz_mat_init(A, rows, cols);
fmpz_mat_init(B, rows, cols);
fmpz_mat_init(C, rows, cols);
fmpz_mat_randtest(A, state, bits);
fmpz_init(mod);
num_primes = 0;
primes[0] = n_nextprime(UWORD(1) << prime_bits, 0);
fmpz_set_ui(mod, primes[0]);
/* + 1 for sign */
while (fmpz_bits(mod) <= bits + 1)
{
primes[num_primes + 1] = n_nextprime(primes[num_primes], 0);
fmpz_mul_ui(mod, mod, primes[num_primes + 1]);
num_primes++;
}
num_primes++;
nmod_mat_init(Amod, rows, cols, primes[0]);
fmpz_mat_get_nmod_mat(Amod, A);
fmpz_mat_set_nmod_mat(B, Amod);
fmpz_set_ui(mod, primes[0]);
for (j = 1; j < num_primes; j++)
{
nmod_mat_clear(Amod);
nmod_mat_init(Amod, rows, cols, primes[j]);
fmpz_mat_get_nmod_mat(Amod, A);
fmpz_mat_CRT_ui(B, B, mod, Amod, 1);
fmpz_mul_ui(mod, mod, primes[j]);
}
if (!fmpz_mat_equal(B, A))
{
flint_printf("FAIL!\n");
flint_printf("primes: ");
for (j = 0; j < num_primes; j++)
flint_printf("%wu ", primes[j]);
flint_printf("\nA: \n");
fmpz_mat_print_pretty(A);
flint_printf("\nB: \n");
fmpz_mat_print_pretty(B);
flint_printf("\n");
abort();
}
nmod_mat_clear(Amod);
fmpz_mat_clear(A);
fmpz_mat_clear(B);
fmpz_mat_clear(C);
fmpz_clear(mod);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,118 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2007 William Hart and David Harvey
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_mat.h"
#include "nmod_mat.h"
int
main(void)
{
int i;
FLINT_TEST_INIT(state);
flint_printf("CRT_ui_unsigned....");
fflush(stdout);
for (i = 0; i < 1000 * flint_test_multiplier(); i++)
{
slong bits, prime_bits, rows, cols, num_primes, j;
fmpz_t mod;
fmpz_mat_t A, B, C;
nmod_mat_t Amod;
mp_limb_t primes[1000];
bits = n_randint(state, 500) + 1;
rows = n_randint(state, 10);
cols = n_randint(state, 10);
prime_bits = 1 + n_randint(state, FLINT_BITS - 1);
fmpz_mat_init(A, rows, cols);
fmpz_mat_init(B, rows, cols);
fmpz_mat_init(C, rows, cols);
fmpz_mat_randtest_unsigned(A, state, bits);
fmpz_init(mod);
num_primes = 0;
primes[0] = n_nextprime(UWORD(1) << prime_bits, 0);
fmpz_set_ui(mod, primes[0]);
while (fmpz_bits(mod) <= bits)
{
primes[num_primes + 1] = n_nextprime(primes[num_primes], 0);
fmpz_mul_ui(mod, mod, primes[num_primes + 1]);
num_primes++;
}
num_primes++;
nmod_mat_init(Amod, rows, cols, primes[0]);
fmpz_mat_get_nmod_mat(Amod, A);
fmpz_mat_set_nmod_mat_unsigned(B, Amod);
fmpz_set_ui(mod, primes[0]);
for (j = 1; j < num_primes; j++)
{
nmod_mat_clear(Amod);
nmod_mat_init(Amod, rows, cols, primes[j]);
fmpz_mat_get_nmod_mat(Amod, A);
fmpz_mat_CRT_ui(B, B, mod, Amod, 0);
fmpz_mul_ui(mod, mod, primes[j]);
}
if (!fmpz_mat_equal(B, A))
{
flint_printf("FAIL!\n");
flint_printf("primes: ");
for (j = 0; j < num_primes; j++)
flint_printf("%wu ", primes[j]);
flint_printf("\nA: \n");
fmpz_mat_print_pretty(A);
flint_printf("\nB: \n");
fmpz_mat_print_pretty(B);
flint_printf("\n");
abort();
}
nmod_mat_clear(Amod);
fmpz_mat_clear(A);
fmpz_mat_clear(B);
fmpz_mat_clear(C);
fmpz_clear(mod);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,81 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_mat.h"
#include "ulong_extras.h"
int
main(void)
{
slong m, n, rep;
FLINT_TEST_INIT(state);
flint_printf("add/sub/neg....");
fflush(stdout);
for (rep = 0; rep < 1000 * flint_test_multiplier(); rep++)
{
fmpz_mat_t A;
fmpz_mat_t B;
fmpz_mat_t C;
m = n_randint(state, 20);
n = n_randint(state, 20);
fmpz_mat_init(A, m, n);
fmpz_mat_init(B, m, n);
fmpz_mat_init(C, m, n);
fmpz_mat_randtest(A, state, 100);
fmpz_mat_randtest(B, state, 100);
fmpz_mat_neg(C, A);
fmpz_mat_add(A, A, B);
fmpz_mat_sub(A, A, B);
fmpz_mat_neg(A, A);
if (!fmpz_mat_equal(A, C))
{
flint_printf("FAIL: matrices not equal!\n");
abort();
}
fmpz_mat_clear(A);
fmpz_mat_clear(B);
fmpz_mat_clear(C);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,92 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
Copyright (C) 2012 Sebastian Pancratz
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_mat.h"
#include "ulong_extras.h"
int
main(void)
{
slong m, n, rep;
FLINT_TEST_INIT(state);
flint_printf("charpoly....");
fflush(stdout);
for (rep = 0; rep < 1000 * flint_test_multiplier(); rep++)
{
fmpz_mat_t A, B, C, D;
fmpz_poly_t f, g;
m = n_randint(state, 4);
n = m;
fmpz_mat_init(A, m, n);
fmpz_mat_init(B, m, n);
fmpz_mat_init(C, m, m);
fmpz_mat_init(D, n, n);
fmpz_poly_init(f);
fmpz_poly_init(g);
fmpz_mat_randtest(A, state, 10);
fmpz_mat_randtest(B, state, 10);
fmpz_mat_mul(C, A, B);
fmpz_mat_mul(D, B, A);
fmpz_mat_charpoly(f, C);
fmpz_mat_charpoly(g, D);
if (!fmpz_poly_equal(f, g))
{
flint_printf("FAIL: charpoly(AB) != charpoly(BA).\n");
flint_printf("Matrix A:\n"), fmpz_mat_print(A), flint_printf("\n");
flint_printf("Matrix B:\n"), fmpz_mat_print(B), flint_printf("\n");
flint_printf("cp(AB) = "), fmpz_poly_print_pretty(f, "X"), flint_printf("\n");
flint_printf("cp(BA) = "), fmpz_poly_print_pretty(g, "X"), flint_printf("\n");
abort();
}
fmpz_mat_clear(A);
fmpz_mat_clear(B);
fmpz_mat_clear(C);
fmpz_mat_clear(D);
fmpz_poly_clear(f);
fmpz_poly_clear(g);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,110 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_vec.h"
#include "fmpz_mat.h"
#include "ulong_extras.h"
int
main(void)
{
fmpz_mat_t A;
slong i, m;
fmpz_t det, result;
FLINT_TEST_INIT(state);
flint_printf("det....");
fflush(stdout);
for (i = 0; i < 1000 * flint_test_multiplier(); i++)
{
m = n_randint(state, 10);
fmpz_mat_init(A, m, m);
fmpz_init(det);
fmpz_init(result);
if (m)
fmpz_randtest(det, state, 30);
else
fmpz_set_ui(det, UWORD(1));
fmpz_mat_randdet(A, state, det);
fmpz_mat_randops(A, state, n_randint(state, 2*m*m + 1));
fmpz_mat_det(result, A);
if (!fmpz_equal(det, result))
{
flint_printf("FAIL:\n");
flint_printf("wrong determinant!\n");
fmpz_mat_print_pretty(A), flint_printf("\n");
flint_printf("expected: "), fmpz_print(det), flint_printf("\n");
flint_printf("ncomputed: "), fmpz_print(result), flint_printf("\n");
abort();
}
fmpz_mat_clear(A);
fmpz_clear(det);
fmpz_clear(result);
}
/* Generate nontrivial singular matrices */
for (i = 0; i < 10000; i++)
{
m = 2 + n_randint(state, 10);
fmpz_mat_init(A, m, m);
fmpz_init(det);
fmpz_mat_randrank(A, state, 1+n_randint(state, m - 1), 1+n_randint(state, 10));
fmpz_mat_randops(A, state, n_randint(state, 2*m*m + 1));
fmpz_mat_det(det, A);
if (*det)
{
flint_printf("FAIL:\n");
flint_printf("expected zero determinant!\n");
fmpz_mat_print_pretty(A), flint_printf("\n");
abort();
}
fmpz_mat_clear(A);
fmpz_clear(det);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,82 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_vec.h"
#include "fmpz_mat.h"
#include "ulong_extras.h"
int
main(void)
{
fmpz_mat_t A;
slong i, m;
fmpz_t det, bound;
FLINT_TEST_INIT(state);
flint_printf("det_bound....");
fflush(stdout);
for (i = 0; i < 1000 * flint_test_multiplier(); i++)
{
m = n_randint(state, 10);
fmpz_mat_init(A, m, m);
fmpz_init(det);
fmpz_init(bound);
fmpz_mat_randtest(A, state, 1+n_randint(state,200));
fmpz_mat_det(det, A);
fmpz_mat_det_bound(bound, A);
if (fmpz_cmp(det, bound) > 0)
{
flint_printf("FAIL:\n");
flint_printf("bound too small!\n");
fmpz_mat_print_pretty(A), flint_printf("\n");
flint_printf("det: "), fmpz_print(det), flint_printf("\n");
flint_printf("bound: "), fmpz_print(bound), flint_printf("\n");
abort();
}
fmpz_clear(det);
fmpz_clear(bound);
fmpz_mat_clear(A);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,106 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_vec.h"
#include "fmpz_mat.h"
#include "ulong_extras.h"
int
main(void)
{
slong i;
int result;
FLINT_TEST_INIT(state);
flint_printf("det_divisor....");
fflush(stdout);
for (i = 0; i < 1000 * flint_test_multiplier(); i++)
{
fmpz_mat_t A;
fmpz_t det, d, q, r;
slong m, bits;
m = n_randint(state, 15);
bits = 1 + n_randint(state, 50);
fmpz_init(det);
fmpz_init(d);
fmpz_init(q);
fmpz_init(r);
fmpz_mat_init(A, m, m);
if (i % 3 == 0 && m > 1)
{
/* Generate a nontrivial singular matrix */
fmpz_mat_randrank(A, state, 1 + n_randint(state, m - 1), bits);
fmpz_mat_randops(A, state, n_randint(state, 2*m*m + 1));
}
else
{
fmpz_mat_randtest(A, state, bits);
}
fmpz_mat_det_divisor(d, A);
fmpz_mat_det_bareiss(det, A);
if (fmpz_is_zero(det) || fmpz_is_zero(d))
{
result = fmpz_equal(det, d);
}
else
{
fmpz_fdiv_qr(q, r, det, d);
result = fmpz_is_zero(r) && (fmpz_sgn(d) > 0);
}
if (!result)
{
flint_printf("FAIL:\n");
fmpz_mat_print_pretty(A), flint_printf("\n");
flint_printf("det: "); fmpz_print(det); flint_printf("\n");
flint_printf("d: "); fmpz_print(d); flint_printf("\n");
abort();
}
fmpz_mat_clear(A);
fmpz_clear(det);
fmpz_clear(d);
fmpz_clear(q);
fmpz_clear(r);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,107 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_vec.h"
#include "fmpz_mat.h"
#include "ulong_extras.h"
int
main(void)
{
fmpz_mat_t A;
slong i, m;
fmpz_t det1, det2;
FLINT_TEST_INIT(state);
flint_printf("det_modular....");
fflush(stdout);
for (i = 0; i < 1000 * flint_test_multiplier(); i++)
{
int proved = n_randlimb(state) % 2;
m = n_randint(state, 10);
fmpz_mat_init(A, m, m);
fmpz_init(det1);
fmpz_init(det2);
fmpz_mat_randtest(A, state, 1+n_randint(state,200));
fmpz_mat_det_bareiss(det1, A);
fmpz_mat_det_modular(det2, A, proved);
if (!fmpz_equal(det1, det2))
{
flint_printf("FAIL:\n");
flint_printf("different determinants!\n");
fmpz_mat_print_pretty(A), flint_printf("\n");
flint_printf("det1: "), fmpz_print(det1), flint_printf("\n");
flint_printf("det2: "), fmpz_print(det2), flint_printf("\n");
abort();
}
fmpz_clear(det1);
fmpz_clear(det2);
fmpz_mat_clear(A);
}
for (i = 0; i < 10000; i++)
{
int proved = n_randlimb(state) % 2;
m = 2 + n_randint(state, 10);
fmpz_mat_init(A, m, m);
fmpz_init(det2);
fmpz_mat_randrank(A, state, 1+n_randint(state, m - 1),
1+n_randint(state, 10));
fmpz_mat_randops(A, state, n_randint(state, 2*m*m + 1));
fmpz_mat_det_modular(det2, A, proved);
if (!fmpz_is_zero(det2))
{
flint_printf("FAIL:\n");
flint_printf("expected zero determinant!\n");
fmpz_mat_print_pretty(A), flint_printf("\n");
abort();
}
fmpz_mat_clear(A);
fmpz_clear(det2);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,107 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_vec.h"
#include "fmpz_mat.h"
#include "ulong_extras.h"
int
main(void)
{
fmpz_mat_t A;
slong i, m;
fmpz_t det1, det2;
FLINT_TEST_INIT(state);
flint_printf("det_modular_accelerated....");
fflush(stdout);
for (i = 0; i < 1000 * flint_test_multiplier(); i++)
{
int proved = n_randlimb(state) % 2;
m = n_randint(state, 10);
fmpz_mat_init(A, m, m);
fmpz_init(det1);
fmpz_init(det2);
fmpz_mat_randtest(A, state, 1+n_randint(state,200));
fmpz_mat_det_bareiss(det1, A);
fmpz_mat_det_modular_accelerated(det2, A, proved);
if (!fmpz_equal(det1, det2))
{
flint_printf("FAIL:\n");
flint_printf("different determinants!\n");
fmpz_mat_print_pretty(A), flint_printf("\n");
flint_printf("det1: "), fmpz_print(det1), flint_printf("\n");
flint_printf("det2: "), fmpz_print(det2), flint_printf("\n");
abort();
}
fmpz_clear(det1);
fmpz_clear(det2);
fmpz_mat_clear(A);
}
for (i = 0; i < 10000; i++)
{
int proved = n_randlimb(state) % 2;
m = 2 + n_randint(state, 10);
fmpz_mat_init(A, m, m);
fmpz_init(det2);
fmpz_mat_randrank(A, state, 1+n_randint(state, m - 1),
1+n_randint(state, 10));
fmpz_mat_randops(A, state, n_randint(state, 2*m*m + 1));
fmpz_mat_det_modular_accelerated(det2, A, proved);
if (!fmpz_is_zero(det2))
{
flint_printf("FAIL:\n");
flint_printf("expected zero determinant!\n");
fmpz_mat_print_pretty(A), flint_printf("\n");
abort();
}
fmpz_mat_clear(A);
fmpz_clear(det2);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,82 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 William Hart
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_mat.h"
#include "ulong_extras.h"
int
main(void)
{
int i;
FLINT_TEST_INIT(state);
flint_printf("entry....");
fflush(stdout);
for (i = 0; i < 1000 * flint_test_multiplier(); i++)
{
fmpz_mat_t a;
slong j, k;
slong rows = n_randint(state, 10);
slong cols = n_randint(state, 10);
fmpz_mat_init(a, rows, cols);
for (j = 0; j < rows; j++)
{
for (k = 0; k < cols; k++)
{
fmpz_set_ui(fmpz_mat_entry(a,j,k), 3*j + 7*k);
}
}
for (j = 0; j < rows; j++)
{
for (k = 0; k < cols; k++)
{
if (fmpz_get_ui(fmpz_mat_entry(a,j,k)) != 3*j + 7*k)
{
flint_printf("FAIL: get/set entry %wd,%wd\n", j, k);
abort();
}
}
}
fmpz_mat_clear(a);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,97 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 William Hart
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_mat.h"
#include "ulong_extras.h"
int
main(void)
{
int i;
FLINT_TEST_INIT(state);
flint_printf("equal....");
fflush(stdout);
for (i = 0; i < 1000 * flint_test_multiplier(); i++)
{
fmpz_mat_t A, B, C, D, E;
slong m, n, j;
m = n_randint(state, 20);
n = n_randint(state, 20);
fmpz_mat_init(A, m, n);
fmpz_mat_init(B, m, n);
fmpz_mat_init(C, m, n);
fmpz_mat_init(D, m+1, n);
fmpz_mat_init(E, m, n+1);
if (fmpz_mat_equal(A, D) || fmpz_mat_equal(A, E))
{
flint_printf("FAIL: different dimensions should not be equal\n");
abort();
}
fmpz_mat_randtest(A, state, 1 + n_randint(state, 100));
fmpz_mat_set(B, A);
if (!fmpz_mat_equal(A, B))
{
flint_printf("FAIL: copied matrices should be equal\n");
abort();
}
if (m && n)
{
j = n_randint(state, m*n);
fmpz_add_ui(A->entries + j, A->entries + j, 1);
if (fmpz_mat_equal(A, B))
{
flint_printf("FAIL: modified matrices should not be equal\n");
abort();
}
}
fmpz_mat_clear(A);
fmpz_mat_clear(B);
fmpz_mat_clear(C);
fmpz_mat_clear(D);
fmpz_mat_clear(E);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,87 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_mat.h"
#include "nmod_mat.h"
#include "ulong_extras.h"
int
main(void)
{
int i;
FLINT_TEST_INIT(state);
flint_printf("get/set_nmod_mat....");
fflush(stdout);
for (i = 0; i < 1000 * flint_test_multiplier(); i++)
{
fmpz_mat_t A;
nmod_mat_t M, M2;
slong rows, cols;
mp_limb_t mod;
rows = n_randint(state, 50);
cols = n_randint(state, 50);
mod = n_randtest_prime(state, 0);
nmod_mat_init(M, rows, cols, mod);
nmod_mat_init(M2, rows, cols, mod);
fmpz_mat_init(A, rows, cols);
nmod_mat_randtest(M, state);
if (i % 2 == 0)
fmpz_mat_set_nmod_mat(A, M);
else
fmpz_mat_set_nmod_mat_unsigned(A, M);
fmpz_mat_scalar_mul_ui(A, A, UWORD(2));
nmod_mat_add(M, M, M);
fmpz_mat_get_nmod_mat(M2, A);
if (!nmod_mat_equal(M, M2))
{
flint_printf("FAIL!\n");
abort();
}
fmpz_mat_clear(A);
nmod_mat_clear(M);
nmod_mat_clear(M2);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,65 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 William Hart
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_mat.h"
#include "ulong_extras.h"
int
main(void)
{
int i;
FLINT_TEST_INIT(state);
flint_printf("init/clear....");
fflush(stdout);
for (i = 0; i < 1000 * flint_test_multiplier(); i++)
{
fmpz_mat_t a;
slong j, k;
slong rows = n_randint(state, 100);
slong cols = n_randint(state, 100);
fmpz_mat_init(a, rows, cols);
for (j = 0; j < rows; j++)
for (k = 0; k < cols; k++)
fmpz_zero(a->rows[j] + k);
fmpz_mat_clear(a);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,148 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_vec.h"
#include "fmpz_mat.h"
#include "ulong_extras.h"
int
main(void)
{
fmpz_mat_t A, B, C, I;
fmpz_t den;
slong i, j, m, r;
FLINT_TEST_INIT(state);
flint_printf("inv....");
fflush(stdout);
for (i = 0; i < 1000 * flint_test_multiplier(); i++)
{
m = n_randint(state, 10);
fmpz_mat_init(A, m, m);
fmpz_mat_init(B, m, m);
fmpz_mat_init(C, m, m);
fmpz_mat_init(I, m, m);
fmpz_init(den);
for (j = 0; j < m; j++)
fmpz_set_ui(&I->rows[j][j], UWORD(1));
/* Verify that A * A^-1 = I for random matrices */
fmpz_mat_randrank(A, state, m, 1+n_randint(state, 2)*n_randint(state, 100));
/* Dense or sparse? */
if (n_randint(state, 2))
fmpz_mat_randops(A, state, 1+n_randint(state, 1 + m*m));
fmpz_mat_inv(B, den, A);
fmpz_mat_mul(C, A, B);
_fmpz_vec_scalar_divexact_fmpz(C->entries, C->entries, m*m, den);
if (!fmpz_mat_equal(C, I))
{
flint_printf("FAIL:\n");
flint_printf("A * A^-1 != I!\n");
flint_printf("A:\n"), fmpz_mat_print_pretty(A), flint_printf("\n");
flint_printf("A^-1:\n"), fmpz_mat_print_pretty(B), flint_printf("\n");
flint_printf("den(A^-1) = "), fmpz_print(den), flint_printf("\n");
flint_printf("A * A^-1:\n"), fmpz_mat_print_pretty(C), flint_printf("\n");
abort();
}
/* Test aliasing */
fmpz_mat_set(C, A);
fmpz_mat_inv(A, den, A);
fmpz_mat_mul(B, A, C);
_fmpz_vec_scalar_divexact_fmpz(B->entries, B->entries, m*m, den);
if (!fmpz_mat_equal(B, I))
{
flint_printf("FAIL:\n");
flint_printf("aliasing failed!\n");
fmpz_mat_print(C); flint_printf("\n");
abort();
}
fmpz_mat_clear(A);
fmpz_mat_clear(B);
fmpz_mat_clear(C);
fmpz_mat_clear(I);
fmpz_clear(den);
}
/* Test singular matrices */
/* Test singular systems */
for (i = 0; i < 1000 * flint_test_multiplier(); i++)
{
m = 1 + n_randint(state, 10);
r = n_randint(state, m);
fmpz_mat_init(A, m, m);
fmpz_mat_init(B, m, m);
fmpz_init(den);
fmpz_mat_randrank(A, state, r, 1+n_randint(state, 2)*n_randint(state, 100));
/* Dense */
if (n_randint(state, 2))
fmpz_mat_randops(A, state, 1+n_randint(state, 1 + m*m));
fmpz_mat_inv(B, den, A);
if (!fmpz_is_zero(den))
{
flint_printf("FAIL:\n");
flint_printf("singular system gave nonzero denominator\n");
abort();
}
/* Aliasing */
fmpz_mat_inv(A, den, A);
if (!fmpz_is_zero(den))
{
flint_printf("FAIL:\n");
flint_printf("singular system gave nonzero denominator\n");
abort();
}
fmpz_mat_clear(A);
fmpz_mat_clear(B);
fmpz_clear(den);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,65 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_mat.h"
#include "ulong_extras.h"
int
main(void)
{
int i;
FLINT_TEST_INIT(state);
flint_printf("is_empty....");
fflush(stdout);
for (i = 0; i < 1000 * flint_test_multiplier(); i++)
{
fmpz_mat_t A;
slong rows = n_randint(state, 10);
slong cols = n_randint(state, 10);
fmpz_mat_init(A, rows, cols);
if (fmpz_mat_is_empty(A) != (rows == 0 || cols == 0))
{
flint_printf("FAIL!\n");
abort();
}
fmpz_mat_clear(A);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,65 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_mat.h"
#include "ulong_extras.h"
int
main(void)
{
int i;
FLINT_TEST_INIT(state);
flint_printf("is_square....");
fflush(stdout);
for (i = 0; i < 1000 * flint_test_multiplier(); i++)
{
fmpz_mat_t A;
slong rows = n_randint(state, 10);
slong cols = n_randint(state, 10);
fmpz_mat_init(A, rows, cols);
if (fmpz_mat_is_square(A) != (rows == cols))
{
flint_printf("FAIL!\n");
abort();
}
fmpz_mat_clear(A);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,76 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_mat.h"
#include "ulong_extras.h"
int
main(void)
{
int i;
FLINT_TEST_INIT(state);
flint_printf("is_zero....");
fflush(stdout);
for (i = 0; i < 1000 * flint_test_multiplier(); i++)
{
fmpz_mat_t A;
slong rows = n_randint(state, 10);
slong cols = n_randint(state, 10);
fmpz_mat_init(A, rows, cols);
if (!fmpz_mat_is_zero(A))
{
flint_printf("FAIL!\n");
abort();
}
if (rows && cols)
{
fmpz_mat_randrank(A, state, FLINT_MIN(rows, cols), 100);
if (fmpz_mat_is_zero(A))
{
flint_printf("FAIL!\n");
abort();
}
}
fmpz_mat_clear(A);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,72 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_mat.h"
#include "fmpz_vec.h"
#include "ulong_extras.h"
int
main(void)
{
slong m, n, rep, res1, res2;
FLINT_TEST_INIT(state);
flint_printf("max_bits....");
fflush(stdout);
for (rep = 0; rep < 100 * flint_test_multiplier(); rep++)
{
fmpz_mat_t A;
m = n_randint(state, 20);
n = n_randint(state, 20);
fmpz_mat_init(A, m, n);
fmpz_mat_randtest(A, state, 1 + n_randint(state, 100));
res1 = fmpz_mat_max_bits(A);
res2 = _fmpz_vec_max_bits(A->entries, m*n);
if (res1 != res2)
{
flint_printf("FAIL!\n");
abort();
}
fmpz_mat_clear(A);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,92 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_vec.h"
#include "fmpz_mat.h"
#include "ulong_extras.h"
int main(void)
{
fmpz_mat_t A, B, C, D;
slong i;
FLINT_TEST_INIT(state);
flint_printf("mul....");
fflush(stdout);
for (i = 0; i < 100 * flint_test_multiplier(); i++)
{
slong m, n, k;
m = n_randint(state, 50);
n = n_randint(state, 50);
k = n_randint(state, 50);
fmpz_mat_init(A, m, n);
fmpz_mat_init(B, n, k);
fmpz_mat_init(C, m, k);
fmpz_mat_init(D, m, k);
fmpz_mat_randtest(A, state, n_randint(state, 200) + 1);
fmpz_mat_randtest(B, state, n_randint(state, 200) + 1);
/* Make sure noise in the output is ok */
fmpz_mat_randtest(C, state, n_randint(state, 200) + 1);
fmpz_mat_mul(C, A, B);
fmpz_mat_mul_classical_inline(D, A, B);
if (!fmpz_mat_equal(C, D))
{
flint_printf("FAIL: results not equal\n");
abort();
}
fmpz_mat_mul(A, A, B);
if (!fmpz_mat_equal(A, C))
{
flint_printf("FAIL: aliasing failed\n");
abort();
}
fmpz_mat_clear(A);
fmpz_mat_clear(B);
fmpz_mat_clear(C);
fmpz_mat_clear(D);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,84 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_vec.h"
#include "fmpz_mat.h"
#include "ulong_extras.h"
int main(void)
{
fmpz_mat_t A, B, C, D;
slong i;
FLINT_TEST_INIT(state);
flint_printf("mul_classical....");
fflush(stdout);
for (i = 0; i < 100 * flint_test_multiplier(); i++)
{
slong m, n, k;
m = n_randint(state, 50);
n = n_randint(state, 50);
k = n_randint(state, 50);
fmpz_mat_init(A, m, n);
fmpz_mat_init(B, n, k);
fmpz_mat_init(C, m, k);
fmpz_mat_init(D, m, k);
fmpz_mat_randtest(A, state, n_randint(state, 200) + 1);
fmpz_mat_randtest(B, state, n_randint(state, 200) + 1);
/* Make sure noise in the output is ok */
fmpz_mat_randtest(C, state, n_randint(state, 200) + 1);
fmpz_mat_mul_classical(C, A, B);
fmpz_mat_mul_classical_inline(D, A, B);
if (!fmpz_mat_equal(C, D))
{
flint_printf("FAIL: results not equal\n");
abort();
}
fmpz_mat_clear(A);
fmpz_mat_clear(B);
fmpz_mat_clear(C);
fmpz_mat_clear(D);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,84 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2010 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_vec.h"
#include "fmpz_mat.h"
#include "ulong_extras.h"
int main(void)
{
fmpz_mat_t A, B, C, D;
slong i;
FLINT_TEST_INIT(state);
flint_printf("mul_multi_mod....");
fflush(stdout);
for (i = 0; i < 100 * flint_test_multiplier(); i++)
{
slong m, n, k;
m = n_randint(state, 50);
n = n_randint(state, 50);
k = n_randint(state, 50);
fmpz_mat_init(A, m, n);
fmpz_mat_init(B, n, k);
fmpz_mat_init(C, m, k);
fmpz_mat_init(D, m, k);
fmpz_mat_randtest(A, state, n_randint(state, 200) + 1);
fmpz_mat_randtest(B, state, n_randint(state, 200) + 1);
/* Make sure noise in the output is ok */
fmpz_mat_randtest(C, state, n_randint(state, 200) + 1);
fmpz_mat_mul_classical_inline(C, A, B);
fmpz_mat_mul_multi_mod(D, A, B);
if (!fmpz_mat_equal(C, D))
{
flint_printf("FAIL: results not equal\n");
abort();
}
fmpz_mat_clear(A);
fmpz_mat_clear(B);
fmpz_mat_clear(C);
fmpz_mat_clear(D);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

View File

@@ -0,0 +1,112 @@
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2007 William Hart and David Harvey
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include "flint.h"
#include "fmpz.h"
#include "fmpz_mat.h"
#include "nmod_mat.h"
int
main(void)
{
int i;
FLINT_TEST_INIT(state);
flint_printf("multi_CRT_ui....");
fflush(stdout);
for (i = 0; i < 1000 * flint_test_multiplier(); i++)
{
slong bits, prime_bits, rows, cols, num_primes, j;
fmpz_t mod;
fmpz_mat_t A, B, C;
nmod_mat_t Amod[1000];
mp_limb_t primes[1000];
bits = n_randint(state, 500) + 1;
rows = n_randint(state, 10);
cols = n_randint(state, 10);
prime_bits = 1 + n_randint(state, FLINT_BITS - 1);
fmpz_mat_init(A, rows, cols);
fmpz_mat_init(B, rows, cols);
fmpz_mat_init(C, rows, cols);
fmpz_mat_randtest(A, state, bits);
fmpz_init(mod);
num_primes = 0;
primes[0] = n_nextprime(UWORD(1) << prime_bits, 0);
fmpz_set_ui(mod, primes[0]);
/* + 1 for sign */
while (fmpz_bits(mod) <= bits + 1)
{
primes[num_primes + 1] = n_nextprime(primes[num_primes], 0);
fmpz_mul_ui(mod, mod, primes[num_primes + 1]);
num_primes++;
}
num_primes++;
for (j = 0; j < num_primes; j++)
nmod_mat_init(Amod[j], rows, cols, primes[j]);
fmpz_mat_multi_mod_ui(Amod, num_primes, A);
fmpz_mat_multi_CRT_ui(B, Amod, num_primes, 1);
if (!fmpz_mat_equal(B, A))
{
flint_printf("FAIL!\n");
flint_printf("primes: ");
for (j = 0; j < num_primes; j++)
flint_printf("%wu ", primes[j]);
flint_printf("\nA: \n");
fmpz_mat_print_pretty(A);
flint_printf("\nB: \n");
fmpz_mat_print_pretty(B);
flint_printf("\n");
abort();
}
for (j = 0; j < num_primes; j++)
nmod_mat_clear(Amod[j]);
fmpz_mat_clear(A);
fmpz_mat_clear(B);
fmpz_mat_clear(C);
fmpz_clear(mod);
}
FLINT_TEST_CLEANUP(state);
flint_printf("PASS\n");
return 0;
}

Some files were not shown because too many files have changed in this diff Show More