#include "flint-mparam.h"
#include "ulong_extras.h"
#include "nmod_mat.h"
#include "nmod.h"
#include "fmpz.h"
void
_nmod_mat_scalar_addmul_ui_generic(nmod_mat_t C, const nmod_mat_t A,
const nmod_mat_t B, const ulong c)
{
for (slong i = 0; i < A->r; i++)
{
for (slong j = 0; j < A->c; j++)
{
nmod_mat_entry(C, i, j) =
n_addmod(nmod_mat_entry(A, i, j),
nmod_mul(nmod_mat_entry(B, i, j), c, B->mod),
A->mod.n);
}
}
}
void
_nmod_mat_scalar_addmul_ui_precomp(nmod_mat_t C, const nmod_mat_t A, const nmod_mat_t B,
const ulong c, const ulong c_pr)
{
for (slong i = 0; i < A->r; i++)
{
for (slong j = 0; j < A->c; j++)
{
nmod_mat_entry(C, i, j) =
n_addmod(nmod_mat_entry(A, i, j),
n_mulmod_shoup(c, nmod_mat_entry(B, i, j),
c_pr, B->mod.n),
A->mod.n);
}
}
}
void
nmod_mat_scalar_addmul_ui(nmod_mat_t C, const nmod_mat_t A, const nmod_mat_t B,
ulong c)
{
c = nmod_set_ui(c, C->mod);
if (c == UWORD(0))
nmod_mat_set(C, A);
else if (c == UWORD(1))
nmod_mat_add(C, A, B);
else if (c == A->mod.n - UWORD(1))
nmod_mat_sub(C, A, B);
else if (A->r * A->c >= FLINT_MULMOD_SHOUP_THRESHOLD && A->mod.norm > 0)
{
const ulong c_pr = n_mulmod_precomp_shoup(c, A->mod.n);
_nmod_mat_scalar_addmul_ui_precomp(C, A, B, c, c_pr);
}
else
_nmod_mat_scalar_addmul_ui_generic(C, A, B, c);
}
void
_nmod_mat_scalar_mul_generic(nmod_mat_t B, const nmod_mat_t A, ulong c)
{
for (slong i = 0; i < A->r; i++)
for (slong j = 0; j < A->c; j++)
nmod_mat_entry(B, i, j) = nmod_mul(nmod_mat_entry(A, i, j), c, A->mod);
}
void
_nmod_mat_scalar_mul_precomp(nmod_mat_t B, const nmod_mat_t A, ulong c, ulong c_pr)
{
for (slong i = 0; i < A->r; i++)
for (slong j = 0; j < A->c; j++)
nmod_mat_entry(B, i, j) = n_mulmod_shoup(
c, nmod_mat_entry(A, i, j), c_pr, A->mod.n);
}
void
nmod_mat_scalar_mul(nmod_mat_t B, const nmod_mat_t A, ulong c)
{
if (c == UWORD(0))
nmod_mat_zero(B);
else if (c == UWORD(1))
nmod_mat_set(B, A);
else if (c == A->mod.n - UWORD(1))
nmod_mat_neg(B, A);
else if (A->r * A->c >= FLINT_MULMOD_SHOUP_THRESHOLD && A->mod.norm > 0)
{
const ulong c_pr = n_mulmod_precomp_shoup(c, A->mod.n);
_nmod_mat_scalar_mul_precomp(B, A, c, c_pr);
}
else
_nmod_mat_scalar_mul_generic(B, A, c);
}
void
nmod_mat_scalar_mul_fmpz(nmod_mat_t B, const nmod_mat_t A, const fmpz_t c)
{
nmod_mat_scalar_mul(B, A, fmpz_get_nmod(c, B->mod));
}