# Vector Dot Product (dotprod)

This module provides interfaces for computing a vector dot product between two equally-sized vectors. Dot products are commonly used in digital signal processing for communications, particularly in filtering and matrix operations. Given two vectors of equal length \(\vec{x} = \left[x(0),x(1),\ldots,x(N-1)\right]^T\) and \(\vec{v} = \left[v(0),v(1),\ldots,v(N-1)\right]^T\) , the vector dot product between them is computed as

$$ \vec{x} \cdot \vec{v} = \vec{x}^T \vec{v} = \sum_{k=0}^{N-1}{ x(k) v(k) } $$A number of other liquid modules rely on dotprod , such as filtering and equalization.

## Specific machine architectures

The vector dot product has a complexity of \(\ord(N)\) multiply-and-accumulate operations. Because of its prevalence in multimedia applications, a considerable amount of research has been put into computing the vector dot product as efficiently as possible. Software-defined radio is no exception as basic profiling will likely demonstrate that a considerable portion of the processor is spent computing it. Certain machine architectures have specific instructions for computing vector dot products, particularly those which use a single instruction for multiple data (SIMD) such as MMX, SSE, AltiVec, etc.

## Interface

There are effectively two ways to use the
dotprod
module.
In the first and most general case, a vector dot product is computed on two
input vectors
\(\vec{x}\)
and
\(\vec{v}\)
whose values are not known
*a priori*
.
In the second case, a
dotprod
object is created around vector
\(\vec{v}\)
which does not change (or rarely changes) throughout its life cycle.
This is the more convenient method for filtering objects which don't usually
have time-dependent coefficients.
Listed below is a simple interface example to the
dotprod
module
object:

```
#include <liquid/liquid.h>
int main() {
// create input arrays
float x[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f};
float v[] = { 0.1f, -0.2f, 1.0f, -0.2f, 0.1f};
float y;
// run the basic vector dot product, store in 'y'
dotprod_rrrf_run(x,v,5,&y);
// create dotprod object and execute, store in 'y'
dotprod_rrrf q = dotprod_rrrf_create(v,5);
dotprod_rrrf_execute(q,x,&y);
dotprod_rrrf_destroy(q);
}
```

In both cases the dotprod can be easily integrated with the window object ( [section-buffer-window] ) for managing input data and alignment. There are three types of dot product objects and are listed in [tab-dotprod-objects] .

```
.. table [tab-dotprod-objects]
caption:`dotprod` object types
_precision_ & _input/output_ & _coefficients_ & _interface_
_float_ & real & real & `dotprod_rrrf`
_float_ & complex & complex & `dotprod_cccf`
_float_ & complex & real & `dotprod_crcf`
```

Listed below is a brief description of the dotprod object interfaces. While the types are described using the dotprod_rrrf object, the same holds true for all other types.

- dotprod_rrrf_run(h,x,n,y) executes a vector dot product between two vectors \(\vec{h}\) and \(\vec{x}\) , each of length \(n\) and stores the result in the output \(y\) . This is not a structured method and does not require creating a dotprod object, however does not take advantage of SIMD instructions if available. Rather than speed, its intent is to provide a simple interface to demonstrate functional correctness.
- dotprod_rrrf_create(v,n) creates a dotprod object with coefficients \(\vec{v}\) of length \(n\) .
- dotprod_rrrf_recreate(q,v,n) recreates a dotprod object with a new set of coefficients \(\vec{v}\) with a (possibly) different length \(n\) .
- dotprod_rrrf_destroy(q) destroys a dotprod object, freeing all internally-allocated memory.
- dotprod_rrrf_print(q) prints the object internals to the screen.
- dotprod_rrrf_execute(q,x,y) executes a dot product with an input vector \(\vec{x}\) and stores the result in \(y\) .