FLINT3.7.0-dev

Dot products

Synopsis#include <flint/gr_vec.h>
int _gr_vec_dot(gr_ptr res, gr_srcptr initial, int subtract, gr_srcptr vec1, gr_srcptr vec2, slong len, gr_ctx_t ctx)source
int _gr_vec_dot_rev(gr_ptr res, gr_srcptr initial, int subtract, gr_srcptr vec1, gr_srcptr vec2, slong len, gr_ctx_t ctx)source

Set res to c+∑i=0n−1aibic + \sum_{i=0}^{n-1} a_i b_i, respectively c+∑i=0n−1aibn−1−ic + \sum_{i=0}^{n-1} a_i b_{n-1-i}, or c−∑c - \sum if subtract is nonzero, where aa = vec1, bb = vec2, nn = len and cc = initial, which may be NULL for c=0c = 0.

int _gr_vec_dot_strided(gr_ptr res, gr_srcptr initial, int subtract, gr_srcptr vec1, slong stride1, gr_srcptr vec2, slong stride2, slong len, gr_ctx_t ctx)source

Sets res to c±∑i=0n−1ais1bis2c \pm \sum_{i=0}^{n-1} a_{i s_1} b_{i s_2} with strides s1s_1 = stride1 and s2s_2 = stride2 (in elements), which may be negative or zero.

int _gr_vec_dot_si(gr_ptr res, gr_srcptr initial, int subtract, gr_srcptr vec1, const slong * vec2, slong len, gr_ctx_t ctx)source
int _gr_vec_dot_ui(gr_ptr res, gr_srcptr initial, int subtract, gr_srcptr vec1, const ulong * vec2, slong len, gr_ctx_t ctx)source
int _gr_vec_dot_fmpz(gr_ptr res, gr_srcptr initial, int subtract, gr_srcptr vec1, const fmpz * vec2, slong len, gr_ctx_t ctx)source

As _gr_vec_dot, with the second vector an array of slong, ulong or fmpz integers.

The dot product c±∑iaibic \pm \sum_i a_i b_i is the central vector operation of the generic interface. Classical polynomial multiplication computes each coefficient of a product as a reversed dot product (_gr_vec_dot_rev), classical and blocked matrix multiplication compute each entry as a dot product of a row and a column (_gr_vec_dot_strided or a dot product with a transposed operand), and triangular solving, LU decomposition, power series inversion and Newton iteration are built from the same primitive. A ring that implements only GR_METHOD_VEC_DOT and GR_METHOD_VEC_DOT_REV efficiently therefore speeds up most generic algorithms (Three levels of operations).

Arguments#

All variants compute

r=c+∑i=0n−1aibσ(i)orr=c−∑i=0n−1aibσ(i)r = c + \sum_{i=0}^{n-1} a_i b_{\sigma(i)} \quad\text{or}\quad r = c - \sum_{i=0}^{n-1} a_i b_{\sigma(i)}

where nn = len, aa = vec1, bb = vec2, the second form is used when subtract is nonzero, and cc = initial may be NULL, which means c=0c = 0. The index map is σ(i)=i\sigma(i) = i for _gr_vec_dot, σ(i)=n−1−i\sigma(i) = n - 1 - i for _gr_vec_dot_rev, and for _gr_vec_dot_strided the entries used are ais1a_{i s_1} and bis2b_{i s_2} for strides s1s_1, s2s_2 counted in elements, which may be negative. The variants _gr_vec_dot_si, _gr_vec_dot_ui and _gr_vec_dot_fmpz take bb as a C array of integers, which is how integer matrices and polynomials act on vectors over other rings without converting the integers first. For n=0n = 0 the result is cc (or zero).

The output res may alias initial but not an entry of vec1 or vec2. Implementations may evaluate the sum in any order and with delayed reductions, so in floating-point rings the rounding differs from that of a loop of gr_addmul calls; ball arithmetic rings return a correct enclosure in any case.

Implementations#

The default gr_generic_vec_dot multiplies and adds through the method table. The strided default, for rings that override VEC_DOT but not VEC_DOT_STRIDED, gathers the strided entries into temporary arrays by shallow copies and calls _gr_vec_dot. Specialised versions include:

  • Z/nZ\mathbb{Z}/n\mathbb{Z} (nmod, nmod8, nmod32, nmod_redc): accumulation of products in two or three words with a single reduction at the end, as in _nmod_vec_dot (Dot products modulo a word-size integer).
  • Z/nZ\mathbb{Z}/n\mathbb{Z} for 2 to 16 limbs (mpn_mod): unreduced multi-limb accumulation with delayed reduction (Delayed reduction for multiword moduli).
  • Z\mathbb{Z} (fmpz): _fmpz_vec_dot_general, which accumulates the products in limb arrays, separately for small terms and for large positive and negative terms, without intermediate fmpz values.
  • Real and complex balls (arb, acb): arb_dot and acb_dot, which sum exactly in a fixed-point accumulator and add a single error bound [Joh2019dot].
  • Floating point (arf, acf, nfloat, dfloat) and finite fields (fq, fq_nmod, fq_zech): their own vector dot products.

Example#

Dot products modulo 7 with the four variants, for a=(1,2,3,4)a = (1, 2, 3, 4), b=(5,6,0,2)b = (5, 6, 0, 2), c=3c = 3 and the integer weights w=(1,−2,3,−4)w = (1, -2, 3, -4):

Examplegr_vec_dot.cchecked by make checkdoc
#include <flint/flint.h>
#include <flint/gr.h>
#include <flint/gr_vec.h>

int main(void)
{
    gr_ctx_t ctx;
    gr_ptr a, b, c, res;
    slong n = 4, w[4] = {1, -2, 3, -4};
    int status = GR_SUCCESS;

    gr_ctx_init_nmod(ctx, 7);
    a = gr_heap_init_vec(n, ctx);
    b = gr_heap_init_vec(n, ctx);
    c = gr_heap_init(ctx);
    res = gr_heap_init(ctx);

    status |= _gr_vec_set_str(a, "[1, 2, 3, 4]", n, ctx);
    status |= _gr_vec_set_str(b, "[5, 6, 0, 2]", n, ctx);
    status |= gr_set_ui(c, 3, ctx);

    status |= _gr_vec_dot(res, NULL, 0, a, b, n, ctx);
    flint_printf("a.b           = %{gr}\n", res, ctx);
    status |= _gr_vec_dot(res, c, 1, a, b, n, ctx);
    flint_printf("3 - a.b       = %{gr}\n", res, ctx);
    status |= _gr_vec_dot_rev(res, NULL, 0, a, b, n, ctx);
    flint_printf("a.rev(b)      = %{gr}\n", res, ctx);
    status |= _gr_vec_dot_strided(res, NULL, 0, a, 2, b, 2, 2, ctx);
    flint_printf("a0b0 + a2b2   = %{gr}\n", res, ctx);
    status |= _gr_vec_dot_si(res, c, 0, a, w, n, ctx);
    flint_printf("3 + a.w       = %{gr}\n", res, ctx);

    gr_heap_clear_vec(a, n, ctx);
    gr_heap_clear_vec(b, n, ctx);
    gr_heap_clear(c, ctx);
    gr_heap_clear(res, ctx);
    gr_ctx_clear(ctx);
    flint_printf("status %d\n", status);
    return 0;
}
Output
a.b           = 4
3 - a.b       = 6
a.rev(b)      = 5
a0b0 + a2b2   = 5
3 + a.w       = 0
status 0

Here a⋅b=25≡4a \cdot b = 25 \equiv 4, the reversed product is 1⋅2+2⋅0+3⋅6+4⋅5=40≡51 \cdot 2 + 2 \cdot 0 + 3 \cdot 6 + 4 \cdot 5 = 40 \equiv 5, and 3+a⋅w=3−10≡03 + a \cdot w = 3 - 10 \equiv 0.

Guides#

References#

  • [Joh2019dot] F. Johansson. Faster arbitrary-precision dot product and matrix multiplication. Proceedings of the 26th IEEE Symposium on Computer Arithmetic (ARITH-26), 2019, 15–22. https://arxiv.org/abs/1901.04289
Cite this page

The FLINT team, “Dot products (gr_vec.h),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/gr_vec/dot.html (generated 2026-11-02).