STATUS: work in progress Numerical Arrays. More...
#include "definitions.h"
#include "mathadd.h"
Go to the source code of this file.
Data Structures | |
struct | Array |
Numerical Array struct. More... | |
Defines | |
#define | DIM_COLS 1 |
#define | DIM_ROWS 0 |
| |
#define | array_SIZEOF_DTYPE(size, dtype) |
get size of datatype. | |
#define | array_DTYPESTRING(dtstring, dtype) |
convert datatype to a string representation. | |
#define | array_NUMEL(a) ( ((a)->nbytes)/((a)->dtype_size) ) |
get number of elements in array. | |
#define | array_DTYPEPRINT(out, dtype, mem) |
Print an array-datatype. | |
#define | array_MEMSET(mem, dtype, val) |
set the memory mem to value of type dtype. | |
#define | array_INDEX1(array, dtype, i1) |
fast 1D array indexing typecasting to C-type. | |
#define | array_INDEX2(array, dtype, i1, i2) |
fast 2D array indexing typecasting to C-type. | |
#define | array_INDEX3(array, dtype, i1, i2, i3) |
fast 3D array indexing typecasting to C-type. | |
#define | array_INDEXMEM1(array, i1) |
fast 1D array indexing returning a void pointer. | |
#define | array_INDEXMEM2(array, i1, i2) |
fast 2D array indexing returning a void pointer. | |
#define | array_INDEXMEM3(array, i1, i2, i3) |
fast 3D array indexing returning a void pointer. | |
enum | DType { CHAR = 0, UINT, INT, LONG, ULONG, FLOAT, DOUBLE } |
Data-types for Array struct. More... | |
Array * | array_new (DType dtype, uint ndim, const uint *dims) |
Initialize new array struct. | |
Array * | array_new2 (DType dtype, uint ndim,...) |
Initialize new array struct. | |
Array * | array_fromptr (DType dtype, uint ndim, void *data, const uint *size) |
Initialize new array struct. | |
Array * | array_fromptr2 (DType dtype, uint ndim, void *data,...) |
Initialize new array struct. | |
Array * | array_new_dummy (DType dtype, uint ndim,...) |
create array that is filled with values from 1 to n over all dimensions. | |
Array * | array_randunif (unsigned long seed, uint ndim,...) |
create array that is filled with random values from [0, ..., 1]. | |
bool | array_comparable (const Array *a, const Array *b) |
Compare two array's dimensions and datatype. | |
Array * | array_copy (const Array *in, bool allocdata) |
makes a copy of an array. | |
void | array_free (Array *a) |
free all memory associated with the array. | |
void | array_shuffle (Array *a, unsigned long seed) |
shuffle the entries of an array. | |
void | array_typecast (Array *a, DType target_type) |
Array-typecast. | |
void * | array_index (const Array *a, uint *idx) |
Index the array. | |
void * | array_index2 (const Array *a,...) |
Index the array. | |
Array * | array_slice (const Array *a, const char *slicedesc) |
Extract sub-arrays from array. | |
Array * | array_concatenate (const Array *a, const Array *b, int dim) |
concatenate two arrays. | |
int | array_scale (Array *a, double x) |
multiply all entries in array with x. | |
void | array_reverse (Array *a) |
Reverse order of elements in a (in-place). | |
int | array_dimred (Array *a) |
Delete unnecessary dimensions (of size 1). | |
void * | array_max (const Array *a) |
Get maximum element from array. | |
void * | array_min (const Array *a) |
Get minimum element from array. | |
Array * | array_convert_rowcolmajor (Array *a, bool alloc) |
convert a row-major array to col-major. | |
void | array_calc_colindex (ulong idx, const uint *size, uint nsize, uint *index) |
calculate the column-major index-tuple given the offset from element 0. | |
void | array_calc_rowindex (ulong idx, const uint *size, uint nsize, uint *index) |
calculate the row-major index-tuple given the offset from element 0. | |
void | array_print (Array *a, uint nel_per_dim, FILE *out) |
print an array. | |
void | array_dtype_to_double (double *out, void *mem, DType dt) |
cast memory of type dt in location mem to double. |
STATUS: work in progress Numerical Arrays.
This is an efficient implementation of a numerical array of
The library provides some convenient functionality:
In principle, an Array struct can hold n-dimensional arrays of any type implemented in DType. All functions starting with the prefix array_*() operate on arbitrary dimensions and types.
Working with arbitray types requires some sophistication if it is conducted at runtime.
To read elements in the array where you don't know the type, you can convert the element to double using array_dtype_to_double()
// void array_dtype_to_double( double *out, void *mem, DType dt ); void *mem = array_index( a, 3, 4 ); // access element (3,4) double el; array_dtype_to_double( &el, mem, a->dtype ); // work with el
To write elements in the array of unknown type, you can use the macro array_MEMSET()
// #define array_MEMSET( mem, dtype, val ) void *mem = array_index( a, 3, 4 ); // access element (3,4) array_MEMSET( mem, a->dtype, 3 ); // set element to 3 (value is casted)
To write functions that operate on arbitrary dimensions is either very simple (if the operation you want to apply is the same for all elements) or very complicated.
If you want to apply a per-element operation on all elements in the array, you can simply loop over them:
Array *a=get_array_from_somewhere(); long i, n = array_NUMEL( a ); // number of elements double *mem; for( i=0; i<n; i++ ){ mem=&array_INDEX1( a, double, i ); // if you know the type // ... // operate on *mem // ... }
However, for numerical work, it is in most cases sufficient to operate on floating point numbers. Therefore, 1D and 2D Array structs of DType DOUBLE are used to represent vectors and matrices, respectively. I.e. that each function starting with matrix_*( Array m ) accepts only 2D Arrays of DType DOUBLE functions starting with vector_*( Array *m ) accept only 1D Arrays of DType DOUBLE. This is checked with the Macros matrix_CHECK() and vector_CHECK(). See also linalg.h .
Indexing the n-dimensional array can be done via two routes:
It is often necessary to get parts of arrays for computation. Inspired by slicing in MATLAB, a string representing the slice is composed as follows:
Examples:
// 3D-array Array *a = array_new( DOUBLE, 3, 10, 11, 12 ); // Here b is a new 3D-array containing all elements in the first dimension, // the first 4 in the second and elements 1,2,3 in the third. Array *b = array_slice( a, ":,0-3,[1 2 3]"); // c is a 2D array Array *c = array_slice( a, ":,:,1"); // d is a 1D array Array *d = array_slice( a, ":,3,1");
Depending on how you initialize and Array, the struct takes over responsibility to free the array->data pointer or not. This is implemented using the array->free_data flag. Some functions take a 'alloc'-flag which indicates whether memory is shared or not. Usually, the 'parent'-array has the resonsibility then.
Definition in file array.h.