Skip to content

Commit eef761b

Browse files
Merge pull request #2444 from fredrik-johansson/precond2
Preconditioned modular multiplication for ``nmod_poly``
2 parents 40e69c2 + 13f26a5 commit eef761b

File tree

8 files changed

+885
-25
lines changed

8 files changed

+885
-25
lines changed

doc/source/nmod_poly.rst

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,53 @@ Multiplication
797797
inverse of the reverse of ``f``. It is required that ``poly1`` and
798798
``poly2`` are reduced modulo ``f``.
799799

800+
Preconditioned modular multiplication
801+
--------------------------------------------------------------------------------
802+
803+
.. type:: nmod_poly_mulmod_precond_struct
804+
nmod_poly_mulmod_precond_t
805+
806+
Stores precomputed data for evaluating `ab \bmod d` where both `a`
807+
and `d` are fixed.
808+
809+
.. function:: void _nmod_poly_mulmod_precond_init_method(nmod_poly_mulmod_precond_t precond, nn_srcptr a, slong alen, nn_srcptr d, slong dlen, nn_srcptr dinv, slong lendinv, int method, nmod_t mod)
810+
void nmod_poly_mulmod_precond_init_method(nmod_poly_mulmod_precond_t precond, const nmod_poly_t a, const nmod_poly_t d, const nmod_poly_t dinv, int method)
811+
void _nmod_poly_mulmod_precond_init_num(nmod_poly_mulmod_precond_t precond, nn_srcptr a, slong alen, nn_srcptr d, slong dlen, nn_srcptr dinv, slong lendinv, slong num, nmod_t mod)
812+
void nmod_poly_mulmod_precond_init_num(nmod_poly_mulmod_precond_t precond, const nmod_poly_t a, const nmod_poly_t d, const nmod_poly_t dinv, slong num)
813+
814+
Initialize ``precond`` for computing `ab \bmod d`.
815+
It is assumed that `a` is already reduced modulo `d`.
816+
The *method* parameter must be one of the following:
817+
818+
* ``NMOD_POLY_MULMOD_PRECOND_NONE`` (no precomputation; multiplication will simply delegate to :func:`_nmod_poly_mulmod_preinv`)
819+
820+
* ``NMOD_POLY_MULMOD_PRECOND_SHOUP`` (use Shoup multiplication)
821+
822+
* ``NMOD_POLY_MULMOD_PRECOND_MATRIX`` (use the matrix algorithm)
823+
824+
The *num* versions of these functions attempt to choose the optimal
825+
method automatically assuming that one intends to perform *num*
826+
multiplications.
827+
828+
Shallow references to ``a``, ``d`` and ``dinv`` may be stored
829+
in ``precond``; the original objects must therefore be kept alive
830+
without modification as long as ``precond`` is used.
831+
The user must supply the precomputed inverse of ``d``, with the same
832+
meaning as in :func:`_nmod_poly_mulmod_preinv` and :func:`nmod_poly_mulmod_preinv`.
833+
834+
.. function:: void nmod_poly_mulmod_precond_clear(nmod_poly_mulmod_precond_t precond)
835+
836+
Clears ``precond``, freeing any allocated memory.
837+
838+
.. function:: void _nmod_poly_mulmod_precond(nn_ptr res, const nmod_poly_mulmod_precond_t precond, nn_srcptr b, slong blen, nmod_t mod)
839+
void nmod_poly_mulmod_precond(nmod_poly_t res, const nmod_poly_mulmod_precond_t precond, const nmod_poly_t b)
840+
841+
Compute `ab \bmod d` where both `a` and `d` are fixed and represented by
842+
the ``precond`` object. We require that `b` is already reduced modulo `d`.
843+
The underscore method requires nonzero lengths and does not allow aliasing
844+
between the output and any inputs (including ``a`` and ``d``).
845+
The non-underscore method allows aliasing between ``b`` and ``res``.
846+
800847

801848
Powering
802849
--------------------------------------------------------------------------------

src/nmod_poly.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,47 @@ void nmod_poly_mulmod_preinv(nmod_poly_t res, const nmod_poly_t poly1, const nmo
369369
int _nmod_poly_invmod(ulong *A, const ulong *B, slong lenB, const ulong *P, slong lenP, const nmod_t mod);
370370
int nmod_poly_invmod(nmod_poly_t A, const nmod_poly_t B, const nmod_poly_t P);
371371

372+
/* Preconditioned modular multiplication *************************************/
373+
374+
#define NMOD_POLY_MULMOD_PRECOND_NONE 0
375+
#define NMOD_POLY_MULMOD_PRECOND_SHOUP 1
376+
#define NMOD_POLY_MULMOD_PRECOND_MATRIX 2
377+
/* TODO
378+
#define NMOD_POLY_MULMOD_PRECOND_SPARSE 3
379+
#define NMOD_POLY_MULMOD_PRECOND_FFT 4
380+
*/
381+
382+
typedef struct
383+
{
384+
int method;
385+
slong n; /* Degree of modulus */
386+
387+
nn_srcptr a; /* Operand (important: shallow reference) */
388+
slong alen;
389+
390+
nn_srcptr d; /* Modulus (important: shallow reference) */
391+
nn_srcptr dinv; /* Modulus inverse (important: shallow reference) */
392+
slong lendinv; /* Length of modulus inverse */
393+
394+
nn_ptr adivd; /* Precomputed quotient a * x^n / d for Shoup. */
395+
396+
nn_ptr matrix; /* Array of size ceil(n / packing) * n storing multiplication matrix */
397+
int packing; /* Matrix entries per word: 1, 2, 3 or 4 */
398+
dot_params_t dot_params;
399+
}
400+
nmod_poly_mulmod_precond_struct;
401+
402+
typedef nmod_poly_mulmod_precond_struct nmod_poly_mulmod_precond_t[1];
403+
404+
void _nmod_poly_mulmod_precond_init_method(nmod_poly_mulmod_precond_t precond, nn_srcptr a, slong alen, nn_srcptr d, slong dlen, nn_srcptr dinv, slong lendinv, int method, nmod_t mod);
405+
void nmod_poly_mulmod_precond_init_method(nmod_poly_mulmod_precond_t precond, const nmod_poly_t a, const nmod_poly_t d, const nmod_poly_t dinv, int method);
406+
void _nmod_poly_mulmod_precond_init_num(nmod_poly_mulmod_precond_t precond, nn_srcptr a, slong alen, nn_srcptr d, slong dlen, nn_srcptr dinv, slong lendinv, slong num, nmod_t mod);
407+
void nmod_poly_mulmod_precond_init_num(nmod_poly_mulmod_precond_t precond, const nmod_poly_t a, const nmod_poly_t d, const nmod_poly_t dinv, slong num);
408+
void nmod_poly_mulmod_precond_clear(nmod_poly_mulmod_precond_t precond);
409+
410+
void _nmod_poly_mulmod_precond(nn_ptr res, const nmod_poly_mulmod_precond_t precond, nn_srcptr b, slong blen, nmod_t mod);
411+
void nmod_poly_mulmod_precond(nmod_poly_t res, const nmod_poly_mulmod_precond_t precond, const nmod_poly_t b);
412+
372413
/* Powering *****************************************************************/
373414

374415
void _nmod_poly_pow_binexp(nn_ptr res, nn_srcptr poly, slong len, ulong e, nmod_t mod);

0 commit comments

Comments
 (0)