The FTS Vector Function Library Reference Manual

This file documents the API of the vector/array processing functions provided in FTS.


Introduction

postlong(size); The FTS Vector Function Library provides a C API to a number of frequently used DSP routines. Most of them are vector routines in the sence of applying a certain function to each element of an array. Others (like the dot product) implement true vector operations.

Function calls

Since there is a an ANSI C implementation of each function, this library is fully portable. In order to reach a better performance on certain plattforms the use of functions provided by this API results in calls of micro coded routines. The user should not rely on the fact that the functions are implemented as true C function calls. Clearly spoken: NEVER USE A POINTER TO ONE OF THESE FUNCTIONS!

Each function of this library exists in two versions. One of these functions can be called with arrays of any size. Its name starts with the prefix "fts_vec_" followed by the actual function name. The name of the second version of each function has the prefix "fts_vecx_". It is probable that this calls a routine using loop unrolling to fasten the execution. At least will this version run as fast as the other. It can be applied only to vectors of a size which is a multiple of a constant.

The value of this constant can be different for different plattforms and is assigned to the C macro FTS_VECX_BASE. However the user can rely on following assumptions:

The arguments in the signature of the "vec" and the "vecx" version of a function are strictly the same. To keep this documentation brief in the following reference just the "fts_vec_..." function call is listed representing both versions.

Data types

In the current version of this library vectors/arrays of elements of three types are processed.

So far we use simply the C data types float as general floating point and long as integer data type.

The complex type is defined as a couple of two floats in a C structure:

    typdef struct{
      float re;
      float im;
    } complex;
  
Since this can be eather in rectangular or in polar representation C marcos are defined to support writing readable code.

In case of rectangular representation use:

    complex z;
    float re = z.RE; /* real part of z */
    float im = z.IM; /* imaginary part of z */
  
In case of polar representation use:

    complex z;
    float mag = z.MAG; /* magnitude of z */
    float arg = z.ARG; /* argument of z */
  

Nomenclatura

Most of the functions - like the arithmetic functions - are implemented for all three data types or - like the comparisons - at least for two of them. As will be seen beginns the name of a function in this case with an f, i or c to indicate the processed vector type.

Is an operation provided for two vectors as well as for a vector and a scalar - again like the arithmetic and comparison functions -, the vector/scalar version has a prefix like "fts_vec_scl_" or "fts_vecx_scl_".


Function Call Reference


vector/vector arithmetic operations

The following vector/vector operations are available for all vector types - float , integer and complex:
add
Vector addition:
out[i] = in0[i] + in1[i], for i = 0...size-1
sub
Vector subtraction:
out[i] = in0[i] - in1[i], for i = 0...size-1
mul
Element by element vector multiplication:
out[i] = in0[i] * in1[i], for i = 0...size-1
div
Element by element vector division:
out[i] = in0[i] / in1[i], for i = 0...size-1
In the case of the complex functions a true complex operation is computed.

The vector elements are treated as if they are in rectangular representation.

The dot product is implemented for float vectors only.

dot
Vector dot product:
*ptr = sum(in0[i] * in1[i], for i = 0...size-1)
Also a function for mixed complex/float multiplication is available.
cfmul
Element by element multiplication of a complex vector in0 with a float vector in1:
out[i].RE = in0[i].RE * in1[i], out[i].IM = in0[i].IM * in1[i], for i = 0...size-1)

vector/vector float arithmetic functions

fts_vec_fadd(float *in0, float *in1, float *out, long size);
fts_vec_fsub(float *in0, float *in1, float *out, long size);
fts_vec_fmul(float *in0, float *in1, float *out, long size);
fts_vec_fdiv(float *in0, float *in1, float *out, long size);
fts_vec_fdot(float *in0, float *in1, float *ptr, long size);

vector/vector integer arithmetic functions

fts_vec_iadd(long *in0, long *in1, long *out, long size);
fts_vec_isub(long *in0, long *in1, long *out, long size);
fts_vec_imul(long *in0, long *in1, long *out, long size);
fts_vec_idiv(long *in0, long *in1, long *out, long size);

vector/vector complex arithmetic functions

fts_vec_cadd(complex *in0, complex *in1, complex *out, long size);
fts_vec_csub(complex *in0, complex *in1, complex *out, long size);
fts_vec_cmul(complex *in0, complex *in1, complex *out, long size);
fts_vec_cdiv(complex *in0, complex *in1, complex *out, long size);
fts_vec_cfmul(complex *in0, float *in1, complex *out, long size);

vector/scalar arithmetic operations

The following vector/scalar operations are available for all vector types - float , integer and complex:
scl add
Adds a constant value to each element a vector:
out[i] = in[i] + scl, for i = 0...size-1
scl sub
Subtracts a constant value from each element of a vector:
out[i] = in[i] - scl, for i = 0...size-1
scl mul
Multiplicates each element of a vector with a scalar:
out[i] = in[i] * scl, for i = 0...size-1
scl bus
Subtracts each element of a vector from a constant value (swaped operants):
out[i] = scl - in[i], for i = 0...size-1
scl vid
Divides a constant value by each element of a vector (swaped operants):
out[i] = scl / in[i], for i = 0...size-1
In the case of the complex functions a true complex operation is computed.

The vector elements are treated as if they are in rectangular representation.

The mixed complex/float multiplication scales a complex vector with a float scalar.

cfmul
Scaling of a complex vector:
out[i].RE = in[i].RE * scl, out[i].IM = in[i].IM * scl, for i = 0...size-1)

vector/scalar float arithmetic functions

fts_vec_scl_fadd(float *in, float scl, float *out, long size);
fts_vec_scl_fsub(float *in, float scl, float *out, long size);
fts_vec_scl_fmul(float *in, float scl, float *out, long size);
fts_vec_scl_fdiv(float *in, float scl, float *out, long size);
fts_vec_scl_fbus(float *in, float scl, float *out, long size);
fts_vec_scl_fvid(float *in, float scl, float *out, long size);

vector/scalar integer arithmetic functions

fts_vec_scl_iadd(long *in, long scl, long *out, long size);
fts_vec_scl_isub(long *in, long scl, long *out, long size);
fts_vec_scl_imul(long *in, long scl, long *out, long size);
fts_vec_scl_idiv(long *in, long scl, long *out, long size);
fts_vec_scl_ibus(long *in, long scl, long *out, long size);
fts_vec_scl_ivid(long *in, long scl, long *out, long size);

vector/scalar complex arithmetic functions

fts_vec_scl_cadd(complex *in, complex scl, complex *out, long size);
fts_vec_scl_csub(complex *in, complex scl, complex *out, long size);
fts_vec_scl_cmul(complex *in, complex scl, complex *out, long size);
fts_vec_scl_cdiv(complex *in, complex scl, complex *out, long size);
fts_vec_scl_cbus(complex *in, complex scl, complex *out, long size);
fts_vec_scl_cvid(complex *in, complex scl, complex *out, long size);
fts_vec_scl_cfmul(complex *in, float scl, complex *out, long size);

vector/vector comparison functions

The following vector/vector comparison functions are available for float and integer vectors:
cmp_eq
Tests for each element of in0 wether it equals to the correspondig element of in1:
out[i] = (in0[i] == in1[i]), for i = 0...size-1
cmp_neq
Tests for each element of in0 wether it does not equal to the correspondig element of in1:
out[i] = (in0[i] != in1[i]), for i = 0...size-1
cmp_leq
Tests for each element of in0 wether it is equal or less than the correspondig element of in1:
out[i] = (in0[i] < = in1[i]), for i = 0...size-1
cmp_geq
Tests for each element of in0 wether it is equal or greater than the correspondig element of in1:
out[i] = (in0[i] > = in1[i]), for i = 0...size-1
cmp_lt
Tests for each element of in0 wether it is less than the correspondig element of in1:
out[i] = (in0[i] < in1[i]), for i = 0...size-1
cmp_gt
Tests for each element of in0 wether it is greater than the correspondig element of in1:
out[i] = (in0[i] > in1[i]), for i = 0...size-1
The result of a test is zero for false non zero for true.

vector/vector float comparison functions

fts_vec_fcmp_eq(float *in0, float *in1, long *out, long size);
fts_vec_fcmp_neq(float *in0, float *in1, long *out, long size);
fts_vec_fcmp_leq(float *in0, float *in1, long *out, long size);
fts_vec_fcmp_geq(float *in0, float *in1, long *out, long size);
fts_vec_fcmp_lt(float *in0, float *in1, long *out, long size);
fts_vec_fcmp_gt(float *in0, float *in1, long *out, long size);

vector/vector integer comparison functions

fts_vec_icmp_eq(long *in0, long *in1, long *out, long size);
fts_vec_icmp_neq(long *in0, long *in1, long *out, long size);
fts_vec_icmp_leq(long *in0, long *in1, long *out, long size);
fts_vec_icmp_geq(long *in0, long *in1, long *out, long size);
fts_vec_icmp_lt(long *in0, long *in1, long *out, long size);
fts_vec_icmp_gt(long *in0, long *in1, long *out, long size);

vector/scalar comparison functions

The following vector/scalar comparison functions are available for float and integer vectors:
scl cmp_eq
Tests for each element of in wether it equals to the constant value scl:
out[i] = (in[i] == scl), for i = 0...size-1
scl cmp_neq
Tests for each element of in wether it does not equal to the constant value scl:
out[i] = (in[i] != scl), for i = 0...size-1
scl cmp_leq
Tests for each element of in wether it is equal or less than the constant value scl:
out[i] = (in[i] < = scl), for i = 0...size-1
scl cmp_geq
Tests for each element of in wether it is equal or greater than the constant value scl:
out[i] = (in[i] > = scl), for i = 0...size-1
scl cmp_lt
Tests for each element of in wether it is less than the constant value scl:
out[i] = (in[i] < scl), for i = 0...size-1
scl cmp_gt
Tests for each element of in wether it is greater than the constant value scl:
out[i] = (in[i] > scl), for i = 0...size-1
The result of a test is zero for true non zero for false.

vector/scalar float comparison functions

fts_vec_scl_fcmp_eq(float *in, float scl, long *out, long size);
fts_vec_scl_fcmp_neq(float *in, float scl, long *out, long size);
fts_vec_scl_fcmp_leq(float *in, float scl, long *out, long size);
fts_vec_scl_fcmp_geq(float *in, float scl, long *out, long size);
fts_vec_scl_fcmp_lt(float *in, float scl, long *out, long size);
fts_vec_scl_fcmp_gt(float *in, float scl, long *out, long size);

vector/scalar integer comparison functions

fts_vec_scl_icmp_eq(long *in, long scl, long *out, long size);
fts_vec_scl_icmp_neq(long *in, long scl, long *out, long size);
fts_vec_scl_icmp_leq(long *in, long scl, long *out, long size);
fts_vec_scl_icmp_geq(long *in, long scl, long *out, long size);
fts_vec_scl_icmp_lt(long *in, long scl, long *out, long size);
fts_vec_scl_icmp_gt(long *in, long scl, long *out, long size);

vector to scalar reducing functions

These functions for float , integer and complex vectors give a scalar result of the same type:
min
Finds the minimum value of all vector elements:
*ptr = min(in[i], for i = 0...size-1)
max
Finds the maximum value of all vector elements:
*ptr = max(in[i], for i = 0...size-1)
sum
Summs all vector elements:
*ptr = sum(in[i], for i = 0...size-1)

float vector to scalar functions

fts_vec_fmin(float *in, float *ptr, long size);
fts_vec_fmax(float *in, float *ptr, long size);
fts_vec_fsum(float *in, float *ptr, long size);

integer vector to scalar functions

fts_vec_imin(long *in, long *ptr, long size);
fts_vec_imax(long *in, long *ptr, long size);
fts_vec_isum(long *in, long *ptr, long size);

complex vector to scalar functions

fts_vec_csum(complex *in, complex *ptr, long size);

vector utility functions

The following vector utility functions are available for all vector types - float , integer and complex:
abs
Computes the absolute value of each vector element:
out[i].RE = |in[i]|, for i = 0...size-1
clip
Clips all vector elements less then min to min, all greater then max to max:
out[i] = (in[i] < min)? (min): ((in[i] > max)? (max): (in[i])), for i = 0...size-1
fill
Asign a constant value to all elements of a vector:
out[i] = scl, for i = 0...size-1
zero
Zero all elements of a vector:
out[i] = 0, for i = 0...size-1
cpy
Copy a vector to another:
out[i] = in[i], for i = 0...size-1

float vector utility functions

fts_vec_fabs(float *in, float *out, long size);
fts_vec_fclip(float *in, float min, float max, float *out, long size);
fts_vec_ffill(float scl, float *out, long size);
fts_vec_fzero(float *out, long size);
fts_vec_fcpy(float *in, float *out, long size);

integer vector utility functions

fts_vec_iabs(long *in, long *out, long size);
fts_vec_iclip(long *in, long min, long max, long *out, long size);
fts_vec_ifill(long scl, long *out, long size);
fts_vec_izero(long *out, long size);
fts_vec_icpy(long *in, long *out, long size);

complex vector utility functions

fts_vec_cabs(complex *in, complex *out, long size);
fts_vec_cfill(complex scl, complex *out, long size);
fts_vec_czero(complex *out, long size);
fts_vec_ccpy(complex *in, complex *out, long size);

math functions

These functions can be applied to float vectors only.

Most of them call functions equivalent to those of the ANSI C math library for each element of a vector:

sin cos tan asin acos atan sinh cosh tanh exp log log10 sqrt
ANSI C math library equivalent functions:
out[i] = sin(in[i]), for i = 0...size-1
expb
Multiplies each vector by a constant and takes it to the power of e (calls exp):
out[i] = exp(scl * in[i]), for i = 0...size-1
logb
Computes the logarithm of each vector element and scales it with a constant (calls log):
out[i] = scl * log(in[i]), for i = 0...size-1
rsqrt
Computes the invers of the square root (which could(!) be more efficient):
out[i] = 1./sqrt(in[i]), for i = 0...size-1
float vector functions
fts_vec_sin(float *in, float *out, long size);
fts_vec_cos(float *in, float *out, long size);
fts_vec_tan(float *in, float *out, long size);
fts_vec_asin(float *in, float *out, long size);
fts_vec_acos(float *in, float *out, long size);
fts_vec_atan(float *in, float *out, long size);
fts_vec_sinh(float *in, float *out, long size);
fts_vec_cosh(float *in, float *out, long size);
fts_vec_tanh(float *in, float *out, long size);
fts_vec_exp(float *in, float *out, long size);
fts_vec_log(float *in, float *out, long size);
fts_vec_log10(float *in, float *out, long size);
fts_vec_expb(float *in, float scl, float *out, long size);
fts_vec_logb(float *in, float scl, float *out, long size);
fts_vec_sqrt(float *in, float *out, long size);
fts_vec_rsqrt(float *in, float *out, long size);

bitwise logic and shift functions

The following bitwise functions can be applied to integer vectors only.

Just like the arithmetic operations and the comparison functions, the bitwise operations (not the not ) are available as a conjunction of a vector with another vector (in0 and in1) or a vector with a scalar (in and scl):

bitnot
Bitwise inversion of each vector element:
out[i] = in[i], for i = 0...size-1
bitand
Bitwise "and" conjunction:
out[i] = in0[i] & in1[i], for i = 0...size-1
out[i] = in[i] & scl, for i = 0...size-1
bitor
Bitwise "or" conjunction:
out[i] = in0[i] | in1[i], for i = 0...size-1
out[i] = in[i] | scl, for i = 0...size-1
bitxor
Bitwise "xor" conjunction:
out[i] = in0[i] ^ in1[i], for i = 0...size-1
out[i] = in[i] ^ scl, for i = 0...size-1
bitshl
Bitshift left (equivalent to the ANSI C "< < " operator - arithmetic or!! logic shift):
out[i] = in0[i] < < in1[i], for i = 0...size-1
out[i] = in[i] < < scl, for i = 0...size-1
bitshr
Bitshift right (equivalent to the ANSI C "> > " operator - arithmetic or!! logic shift):
out[i] = in0[i] > > in1[i], for i = 0...size-1
out[i] = in[i] > > scl, for i = 0...size-1

bitwise logic inversion

fts_vec_bitnot(long *in, long *out, long size);

vector/vector bitwise logic and shift functions

fts_vec_bitand(long *in0, long *in1, long *out, long size);
fts_vec_bitor(long *in0, long *in1, long *out, long size);
fts_vec_bitxor(long *in0, long *in1, long *out, long size);
fts_vec_bitshl(long *in0, long *in1, long *out, long size);
fts_vec_bitshr(long *in0, long *in1, long *out, long size);

vector/scalar bitwise logic and shift functions

fts_vec_scl_bitand(long *in, long scl, long *out, long size);
fts_vec_scl_bitor(long *in, long scl, long *out, long size);
fts_vec_scl_bitxor(long *in, long scl, long *out, long size);
fts_vec_scl_bitshl(long *in, long scl, long *out, long size);
fts_vec_scl_bitshr(long *in, long scl, long *out, long size);

complex functions

These are the functions for vectors of complex elements (in all functions exept for crect the vector elements are treated as if they are in rectangular representation):
conj
Conjugates each vector element:
out[i].RE = in[i].RE, out[i].IM = -in[i].IM, for i = 0...size-1
csqr
Computes the sqare of the absolute value of each vector element:
out[i].RE = in[i].RE * in[i].RE + in[i].IM * in[i].IM, for i = 0...size-1
cpolar
Converts each vector element from rectangular to polar representation and stores the magnitude as real, the argument as imaginary part:
out[i].MAG = cabs(in), out[i].ARG = atan2(in[i].IM, in[i].RE), for i = 0...size-1
crect
Converts each vector element from polar to rectangular representation (wether it was the current representation or not...):
out[i].RE = in[i].MAG * cos(in[i].ARG), out[i].IM = in[i].MAG * sin(in[i].ARG), for i = 0...size-1
See also the functions for type conversion.
complex functions
fts_vec_conj(complex *in, complex *out, long size);
fts_vec_csqr(complex *in, complex *out, long size);
fts_vec_cpolar(complex *in, complex *out, long size);
fts_vec_crect(complex *in, complex *out, long size);

type conversions

These are functions for type conversion of the elements of a vector between float and complex as well as float and integer .

(in all functions converting complex vectors the complex vector elements are treated as if they are in rectangular representation):

cabsf
Computes the absolute value of all (complex) vector elements as elements of a float vector:
out[i] = sqrt(in[i].RE * in[i].RE + in[i].IM * in[i].IM), for i = 0...size-1
csqrf
Computes the square of all (complex) vector elements as elements of a float vector:
out[i] = in[i].RE * in[i].RE + in[i].IM * in[i].IM, for i = 0...size-1
csplit
Splits each element of a complex vector in to float elements of two float vectors out0 and out1:
out0[i] = in[i].RE, out1[i] = in[i].IM, for i = 0...size-1
cmerge
Merges the elements of two float vectors in0 and in1 to an element of a complex vector out:
out[i].RE = in0[i], out[i].IM = in1[i], for i = 0...size-1
fcpyre
Copies each element of a float vector in to the real part of the corresponding element of a complex vector out:
out[i].RE = in[i], for i = 0...size-1
fcpyim
Copies each element of a float vector in to the imaginary part of the corresponding element of a complex vector out:
out[i].IM = in[i], for i = 0...size-1
ffillre
Fills the real part of a complex vector with a float constant:
out[i].RE = scl, for i = 0...size-1
ffillim
Fills the imaginary part of a complex vector with a float constant:
out[i].IM = scl, for i = 0...size-1
re
Copies the real part of each element of a complex vector to the corresponding element of a float vector:
out[i] = in[i].RE, for i = 0...size-1
im
Copies the real part of each element of a complex vector to the corresponding element of a float vector:
out[i] = in[i].IM, for i = 0...size-1
fcasti
Converts a float vector in to an integer vector out by casting each element:
out[i] = (long)in[i], for i = 0...size-1
icastf
Converts an integer vector in to a float vector out by casting each element:
out[i] = (float)in[i], for i = 0...size-1
fcasti
Converts a float vector in to an integer vector out by rounding each element:
out[i] = (long)(in[i] + 0.5), for i = 0...size-1

float/complex conversion functions

fts_vec_cabsf(complex *in, float *out, long size);
fts_vec_csqrf(complex *in, float *out, long size);
fts_vec_re(complex in, float *out, long size);
fts_vec_im(complex in, float *out, long size);
fts_vec_csplit(complex *in0, float *out0, float *out1, long size);
fts_vec_cmerge(float *in0, float *in1, complex *out, long size);
fts_vec_fcpyre(float *in, complex *out, long size);
fts_vec_fcpyim(float *in, complex *out, long size);
fts_vec_ffillre(float scl, complex *out, long size);
fts_vec_ffillim(float scl, complex *out, long size);

float/integer conversion functions

fts_vec_fcasti(float *in, long *out, long size);
fts_vec_icastf(long *in, float *out, long size);
fts_vec_round(float *in, long *out, long size);

FFT functions

So far in FTS are implemented the classical FFT's with complex input and output and FFT functions for real signals.

The "real" FFT's are computed for a float time domain signal of size by use of a size/2 point complex FFT and some extra computation. In frequency domain there is just half of the complex spectrum and a single float for the signed magnitude of the bin related to the half sampling frequency.

There are two versions of each FFT function; one does the computation inplace the other may be used inplace as well as out of place. The inplace versions might be a little more efficient on some plattforms.

The size argument is allways related to the time domain data (number of float or complex points) and must be strictly a power of two. The lower and upper limit of the size is assigned to C makros.

    FTS_MIN_FFT_SIZE 16
    FTS_MAX_FFT_SIZE 134217728
  
This range can be guarantied for all plattforms, but on a single plattform the called routine (and with it the efficientcy of the FFT computation) might depend on the size argument.

Ones before an FFT computation of a certain size the function fts_fft_declaresize() must be called successfully with the size argument. The call of this function might cause the allocation and initialisation of FFT coefficient tables.

The function fts_is_fft_size() returns non zero if the given size argument is possible for an FFT computation, otherwise zero. The other FFT functions return fts_Success in case of success, otherwise an error handle.

FFT size declaration and test

fts_status_t fts_fft_declaresize(long size);
int fts_is_fft_size(long size);

complex FFT/IFFT

fts_status_t fts_cfft(complex *in, complex *out, long size);
fts_status_t fts_cfft_inplc(complex *buf, long size);
fts_status_t fts_cifft(complex *in, complex *buf, long size);
fts_status_t fts_cifft_inplc(complex *buf, long size);

real FFT/IFFT

fts_status_t fts_rfft(float *in, complex *out, float *mag_pi, long size);
fts_status_t fts_rfft_inplc(float *buf, float *mag_pi, long size);
fts_status_t fts_rifft(complex *in, float mag_pi, float *out, long size);
fts_status_t fts_rifft_inplc(float *buf, float mag_pi, long size);

The FTS Vector Library Reference Manual.

Author: nos

Copyright © 1996 IRCAM .