PyFI C++ API

The Array Object

template <class T>
class PyFI::Array

A simple n-D array class that is portable.

This array class holds a simple C-array segment with some additional dimension and type information that allows it to be converted to or from a Numpy (NPY) array. New instances can wrap existing C-array segments or can allocate new memory either from C (via calloc()) or from the Python interpreter (via PyFI::SET_OUTPUT_ALLOC()).

The Array class also contains member functions for simplifying indexing, debugging, math operators and other common operations used in signal processing.

Public Functions

Array(const std::vector<uint64_t> &dims)

Construct an Array from a standard vector object.

Parameters
  • dims -

    A vector holding the dimension lengths.

Array(const ArrayDimensions &dmo)

Construct an Array from an ArrayDimensions object.

Parameters

Array(uint64_t ndim, uint64_t *dimensions)

Construct an Array from a C-array.

Parameters
  • ndim -

    The number of dimensions (rank).

  • dimensions -

    A pointer to a C-array that holds the lengths of each dimension.

Array(uint64_t ndim, uint64_t *dimensions, T *seg_ptr)

Construct an existing memory segment (i.e.

pre-allocated C-array).

Parameters
  • ndim -

    The number of dimensions (rank).

  • dimensions -

    A pointer to a C-array that holds the lengths of each dimension.

  • seg_ptr -

    A pointer to the first element of a C-array of the same type as this Array.

Array(const Array<T> &arr)

The copy constructor.

Construct a copy of another Array instance.

Parameters
  • arr -

    An Array to copy.

Array(const uint64_t ndim, const Array<uint64_t> &arr)

Construct and copy the first few dimensions of an Array.

Parameters
  • ndim -

    The number of dimensions to copy starting from the n-th dimension of arr.dimensions().

  • arr -

    An Array to copy.

Array(uint64_t i)

Construct a new Array instance by dimension length (column major ordering).

Array<float> myArray(10); // a 1D array
Array<float> myArray3(10,10,2); // a 3D array with the fastest
                                // varying dimension of length 2.

Parameters
  • i...n -

    lengths for each dimension.

~Array()

The Array destructor frees all data()-segment and dimensions() array memory.

If the array is wrapping an external segment (i.e. isWrapper()) then only the dimensions() array is free’d.

const uint64_t ndim() const

Return
The number of dimensions (or rank) of this Array.

const uint64_t *dimensions() const

Return
A pointer to the first element of the dimensions() array, which is a standard C-array.

std::vector<uint64_t> dimensions_vector()

Return
A standard template library vector object that represents the size and dimensionality of this Array instance.

const uint64_t dimensions(uint64_t i) const

Return
The length of a specific dimension (indexed by i) of this Array.

const uint64_t size(uint64_t i) const

Return
The length of a specific dimension (indexed by i) of this Array.

ArrayDimensions dims_object()

Return
An ArrayDimensions object that represents the size and dimensionality of this Array instance.

const uint64_t size() const

Return
The total number of elements in this array (if its multi-dimensional then its the number of elements as if it were 1D).

T *data() const

Return
A pointer to the first element of the internal C-array segment.

const bool isWrapper() const

Return
Whether or not this Array instance is wrapping a data segment that is owned by another piece of code (e.g. Python/Numpy or another Array).

T &get1v(uint64_t i, uint64_t v)

Index the array as if it were a 2D array where i indexes all dimensions up to n-1 as if they were concatenated into one dimension and v indexes the remaining n-th dimension.

Return
The data() value at the given index.
Parameters
  • i -

    One dimensional indexing.

  • v -

    Index of the last dimension.

T &operator()(uint64_t i)

Index the array as if it were a 1D array.

If this is a multidimensional array, i indexes all dimensions as if they were concatenated into one dimension. If multiple indices are used they must match the number of dimensions (ndim()) of the Array.

For example, an 3D array arr can be indexed as a 1D array:

Array<float> arr(10,10,10);
arr(0);
arr(999);

Or as a 3D array:

arr(2,3,4);

In order to use the full debugging features of the Array class the indexing must be done with the ‘get<ndim>’ macros as shown below:

get1(arr, 0);
get1(arr, 999);
get3(arr, 2,3,4);

The ‘get’ macros automatically add the filename and line number for each indexing call to an array. When compiled in debug mode, any array faults or exceptions will contain this information.

Note
The 1-6 dimensional indexing uses direct multiplication operations to reference the index. For 7 and up dimensions use looped indexing functions which can be a little slower.
Return
The data() value at the given index.
Parameters
  • i...n -

    indexes for each dimension.

Array<T> &operator=(const Array<T> &arr)

Array assignment operator.

This an be used to copy the elements of one array to another.

Array<float> arr1(10);
Array<float> arr2(10);

arr1 = arr2;

Note
This only copies elements because the segment being wrapped might be owned by Python.
Parameters

Array<T> &operator*=(Array<T> arr)

Multiplication assignment operator.

Does element-wise multiplication.

Parameters

Array<T> &operator/=(Array<T> arr)

Division assignment operator.

Does element-wise division.

Note
debug mode will throw an exception for divide by zeros.
Parameters

Array<T> &operator-=(Array<T> arr)

Subtraction assignment operator.

Does element-wise subtraction.

Parameters

Array<T> &operator+=(Array<T> arr)

Addition assignment operator.

Does element-wise addition.

Parameters

Array<T> operator*(Array<T> arr)

Multiplication operator.

Return
element-wise Array product.
Parameters

Array<T> operator/(Array<T> arr)

Division operator.

Return
element-wise Array division.
Note
debug mode will throw an exception for divide by zeros.
Parameters

Array<T> operator-(Array<T> arr)

Subtraction operator.

Return
element-wise Array difference.
Parameters

Array<T> operator+(Array<T> arr)

Addition operator.

Return
element-wise Array addition.
Parameters

Array<T> &operator=(T c)

Assignment operator.

Parameters
  • c -

    a single value to set all elements.

void set(T c)

Sets all values to the constant and implicit casting of c.

Parameters
  • c -

    A value.

Array<T> &operator*=(T c)

Multiplication assignment operator.

Parameters
  • c -

    a single value to multiply all elements.

Array<T> &operator/=(T c)

Division assignment operator.

Note
debug mode will throw an exception for divide by zeros.
Parameters
  • c -

    a single value to divide all elements.

Array<T> &operator-=(T c)

Subtraction assignment operator.

Parameters
  • c -

    a single value to subtract from all elements.

Array<T> &operator+=(T c)

Addition assignment operator.

Parameters
  • c -

    a single value to add to all elements.

Array<bool> operator==(T c)

Boolean equivalence operator.

Return
A boolean mask (Array) of the element-wise comparison.
Parameters
  • c -

    A single value to compare to all elements.

Array<bool> operator!=(T c)

Boolean non-equivalence operator.

Return
A boolean mask (Array) of the element-wise comparison.
Parameters
  • c -

    A single value to compare to all elements.

Array<bool> operator<=(T c)

Boolean less-than or equal-to operator.

Return
A boolean mask (Array) of the element-wise comparison.
Parameters
  • c -

    A single value to compare to all elements.

Array<bool> operator>=(T c)

Boolean greater-than or equal-to operator.

Return
A boolean mask (Array) of the element-wise comparison.
Parameters
  • c -

    A single value to compare to all elements.

Array<bool> operator<(T c)

Boolean less-than operator.

Return
A boolean mask (Array) of the element-wise comparison.
Parameters
  • c -

    A single value to compare to all elements.

Array<bool> operator>(T c)

Boolean greater-than operator.

Return
A boolean mask (Array) of the element-wise comparison.
Parameters
  • c -

    A single value to compare to all elements.

Array<bool> operator==(Array<T> arr)

Boolean array equivalence operator.

Return
A boolean mask (Array) of the element-wise comparison.
Parameters

Array<bool> operator!=(Array<T> arr)

Boolean array non-equivalence operator.

Return
A boolean mask (Array) of the element-wise comparison.
Parameters

Array<bool> operator>=(Array<T> arr)

Boolean array greater-than or equal-to operator.

Return
A boolean mask (Array) of the element-wise comparison.
Parameters

Array<bool> operator<=(Array<T> arr)

Boolean array less-than or equal-to operator.

Return
A boolean mask (Array) of the element-wise comparison.
Parameters

Array<bool> operator<(Array<T> arr)

Boolean array less-than operator.

Return
A boolean mask (Array) of the element-wise comparison.
Parameters

Array<bool> operator>(Array<T> arr)

Boolean array greater-than operator.

Return
A boolean mask (Array) of the element-wise comparison.
Parameters

T sum()

Array Sum.

Return
The sum of all elements.

T prod()

Array Product.

Return
The product of all elements.

T min()

Array Min.

Return
The Array min value.

T max()

Array Max.

Return
The Array max value.

double max_mag()

Array Max Magnitude.

Return
The Array max magnitude value (handy for complex Array types).

void abs()

Sets each element of this Array to the absolute value of the element.

bool any_infs()

Checks for Inf values.

Return
true if at least one element value is inf.

bool any_nans()

Checks for NaN values.

Return
true if at least one element value is NaN.

void clamp_min(T thresh)

Threshold the data, set all data less than thresh equal to thresh.

Parameters
  • thresh -

    The threshold value.

void clamp_max(T thresh)

Threshold the data, set all data greater than thresh equal to thresh.

Parameters
  • thresh -

    The threshold value.

bool any(T val)

See if there are any elements with this value.

Return
true if the value is present in the Array.
Parameters
  • val -

    The value to search for.

T mean()

The average of all the elements.

Return
The average value.

T stddev()

The standard deviation of all elements.

Return
The standard deviation.

Array<uint64_t> as_ULONG()

Recast Array as uint64_t.

Return
Array<uint64_t> with recast elements from this Array.

Array<float> as_FLOAT()

Recast Array as float.

Return
Array<float> with recast elements from this Array.

Array<complex<float>> as_CFLOAT()

Recast Array as complex<float>.

Return
Array<complex<float> > with recast elements from this Array.

Array<double> as_DOUBLE()

Recast Array as complex<double>.

Return
Array<complex<double> > with recast elements from this Array.

Array<complex<double>> as_CDOUBLE()

Recast Array as complex<double>.

Return
Array<complex<double> > with recast elements from this Array.

Array<int64_t> as_LONG()

Recast Array as int64_t.

Return
Array<int64_t> with recast elements from this Array.

Array<int32_t> as_INT()

Recast Array as int32_t.

Return
Array<int32_t> with recast elements from this Array.

Array<uint8_t> as_UCHAR()

Recast Array as int8_t.

Return
Array<int8_t> with recast elements from this Array.

Array<T> &insert(Array<T> &in)

Inserts the data from in into this Array in a centered way by cropping or zero-padding.

This will insert a zero-padded or cropped Array into this. This occurs, keeping fft in mind. For instance a cropped version will crop the outer extra data, inserting the center into this. Each dimension is handled independently, therefore allowing cropping in one dimension while zero-padding in another.

Return
A reference to this Array of the same type as in, yet each dimension may independently be resized to a smaller or larger size. The number of dimensions, ndim(), must match with in.
Parameters

void reshape(std::vector<uint64_t> &idims)

Make this array a new dimensionality that has the same total size as the original (i.e.

modify the dimensions()).

Parameters
  • idims -

    A standard vector containing the new dimensions (the dimension size() must match).

Array<T> get_resized(std::vector<uint64_t> idims)

Create a new resized array with the contents of THIS array centered.

Return
A new Array.
Parameters
  • idims -

    A standard vector with number of dimensions (ndim() equal to this.ndim()).

Array<T> get_resized(double scale)

Create a new resized array with the contents of THIS array centered.

Return
A new Array.
Parameters
  • scale -

    The factor applied to each of the dimension lengths of this array.

Array<T> get_resized(double *scale)

Create a new resized array with the contents of THIS array centered.

Return
A new Array.
Parameters
  • scale -

    A C-array containing the scale factors applied to each of the dimension lengths of this.dimensions() array.

Array<T> get_resized(std::vector<double> scale)

Create a new resized array with the contents of THIS array centered.

Return
A new Array.
Parameters
  • scale -

    A standard vector containing the scale factors applied to each of the dimension lengths of this.dimensions() array.

Array<T> get_resized(uint64_t *idims)

Create a new resized array with the contents of THIS array centered.

Return
A new Array.
Parameters
  • idims -

    A C-array with length equal to this.ndim() which contains the new dimensions of the output Array.

The ArrayDimensions Object

class PyFI::ArrayDimensions

An object that holds Array dimensionality information for constructing Array instances or converting this information between objects such as C-arrays or standard vectors.

Public Functions

const uint64_t ndim() const

Return
The number of Array dimensions (i.e. rank).

const uint64_t *dimensions() const

Return
A pointer to the first element in the dimensions array.

std::vector<uint64_t> dimensions_vector()

Return
A standard vector loaded with the elements of the dimensions() array.

const uint64_t dimensions(uint64_t i) const

Return
The length of the dimension at index i.
Parameters
  • i -

    Dimension index.

ArrayDimensions(const std::vector<uint64_t> &dims)

Construct an ArrayDimensions object from a standard vector.

Parameters
  • dims -

    A standard vector.

ArrayDimensions(uint64_t ndim, uint64_t *dimensions)

Construct an ArrayDimensions object from a C-array.

An Array can also be used to construct an ArrayDimensions object via the DA() macro, which uses this constructor interface.

Array<uint64_t> arr(3); // a 1D array
arr(0) = 10;
arr(1) = 10;
arr(2) = 2;
DA(arr); // an ArrayDimensions object with dimensions (10,10,2)
         // taken from the elements of the Array.

Parameters
  • ndim -

    The number of dimensions (i.e. rank).

  • dimensions -

    A pointer to a C-array containing the dimension lengths.

ArrayDimensions(uint64_t i)

Construct a new ArrayDimensions instance by dimension length (column major ordering).

ArrayDimensions aDims(10); // dims for a 1D array
ArrayDimensions myDims(10,10,2); // dims for a 3D array with the
                                 // fastest varying dimension of
                                 // length 2.

Parameters
  • i...n -

    lengths for each dimension.

~ArrayDimensions()

The ArrayDimensions destructor.

This frees the contained C-array.

bool operator==(const ArrayDimensions &rhs) const

The equality operator.

Return
true if the two ArrayDimensions are the same.

bool operator!=(const ArrayDimensions &rhs) const

The equality operator.

Return
false if the two ArrayDimensions are the same.

PyFEigen Interface

namespace PyFI::PyFEigen

Functions

template <class T>
void PrintArrayAsEigenMat(Array<T> &A)

PrintArrayAsEigenMat(Array<T> &A)

Wraps a PyFI array in an Eigen Matrix and prints the contents. This is a useful test for the Eigen wrapping method.

Parameters
  • A -

    An input Array object.

template <class T>
void PseudoInverse(Array<T> &Matrix, Array<T> &InverseMatrix)

Pseudo Inverse.

Parameters
  • Matrix -

    An input Array representing a 2D matrix.

  • InverseMatrix -

    The output Array representing the matrix inverse.

template <class T>
void MMult(Array<T> &A, Array<T> &B, Array<T> &C)

Matrix multiplication A*B = C.

Parameters
  • A -

    An input Array (matrix).

  • B -

    An input Array (matrix).

  • C -

    The output Array (matrix).

template <class T>
void MLDivide(Array<T> &A, Array<T> &B, Array<T> &X)

A linear solver for systems of the form Ax = B.

Parameters
  • A -

    The encoding matrix.

  • B -

    The observation vector.

  • X -

    The solution matrix.

FFTW Interface

namespace PyFI::FFTW

Functions

template <class T>
void check_array(Array<T> &in, Array<T> &out, uint64_t numberDimensions, int fftDirection, const char *functionName)
template <class T>
void fft_scale(Array<T> &toBeScaled, double scale)
template <class T>
void shift1(Array<T> &shiftIn, Array<T> &shiftOut, int position)

These functions perform an out-of-place shift on R2 Arrays.

Both odd and even length data sets are accounted for. In k-space, the DC value is commonly placed at the middle point. In order to perform the fft using FFTW, the DC value needs to be shifted to the first index (i.e. (0,0) for a 2D data set). Upon completion of the fft, the first index needs to be shifted back to the middle point. (This shifting is also required when going from image space to k-space.) For even length data sets, the same shift can be used before and after the fft operation. However, odd length data sets require a different shift before and after the fft operation.

Usage: the following are examples of how the functions are used:

shift1(in,out,beforeFFT); // 1D shift performed before fft
shift2(in,out,afterFFT); // 2D shift performed after fft
Parameters
  • shiftIn -

    is of Array<T> type and represents the array for which shifting needs to be done.

  • shiftOut -

    is of Array<T> type and represents the field to which the shifted data will be written. (FOR OUT-OF-PLACE SHIFTING, shiftOut CANNOT BE EQUAL TO shiftIn.)

  • position -

    is of int type and represents the position of the shift in respect to the fft operation. Position can be set equal to beforeFFT or afterFFT which are predefined constants (see fft_utils.hpp).

template <class T>
void shift2(Array<T> &shiftIn, Array<T> &shiftOut, int position)

2D array shift (see shift1()).

template <class T>
void shift3(Array<T> &shiftIn, Array<T> &shiftOut, int position)

3D array shift (see shift1()).

template <class T>
void shift1n(Array<T> &shiftIn, Array<T> &shiftOut, int position, uint64_t fftDim)

1D array shift in any dimension (see shift1()).

template <class T>
void fft1(Array<T> &in, Array<T> &out, int fftDirection)

These functions perform the called fft on the data.

They are responsible for generating the fft plan (for FFTW), calling on the appropriate shifting functions, and executing the fft plan (using FFTW functions). The fftw advanced interface is used for fft1, fft2, and fft3, while the fftw guru interface is used for fft1n. If the global_shiftMode flag is set to SHIFT_OFF, the following functions will perform an fft without shifting the data.

Parameters
  • in -

    Represents the array upon which the fft will be performed.

  • out -

    Represents the array to which the result of the fft will be written. (in CAN BE EQUAL TO out).

  • fftDirection -

    Represents the direction of fft. It can be set equal to one of two constants (FFTW_FORWARD for a forward fft or FFTW_BACKWARD for an inverse fft) as pre-defined by the FFTW library.

template <class T>
void fft2(Array<T> &in, Array<T> &out, int fftDirection)

2D fft (see fft1).

template <class T>
void fft3(Array<T> &in, Array<T> &out, int fftDirection)

3D fft (see fft1).

template <class T>
void fft1n(Array<T> &in, Array<T> &out, int fftDirection, uint64_t fftDim)

1D fft in any dimension (see fft1).

Variables

pthread_mutex_t _fftw_mutex
unsigned global_fftFlags
int global_shiftMode

Numpy Interface

namespace PyFI::Numpy

Functions

template <class T>
Array<T> pinv(Array<T> &A)

Pseudo inverse from the numpy.linalg package.

Return
The pseudo inverse of A.
Parameters
  • A -

    A 2D Array to be inverted.

template <class T>
double cond(Array<T> &A)

The numpy.linalg.cond() function.

To check the condition numbers before running pinv.

Return
The condition of A.
Parameters
  • A -

    A 2D Array to be inverted.

template <class T>
void writeNPY(const std::string fname, Array<T> &A)

Write an Array to a numpy formatted file.

Parameters
  • fname -

    A standard template library string containing a valid filename.

  • A -

    An Array to be written to file.

template <class T>
Array<T> fft1(Array<T> &in, bool forward)
template <class T>
void printArray(Array<T> &in)

Take advantage of the pretty numpy array printing (for supported array types).

Parameters
  • in -

    An Array to be printed to stdout.

template <class T>
Array<T> matmult(Array<T> &a, Array<T> &b)

Matrix multiplication using the numpy.dot function.

Return
Array dot product.
Parameters

template <class T>
Array<T> transpose(Array<T> &a)

Matrix transpose using the numpy.transpose function.

Return
A^T
Parameters

The PyCallable Object

class PyFI::PyCallable

A simple interface object to a Python callable.

This provides Python functions to the C/C++ environment with minimal setup. The PyCallable object essentially does 3 things: 1 the numeric array translation is handled between Numpy and the Array object, 2 embeds the Python interpreter and 3 all array pointers are destructed when the PyCallable object falls out of scope.

An example a matrix transpose using the numpy.transpose function:

Array<double> A(5,10); // matrix to be transposed

PyCallable tp("numpy", "transpose"); // setup the transpose function

tp.SetArg_Array(&A); // push 'A' onto the arg list to be passed to numpy.transpose(*arg)

Array<T> *out=NULL;
tp.GetReturn_Array(&out); // exec Python and pop the result from the return list

Public Functions

PyCallable(const string module, const string function)

The “module-function” constructor.

Run an existing function from the given module & function supplied in each string.

// C-code...
PyCallable myPinv("scipy.linalg", "pinv");

# Under the hood in Python...
from scipy.linalg import pinv

Parameters
  • module -

    The Python accessible module name (e.g. “scipy.linalg”).

  • function -

    The function implemented by that module (e.g. “pinv”).

PyCallable(const string code)

The “script-as-a-string” constructor.

Run a Python script from a supplied string. The script must define a function named “func”. This function will be executed by PyCallable and if it returns the output will be made available via the GetReturn_<type>() member functions.

// Define the python code in a string, taking care to include line
// endings and correct indentation.
string code = "def func(in1):\n"
              "    from numpy.fft import fft, fftshift, ifftshift\n"
              "    return fftshift( fft( ifftshift(in1) ) ).astype(in1.dtype)\n";
PyCallable fft_script(code);

Parameters
  • code -

~PyCallable()

The destructor frees all input arguments, generated arrays, and unloads any Python modules and functions.

void Reset(void)

Resets the input and output args for a new run.

void Run(void)

Runs the Python code assembled by the constructor.

Note
This is only necessary if a GetReturn_<type>() function is not going to be called or if the actual Python code execution time is crucial.

void SetArg_String(const string in)

Push a string onto the argument list that will be sent to the function defined in the constructor.

Parameters
  • in -

    A string argument to be passed to Python code.

void SetArg_Long(const int64_t in)

Push an integer onto the argument list that will be sent to the function defined in the constructor.

Parameters
  • in -

    An integer argument to be passed to Python code.

void SetArg_Double(double in)

Push an double precision float onto the argument list that will be sent to the function defined in the constructor.

Parameters
  • in -

    An double precision float argument to be passed to Python code.

template <class T>
void SetArg_Array(T *out_ptr)

Push an Array onto the argument list that will be sent to the function defined in the constructor.

This will convert to a Numpy array in Python.

Parameters
  • in -

    An Array argument to be passed to Python code.

template <class T>
void GetReturn_Array(T **out_ptr)

Pop an Array off of the return-list object that will be sent back to the PyCallable defined in the C-code.

This will convert a Numpy array to an Array object.

Note
If Run() hasen’t been called yet, the first GetReturn_<type>() function will automatically call it.
Return
Array

string GetReturn_String(void)

Pop a string off of the return-list object that will be sent back to the PyCallable defined in the C-code.

Note
If Run() hasen’t been called yet, the first GetReturn_<type>() function will automatically call it.
Return
standard library string

int64_t GetReturn_Long(void)

Pop a long integer off of the return-list object that will be sent back to the PyCallable defined in the C-code.

Note
If Run() hasen’t been called yet, the first GetReturn_<type>() function will automatically call it.
Return
an int64_t long integer type

double GetReturn_Double(void)

Pop a double precision float off of the return-list object that will be sent back to the PyCallable defined in the C-code.

Note
If Run() hasen’t been called yet, the first GetReturn_<type>() function will automatically call it.
Return
a double precision float