# Matrico f64vector Module

`matrico`

’s Double-Precision Flonum Vector `f64vector`

Module

For `matrico`

, the basic homogeneous vector support of the included `srfi-4`

module needs to be expanded to provide basic functional tools,
such as “map” and “reduce” functions.
I limit myself to the `f64vector`

variant of homogeneous vectors, as this type will be a basis for `matrico`

’s matrix type.
This module imports the `fpmath`

module,
solely for its `fp*+`

function which is needed for the implemented dot product function (`f64vector-dot`

see below).
However, in the future, once `(chicken flonum)`

provides `fp*+`

natively and former versions don’t need to be supported,
i.e. Ubuntu LTS repositories feature a CHICKEN including `fp*+`

, `fpmath`

can be removed from the list of imports.
As this module is useless without the `(chicken srfi-4)`

module, it is reexported.
You can take a look at the `src/f64vector.scm`

source file here.

### Generators

First, a procedural generation of vectors needs to be available, to avoid the user having to do such operations via a mutation and consequentially also avoid an unnecessary zero initialization of the vector.

`(f64vector-unfold dim fun)`

- Returns`f64vector`

with dimension-argument-many elements resulting from applying function argument to respective elements’ indices.

Another constructor of sorts is the concatenation of two or more vectors:

`(f64vector-concat . vecs)`

- Returns`f64vector`

holding all argument list-of-vectors elements concatenated vector-by-vector.

### Predicates

Next, a generalization of predicates for vectors, similar to `any`

and `every`

of SRFI-1 is provided.
These functions return true or false and are thus marked with a question-mark.
Naming-wise, I prefer Matlab’s `all`

to Scheme’s `every`

:

`(f64vector-any? pred vec)`

- Returns true if any element of argument`f64vector`

fulfills predicate argument.`(f64vector-all? pred vec)`

- Returns true if all elements of argument`f64vector`

fulfill predicate argument.

Testing elements of a vector on a predicate and returning matching elements and/or indices is not covered by these functions,
and may be added later on as a `f64vector-find`

function.

## Mappers

An important sub-set of iterator functions are the mappers.
R6RS defines a `vector-map`

in the standard, R5RS does not,
and hence (I assume), CHICKEN’s `srfi-4`

does not provide a `f64vector-map`

.
For performance reasons the basic map operation is implemented for one, two, and variable number of vector arguments (see `case-lambda`

).
As opposed to lists, the index of a vector element is not only readily available without traversing the container,
but also a lot more relevant than for lists.
Hence, I added a variant of map, whose function has, in addition to the vector element, the element’s index as argument,
similar to Gauche’s `vector-map-index`

and `vector-map`

in SRFI-43.
For lists however, I made it a rule, that whenever I was considering list indices (and thus may want a `map-index`

),
I would rethink the algorithm.

A sibling of the `map`

function, is the `for-each`

function, which, opposed to `map`

, does not return a list (or vector),
but always iterates in order through the container.
Here, I implemented `f64vector`

versions of `for-each`

and `for-each-index`

,
whose practical use lies in my case only in side-effect operations, like printing to terminal or writing to file.
As a special case due to its importance for numerical algorithms, a specialized mapper is included,
which maps a scalar and two vectors of the same dimensions to a new vector,
where entries of the first vector are scaled by the scalar and added to the second vector.
This operation is known in the BLAS library as “axpy” - a (times) x plus y.

`(f64vector-map fun vec)`

- Returns`f64vector`

of elements of function argument applied to`f64vector`

argument’s elements.`(f64vector-map fun vec wec)`

- Returns`f64vector`

of elements of function argument applied to`f64vector`

arguments’ elements.`(f64vector-map fun . vecs)`

- Returns`f64vector`

of elements of function argument applied to`f64vector`

arguments’ elements.`(f64vector-map-index fun . vec)`

- Returns`f64vector`

of elements of function argument applied to`f64vector`

arguments’ elements and their index.`(f64vector-foreach fun . vec)`

- Returns`void`

, apply function argument applied to`f64vector`

arguments’ elements in-order.`(f64vector-foreach-index fun . vec)`

- Returns`void`

, apply function argument applied to`f64vector`

arguments’ elements in-order and their index.`(f64vector-axpy a x y)`

- Returns`f64vector`

of elements given by`flonum`

a times first`f64vector`

plus second`f64vector`

.

### Reducers

Finally, and of vital importance, the folders (or reducers) are defined.
Naturally, two folds, forward and backward, join the mappers.
It might not be obvious why one variant is not sufficient:
First, a “fold” reducer can return anything and not only `f64vector`

s or `flonum`

s.
Second, even if one thinks of numerical operations like summing the elements of a vector,
it may be beneficial to sum from the front (back) if the vector is sorted increasingly (decreasingly),
which is, for example, typically the case for Singular values of matrices, to prevent numerical annihilation.
Furthermore, the “backward fold” will play a central role in a specific matrix operation.
Due to its principal role in (numerical) linear algebra,
a specialized third reducer is included - the dot product (also known as: “inner product” or “scalar product”) of two vectors (of same dimension).
While the dot product is a prime example of a “map” (`fp*`

) and a “fold” (`fp+`

) operation,
again performance dictates to specialize this function.

`(f64vector-fold fun ini . vec)`

- Returns accumulator of applying function argument to accumulator (starting with initializer argument) and vector arguments’ entries from front to back.`(f64vector-fold* fun ini . vec)`

- Returns accumulator of applying function argument to accumulator (starting with initializer argument) and vector arguments’ entries from back to front.`(f64vector-dot x y)`

- Returns flonum resulting from dot product of same dimension vector arguments.

In principles the predicates and mappers could have been implemented as special cases of the reducers, which, while elegant, is not achieving best performance.

Altogether, the `f64vector`

module is balancing minimally required functions
with maximum performance for `matrico`

.
Next time, I will discuss CHICKEN Scheme’s outstanding module system.