PyFI C++ API¶
The Array Object¶
- template <class T>
- class
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
-
PyFI::Array
::
Array
(const std::vector<uint64_t> &dims)¶ Construct an Array from a standard vector object.
- Parameters
dims
-A vector holding the dimension lengths.
-
PyFI::Array
::
Array
(const ArrayDimensions &dmo)¶ Construct an Array from an ArrayDimensions object.
- Parameters
dmo
-An ArrayDimensions object holding the dimension lengths.
-
PyFI::Array
::
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.
-
PyFI::Array
::
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.
-
PyFI::Array
::
Array
(const Array<T> &arr)¶ The copy constructor.
Construct a copy of another Array instance.
- Parameters
arr
-An Array to copy.
-
PyFI::Array
::
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.
-
PyFI::Array
::
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.
-
PyFI::Array
::
~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 *PyFI::Array
::
dimensions
()¶
const - Return
- A pointer to the first element of the dimensions() array, which is a standard C-array.
-
std::vector<uint64_t> PyFI::Array
::
dimensions_vector
()¶ - Return
- A standard template library vector object that represents the size and dimensionality of this Array instance.
-
const uint64_t PyFI::Array
::
dimensions
(uint64_t i)¶
const - Return
- The length of a specific dimension (indexed by
i
) of this Array.
-
const uint64_t PyFI::Array
::
size
(uint64_t i)¶
const - Return
- The length of a specific dimension (indexed by
i
) of this Array.
-
ArrayDimensions PyFI::Array
::
dims_object
()¶ - Return
- An ArrayDimensions object that represents the size and dimensionality of this Array instance.
-
const uint64_t PyFI::Array
::
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 *PyFI::Array
::
data
()¶
const - Return
- A pointer to the first element of the internal C-array segment.
-
T &PyFI::Array
::
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 andv
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 &PyFI::Array
::
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> &PyFI::Array
::
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;
-
Array<T> &PyFI::Array
::
operator*=
(Array<T> arr)¶ Multiplication assignment operator.
Does element-wise multiplication.
-
Array<T> &PyFI::Array
::
operator/=
(Array<T> arr)¶ Division assignment operator.
Does element-wise division.
-
Array<T> &PyFI::Array
::
operator-=
(Array<T> arr)¶ Subtraction assignment operator.
Does element-wise subtraction.
-
Array<T> &PyFI::Array
::
operator+=
(Array<T> arr)¶ Addition assignment operator.
Does element-wise addition.
-
Array<T> &PyFI::Array
::
operator=
(T c)¶ Assignment operator.
- Parameters
c
-a single value to set all elements.
-
void PyFI::Array
::
set
(T c)¶ Sets all values to the constant and implicit casting of c.
- Parameters
c
-A value.
-
Array<T> &PyFI::Array
::
operator*=
(T c)¶ Multiplication assignment operator.
- Parameters
c
-a single value to multiply all elements.
-
Array<T> &PyFI::Array
::
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> &PyFI::Array
::
operator-=
(T c)¶ Subtraction assignment operator.
- Parameters
c
-a single value to subtract from all elements.
-
Array<T> &PyFI::Array
::
operator+=
(T c)¶ Addition assignment operator.
- Parameters
c
-a single value to add to all elements.
-
Array<bool> PyFI::Array
::
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> PyFI::Array
::
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> PyFI::Array
::
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> PyFI::Array
::
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> PyFI::Array
::
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> PyFI::Array
::
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.
-
bool PyFI::Array
::
any_infs
()¶ Checks for Inf values.
- Return
- true if at least one element value is inf.
-
bool PyFI::Array
::
any_nans
()¶ Checks for NaN values.
- Return
- true if at least one element value is NaN.
-
void PyFI::Array
::
clamp_min
(T thresh)¶ Threshold the data, set all data less than thresh equal to thresh.
- Parameters
thresh
-The threshold value.
-
void PyFI::Array
::
clamp_max
(T thresh)¶ Threshold the data, set all data greater than thresh equal to thresh.
- Parameters
thresh
-The threshold value.
-
bool PyFI::Array
::
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.
-
Array<uint64_t> PyFI::Array
::
as_ULONG
()¶ Recast Array as uint64_t.
- Return
- Array<uint64_t> with recast elements from this Array.
-
Array<float> PyFI::Array
::
as_FLOAT
()¶ Recast Array as float.
- Return
- Array<float> with recast elements from this Array.
-
Array<int64_t> PyFI::Array
::
as_LONG
()¶ Recast Array as int64_t.
- Return
- Array<int64_t> with recast elements from this Array.
-
Array<int32_t> PyFI::Array
::
as_INT
()¶ Recast Array as int32_t.
- Return
- Array<int32_t> with recast elements from this Array.
-
Array<uint8_t> PyFI::Array
::
as_UCHAR
()¶ Recast Array as int8_t.
- Return
- Array<int8_t> with recast elements from this Array.
-
Array<T> &PyFI::Array
::
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.
-
void PyFI::Array
::
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> PyFI::Array
::
get_resized
(std::vector<uint64_t> idims)¶ Create a new resized array with the contents of THIS array centered.
-
Array<T> PyFI::Array
::
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> PyFI::Array
::
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.
-
PyFI::Array
The ArrayDimensions Object¶
- class
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 PyFI::ArrayDimensions
::
ndim
()¶
const - Return
- The number of Array dimensions (i.e. rank).
-
const uint64_t *PyFI::ArrayDimensions
::
dimensions
()¶
const - Return
- A pointer to the first element in the dimensions array.
-
std::vector<uint64_t> PyFI::ArrayDimensions
::
dimensions_vector
()¶ - Return
- A standard vector loaded with the elements of the dimensions() array.
-
const uint64_t PyFI::ArrayDimensions
::
dimensions
(uint64_t i)¶
const - Return
- The length of the dimension at index i.
- Parameters
i
-Dimension index.
-
PyFI::ArrayDimensions
::
ArrayDimensions
(const std::vector<uint64_t> &dims)¶ Construct an ArrayDimensions object from a standard vector.
- Parameters
dims
-A standard vector.
-
PyFI::ArrayDimensions
::
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.
-
PyFI::ArrayDimensions
::
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.
-
PyFI::ArrayDimensions
::
~ArrayDimensions
()¶ The ArrayDimensions destructor.
This frees the contained C-array.
-
bool PyFI::ArrayDimensions
::
operator==
(const ArrayDimensions &rhs)¶
const The equality operator.
- Return
- true if the two ArrayDimensions are the same.
-
bool PyFI::ArrayDimensions
::
operator!=
(const ArrayDimensions &rhs)¶
const The equality operator.
- Return
- false if the two ArrayDimensions are the same.
-
const uint64_t PyFI::ArrayDimensions
PyFEigen Interface¶
- namespace
Functions
- template <class T>
-
void PyFI::PyFEigen
::
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 PyFI::PyFEigen
::
PseudoInverse
(Array<T> &Matrix, Array<T> &InverseMatrix)¶ Pseudo Inverse.
FFTW Interface¶
- namespace
Functions
- template <class T>
-
void PyFI::FFTW
::
check_array
(Array<T> &in, Array<T> &out, uint64_t numberDimensions, int fftDirection, const char *functionName)¶
- template <class T>
-
void PyFI::FFTW
::
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 PyFI::FFTW
::
shift2
(Array<T> &shiftIn, Array<T> &shiftOut, int position)¶ 2D array shift (see shift1()).
- template <class T>
-
void PyFI::FFTW
::
shift3
(Array<T> &shiftIn, Array<T> &shiftOut, int position)¶ 3D array shift (see shift1()).
- template <class T>
-
void PyFI::FFTW
::
shift1n
(Array<T> &shiftIn, Array<T> &shiftOut, int position, uint64_t fftDim)¶ 1D array shift in any dimension (see shift1()).
- template <class T>
-
void PyFI::FFTW
::
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 PyFI::FFTW
::
fft2
(Array<T> &in, Array<T> &out, int fftDirection)¶ 2D fft (see fft1).
Numpy Interface¶
- namespace
Functions
- template <class T>
-
Array<T> PyFI::Numpy
::
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 PyFI::Numpy
::
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 PyFI::Numpy
::
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>
-
void PyFI::Numpy
::
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.
The PyCallable Object¶
- class
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
-
PyFI::PyCallable
::
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”).
-
PyFI::PyCallable
::
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
-
-
PyFI::PyCallable
::
~PyCallable
()¶ The destructor frees all input arguments, generated arrays, and unloads any Python modules and functions.
-
void PyFI::PyCallable
::
Reset
(void)¶ Resets the input and output args for a new run.
-
void PyFI::PyCallable
::
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 PyFI::PyCallable
::
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 PyFI::PyCallable
::
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 PyFI::PyCallable
::
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 PyFI::PyCallable
::
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 PyFI::PyCallable
::
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.
-
string PyFI::PyCallable
::
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 PyFI::PyCallable
::
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 PyFI::PyCallable
::
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
-
PyFI::PyCallable