void fmpz_mat_mul(fmpz_mat_t C, const fmpz_mat_t A, const fmpz_mat_t B) { long dim, m, n, k, ab, bb; 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 < 10) { fmpz_mat_mul_classical(C, A, B); return; } ab = fmpz_mat_max_bits(A); bb = fmpz_mat_max_bits(B); ab = FLINT_ABS(ab); bb = FLINT_ABS(bb); if (5*(ab + bb) > dim * dim) { fmpz_mat_mul_classical(C, A, B); } else { _fmpz_mat_mul_multi_mod(C, A, B, ab + bb + FLINT_BIT_COUNT(n) + 1); } }
void sample(void * arg, ulong count) { mat_mul_t * params = (mat_mul_t *) arg; long i, m = params->m, n = params->n, k = params->k; long bits = params->bits; int algorithm = params->algorithm; flint_rand_t rnd; fmpz_mat_t A, B, C; flint_rand_t state; flint_randinit(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); }