Dot products
#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)sourceint _gr_vec_dot_rev(gr_ptr res, gr_srcptr initial, int subtract, gr_srcptr vec1, gr_srcptr vec2, slong len, gr_ctx_t ctx)sourceSet res to , respectively , or if subtract is nonzero, where = vec1, = vec2, = len and = initial, which may be NULL for .
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)sourceSets res to with strides = stride1 and = 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)sourceint _gr_vec_dot_ui(gr_ptr res, gr_srcptr initial, int subtract, gr_srcptr vec1, const ulong * vec2, slong len, gr_ctx_t ctx)sourceint _gr_vec_dot_fmpz(gr_ptr res, gr_srcptr initial, int subtract, gr_srcptr vec1, const fmpz * vec2, slong len, gr_ctx_t ctx)sourceAs _gr_vec_dot, with the second vector an array of slong, ulong or fmpz integers.
The dot product 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
where = len, = vec1, = vec2, the second form is used when subtract is nonzero, and = initial may be NULL, which means . The index map is for _gr_vec_dot, for _gr_vec_dot_rev, and for _gr_vec_dot_strided the entries used are and for strides , counted in elements, which may be negative. The variants _gr_vec_dot_si, _gr_vec_dot_ui and _gr_vec_dot_fmpz take 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 the result is (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:
- (
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). - for 2 to 16 limbs (
mpn_mod): unreduced multi-limb accumulation with delayed reduction (Delayed reduction for multiword moduli). - (
fmpz):_fmpz_vec_dot_general, which accumulates the products in limb arrays, separately for small terms and for large positive and negative terms, without intermediatefmpzvalues. - Real and complex balls (
arb,acb):arb_dotandacb_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 , , and the integer weights :
#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;
}a.b = 4 3 - a.b = 6 a.rev(b) = 5 a0b0 + a2b2 = 5 3 + a.w = 0 status 0
Here , the reversed product is , and .
Guides#
- Performance of dfloat (
dfloat) - Getting started with generic rings (
gr)
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
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).
@misc{flint-doc-gr-vec-dot,
author = {{The FLINT team}},
title = {{Dot products (gr\_vec.h)}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/gr_vec/dot.html},
note = {Generated 2026-11-02}
}