int _is_superficially_ok_entrywise(const fmpz_mat_t A) { slong n, i, j, d; if (!fmpz_mat_is_square(A)) return 0; n = fmpz_mat_nrows(A); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { d = fmpz_get_si(fmpz_mat_entry(A, i, j)); if (d < -2 || d > n-1) return 0; if (i == j && d == -1) return 0; if (i != j && d == 0) return 0; } } return 1; }
int fmpz_mat_solve_cramer(fmpz_mat_t X, fmpz_t den, const fmpz_mat_t A, const fmpz_mat_t B) { long i, dim = fmpz_mat_nrows(A); if (dim == 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 { printf("Exception: fmpz_mat_solve_cramer: dim > 3 not implemented"); abort(); } }
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; }
void _fmpz_mat_det_bareiss(fmpz_t det, fmpz_mat_t tmp) { long *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_trace(fmpz_t trace, const fmpz_mat_t mat) { slong i, n = fmpz_mat_nrows(mat); if (n == 0) fmpz_zero(trace); else { fmpz_set(trace, fmpz_mat_entry(mat, 0, 0)); for (i = 1; i < n; i++) fmpz_add(trace, trace, fmpz_mat_entry(mat, i, i)); } }
void _fmpz_mat_permute(fmpz_mat_t B, const fmpz_mat_t A, const slong *perm) { slong n, i, j; if (!fmpz_mat_is_square(A)) abort(); /* assert */ if (A == B) abort(); /* assert */ n = fmpz_mat_nrows(A); for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { fmpz_set( fmpz_mat_entry(B, perm[i], perm[j]), fmpz_mat_entry(A, i, j)); } } }
void fmpz_mat_set_perm(fmpz_mat_t X, const long * perm, const fmpz_mat_t B) { if (X == B) { /* Not implemented */ abort(); } else { long 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)); } }
int dgsl_mp_call_inlattice(fmpz *rop, const dgsl_mp_t *self, gmp_randstate_t state) { assert(rop); assert(self); const long m = fmpz_mat_nrows(self->B); const long n = fmpz_mat_ncols(self->B); mpz_t tmp_g; mpz_init(tmp_g); fmpz_t tmp_f; fmpz_init(tmp_f); _fmpz_vec_zero(rop, n); for(long i=0; i<m; i++) { self->D[i]->call(tmp_g, self->D[i], state); fmpz_set_mpz(tmp_f, tmp_g); _fmpz_vec_scalar_addmul_fmpz(rop, self->B->rows[i], n, tmp_f); } _fmpz_vec_add(rop, rop, self->c_z, n); mpz_clear(tmp_g); fmpz_clear(tmp_f); return 0; }
void fmpz_mat_multi_CRT_ui_precomp(fmpz_mat_t mat, nmod_mat_t * const residues, long nres, fmpz_comb_t comb, fmpz_comb_temp_t temp, int sign) { long 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); }
int dgsl_mp_call_coset(fmpz *rop, const dgsl_mp_t *self, gmp_randstate_t state) { assert(rop); assert(self); const long n = fmpz_mat_ncols(self->B); _fmpz_vec_zero(rop, n); mpfr_t *c = _mpfr_vec_init(n, mpfr_get_prec(self->sigma)); _mpfr_vec_set(c, self->c, n, MPFR_RNDN); mpfr_t c_prime; mpfr_init2(c_prime, mpfr_get_prec(self->sigma)); mpfr_t tmp; mpfr_init2(tmp, mpfr_get_prec(self->sigma)); mpfr_t sigma_prime; mpfr_init2(sigma_prime, mpfr_get_prec(self->sigma)); mpz_t z; mpz_init(z); mpfr_t z_mpfr; mpfr_init2(z_mpfr, mpfr_get_prec(self->sigma)); fmpz_t z_fmpz; fmpz_init(z_fmpz); size_t tau = 3; if (ceil(sqrt(log2((double)n))) > tau) tau = ceil(sqrt(log2((double)n))); mpfr_t *b = _mpfr_vec_init(n, mpfr_get_prec(self->sigma)); const long m = fmpz_mat_nrows(self->B); for(long j=0; j<m; j++) { long i = m-j-1; _mpfr_vec_dot_product(c_prime, c, self->G->rows[i], n, MPFR_RNDN); _mpfr_vec_dot_product(tmp, self->G->rows[i], self->G->rows[i], n, MPFR_RNDN); mpfr_div(c_prime, c_prime, tmp, MPFR_RNDN); mpfr_sqrt(tmp, tmp, MPFR_RNDN); mpfr_div(sigma_prime, self->sigma, tmp, MPFR_RNDN); assert(mpfr_cmp_d(sigma_prime, 0.0) > 0); dgs_disc_gauss_mp_t *D = dgs_disc_gauss_mp_init(sigma_prime, c_prime, tau, DGS_DISC_GAUSS_UNIFORM_ONLINE); D->call(z, D, state); dgs_disc_gauss_mp_clear(D); mpfr_set_z(z_mpfr, z, MPFR_RNDN); mpfr_neg(z_mpfr, z_mpfr, MPFR_RNDN); _mpfr_vec_set_fmpz_vec(b, self->B->rows[i], n, MPFR_RNDN); _mpfr_vec_scalar_addmul_mpfr(c, b, n, z_mpfr, MPFR_RNDN); fmpz_set_mpz(z_fmpz, z); _fmpz_vec_scalar_addmul_fmpz(rop, self->B->rows[i], n, z_fmpz); } fmpz_clear(z_fmpz); mpfr_clear(z_mpfr); mpfr_clear(sigma_prime); mpfr_clear(tmp); mpfr_clear(c_prime); _mpfr_vec_clear(c, n); _mpfr_vec_clear(b, n); return 0; }
dgsl_mp_t *dgsl_mp_init(const fmpz_mat_t B, mpfr_t sigma, mpfr_t *c, const dgsl_alg_t algorithm) { assert(mpfr_cmp_ui(sigma, 0) > 0); dgsl_mp_t *self = (dgsl_mp_t*)calloc(1, sizeof(dgsl_mp_t)); if(!self) dgs_die("out of memory"); dgsl_alg_t alg = algorithm; long m = fmpz_mat_nrows(B); long n = fmpz_mat_ncols(B); const mpfr_prec_t prec = mpfr_get_prec(sigma); fmpz_mat_init_set(self->B, B); self->c_z = _fmpz_vec_init(n); self->c = _mpfr_vec_init(n, prec); mpfr_init2(self->sigma, prec); mpfr_set(self->sigma, sigma, MPFR_RNDN); if (alg == DGSL_DETECT) { if (fmpz_mat_is_one(self->B)) { alg = DGSL_IDENTITY; } else if (_mpfr_vec_is_zero(c, n)) alg = DGSL_INLATTICE; else alg = DGSL_COSET; //TODO: we could test for lattice membership here } mpfr_t c_; mpfr_init2(c_, prec); size_t tau = 3; if (2*ceil(sqrt(log2((double)n))) > tau) tau = 2*ceil(sqrt(log2((double)n))); switch(alg) { case DGSL_IDENTITY: self->D = (dgs_disc_gauss_mp_t**)calloc(1, sizeof(dgs_disc_gauss_mp_t*)); mpfr_set_d(c_, 0.0, MPFR_RNDN); self->D[0] = dgs_disc_gauss_mp_init(self->sigma, c_, tau, DGS_DISC_GAUSS_DEFAULT); self->call = dgsl_mp_call_identity; break; case DGSL_INLATTICE: self->D = (dgs_disc_gauss_mp_t**)calloc(m, sizeof(dgs_disc_gauss_mp_t*)); if (c) _fmpz_vec_set_mpfr_vec(self->c_z, c, n); mpfr_mat_t G; mpfr_mat_init(G, m, n, prec); mpfr_mat_set_fmpz_mat(G, B); mpfr_mat_gso(G, MPFR_RNDN); mpfr_t sigma_; mpfr_init2(sigma_, prec); mpfr_t norm; mpfr_init2(norm, prec); mpfr_set_d(c_, 0.0, MPFR_RNDN); for(long i=0; i<m; i++) { _mpfr_vec_2norm(norm, G->rows[i], n, MPFR_RNDN); assert(mpfr_cmp_d(norm, 0.0) > 0); mpfr_div(sigma_, self->sigma, norm, MPFR_RNDN); assert(mpfr_cmp_d(sigma_, 0.0) > 0); self->D[i] = dgs_disc_gauss_mp_init(sigma_, c_, tau, DGS_DISC_GAUSS_DEFAULT); } mpfr_clear(sigma_); mpfr_clear(norm); mpfr_mat_clear(G); self->call = dgsl_mp_call_inlattice; break; case DGSL_COSET: mpfr_mat_init(self->G, m, n, prec); mpfr_mat_set_fmpz_mat(self->G, B); mpfr_mat_gso(self->G, MPFR_RNDN); self->call = dgsl_mp_call_coset; break; default: dgs_die("not implemented"); } mpfr_clear(c_); return self; }
size_t numRows() const { return fmpz_mat_nrows(mArray); }