# Componentwise operations

SYNOPSIS

#include "matrix.h"
VEC *v_conv (VEC *x, VEC *y, VEC *out)
VEC *v_pconv(VEC *x, VEC *y, VEC *out)
VEC *v_map (double (*fn)(double), VEC *x, VEC *out)
double v_max (VEC *x, int *index)
double v_min (VEC *x, int *index)
VEC *v_star (VEC *x, VEC *y, VEC *out)
VEC *v_slash(VEC *x, VEC *y, VEC *out)
VEC *v_sort (VEC *x, PERM *order)
double v_sum (VEC *x)

#include "mzatrix.h"
ZVEC *zv_map(complex (*fn)(complex), ZVEC *x, ZVEC *out)
ZVEC *zv_star(ZVEC *x, ZVEC *y, ZVEC *out)
ZVEC *zv_slash(ZVEC *x, ZVEC *y, ZVEC *out)
complex zv_sum(ZVEC *x)

DESCRIPTION

The routines `v_conv()` and `v_pconv()` compute convolution-type
products of vectors.
The routine `v_conv()` computes the vector $z$ where
$z_i = \sum_{0\le j\le i} x_j y_{i-j}$.
The routine `v_pconv()` computes a periodic convolution with period
`y->dim`.
The routine `v_conv()` can be used to compute the product of two
polynomials, with the polynomial $x(t) = \sum_{i=0}^{\deg x} x_i t^i$ and
$y(t) = \sum_{i=0}^{\deg y} y_i t^i$.
The routines `v_map()` and `zv_map()` apply the function
`(*fn)()` to the components of `x` to give the vector `out`.
That is, `out->ve[i] = (*fn)(x->ve[i])`.
There are also versions

VEC *_v_map(double (*fn)(void *,double),
void *fn_params, VEC *x, VEC *out)
ZVEC *_zv_map(complex (*fn)(void *,complex),
void *fn_params, ZVEC *x, ZVEC *out)

where `out->ve[i] = (*fn)(fn_params,x->ve[i])`.
This enables more flexible use of this function.
Both of these functions may be used *in situ\/* with
`x == out`.
The routine `v_max()` returns the maximum entry of the vector
`x`, and sets `index` to be the index of this maximum value in
`x`.
Note that `index` is the index for the *first\/* entry with this
value.
Thus `max_x = v_max(x, &i)` means that `x->ve[i] == max_x`.
The routine `v_min()` returns the minimum entry of the vector
`x`, and sets `index` to be the index of this minimum value
similarly to `v_max()`.
Both `v_min()` and `v_max()` raise an `E_SIZES` error if
they are passed zero dimensional vectors.
The routines `v_star()` and `zv_star()` compute the
componentwise, or Hadamard, product of `x` and `y`.
That is, `out->ve[i] = x->ve[i]*y->ve[i]` for all `i`.
Note that `v_star()` is equivalent to multiplying `y` by a
diagonal matrix whose diagonal entries are given by the entries of
`x`.
This routine may be used *in situ\/* with `x == out`.
The routines `v_slash()` and `zv_slash()` compute the
componentwise ratio of entries of `y` and `x`. (Note the order!)
That is, `out->ve[i] = y->ve[i]/x->ve[i]` for all `i`.
Note that this is equivalent to multiplying `y` by the inverse of the
diagonal matrix described in the previous paragraph.
This could be useful for preconditioning, for
example.
This routine may be used *in situ\/* with `x == out` and/or
`y == out`.
The routine `v_slash()` raises an `E_SING` error if `x` has
a zero entry (the rationale being that it is really solving the system of
equations $Xz = y$ where $z$ is `out`).
The routine `v_sort()` sorts the entries of the vector `x`
*in situ\/*, and sets `order` to be the permutation that achieves
this.
Note that the old ordering of `x` can be obtained by using
`pxinv_vec()` as illustrated in the example below.
The algorithm used is a version of quicksort based on that given in
*Algorithms in C*, by R.~Sedgewick, pp.~116--124 (1990).
The routines `v_sum()` and `zv_sum()` return the sum of the
entries of `x`.
Note that there are no complex ``min'', ``max'' or ``sorting'' routines, as
there is no suitable ordering on the complex numbers.
EXAMPLE

An alternative way of computing $\|x\|_\infty$ (but slower):

VEC *x, *y, *z;
PERM *order;
Real norm;
int i;
......
y = v_map(fabs,x,VNULL);
norm = v_max(y,&i);

Sorting a vector:
v_sort(x,order);
/* x now sorted */
y = pxinv_vec(order,x,VNULL);
/* y is now the original x */

Using the Hadamard product for setting $y_i = w_i x_i$:
VEC *weights;
......
for ( i = 0; i < weights->dim; i++ )
weights->ve[i] = ...;
......
v_star(weights,x,y);

SEE ALSO:
Other componentwise operations: `v_add()`, `v_sub()`,
`sv_mlt()`.
Iterative routines benefiting from diagonal preconditioning:
`iter_cg()`, \newline`iter_cgs()`, and `iter_lsqr()`.

SOURCE FILE: `vecop.c, zvecop.c`