macromax.backend package

This package defines a general interface to do parallel operations efficiently on different architectures, and it provides specific implementations that are used by the macromax.Solution class.

The specific implementation that is used can be:

  • selected automatically based on availability and in order of deemed efficiency, or

  • specified when loading the backend with the load() function, or

  • configured using config() function.

macromax.backend.config(*args, **kwargs)[source]

Configure a specific back-end, overriding the automatic detection. E.g. use from macromax import backend followed by:

backend.config(type='numpy')
backend.config(dict(type='numpy'))
backend.config(type='torch', device='cpu')
backend.config(dict(type='torch', device='cpu'))
backend.config(dict(type='torch', device='cuda'))
backend.config(dict(type='torch', device='cuda'))
backend.config([dict(type='torch', device='cuda'), dict(type='numpy')])

Default back-ends can be specified in the file backend_config.json in the current folder. This configuration file should contain a list of potential back-ends in [JSON format](https://en.wikipedia.org/wiki/JSON), e.g. ```json [

{“type”: “torch”, “device”: “cuda”}, {“type”: “numpy”}, {“type”: “torch”, “device”: “cpu”}

]

The first back-end that loads correctly will be used.

type args:

Sequence[Dict]

param args:

A dictionary or a sequence of dictionaries with at least the ‘type’ key. Key-word arguments are interpreted as a dictionary.

macromax.backend.load(nb_pol_dims, grid, dtype, config_list=None)[source]

Load the default or the backend specified using backend.config(). This configuration file should contain a list of potential back-ends in [JSON format](https://en.wikipedia.org/wiki/JSON), e.g. ```json [

{“type”: “torch”, “device”: “cuda”}, {“type”: “numpy”}, {“type”: “torch”, “device”: “cpu”}

]

The first back-end that loads correctly will be used.

type nb_pol_dims:

int

param nb_pol_dims:

The number of polarization dimensions: 1 for scalar, 3 for vectorial calculations.

type grid:

Grid

param grid:

The uniformly-spaced Cartesian calculation grid as a Grid object.

type dtype:

param dtype:

The scalar data type. E.g. np.complex64 or np.complex128.

type config_list:

Optional[List[Dict]]

param config_list:

List of alternative backend configurations.

rtype:

BackEnd

return:

A BackEnd object to start the calculation with.

class macromax.backend.BackEnd(nb_dims, grid, hardware_dtype=<class 'numpy.complex128'>)[source]

Bases: ABC

A class that provides methods to work with arrays of matrices or block-diagonal matrices, represented as ndarrays, where the first two dimensions are those of the matrix, and the final dimensions are the coordinates over which the operations are parallelized and the Fourier transforms are applied.

__init__(nb_dims, grid, hardware_dtype=<class 'numpy.complex128'>)[source]

Construct object to handle parallel operations on square matrices of nb_rows x nb_rows elements. The matrices refer to points in space on a uniform plaid grid.

Parameters:
  • nb_dims (int) – The number of rows and columns in each matrix. 1 for scalar operations, 3 for polarization

  • grid (Grid) – The grid that defines the position of the matrices.

  • hardware_dtype – (optional) The datatype to use for operations.

property vector_length: int

The shape of the square matrix that transforms a single vector in the set. This is a pair of identical integer numbers.

property ft_axes: tuple

The integer indices of the spatial dimensions, i.e. on which to Fourier Transform.

property grid: Grid

A Grid object representing the sample points in the spatial dimensions.

property vectorial: bool

A boolean indicating if this object represents a vector space (as opposed to a scalar space).

property hardware_dtype

The scalar data type that is processed by this back-end.

property numpy_dtype

The equivalent hardware data type in numpy

astype(arr, dtype=None)[source]
Parameters:
  • arr (Union[Complex, Sequence, ndarray]) – An object that is, or can be converted to, an ndarray.

  • dtype – (optional) scalar data type of the returned array elements

Return type:

ndarray

Returns:

torch.Tensor type

asnumpy(arr)[source]

Convert the internal array (or tensor) presentation to a numpy.ndarray.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The to-be-converted array.

Return type:

ndarray

Returns:

The corresponding numpy ndarray.

property eps: float

The precision of the data type (self.dtype) of this back-end.

abstract allocate_array(shape=None, dtype=None, fill_value=None)[source]

Allocates a new vector array of shape grid.shape and word-aligned for efficient calculations.

Parameters:
  • shape (Union[Complex, Sequence, ndarray, None]) – (optional) The shape of the returned array.

  • dtype (Union[Type[float64], Type[float32], None]) – (optional) The scalar data type of the elements in the array. This may be converted to an equivalent, back-end, specific data type.

  • fill_value (Optional[Complex]) – (optional) A scalar value to pre-populate the array. The default (None) does not pre-populate the array, leaving it in a random state.

Return type:

ndarray

Returns:

A reference to the array.

assign(arr, out)[source]

Assign the values of one array to those of another. The dtype and shape is broadcasted to match that of the output array.

Parameters:
  • arr (Union[Complex, Sequence, ndarray]) – The values that need to be assigned to another array.

  • out (ndarray) – (optional) The target array, which must be of the same shape.

Return type:

ndarray

Returns:

The target array or a newly allocated array with the same values as those in arr.

assign_exact(arr, out)[source]

Assign the values of one array to those of another. The dtype and shape must match that of the output array.

Parameters:
  • arr (Union[Complex, Sequence, ndarray]) – The values that need to be assigned to another array.

  • out (ndarray) – (optional) The target array, which must be of the same shape.

Return type:

ndarray

Returns:

The target array or a newly allocated array with the same values as those in arr.

copy(arr)[source]

Makes an independent copy of an ndarray.

Return type:

ndarray

ravel(arr)[source]

Returns a flattened view of the array.

Return type:

ndarray

sign(arr)[source]

Returns an array with values of -1 where arr is negative, 0 where arr is 0, and 1 where arr is positive.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The array to check.

Return type:

ndarray

Returns:

np.sign(arr) or equivalent.

first(arr)[source]

Returns the first element of the flattened array.

Return type:

Complex

static expand_dims(arr, axis)[source]

Inserts a new singleton axis at the indicated position, thus increasing ndim by 1.

Return type:

ndarray

property eye: ndarray

Returns an identity tensor that can be multiplied using singleton expansion. This can be useful for scalar additions or subtractions.

Returns:

an array with the number of dimensions matching that of the BackEnds’s data set.

any(arr)[source]

Returns True if all elements of the array are True.

Return type:

bool

allclose(arr, other=0.0)[source]

Returns True if all elements in arr are close to other.

Return type:

bool

amax(arr)[source]

Returns the maximum of the flattened array.

Return type:

float

sort(arr)[source]

Sorts array elements along the first (left-most) axis.

Return type:

ndarray

abstract ft(arr)[source]

Calculates the discrete Fourier transform over the spatial dimensions of E. The computational complexity is that of a Fast Fourier Transform: O(N.log(N)).

Parameters:

arr (Union[Complex, Sequence, ndarray]) – An ndarray representing a vector field.

Return type:

ndarray

Returns:

An ndarray holding the Fourier transform of the vector field E.

abstract ift(arr)[source]

Calculates the inverse Fourier transform over the spatial dimensions of E. The computational complexity is that of a Fast Fourier Transform: O(N.log(N)). The scaling is so that E == self.ift(self.ft(E))

Parameters:

arr (Union[Complex, Sequence, ndarray]) – An ndarray representing a Fourier-transformed vector field.

Return type:

ndarray

Returns:

An ndarray holding the inverse Fourier transform of the vector field E.

property array_ft_input: ndarray

The pre-allocate array for Fourier Transform inputs

property array_ft_output: ndarray

The pre-allocate array for Fourier Transform outputs

property array_ift_input: ndarray

The pre-allocate array for Inverse Fourier Transform inputs

property array_ift_output: ndarray

The pre-allocate array for Inverse Fourier Transform outputs

conj(arr)[source]

Returns the conjugate of the elements in the input.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The input array.

Return type:

ndarray

Returns:

arr.conj or equivalent

abs(arr)[source]

Returns the absolute value (magnitude) of the elements in the input.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The input array.

Return type:

ndarray

Returns:

np.abs(arr) or equivalent

real(arr)[source]
Return type:

ndarray

convolve(operation_ft, arr)[source]

Apply an operator in Fourier space. This is used to perform a cyclic FFT convolution which overwrites its input argument arr.

Parameters:
Return type:

ndarray

Returns:

the convolved input array.

is_scalar(arr)[source]

Tests if A represents a scalar field (as opposed to a vector field).

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The ndarray to be tested.

Return type:

bool

Returns:

A boolean indicating whether A represents a scalar field (True) or not (False).

is_vector(arr)[source]

Tests if A represents a vector field.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The ndarray to be tested.

Return type:

bool

Returns:

A boolean indicating whether A represents a vector field (True) or not (False).

is_matrix(arr)[source]

Checks if an ndarray is a matrix as defined by this parallel_ops_column object.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The matrix to be tested.

Return type:

bool

Returns:

boolean value, indicating if A is a matrix.

swapaxes(arr, ax_from, ax_to)[source]

Transpose (permute) two axes of an ndarray.

Return type:

ndarray

to_matrix_field(arr)[source]

Converts the input to an array of the full number of dimensions: len(self.matrix_shape) + len(self.grid.shape), and dtype. The size of each dimensions must match that of that set for the BackEnd or be 1 (assumes broadcasting). For electric fields in 3-space, self.matrix_shape == (N, N) == (3, 3) The first (left-most) dimensions of the output are either

  • 1x1: The identity matrix for a scalar field, as sound waves or isotropic permittivity.

  • Nx1: A vector for a vector field, as the electric field.

  • NxN: A matrix for a matrix field, as anisotropic permittivity

None is interpreted as 0. Singleton dimensions are added on the left so that all dimensions are present. Inputs with 1xN are transposed (not conjugate) to Nx1 vectors.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The input can be scalar, which assumes that its value is assumed to be repeated for all space. The value can be a one-dimensional vector, in which case the vector is assumed to be repeated for all space.

Return type:

ndarray

Returns:

An array with ndim == len(self.matrix_shape) + len(self.grid.shape) and with each non-singleton dimension matching those of the nb_rows and data_shape.

adjoint(mat)[source]

Transposes the elements of individual matrices with complex conjugation.

Parameters:

mat (Union[Complex, Sequence, ndarray]) – The ndarray with the matrices in the first two dimensions.

Return type:

ndarray

Returns:

An ndarray with the complex conjugate transposed matrices.

subtract(left_term, right_term)[source]

Point-wise difference of A and B.

Parameters:
  • left_term (Union[Complex, Sequence, ndarray]) – The left matrix array, must start with dimensions n x m

  • right_term (Union[Complex, Sequence, ndarray]) – The right matrix array, must have matching or singleton dimensions to those of A. In case of missing dimensions, singletons are assumed.

Return type:

ndarray

Returns:

The point-wise difference of both sets of matrices. Singleton dimensions are expanded.

mul(left_factor, right_factor, out=None)[source]

Point-wise matrix multiplication of A and B. Overwrites right_factor!

Parameters:
  • left_factor (Union[Complex, Sequence, ndarray]) – The left matrix array, must start with dimensions n x m

  • right_factor (Union[Complex, Sequence, ndarray]) – The right matrix array, must have matching or singleton dimensions to those of A, bar the first two dimensions. In case of missing dimensions, singletons are assumed. The first dimensions must be m x p. Where the m matches that of the left hand matrix unless both m and p are 1 or both n and m are 1, in which case the scaled identity is assumed.

  • out (Optional[ndarray]) – (optional) The destination array for the results.

Return type:

ndarray

Returns:

An array of matrix products with all but the first two dimensions broadcast as needed.

abstract ldivide(denominator, numerator=1.0)[source]

Parallel matrix left division, A^{-1}B, on the final two dimensions of A and B result_lm = A_kl B_km

A and B must have have all but the final dimension identical or singletons. B defaults to the identity matrix.

Parameters:
Return type:

ndarray

Returns:

The set of divided matrices.

inv(mat)[source]

Inverts the set of input matrices M.

Parameters:

mat (Union[Complex, Sequence, ndarray]) – The set of input matrices.

Return type:

ndarray

Returns:

The set of inverted matrices.

curl(field_array)[source]

Calculates the curl of a vector E with the final dimension the vector dimension. The input argument may be overwritten!

Parameters:

field_array (Union[Complex, Sequence, ndarray]) – The set of input matrices.

Return type:

ndarray

Returns:

The curl of E.

curl_ft(field_array_ft)[source]

Calculates the Fourier transform of the curl of a Fourier transformed E with the final dimension the vector dimension. The final dimension of the output will always be of length 3; however, the input length may be shorter, in which case the missing values are assumed to be zero. The first dimension of the input array corresponds to the first element in the final dimension, if it exists, the second dimension corresponds to the second element etc.

Parameters:

field_array_ft (Union[Complex, Sequence, ndarray]) – The input vector array of dimensions [vector_length, 1, *data_shape].

Return type:

ndarray

Returns:

The Fourier transform of the curl of F.

cross(A, B)[source]

Calculates the cross product of vector arrays A and B.

Parameters:
Return type:

ndarray

Returns:

A vector array of dimensions [vector_length, 1, *data_shape] containing the cross product A x B in the first dimension and the other dimensions remain on the same axes.

outer(A, B)[source]

Calculates the Dyadic product of vector arrays A and B.

Parameters:
Return type:

ndarray

Returns:

A matrix array of dimensions [vector_length, vector_length, *data_shape] containing the dyadic product \(A \otimes B\) in the first two dimensions and the other dimensions remain on the same axes.

div(field_array)[source]

Calculate the divergence of the input vector or tensor field E. The input argument may be overwritten!

Parameters:

field_array (Union[Complex, Sequence, ndarray]) – The input array representing vector or tensor field. The input is of the shape [m, n, x, y, z, ...]

Return type:

ndarray

Returns:

The divergence of the vector or tensor field in the shape [n, 1, x, y, z].

div_ft(field_array_ft)[source]

Calculate the Fourier transform of the divergence of the pre-Fourier transformed input electric field.

Parameters:

field_array_ft (Union[Complex, Sequence, ndarray]) – The input array representing the field pre-Fourier-transformed in all spatial dimensions. The input is of the shape [m, n, x, y, z, ...]

Return type:

ndarray

Returns:

The Fourier transform of the divergence of the field in the shape [n, 1, x, y, z].

transversal_projection(field_array)[source]

Projects vector arrays onto their transverse component. The input argument may be overwritten!

Parameters:

field_array (Union[Complex, Sequence, ndarray]) – The input vector E array.

Return type:

ndarray

Returns:

The transversal projection.

longitudinal_projection(field_array)[source]

Projects vector arrays onto their longitudinal component. The input argument may be overwritten!

Parameters:

field_array (Union[Complex, Sequence, ndarray]) – The input vector E array.

Return type:

ndarray

Returns:

The longitudinal projection.

transversal_projection_ft(field_array_ft)[source]

Projects the Fourier transform of a vector E array onto its transversal component.

Parameters:

field_array_ft (Union[Complex, Sequence, ndarray]) – The Fourier transform of the input vector E array.

Return type:

ndarray

Returns:

The Fourier transform of the transversal projection.

longitudinal_projection_ft(field_array_ft)[source]

Projects the Fourier transform of a vector array onto its longitudinal component. Overwrites self.array_ft_input!

Parameters:

field_array_ft (Union[Complex, Sequence, ndarray]) – The Fourier transform of the input vector E array.

Return type:

ndarray

Returns:

The Fourier transform of the longitudinal projection.

property k: Sequence[ndarray]

A list of the k-vector components along each axis.

property k2: ndarray

Helper def for calculation of the Fourier transform of the Green def

Returns:

\(|k|^2\) for the specified sample grid and output shape

mat3_eigh(arr)[source]

Calculates the eigenvalues of the 3x3 Hermitian matrices represented by A and returns a new array of 3-vectors, one for each matrix in A and of the same dimensions, baring the second dimension. When the first two dimensions are 3x1 or 1x3, a diagonal matrix is assumed. When the first two dimensions are singletons (1x1), a constant diagonal matrix is assumed and only one eigenvalue is returned. Returns an array of one dimension less: 3 x data_shape. With the exception of the first dimension, the shape is maintained.

Before substituting this for `numpy.linalg.eigvalsh`, note that this implementation is about twice as fast as the current numpy implementation for 3x3 Hermitian matrix fields. The difference is even greater for the PyTorch implementation. The implementation below can be made more efficient by limiting it to Hermitian matrices and thus real eigenvalues. In the end, only the maximal eigenvalue is required, so an iterative power iteration may be even faster, perhaps after applying a Given’s rotation or Householder reflection to make Hermitian tridiagonal.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The set of 3x3 input matrices for which the eigenvalues are requested. This must be an ndarray with the first two dimensions of size 3.

Return type:

ndarray

Returns:

The set of eigenvalue-triples contained in an ndarray with its first dimension of size 3, and the remaining dimensions equal to all but the first two input dimensions.

calc_roots_of_low_order_polynomial(C)[source]

Calculates the (complex) roots of polynomials up to order 3 in parallel. The coefficients of the polynomials are in the first dimension of C and repeated in the following dimensions, one for each polynomial to determine the roots of. The coefficients are input for low to high order in each column. In other words, the polynomial is: np.sum(C * (x**range(C.size))) == 0

This method is used by mat3_eigh, but only for polynomials with real roots.

Parameters:

C (Union[Complex, Sequence, ndarray]) – The coefficients of the polynomial, per polynomial.

Return type:

ndarray

Returns:

The zeros in the complex plane, per polynomial.

static evaluate_polynomial(C, X)[source]

Evaluates the polynomial P at X for testing.

Parameters:
Return type:

ndarray

Returns:

The values of the polynomials for the arguments X.

static clear_cache()[source]
norm(arr)[source]

Returns the l2-norm of a vectorized array.

Return type:

float

macromax.backend.tensor_type

alias of ndarray

Submodules

macromax.backend.numpy module

The module providing the pure-python NumPy back-end implementation.

class macromax.backend.numpy.BackEndNumpy(nb_dims, grid, hardware_dtype=<class 'numpy.complex128'>)[source]

Bases: BackEnd

A class that provides methods to work with arrays of matrices or block-diagonal matrices, represented as ndarrays, where the first two dimensions are those of the matrix, and the final dimensions are the coordinates over which the operations are parallelized and the Fourier transforms are applied.

__init__(nb_dims, grid, hardware_dtype=<class 'numpy.complex128'>)[source]

Construct object to handle parallel operations on square matrices of nb_rows x nb_rows elements. The matrices refer to points in space on a uniform plaid grid.

Parameters:
  • nb_dims (int) – The number of rows and columns in each matrix. 1 for scalar operations, 3 for polarization

  • grid (Grid) – The grid that defines the position of the matrices.

  • hardware_dtype – (optional) The data type to use for operations.

allocate_array(shape=None, dtype=None, fill_value=None)[source]

Allocates a new vector array of shape grid.shape and word-aligned for efficient calculations.

Return type:

ndarray

ft(arr)[source]

Calculates the discrete Fourier transform over the spatial dimensions of E. The computational complexity is that of a Fast Fourier Transform: O(N\log(N)).

Parameters:

arr (Union[Complex, Sequence, ndarray]) – An ndarray representing a vector field.

Return type:

ndarray

Returns:

An ndarray holding the Fourier transform of the vector field E.

ift(arr)[source]

Calculates the inverse Fourier transform over the spatial dimensions of E. The computational complexity is that of a Fast Fourier Transform: O(N\log(N)). The scaling is so that E == self.ift(self.ft(E))

Parameters:

arr (Union[Complex, Sequence, ndarray]) – An ndarray representing a Fourier-transformed vector field.

Return type:

ndarray

Returns:

An ndarray holding the inverse Fourier transform of the vector field E.

abs(arr)

Returns the absolute value (magnitude) of the elements in the input.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The input array.

Return type:

ndarray

Returns:

np.abs(arr) or equivalent

adjoint(mat)

Transposes the elements of individual matrices with complex conjugation.

Parameters:

mat (Union[Complex, Sequence, ndarray]) – The ndarray with the matrices in the first two dimensions.

Return type:

ndarray

Returns:

An ndarray with the complex conjugate transposed matrices.

allclose(arr, other=0.0)

Returns True if all elements in arr are close to other.

Return type:

bool

amax(arr)

Returns the maximum of the flattened array.

Return type:

float

any(arr)

Returns True if all elements of the array are True.

Return type:

bool

property array_ft_input: ndarray

The pre-allocate array for Fourier Transform inputs

property array_ft_output: ndarray

The pre-allocate array for Fourier Transform outputs

property array_ift_input: ndarray

The pre-allocate array for Inverse Fourier Transform inputs

property array_ift_output: ndarray

The pre-allocate array for Inverse Fourier Transform outputs

asnumpy(arr)

Convert the internal array (or tensor) presentation to a numpy.ndarray.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The to-be-converted array.

Return type:

ndarray

Returns:

The corresponding numpy ndarray.

assign(arr, out)

Assign the values of one array to those of another. The dtype and shape is broadcasted to match that of the output array.

Parameters:
  • arr (Union[Complex, Sequence, ndarray]) – The values that need to be assigned to another array.

  • out (ndarray) – (optional) The target array, which must be of the same shape.

Return type:

ndarray

Returns:

The target array or a newly allocated array with the same values as those in arr.

assign_exact(arr, out)

Assign the values of one array to those of another. The dtype and shape must match that of the output array.

Parameters:
  • arr (Union[Complex, Sequence, ndarray]) – The values that need to be assigned to another array.

  • out (ndarray) – (optional) The target array, which must be of the same shape.

Return type:

ndarray

Returns:

The target array or a newly allocated array with the same values as those in arr.

astype(arr, dtype=None)
Parameters:
  • arr (Union[Complex, Sequence, ndarray]) – An object that is, or can be converted to, an ndarray.

  • dtype – (optional) scalar data type of the returned array elements

Return type:

ndarray

Returns:

torch.Tensor type

calc_roots_of_low_order_polynomial(C)

Calculates the (complex) roots of polynomials up to order 3 in parallel. The coefficients of the polynomials are in the first dimension of C and repeated in the following dimensions, one for each polynomial to determine the roots of. The coefficients are input for low to high order in each column. In other words, the polynomial is: np.sum(C * (x**range(C.size))) == 0

This method is used by mat3_eigh, but only for polynomials with real roots.

Parameters:

C (Union[Complex, Sequence, ndarray]) – The coefficients of the polynomial, per polynomial.

Return type:

ndarray

Returns:

The zeros in the complex plane, per polynomial.

static clear_cache()
conj(arr)

Returns the conjugate of the elements in the input.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The input array.

Return type:

ndarray

Returns:

arr.conj or equivalent

convolve(operation_ft, arr)

Apply an operator in Fourier space. This is used to perform a cyclic FFT convolution which overwrites its input argument arr.

Parameters:
Return type:

ndarray

Returns:

the convolved input array.

copy(arr)

Makes an independent copy of an ndarray.

Return type:

ndarray

cross(A, B)

Calculates the cross product of vector arrays A and B.

Parameters:
Return type:

ndarray

Returns:

A vector array of dimensions [vector_length, 1, *data_shape] containing the cross product A x B in the first dimension and the other dimensions remain on the same axes.

curl(field_array)

Calculates the curl of a vector E with the final dimension the vector dimension. The input argument may be overwritten!

Parameters:

field_array (Union[Complex, Sequence, ndarray]) – The set of input matrices.

Return type:

ndarray

Returns:

The curl of E.

curl_ft(field_array_ft)

Calculates the Fourier transform of the curl of a Fourier transformed E with the final dimension the vector dimension. The final dimension of the output will always be of length 3; however, the input length may be shorter, in which case the missing values are assumed to be zero. The first dimension of the input array corresponds to the first element in the final dimension, if it exists, the second dimension corresponds to the second element etc.

Parameters:

field_array_ft (Union[Complex, Sequence, ndarray]) – The input vector array of dimensions [vector_length, 1, *data_shape].

Return type:

ndarray

Returns:

The Fourier transform of the curl of F.

div(field_array)

Calculate the divergence of the input vector or tensor field E. The input argument may be overwritten!

Parameters:

field_array (Union[Complex, Sequence, ndarray]) – The input array representing vector or tensor field. The input is of the shape [m, n, x, y, z, ...]

Return type:

ndarray

Returns:

The divergence of the vector or tensor field in the shape [n, 1, x, y, z].

div_ft(field_array_ft)

Calculate the Fourier transform of the divergence of the pre-Fourier transformed input electric field.

Parameters:

field_array_ft (Union[Complex, Sequence, ndarray]) – The input array representing the field pre-Fourier-transformed in all spatial dimensions. The input is of the shape [m, n, x, y, z, ...]

Return type:

ndarray

Returns:

The Fourier transform of the divergence of the field in the shape [n, 1, x, y, z].

property eps: float

The precision of the data type (self.dtype) of this back-end.

static evaluate_polynomial(C, X)

Evaluates the polynomial P at X for testing.

Parameters:
Return type:

ndarray

Returns:

The values of the polynomials for the arguments X.

static expand_dims(arr, axis)

Inserts a new singleton axis at the indicated position, thus increasing ndim by 1.

Return type:

ndarray

property eye: ndarray

Returns an identity tensor that can be multiplied using singleton expansion. This can be useful for scalar additions or subtractions.

Returns:

an array with the number of dimensions matching that of the BackEnds’s data set.

first(arr)

Returns the first element of the flattened array.

Return type:

Complex

property ft_axes: tuple

The integer indices of the spatial dimensions, i.e. on which to Fourier Transform.

property grid: Grid

A Grid object representing the sample points in the spatial dimensions.

property hardware_dtype

The scalar data type that is processed by this back-end.

inv(mat)

Inverts the set of input matrices M.

Parameters:

mat (Union[Complex, Sequence, ndarray]) – The set of input matrices.

Return type:

ndarray

Returns:

The set of inverted matrices.

is_matrix(arr)

Checks if an ndarray is a matrix as defined by this parallel_ops_column object.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The matrix to be tested.

Return type:

bool

Returns:

boolean value, indicating if A is a matrix.

is_scalar(arr)

Tests if A represents a scalar field (as opposed to a vector field).

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The ndarray to be tested.

Return type:

bool

Returns:

A boolean indicating whether A represents a scalar field (True) or not (False).

is_vector(arr)

Tests if A represents a vector field.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The ndarray to be tested.

Return type:

bool

Returns:

A boolean indicating whether A represents a vector field (True) or not (False).

property k: Sequence[ndarray]

A list of the k-vector components along each axis.

property k2: ndarray

Helper def for calculation of the Fourier transform of the Green def

Returns:

\(|k|^2\) for the specified sample grid and output shape

ldivide(denominator, numerator=1.0)[source]

Parallel matrix left division, A^{-1}B, on the final two dimensions of A and B result_lm = A_kl B_km

A and B must have have all but the final dimension identical or singletons. B defaults to the identity matrix.

Parameters:
Return type:

ndarray

Returns:

The set of divided matrices.

longitudinal_projection(field_array)

Projects vector arrays onto their longitudinal component. The input argument may be overwritten!

Parameters:

field_array (Union[Complex, Sequence, ndarray]) – The input vector E array.

Return type:

ndarray

Returns:

The longitudinal projection.

longitudinal_projection_ft(field_array_ft)

Projects the Fourier transform of a vector array onto its longitudinal component. Overwrites self.array_ft_input!

Parameters:

field_array_ft (Union[Complex, Sequence, ndarray]) – The Fourier transform of the input vector E array.

Return type:

ndarray

Returns:

The Fourier transform of the longitudinal projection.

mat3_eigh(arr)

Calculates the eigenvalues of the 3x3 Hermitian matrices represented by A and returns a new array of 3-vectors, one for each matrix in A and of the same dimensions, baring the second dimension. When the first two dimensions are 3x1 or 1x3, a diagonal matrix is assumed. When the first two dimensions are singletons (1x1), a constant diagonal matrix is assumed and only one eigenvalue is returned. Returns an array of one dimension less: 3 x data_shape. With the exception of the first dimension, the shape is maintained.

Before substituting this for `numpy.linalg.eigvalsh`, note that this implementation is about twice as fast as the current numpy implementation for 3x3 Hermitian matrix fields. The difference is even greater for the PyTorch implementation. The implementation below can be made more efficient by limiting it to Hermitian matrices and thus real eigenvalues. In the end, only the maximal eigenvalue is required, so an iterative power iteration may be even faster, perhaps after applying a Given’s rotation or Householder reflection to make Hermitian tridiagonal.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The set of 3x3 input matrices for which the eigenvalues are requested. This must be an ndarray with the first two dimensions of size 3.

Return type:

ndarray

Returns:

The set of eigenvalue-triples contained in an ndarray with its first dimension of size 3, and the remaining dimensions equal to all but the first two input dimensions.

mul(left_factor, right_factor, out=None)

Point-wise matrix multiplication of A and B. Overwrites right_factor!

Parameters:
  • left_factor (Union[Complex, Sequence, ndarray]) – The left matrix array, must start with dimensions n x m

  • right_factor (Union[Complex, Sequence, ndarray]) – The right matrix array, must have matching or singleton dimensions to those of A, bar the first two dimensions. In case of missing dimensions, singletons are assumed. The first dimensions must be m x p. Where the m matches that of the left hand matrix unless both m and p are 1 or both n and m are 1, in which case the scaled identity is assumed.

  • out (Optional[ndarray]) – (optional) The destination array for the results.

Return type:

ndarray

Returns:

An array of matrix products with all but the first two dimensions broadcast as needed.

norm(arr)

Returns the l2-norm of a vectorized array.

Return type:

float

property numpy_dtype

The equivalent hardware data type in numpy

outer(A, B)

Calculates the Dyadic product of vector arrays A and B.

Parameters:
Return type:

ndarray

Returns:

A matrix array of dimensions [vector_length, vector_length, *data_shape] containing the dyadic product \(A \otimes B\) in the first two dimensions and the other dimensions remain on the same axes.

ravel(arr)

Returns a flattened view of the array.

Return type:

ndarray

real(arr)
Return type:

ndarray

sign(arr)

Returns an array with values of -1 where arr is negative, 0 where arr is 0, and 1 where arr is positive.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The array to check.

Return type:

ndarray

Returns:

np.sign(arr) or equivalent.

sort(arr)

Sorts array elements along the first (left-most) axis.

Return type:

ndarray

subtract(left_term, right_term)

Point-wise difference of A and B.

Parameters:
  • left_term (Union[Complex, Sequence, ndarray]) – The left matrix array, must start with dimensions n x m

  • right_term (Union[Complex, Sequence, ndarray]) – The right matrix array, must have matching or singleton dimensions to those of A. In case of missing dimensions, singletons are assumed.

Return type:

ndarray

Returns:

The point-wise difference of both sets of matrices. Singleton dimensions are expanded.

swapaxes(arr, ax_from, ax_to)

Transpose (permute) two axes of an ndarray.

Return type:

ndarray

to_matrix_field(arr)

Converts the input to an array of the full number of dimensions: len(self.matrix_shape) + len(self.grid.shape), and dtype. The size of each dimensions must match that of that set for the BackEnd or be 1 (assumes broadcasting). For electric fields in 3-space, self.matrix_shape == (N, N) == (3, 3) The first (left-most) dimensions of the output are either

  • 1x1: The identity matrix for a scalar field, as sound waves or isotropic permittivity.

  • Nx1: A vector for a vector field, as the electric field.

  • NxN: A matrix for a matrix field, as anisotropic permittivity

None is interpreted as 0. Singleton dimensions are added on the left so that all dimensions are present. Inputs with 1xN are transposed (not conjugate) to Nx1 vectors.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The input can be scalar, which assumes that its value is assumed to be repeated for all space. The value can be a one-dimensional vector, in which case the vector is assumed to be repeated for all space.

Return type:

ndarray

Returns:

An array with ndim == len(self.matrix_shape) + len(self.grid.shape) and with each non-singleton dimension matching those of the nb_rows and data_shape.

transversal_projection(field_array)

Projects vector arrays onto their transverse component. The input argument may be overwritten!

Parameters:

field_array (Union[Complex, Sequence, ndarray]) – The input vector E array.

Return type:

ndarray

Returns:

The transversal projection.

transversal_projection_ft(field_array_ft)

Projects the Fourier transform of a vector E array onto its transversal component.

Parameters:

field_array_ft (Union[Complex, Sequence, ndarray]) – The Fourier transform of the input vector E array.

Return type:

ndarray

Returns:

The Fourier transform of the transversal projection.

property vector_length: int

The shape of the square matrix that transforms a single vector in the set. This is a pair of identical integer numbers.

property vectorial: bool

A boolean indicating if this object represents a vector space (as opposed to a scalar space).

macromax.backend.tensorflow module

The module providing the TensorFlow back-end implementation.

class macromax.backend.tensorflow.BackEndTensorFlow(nb_dims, grid, hardware_dtype=tensorflow.complex128, device=None, address=None)[source]

Bases: BackEnd

A class that provides methods to work with arrays of matrices or block-diagonal matrices, represented as ndarrays, where the first two dimensions are those of the matrix, and the final dimensions are the coordinates over which the operations are parallelized and the Fourier transforms are applied.

__init__(nb_dims, grid, hardware_dtype=tensorflow.complex128, device=None, address=None)[source]

Construct object to handle parallel operations on square matrices of nb_rows x nb_rows elements. The matrices refer to points in space on a uniform plaid grid.

Parameters:
  • nb_dims (int) – The number of rows and columns in each matrix. 1 for scalar operations, 3 for polarization

  • grid (Grid) – The grid that defines the position of the matrices.

  • hardware_dtype – (optional) The data type to use for operations.

  • device (Optional[str]) – (optional) ‘cpu’, ‘gpu’, or ‘tpu’ to indicate where the calculation will happen.

  • address (Optional[str]) – (optional)

property numpy_dtype

The equivalent hardware data type in numpy

property eps: float

The precision of the data type (self.dtype) of this back-end.

astype(arr, dtype=None)[source]

As necessary, convert the ndarray arr to the type dtype.

Return type:

Tensor

asnumpy(arr)[source]

Convert the internal array (or tensor) presentation to a numpy.ndarray.

Parameters:

arr (Union[Complex, Sequence, ndarray, Tensor]) – The to-be-converted array.

Return type:

ndarray

Returns:

The corresponding numpy ndarray.

assign(arr, out)[source]

Assign the values of one array to those of another. The dtype and shape is broadcasted to match that of the output array.

Parameters:
  • arr – The values that need to be assigned to another array.

  • out – (optional) The target array, which must be of the same shape.

Return type:

Tensor

Returns:

The target array or a newly allocated array with the same values as those in arr.

assign_exact(arr, out)[source]

Assign the values of one array to those of another. The dtype and shape must match that of the output array.

Parameters:
  • arr – The values that need to be assigned to another array.

  • out (Tensor) – (optional) The target array, which must be of the same shape.

Return type:

Tensor

Returns:

The target array or a newly allocated array with the same values as those in arr.

allocate_array(shape=None, dtype=None, fill_value=None)[source]

Allocates a new vector array of shape grid.shape and word-aligned for efficient calculations.

Return type:

Tensor

copy(arr)[source]

Makes an independent copy of an ndarray.

Return type:

Tensor

ravel(arr)[source]

Returns a flattened view of the array.

Return type:

Tensor

sign(arr)[source]

Returns an array with values of -1 where arr is negative, 0 where arr is 0, and 1 where arr is positive.

Parameters:

arr (Union[Complex, Sequence, ndarray, Tensor]) – The array to check.

Return type:

Tensor

Returns:

np.sign(arr) or equivalent.

swapaxes(arr, ax_from, ax_to)[source]

Transpose (permute) two axes of an ndarray.

Return type:

Tensor

static expand_dims(arr, axis)[source]

Inserts a new singleton axis at the indicated position, thus increasing ndim by 1.

Return type:

Tensor

abs(arr)[source]

Returns the absolute value (magnitude) of the elements in the input.

Parameters:

arr – The input array.

Return type:

Tensor

Returns:

np.abs(arr) or equivalent

real(arr)[source]
Return type:

Tensor

conj(arr)[source]

Returns the conjugate of the elements in the input.

Parameters:

arr – The input array.

Return type:

Tensor

Returns:

arr.conj or equivalent

any(arr)[source]

Returns True if all elements of the array are True.

allclose(arr, other=0.0)[source]

Returns True if all elements in arr are close to other.

Return type:

bool

amax(arr)[source]

Returns the maximum of the flattened array.

sort(arr)[source]

Sorts array elements along the first (left-most) axis.

Return type:

Tensor

ft(arr)[source]

Calculates the discrete Fourier transform over the spatial dimensions of E. The computational complexity is that of a Fast Fourier Transform: O(N\log(N)).

Parameters:

arr (Union[Complex, Sequence, ndarray, Tensor]) – An ndarray representing a vector field.

Return type:

Tensor

Returns:

An ndarray holding the Fourier transform of the vector field E.

ift(arr)[source]

Calculates the inverse Fourier transform over the spatial dimensions of E. The computational complexity is that of a Fast Fourier Transform: O(N\log(N)). The scaling is so that E == self.ift(self.ft(E))

Parameters:

arr (Union[Complex, Sequence, ndarray, Tensor]) – An ndarray representing a Fourier-transformed vector field.

Return type:

Tensor

Returns:

An ndarray holding the inverse Fourier transform of the vector field E.

convolve(operation_ft, arr)

Apply an operator in Fourier space. This is used to perform a cyclic FFT convolution which overwrites its input argument arr.

Parameters:
Return type:

Tensor

Returns:

the convolved input array.

adjoint(mat)[source]

Transposes the elements of individual matrices with complex conjugation.

Parameters:

mat (Union[Complex, Sequence, ndarray, Tensor]) – The ndarray with the matrices in the first two dimensions.

Return type:

Tensor

Returns:

An ndarray with the complex conjugate transposed matrices.

subtract(left_term, right_term)[source]

Point-wise difference of A and B.

Parameters:
  • left_term (Union[Complex, Sequence, ndarray, Tensor]) – The left matrix array, must start with dimensions n x m

  • right_term (Union[Complex, Sequence, ndarray, Tensor]) – The right matrix array, must have matching or singleton dimensions to those of A. In case of missing dimensions, singletons are assumed.

Return type:

ndarray

Returns:

The point-wise difference of both sets of matrices. Singleton dimensions are expanded.

is_scalar(arr)[source]

Tests if A represents a scalar field (as opposed to a vector field).

Parameters:

arr (Union[Complex, Sequence, ndarray, Tensor]) – The ndarray to be tested.

Return type:

bool

Returns:

A boolean indicating whether A represents a scalar field (True) or not (False).

mul(left_factor, right_factor, out=None)

Point-wise matrix multiplication of A and B. Overwrites right_factor!

Parameters:
  • left_factor (Union[Complex, Sequence, ndarray, Tensor]) – The left matrix array, must start with dimensions n x m

  • right_factor (Union[Complex, Sequence, ndarray, Tensor]) – The right matrix array, must have matching or singleton dimensions to those of A, bar the first two dimensions. In case of missing dimensions, singletons are assumed. The first dimensions must be m x p. Where the m matches that of the left hand matrix unless both m and p are 1 or both n and m are 1, in which case the scaled identity is assumed.

  • out (Optional[Tensor]) – (optional) The destination array for the results.

Return type:

Tensor

Returns:

An array of matrix products with all but the first two dimensions broadcast as needed.

ldivide(denominator, numerator=1.0)[source]

Parallel matrix left division, A^{-1}B, on the final two dimensions of A and B result_lm = A_kl B_km

A and B must have have all but the final dimension identical or singletons. B defaults to the identity matrix.

Parameters:
Return type:

Tensor

Returns:

The set of divided matrices.

norm(arr)[source]

Returns the l2-norm of a vectorized array.

Return type:

float

longitudinal_projection_ft(field_array_ft)[source]

Projects the Fourier transform of a vector array onto its longitudinal component. Overwrites self.array_ft_input!

Parameters:

field_array_ft (Union[Complex, Sequence, ndarray, Tensor]) – The Fourier transform of the input vector E array.

Return type:

ndarray

Returns:

The Fourier transform of the longitudinal projection.

transversal_projection_ft(field_array_ft)[source]

Projects the Fourier transform of a vector E array onto its transversal component.

Parameters:

field_array_ft (Union[Complex, Sequence, ndarray, Tensor]) – The Fourier transform of the input vector E array.

Return type:

Tensor

Returns:

The Fourier transform of the transversal projection.

div(field_array)[source]

Calculates the divergence of input field_array.

Parameters:

field_array (Union[Complex, Sequence, ndarray, Tensor]) – The input array representing the field in all spatial dimensions. The input is of the shape [m, n, x, y, z, ...]

Return type:

Tensor

Returns:

The divergence of the field in the shape [n, 1, x, y, z].

curl_ft(field_array_ft)[source]

Calculates the Fourier transform of the curl of a Fourier transformed E with the final dimension the vector dimension. The final dimension of the output will always be of length 3; however, the input length may be shorter, in which case the missing values are assumed to be zero. The first dimension of the input array corresponds to the first element in the final dimension, if it exists, the second dimension corresponds to the second element etc.

Parameters:

field_array_ft (Union[Complex, Sequence, ndarray, Tensor]) – The input vector array of dimensions [vector_length, 1, *data_shape].

Return type:

Tensor

Returns:

The Fourier transform of the curl of F.

property array_ft_input: ndarray

The pre-allocate array for Fourier Transform inputs

property array_ft_output: ndarray

The pre-allocate array for Fourier Transform outputs

property array_ift_input: ndarray

The pre-allocate array for Inverse Fourier Transform inputs

property array_ift_output: ndarray

The pre-allocate array for Inverse Fourier Transform outputs

calc_roots_of_low_order_polynomial(C)

Calculates the (complex) roots of polynomials up to order 3 in parallel. The coefficients of the polynomials are in the first dimension of C and repeated in the following dimensions, one for each polynomial to determine the roots of. The coefficients are input for low to high order in each column. In other words, the polynomial is: np.sum(C * (x**range(C.size))) == 0

This method is used by mat3_eigh, but only for polynomials with real roots.

Parameters:

C (Union[Complex, Sequence, ndarray]) – The coefficients of the polynomial, per polynomial.

Return type:

ndarray

Returns:

The zeros in the complex plane, per polynomial.

static clear_cache()
cross(A, B)

Calculates the cross product of vector arrays A and B.

Parameters:
Return type:

ndarray

Returns:

A vector array of dimensions [vector_length, 1, *data_shape] containing the cross product A x B in the first dimension and the other dimensions remain on the same axes.

curl(field_array)

Calculates the curl of a vector E with the final dimension the vector dimension. The input argument may be overwritten!

Parameters:

field_array (Union[Complex, Sequence, ndarray]) – The set of input matrices.

Return type:

ndarray

Returns:

The curl of E.

div_ft(field_array_ft)

Calculate the Fourier transform of the divergence of the pre-Fourier transformed input electric field.

Parameters:

field_array_ft (Union[Complex, Sequence, ndarray]) – The input array representing the field pre-Fourier-transformed in all spatial dimensions. The input is of the shape [m, n, x, y, z, ...]

Return type:

ndarray

Returns:

The Fourier transform of the divergence of the field in the shape [n, 1, x, y, z].

static evaluate_polynomial(C, X)

Evaluates the polynomial P at X for testing.

Parameters:
Return type:

ndarray

Returns:

The values of the polynomials for the arguments X.

property eye: ndarray

Returns an identity tensor that can be multiplied using singleton expansion. This can be useful for scalar additions or subtractions.

Returns:

an array with the number of dimensions matching that of the BackEnds’s data set.

first(arr)

Returns the first element of the flattened array.

Return type:

Complex

property ft_axes: tuple

The integer indices of the spatial dimensions, i.e. on which to Fourier Transform.

property grid: Grid

A Grid object representing the sample points in the spatial dimensions.

property hardware_dtype

The scalar data type that is processed by this back-end.

inv(mat)

Inverts the set of input matrices M.

Parameters:

mat (Union[Complex, Sequence, ndarray]) – The set of input matrices.

Return type:

ndarray

Returns:

The set of inverted matrices.

is_matrix(arr)

Checks if an ndarray is a matrix as defined by this parallel_ops_column object.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The matrix to be tested.

Return type:

bool

Returns:

boolean value, indicating if A is a matrix.

is_vector(arr)

Tests if A represents a vector field.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The ndarray to be tested.

Return type:

bool

Returns:

A boolean indicating whether A represents a vector field (True) or not (False).

property k: Sequence[ndarray]

A list of the k-vector components along each axis.

property k2: ndarray

Helper def for calculation of the Fourier transform of the Green def

Returns:

\(|k|^2\) for the specified sample grid and output shape

longitudinal_projection(field_array)

Projects vector arrays onto their longitudinal component. The input argument may be overwritten!

Parameters:

field_array (Union[Complex, Sequence, ndarray]) – The input vector E array.

Return type:

ndarray

Returns:

The longitudinal projection.

mat3_eigh(arr)[source]

Calculates the eigenvalues of the 3x3 Hermitian matrices represented by A and returns a new array of 3-vectors, one for each matrix in A and of the same dimensions, baring the second dimension. When the first two dimensions are 3x1 or 1x3, a diagonal matrix is assumed. When the first two dimensions are singletons (1x1), a constant diagonal matrix is assumed and only one eigenvalue is returned. Returns an array of one dimension less: 3 x data_shape. With the exception of the first dimension, the shape is maintained.

Parameters:

arr (Union[Complex, Sequence, ndarray, Tensor]) – The set of 3x3 input matrices for which the eigenvalues are requested. This must be an ndarray with the first two dimensions of size 3.

Return type:

Tensor

Returns:

The set of eigenvalue-triples contained in an ndarray with its first dimension of size 3, and the remaining dimensions equal to all but the first two input dimensions.

outer(A, B)

Calculates the Dyadic product of vector arrays A and B.

Parameters:
Return type:

ndarray

Returns:

A matrix array of dimensions [vector_length, vector_length, *data_shape] containing the dyadic product \(A \otimes B\) in the first two dimensions and the other dimensions remain on the same axes.

to_matrix_field(arr)

Converts the input to an array of the full number of dimensions: len(self.matrix_shape) + len(self.grid.shape), and dtype. The size of each dimensions must match that of that set for the BackEnd or be 1 (assumes broadcasting). For electric fields in 3-space, self.matrix_shape == (N, N) == (3, 3) The first (left-most) dimensions of the output are either

  • 1x1: The identity matrix for a scalar field, as sound waves or isotropic permittivity.

  • Nx1: A vector for a vector field, as the electric field.

  • NxN: A matrix for a matrix field, as anisotropic permittivity

None is interpreted as 0. Singleton dimensions are added on the left so that all dimensions are present. Inputs with 1xN are transposed (not conjugate) to Nx1 vectors.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The input can be scalar, which assumes that its value is assumed to be repeated for all space. The value can be a one-dimensional vector, in which case the vector is assumed to be repeated for all space.

Return type:

ndarray

Returns:

An array with ndim == len(self.matrix_shape) + len(self.grid.shape) and with each non-singleton dimension matching those of the nb_rows and data_shape.

transversal_projection(field_array)

Projects vector arrays onto their transverse component. The input argument may be overwritten!

Parameters:

field_array (Union[Complex, Sequence, ndarray]) – The input vector E array.

Return type:

ndarray

Returns:

The transversal projection.

property vector_length: int

The shape of the square matrix that transforms a single vector in the set. This is a pair of identical integer numbers.

property vectorial: bool

A boolean indicating if this object represents a vector space (as opposed to a scalar space).

macromax.backend.torch module

The module providing the PyTorch back-end implementation.

class macromax.backend.torch.BackEndTorch(nb_dims, grid, hardware_dtype=torch.complex128, device=None)[source]

Bases: BackEnd

A class that provides methods to work with arrays of matrices or block-diagonal matrices, represented as ndarrays, where the first two dimensions are those of the matrix, and the final dimensions are the coordinates over which the operations are parallelized and the Fourier transforms are applied.

__init__(nb_dims, grid, hardware_dtype=torch.complex128, device=None)[source]

Construct object to handle parallel operations on square matrices of nb_rows x nb_rows elements. The matrices refer to points in space on a uniform plaid grid.

Parameters:
  • nb_dims (int) – The number of rows and columns in each matrix. 1 for scalar operations, 3 for polarization

  • grid (Grid) – The grid that defines the position of the matrices.

  • hardware_dtype – (optional) The data type to use for operations.

  • device (Optional[str]) – (optional) ‘cuda’ or ‘cpu’, to indicate where the calculation will happen.

property numpy_dtype

The equivalent hardware data type in numpy

property eps: float

The precision of the data type (self.dtype) of this back-end.

astype(arr, dtype=None)[source]

As necessary, convert the ndarray arr to the type dtype.

Return type:

Tensor

asnumpy(arr)[source]

Convert the internal array (or tensor) presentation to a numpy.ndarray.

Parameters:

arr (Union[Complex, Sequence, ndarray, Tensor]) – The to-be-converted array.

Return type:

ndarray

Returns:

The corresponding numpy ndarray.

assign(arr, out)[source]

Assign the values of one array to those of another. The dtype and shape is broadcasted to match that of the output array.

Parameters:
  • arr – The values that need to be assigned to another array.

  • out – (optional) The target array, which must be of the same shape.

Return type:

Tensor

Returns:

The target array or a newly allocated array with the same values as those in arr.

assign_exact(arr, out)[source]

Assign the values of one array to those of another. The dtype and shape must match that of the output array.

Parameters:
  • arr – The values that need to be assigned to another array.

  • out – (optional) The target array, which must be of the same shape.

Return type:

Tensor

Returns:

The target array or a newly allocated array with the same values as those in arr.

allocate_array(shape=None, dtype=None, fill_value=None)[source]

Allocates a new vector array of shape grid.shape and word-aligned for efficient calculations.

Return type:

Tensor

copy(arr)[source]

Makes an independent copy of an ndarray.

Return type:

Tensor

ravel(arr)[source]

Returns a flattened view of the array.

Return type:

Tensor

sign(arr)[source]

Returns an array with values of -1 where arr is negative, 0 where arr is 0, and 1 where arr is positive.

Parameters:

arr (Union[Complex, Sequence, ndarray, Tensor]) – The array to check.

Return type:

Tensor

Returns:

np.sign(arr) or equivalent.

swapaxes(arr, ax_from, ax_to)[source]

Transpose (permute) two axes of an ndarray.

Return type:

Tensor

static expand_dims(arr, axis)[source]

Inserts a new singleton axis at the indicated position, thus increasing ndim by 1.

Return type:

Tensor

abs(arr)[source]

Returns the absolute value (magnitude) of the elements in the input.

Parameters:

arr – The input array.

Return type:

Tensor

Returns:

np.abs(arr) or equivalent

conj(arr)[source]

Returns the conjugate of the elements in the input.

Parameters:

arr – The input array.

Return type:

Tensor

Returns:

arr.conj or equivalent

any(arr)[source]

Returns True if all elements of the array are True.

allclose(arr, other=0.0)[source]

Returns True if all elements in arr are close to other.

Return type:

bool

amax(arr)[source]

Returns the maximum of the flattened array.

sort(arr)[source]

Sorts array elements along the first (left-most) axis.

Return type:

Tensor

ft(arr)[source]

Calculates the discrete Fourier transform over the spatial dimensions of E. The computational complexity is that of a Fast Fourier Transform: O(N\log(N)).

Parameters:

arr (Union[Complex, Sequence, ndarray, Tensor]) – An ndarray representing a vector field.

Return type:

Tensor

Returns:

An ndarray holding the Fourier transform of the vector field E.

ift(arr)[source]

Calculates the inverse Fourier transform over the spatial dimensions of E. The computational complexity is that of a Fast Fourier Transform: O(N\log(N)). The scaling is so that E == self.ift(self.ft(E))

Parameters:

arr (Union[Complex, Sequence, ndarray, Tensor]) – An ndarray representing a Fourier-transformed vector field.

Return type:

Tensor

Returns:

An ndarray holding the inverse Fourier transform of the vector field E.

adjoint(mat)[source]

Transposes the elements of individual matrices with complex conjugation.

Parameters:

mat (Union[Complex, Sequence, ndarray, Tensor]) – The ndarray with the matrices in the first two dimensions.

Return type:

Tensor

Returns:

An ndarray with the complex conjugate transposed matrices.

real(arr)[source]
Return type:

Tensor

mul(left_factor, right_factor, out=None)[source]

Point-wise matrix multiplication of A and B. Overwrites right_factor!

Parameters:
  • left_factor (Union[Complex, Sequence, ndarray, Tensor]) – The left matrix array, must start with dimensions n x m

  • right_factor (Union[Complex, Sequence, ndarray, Tensor]) – The right matrix array, must have matching or singleton dimensions to those of A, bar the first two dimensions. In case of missing dimensions, singletons are assumed. The first dimensions must be m x p. Where the m matches that of the left hand matrix unless both m and p are 1 or both n and m are 1, in which case the scaled identity is assumed.

  • out (Optional[Tensor]) – (optional) The destination array for the results.

Return type:

Tensor

Returns:

An array of matrix products with all but the first two dimensions broadcast as needed.

ldivide(denominator, numerator=1.0)[source]

Parallel matrix left division, A^{-1}B, on the final two dimensions of A and B result_lm = A_kl B_km

A and B must have have all but the final dimension identical or singletons. B defaults to the identity matrix.

Parameters:
Return type:

Tensor

Returns:

The set of divided matrices.

static clear_cache()[source]
property array_ft_input: ndarray

The pre-allocate array for Fourier Transform inputs

property array_ft_output: ndarray

The pre-allocate array for Fourier Transform outputs

property array_ift_input: ndarray

The pre-allocate array for Inverse Fourier Transform inputs

property array_ift_output: ndarray

The pre-allocate array for Inverse Fourier Transform outputs

calc_roots_of_low_order_polynomial(C)

Calculates the (complex) roots of polynomials up to order 3 in parallel. The coefficients of the polynomials are in the first dimension of C and repeated in the following dimensions, one for each polynomial to determine the roots of. The coefficients are input for low to high order in each column. In other words, the polynomial is: np.sum(C * (x**range(C.size))) == 0

This method is used by mat3_eigh, but only for polynomials with real roots.

Parameters:

C (Union[Complex, Sequence, ndarray]) – The coefficients of the polynomial, per polynomial.

Return type:

ndarray

Returns:

The zeros in the complex plane, per polynomial.

convolve(operation_ft, arr)

Apply an operator in Fourier space. This is used to perform a cyclic FFT convolution which overwrites its input argument arr.

Parameters:
Return type:

ndarray

Returns:

the convolved input array.

cross(A, B)

Calculates the cross product of vector arrays A and B.

Parameters:
Return type:

ndarray

Returns:

A vector array of dimensions [vector_length, 1, *data_shape] containing the cross product A x B in the first dimension and the other dimensions remain on the same axes.

curl(field_array)

Calculates the curl of a vector E with the final dimension the vector dimension. The input argument may be overwritten!

Parameters:

field_array (Union[Complex, Sequence, ndarray]) – The set of input matrices.

Return type:

ndarray

Returns:

The curl of E.

curl_ft(field_array_ft)

Calculates the Fourier transform of the curl of a Fourier transformed E with the final dimension the vector dimension. The final dimension of the output will always be of length 3; however, the input length may be shorter, in which case the missing values are assumed to be zero. The first dimension of the input array corresponds to the first element in the final dimension, if it exists, the second dimension corresponds to the second element etc.

Parameters:

field_array_ft (Union[Complex, Sequence, ndarray]) – The input vector array of dimensions [vector_length, 1, *data_shape].

Return type:

ndarray

Returns:

The Fourier transform of the curl of F.

div(field_array)

Calculate the divergence of the input vector or tensor field E. The input argument may be overwritten!

Parameters:

field_array (Union[Complex, Sequence, ndarray]) – The input array representing vector or tensor field. The input is of the shape [m, n, x, y, z, ...]

Return type:

ndarray

Returns:

The divergence of the vector or tensor field in the shape [n, 1, x, y, z].

div_ft(field_array_ft)

Calculate the Fourier transform of the divergence of the pre-Fourier transformed input electric field.

Parameters:

field_array_ft (Union[Complex, Sequence, ndarray]) – The input array representing the field pre-Fourier-transformed in all spatial dimensions. The input is of the shape [m, n, x, y, z, ...]

Return type:

ndarray

Returns:

The Fourier transform of the divergence of the field in the shape [n, 1, x, y, z].

static evaluate_polynomial(C, X)

Evaluates the polynomial P at X for testing.

Parameters:
Return type:

ndarray

Returns:

The values of the polynomials for the arguments X.

property eye: ndarray

Returns an identity tensor that can be multiplied using singleton expansion. This can be useful for scalar additions or subtractions.

Returns:

an array with the number of dimensions matching that of the BackEnds’s data set.

first(arr)

Returns the first element of the flattened array.

Return type:

Complex

property ft_axes: tuple

The integer indices of the spatial dimensions, i.e. on which to Fourier Transform.

property grid: Grid

A Grid object representing the sample points in the spatial dimensions.

property hardware_dtype

The scalar data type that is processed by this back-end.

inv(mat)

Inverts the set of input matrices M.

Parameters:

mat (Union[Complex, Sequence, ndarray]) – The set of input matrices.

Return type:

ndarray

Returns:

The set of inverted matrices.

is_matrix(arr)

Checks if an ndarray is a matrix as defined by this parallel_ops_column object.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The matrix to be tested.

Return type:

bool

Returns:

boolean value, indicating if A is a matrix.

is_scalar(arr)

Tests if A represents a scalar field (as opposed to a vector field).

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The ndarray to be tested.

Return type:

bool

Returns:

A boolean indicating whether A represents a scalar field (True) or not (False).

is_vector(arr)

Tests if A represents a vector field.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The ndarray to be tested.

Return type:

bool

Returns:

A boolean indicating whether A represents a vector field (True) or not (False).

property k: Sequence[ndarray]

A list of the k-vector components along each axis.

property k2: ndarray

Helper def for calculation of the Fourier transform of the Green def

Returns:

\(|k|^2\) for the specified sample grid and output shape

longitudinal_projection(field_array)

Projects vector arrays onto their longitudinal component. The input argument may be overwritten!

Parameters:

field_array (Union[Complex, Sequence, ndarray]) – The input vector E array.

Return type:

ndarray

Returns:

The longitudinal projection.

longitudinal_projection_ft(field_array_ft)

Projects the Fourier transform of a vector array onto its longitudinal component. Overwrites self.array_ft_input!

Parameters:

field_array_ft (Union[Complex, Sequence, ndarray]) – The Fourier transform of the input vector E array.

Return type:

ndarray

Returns:

The Fourier transform of the longitudinal projection.

mat3_eigh(arr)

Calculates the eigenvalues of the 3x3 Hermitian matrices represented by A and returns a new array of 3-vectors, one for each matrix in A and of the same dimensions, baring the second dimension. When the first two dimensions are 3x1 or 1x3, a diagonal matrix is assumed. When the first two dimensions are singletons (1x1), a constant diagonal matrix is assumed and only one eigenvalue is returned. Returns an array of one dimension less: 3 x data_shape. With the exception of the first dimension, the shape is maintained.

Before substituting this for `numpy.linalg.eigvalsh`, note that this implementation is about twice as fast as the current numpy implementation for 3x3 Hermitian matrix fields. The difference is even greater for the PyTorch implementation. The implementation below can be made more efficient by limiting it to Hermitian matrices and thus real eigenvalues. In the end, only the maximal eigenvalue is required, so an iterative power iteration may be even faster, perhaps after applying a Given’s rotation or Householder reflection to make Hermitian tridiagonal.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The set of 3x3 input matrices for which the eigenvalues are requested. This must be an ndarray with the first two dimensions of size 3.

Return type:

ndarray

Returns:

The set of eigenvalue-triples contained in an ndarray with its first dimension of size 3, and the remaining dimensions equal to all but the first two input dimensions.

norm(arr)[source]

Returns the l2-norm of a vectorized array.

Return type:

float

outer(A, B)

Calculates the Dyadic product of vector arrays A and B.

Parameters:
Return type:

ndarray

Returns:

A matrix array of dimensions [vector_length, vector_length, *data_shape] containing the dyadic product \(A \otimes B\) in the first two dimensions and the other dimensions remain on the same axes.

subtract(left_term, right_term)

Point-wise difference of A and B.

Parameters:
  • left_term (Union[Complex, Sequence, ndarray]) – The left matrix array, must start with dimensions n x m

  • right_term (Union[Complex, Sequence, ndarray]) – The right matrix array, must have matching or singleton dimensions to those of A. In case of missing dimensions, singletons are assumed.

Return type:

ndarray

Returns:

The point-wise difference of both sets of matrices. Singleton dimensions are expanded.

to_matrix_field(arr)

Converts the input to an array of the full number of dimensions: len(self.matrix_shape) + len(self.grid.shape), and dtype. The size of each dimensions must match that of that set for the BackEnd or be 1 (assumes broadcasting). For electric fields in 3-space, self.matrix_shape == (N, N) == (3, 3) The first (left-most) dimensions of the output are either

  • 1x1: The identity matrix for a scalar field, as sound waves or isotropic permittivity.

  • Nx1: A vector for a vector field, as the electric field.

  • NxN: A matrix for a matrix field, as anisotropic permittivity

None is interpreted as 0. Singleton dimensions are added on the left so that all dimensions are present. Inputs with 1xN are transposed (not conjugate) to Nx1 vectors.

Parameters:

arr (Union[Complex, Sequence, ndarray]) – The input can be scalar, which assumes that its value is assumed to be repeated for all space. The value can be a one-dimensional vector, in which case the vector is assumed to be repeated for all space.

Return type:

ndarray

Returns:

An array with ndim == len(self.matrix_shape) + len(self.grid.shape) and with each non-singleton dimension matching those of the nb_rows and data_shape.

transversal_projection(field_array)

Projects vector arrays onto their transverse component. The input argument may be overwritten!

Parameters:

field_array (Union[Complex, Sequence, ndarray]) – The input vector E array.

Return type:

ndarray

Returns:

The transversal projection.

transversal_projection_ft(field_array_ft)

Projects the Fourier transform of a vector E array onto its transversal component.

Parameters:

field_array_ft (Union[Complex, Sequence, ndarray]) – The Fourier transform of the input vector E array.

Return type:

ndarray

Returns:

The Fourier transform of the transversal projection.

property vector_length: int

The shape of the square matrix that transforms a single vector in the set. This is a pair of identical integer numbers.

property vectorial: bool

A boolean indicating if this object represents a vector space (as opposed to a scalar space).