Ikaros Math Functions

This document documents all functions in the Ikaros math library. An introduction to the library is also aviable.

The functions in the Ikaros math library replace the functions in <math.h> or <cmath> with functions that are optimized for use with scalars, arrays, and matrices of floats. The library interfaces with BLAS functions and other vector optimized libraries, but also includes scalar implementations for use on systems that does not have Altivec or SSE support.

To use the matrix functions, the matrices should be allocated by the kernel or by using one of the utility functions. The matrix functions may not work if memory is allocated in some other way.

All the math functions are listed below divided into the following categories:

Constants

extern const float	pi;
extern const float	sqrt2pi;
extern const float	maxfloat;

Scalar Functions

float	exp(float x);
float	pow(float x, float y);

float	log(float x);
float	log10(float x);

Trigonometric Functions

The trigonometric functions are identical to the standard onces expect tah they operate on floats by default. The function atan2 also operates on arrays and matrices.

float    sin(float x);
float    cos(float x);
float    tan(float x);
float	 asin(float x);
float	 acos(float x);
float	 atan(float x);
float    atan2(float x, float y);
float *  atan2(float * r, float * a, float * b, int size);
float ** atan2(float ** r, float ** a, float ** b, int sizex, int sizey);

Gaussians

The scalar function gaussian calculates the gaussian of x with width set by sigma. The array and matrix versions do the same but for each element of the array or matrix. They all have the same sigma.

The set of functions gausian1 work in the same way but does not normalize the result. That is, the maximum element will be 1.

float    gaussian(float x, float sigma);
float *	 gaussian(float * r, float * a, float sigma, int size);
float ** gaussian(float ** r, float ** m, float sigma,
                                       int sizex, int sizey);

float    gaussian1(float x, float sigma);
float *	 gaussian1(float * r, float * a, float sigma, int size);
float ** gaussian1(float ** r, float ** m, float sigma,
                                       int sizex, int sizey);

There are also a number of functions to fill an array or matrix with a gaussian. The lcoation of the center of the gaussian is given by the argument x or x and y for the matrix case. The gaussian is clipped at the edges of the array or matrix and is subject to dithering. It can thus not be assumed that the sum of the elements will be exactly 1. As above, the gaussian1 functions do not normalize the gaussian.

float *  gaussian(float * r, float x, float sigma, int size);
float ** gaussian(float ** r, float x, float y, float sigma,
                                       int sizex, int sizey);

float *  gaussian1(float * r, float x, float sigma, int size);
float ** gaussian1(float ** r, float x, float y, float sigma,
                                       int sizex, int sizey);

Random Values

The function random is used to get a pseudorandom number between low an high. The array and matrix versions set every element to a random value.

float    random(float low, float high);
float *  random(float * r, float low, float high, int size);
float ** random(float ** r, float low, float high, int sizex, int sizey);

Tests

The functions zero and non_zero tests if an array or matrix contains only zero elements.

bool zero(float * a, int size);
bool zero(float ** m, int sizex, int sizey);
bool non_zero(float * a, int size);
bool non_zero(float ** m, int sizex, int sizey);

Squares and Square Roots

int      sqr(int x);
float    sqr(float x);
float *  sqr(float * a, int size);
float ** sqr(float ** r, int sizex, int sizey);
float *  sqr(float * r, float * a, int size);
float ** sqr(float ** r, float ** a, int sizex, int sizey);

float    sqrt(int x);
float    sqrt(float x);
float *  sqrt(float * a, int size);
float ** sqrt(float ** m, int sizex, int sizey);
float *  sqrt(float * r, float * a, int size);
float ** sqrt(float ** r, float ** a, int sizex, int sizey);

float    hypot(float x, float y);
float *  hypot(float * r, float * a, float * b, int size);
float ** hypot(float ** r, float ** a, float ** b, int sizex, int sizey);

Distances and Norms

The function dist calculates the euclidean distance between two arrays or matrices. In the matrix case, the whole matrix is treated as a single array. The function norm calculates the euclideas norm of its argument. The functions dist1 and norm1 operate in the same way, but use the city-block norm.

float dist(float * a, float * b, int size);
float dist(float ** a, float ** b, int sizex, int sizey);

float norm(float * a, int size);
float norm(float ** a, int sizex, int sizey);

float dist1(float * a, float * b, int size);
float dist1(float ** a, float ** b, int sizex, int sizey);

float norm1(float * a, int size);
float norm1(float ** a, int sizex, int sizey);

Three functions are available to normalize an array or matrix. The function normalize uses the euclidean norm and the resulting vector will have the length 1; normalize1 uses the city-block norm which results in a vector where the aboslute sum of the elemnts is 1; and normalize_max uses the max-norm which will reult in an array where the maximal element is 1.

float *     normalize(float * a, int size);
float **    normalize(float ** m, int sizex, int sizey);

float *     normalize1(float * a, int size);
float **    normalize1(float ** m, int sizex, int sizey);

float *     normalize_max(float * a, int size);
float **    normalize_max(float ** m, int sizex, int sizey);

Absolute Value

int      abs(int x);
float    abs(float x);
float *  abs(float * a, int size);
float ** abs(float ** m, int sizex, int sizey);
float *  abs(float * r, float * a, int size);
float ** abs(float ** r, float ** m, int sizex, int sizey);

Min and Max

int      min(int x, int y);
float    min(float x, float y);
float    min(float * a, int size);
float    min(float ** a, int sizex, int sizey);
float *  min(float * r, float * a, int size);
float ** min(float ** r, float ** a, int sizex, int sizey);
float *  min(float * r, float * a, float * b, int size);
float ** min(float ** r, float ** a, float ** b, int sizex, int sizey);

int      arg_min(float * a, int size);
void     arg_min(int & x, int & y, float ** a, int sizex, int sizey);

int      max(int x, int y);
float    max(float x, float y);
float    max(float * a, int size);
float    max(float ** a, int sizex, int sizey);
float *	 max(float * r, float * a, int size);
float ** max(float ** r, float ** a, int sizex, int sizey);
float *	 max(float * r, float * a, float * b, int size);
float ** max(float ** r, float ** a, float ** b, int sizex, int sizey);

int      arg_max(float * a, int size);
void     arg_max(int & x, int & y, float ** a, int sizex, int sizey);

float *  minmax(float & min, float & max, float * a, int size);
float ** minmax(float & min, float & max, float ** a, int sizex, int sizey);

Mean

The mean function calucalted the mean value of an array of matrix.

float mean(float * a, int size);
float mean(float ** a, int sizex, int sizey);

Clipping

The clip functions limit the value of a scalar, or the lements of an array or matix to the range specified.

float    clip(float x, float low, float high);
float *  clip(float * a, float low, float high, int size);
float ** clip(float ** a, float low, float high, int sizex, int sizey);
float *  clip(float * r, float * a, float low, float high, int size);
float ** clip(float ** r, float ** a, float low, float high, int sizex,
                                                             int sizey);

Addition

Calculating the sum of the elements in an array or matrix

float    add(float * a, int size); // sum a
float    add(float ** a, int sizex, int sizey); // sum a

Accumulation into an array or matrix

// r = r + alpha
float *  add(float * r, float alpha, int size);

// r = r + alpha
float ** add(float ** r, float alpha, int sizex, int sizey);

// r = r + a
float *  add(float * r, float * a, int size);

// r = r + a
float ** add(float ** r, float ** a, int sizex, int sizey);

Adding two values, possibly with scaling.

// r = a + b
float *  add(float * r, float * a, float * b, int size);

// r = a + b
float ** add(float ** r, float ** a, float ** b, int sizex, int sizey);

// r = r + alpha * a
float *  add(float * r, float alpha, float * a, int size);

// r = r + alpha * a
float ** add(float ** r, float alpha, float ** a, int sizex, int sizey);

// r = alpha * a + beta * b
float *  add(float * r, float alpha, float * a, float beta,
                                         float * b, int size);

// r = alpha * a + beta * b
float ** add(float ** r, float alpha, float ** a, float beta, 
                               float * b, int sizex, int sizey);

// r = alpha * a + beta
float *  add(float * r, float alpha, float * a, float beta, int size);

// r = alpha * a + beta
float ** add(float ** r, float alpha, float ** a, float beta,
                               int sizex, int sizey); 

Subtraction

There are four functions to subtract a constant from an array or matrix, or to subtract each element from a constant:

float *     subtract(float * r, float alpha, int size);
float **    subtract(float ** r, float alpha, int sizex, int sizey);
float *     subtract(float alpha, float * r, int size);
float **    subtract(float alpha, float ** r, int sizex, int sizey);

The other set of suntraction functions subtract two arrays or matrices:

float *  subtract(float * r, float * a, int size);
float ** subtract(float ** r, float ** a, int sizex, int sizey);
float *  subtract(float * r, float * a, float * b, int size);
float ** subtract(float ** r, float ** a, float ** b, int sizex, int sizey);

Multiplication

A number of multiplication functions perform element-wise multiplication:

float *	 multiply(float * a, float alpha, int size);
float ** multiply(float ** a, float alpha, int size);
float *  multiply(float * r, float * a, float alpha, int size);
float ** multiply(float ** r, float ** a, float alpha, int size);

float *  multiply(float * r, float * a, int size);
float ** multiply(float ** r, float ** a, int sizex, int sizey);
float *	 multiply(float * r, float * a, float * b, int size);
float ** multiply(float ** r, float ** a, float ** b, int sizex, int sizey);

The function multiply can also be used to perform a multiplcation between a matrix and a vector. The matrix a has sizey rows and sizex columns. The array b has sizex elements, and the result array r has sizey elements. The follwing syntax is used:

float *  multiply(float * r, float ** a, float * b, int sizex, int sizey);	

It is also possible to multiply two matrices. The arguments sizex and sizey are the size of resulting matrix. The argument n is the columns of a which must be equal to the number of rows of b.

float ** multiply(float ** r, float ** a, float ** b, int sizex,
                                                 int sizey, int n);	

The scalar product is calculated with the function dot. For a matrix, dot treats the matrix as one large vector (not as a set of vectors).

float    dot(float * a, float * b, int size);
float    dot(float ** a, float ** b, int sizex, int sizey);

The math library also contains a function to calculate the outer product of two array. The outer product is a matrix where each element is the product of two elements in the the two arrays: r[j][i] = a[i]*b[j]; sizex = sizeof(a), sizey = sizeof(b).

float ** outer(float ** r, float * a, float * b, int sizex, int sizey);		

Division

float *	 divide(float * r, float * a, int size);
float ** divide(float ** r, float ** a, int sizex, int sizey);
float *	 divide(float * r, float * a, float * b, int size);
float ** divide(float ** r, float ** a, float ** b, int sizex, int sizey);

Conversion

float trunc(float x);
int   lround(float x);


// min, max of float; byte is always 0-255

void  float_to_byte(unsigned char * r, float * a, float min, float max,
                                                              int size);


// min, max of float; byte is always 0-255

void  byte_to_float(float * r, unsigned char * a, float min, float max,
                                                              int size);


// convert to int; use d if char is NULL

int	  string_to_int(char * s, int d=0);  


// convert to float; use d if char is NULL

float  string_to_float(char * s, float d=0.0); 

Miscellaneous Functions

The function select_boltzmann selects an element of the matrix m accroing to the Bolzmann distributed generated by the lements in m. The result is returned in the arguments x an y, and T is the temperature of the distribution.

void  select_boltzmann(int & x, int & y, float ** m, int sizex, int sizey,
                                                                  float T);

To ascend or descend a gradient of the values represnted in a matyrix there are two functions ascend_gradient and descend_gradient. The starting point for the search for the local optimum is set in the arguments x and y and on return these values contain the coordinates for the local maximum (for ascend_gradient) or minium (for descend_gradient).

In the current implementation, these functions will not find an optimum along the border of the matrix.

void  ascend_gradient(int & x, int & y, float ** m, int sizex, int sizey);
void  descend_gradient(int & x, int & y, float ** m, int sizex, int sizey);

Image Processing

The functions convolve performs two-dimensional convolution of a source matrix (or image) with a kernel. The constants rsizex and rsizey give the size of the result matrix and ksizex and ksizey give the size of the kernel. The source matrix must have size (rsizex+ksizex-1) x (rsizey+ksizey-1). If ksizex and ksizey are odd, the function will call harware-optimized convolution functions when available. The argument bias is a constant which is added to each element of the result.

float ** convolve(
              float ** result,
              float ** source,
              float ** kernel,
              int rsizex,
              int rsizey,
              int ksizex,
              int ksizey,
              float bias = 0.0
         );

The function box_filter is a reasonably fast implementation of the box filter that sums all the matrix elements within each box of size boxsize x boxsize. After the call, the matrix r of size sizex x sizey will contain all the sums. The matrix a contains the source data and should be of size [sizex + boxsize - 1] x [sizey + boxsize - 1]. Finally, t is an optional temporary storage m,atrix of size [sizex] x [sizey + boxsize - 1]. If t==NULL, this matrix will be allocated internally for each call.

float ** box_filter(
              float ** r,
              float ** a,
              int sizex,
              int sizey,
              int boxsize,
              bool scale = false,
              float ** t = 0
         );