Operators

Classes and functions for the definition of operators are provided in the janus.operators module. Operator should be understood in the most general sense, as a mapping from a (real) vector space to another. If the mapping is linear, then the resulting operator is a tensor.

The root of the hierarchy tree of operators is the class AbstractOperator. Instances of this class have two attributes, isize and osize which are the sizes of the input and output of the operator, respectively (in other words, these attributes are the dimensions of the domain and codomain, respectively).

Operator op is mapped to the vector x through the method AbstractOperator.apply:

y = op.apply(x)

where x (resp. y) is a 1D array of length op.isize (resp. op.osize).

Structured operators

Structured operators are operators whose input and output are structured in multi-dimensional grids. The content of each cell might be tensorial, so that the input and output of 2D structured operators are 3-dimensional arrays. Likewise, the input and output arrays of 3D structured operators are 4-dimensional arrays. The local input and output then refer to data contained in one specific cell. For example, let x[:, :, :] (resp. y[:, :, :]) be the input (resp. output) of a 2D structured operator; the local input (resp. output) of cell (i0, i1) is the 1D array x[i0, i1, :] (resp y[i0, i1, :]).

Two- and three- dimensional structured operators are defined in this module through the classes AbstractStructuredOperator2D and AbstractStructuredOperator3D). Instances of these classes have two attributes, ishape and oshape which are the shapes (tuples of dimensions) of the input and output of the operator, respectively. It should be noted that the data layout (the dimensions of the spatial grid) of the input and output are identical. In other words:

op.ishape[:-1] == op.oshape[:-1]

for any structured operator op. Of course, op.ishape[-1] and op.oshape[-1] may differ. Structured operators are applied to multidimensional arrays as follows:

y = op.apply(x)

where x.shape == op.ishape and y.shape == op.oshape.

Block-diagonal operators

Block-diagonal operators (BlockDiagonalOperator2D, BlockDiagonalOperator3D) are defined as structured operators for which the local output depends on the local input only. Any block diagonal operator can be represented as an array of local operators (of type AbstractOperator) loc. Then, the input x is mapped to the output y as follows

y[i0, i1, :] = loc[i0, i1].apply(x[i0, i1, :])

in 2D, and

y[i0, i1, i2, :] = loc[i0, i1, i2].apply(x[i0, i1, i2, :])

in 3D.

Block-diagonal linear operators

This can be further simplified in the case of linear, block-diagonal operators (BlockDiagonalLinearOperator2D, BlockDiagonalLinearOperator3D). Indeed, loc is then an array of matrices, which can be viewed as a higher-dimension array. Therefore, a block-diagonal linear operator can be defined through a float64 array a such that

y[i0, i1, i2] = sum(a[i0, i1, i2, j2] * x[i0, i1, j2], j2)

in 2D, and

y[i0, i1, i2, i3] = sum(a[i0, i1, i2, i3, j3] * x[i0, i1, i2, j3], j3)

in 3D.

Block-diagonal linear operators are created with the function block_diagonal_linear_operator, which takes as an input an array, whose last two dimensions correspond to the matrix of the local operator.

>>> import numpy as np
>>> import janus.operators as operators
>>> a = np.arange(120., dtype=np.float64).reshape(2, 3, 4, 5)
>>> op = operators.block_diagonal_linear_operator(a)
>>> x = np.arange(30., dtype=np.float64).reshape(2, 3, 5)
>>> y = op.apply(x)
>>> yy = np.sum(a * x[:, :, np.newaxis, :], axis=-1)
>>> np.sqrt(np.sum((yy - y)**2))
0.0

Performing in-place operations

All types of operators define a method apply(x, y), where x is a memoryview of the input and y is a memoryview of the output. If y is None, then apply returns a newly created memoryview. If y is not None, then apply returns a reference to y.

Depending on the implementation, some operators allow for in-place operations, which can further reduce memory allocations. In other words, apply(x, x) is valid for such operators and returns the expected value. Whether or not an operator allows for in-place operations is implementation dependent, and should be specified in the documentation. Unless otherwise stated, it should be assumed that in-place operations are not supported.

If relevant, the above also applies to the Cython method c_apply(x, y).

API of module janus.operators

This module defines operators in the general sense, as a mapping from a (real) vector space to another.

Functions defined in this module

Classes defined in this module

class janus.operators.AbstractLinearOperator

Specialization of class AbstractOperator to linear operators.

This abstract class defines the method to_memoryview(), which returns the matrix of this linear operator as a memoryview.

to_memoryview(self, double[:, :] out=None)

Return the matrix of this operator as a memoryview.

If out is None, a new memoryview is allocated and returned. Otherwise, the matrix is stored in out, and a view of out is returned.

Parameters

(float[ (out) – , :]): The output array.

class janus.operators.AbstractOperator

General operator.

Concrete instances of this class map arrays of size isize to arrays of size osize.

apply(self, double[:] x, double[:] y=None)

Return the result of applying this operator to x.

If y is None, then a new memoryview is created and returned. Otherwise, the image of x is stored in y, and a view of y is returned.

Parameters
  • (float[ (y) – ]): The input vector.

  • (float[ – ]): The output vector (optional).

init_sizes(self, int isize, int osize)

Initialize the values of isize and osize.

This method is provided as a convenience to users who want to create pure Python implementations of this class. It should be called only once at the initialization of the instance, as it can potentially modify the isize and osize attributes (which are otherwise read-only).

Parameters
  • isize (int) – The size of the input.

  • osize (int) – The size of the output.

isize

The size of the input (int, read-only).

osize

The size of the output (int, read-only).

class janus.operators.AbstractStructuredOperator2D

Operator applied to vectorial data structured in a 2D grid.

Structured operators map real vectors of dimension isize to real vectors of dimension osize. Input and output vectors are structured in 2D grids, each grid-cell being a vector itself. Therefore, the input is a float[:, :, :] of shape:

(shape0, shape1, ishape2),

while the output is a float[:, :, :] of shape:

(shape0, shape1, oshape2).

Furthermore:

isize = shape0 * shape1 * ishape2,
osize = shape0 * shape1 * oshape2.
apply(self, double[:, :, :] x, double[:, :, :] y=None)

Return the result of applying this operator to x.

If y is None, then a new memoryview is created and returned. Otherwise, the image of x is stored in y, and a view of y is returned.

The default implementation calls the (Cython) method c_apply().

Parameters
  • (float[ (y) – , :, :]): The input vector.

  • (float[ – , :, :]): The output vector.

init_shapes(self, int shape0, int shape1, int ishape2, int oshape2)

Initialize the values of ishape and oshape.

This method is provided as a convenience to users who want to create pure Python implementations of this class. It should be called only once at the initialization of the instance, as it can potentially modify these attributes (which are otherwise read-only).

See shape0, shape1, ishape2 and oshape2 for the meaning of the arguments of this function.

dim

The dimension of the structured grid (int, 2).

ishape

The shape of the input (tuple).

ishape2

The third dimension of the input (int).

oshape

The shape of the output (tuple).

oshape2

The third dimension of the output (int).

shape0

The first dimension of the input and output (int).

shape1

The second dimension of the input and output (int).

class janus.operators.AbstractStructuredOperator3D

Operator applied to vectorial data structured in a 3D grid.

Structured operators map real vectors of dimension isize to real vectors of dimension osize. Input and output vectors are structured in 3D grids, each grid-cell being a vector itself. Therefore, the input is a float[:, :, :, :] of shape:

(shape0, shape1, shape2, ishape3),

while the output is a float[:, :, :, :] of shape:

(shape0, shape1, shape2, oshape3).

Furthermore:

isize = shape0 * shape1 * shape2 * ishape3,
osize = shape0 * shape1 * shape2 * oshape3.
apply(self, double[:, :, :, :] x, double[:, :, :, :] y=None)

Return the result of applying this operator to x.

If y is None, then a new memoryview is created and returned. Otherwise, the image of x is stored in y, and a view of y is returned.

The default implementation calls the (Cython) method c_apply().

Parameters
  • (float[ (y) – , :, :, :]): The input vector.

  • (float[ – , :, :, :]): The output vector.

init_shapes(self, int shape0, int shape1, int shape2, int ishape3, int oshape3)

Initialize the values of ishape and oshape.

This method is provided as a convenience to users who want to create pure Python implementations of this class. It should be called only once at the initialization of the instance, as it can potentially modify these attributes (which are otherwise read-only).

See shape0, shape1, shape2, ishape3 and oshape3 for the meaning of the arguments of this function.

dim

The dimension of the structured grid (int, 3).

ishape

The shape of the input (tuple).

ishape3

The fourth dimension of the input (int).

oshape

The shape of the output (tuple).

oshape3

The fourth dimension of the output (int).

shape0

The first dimension of the input and output (int).

shape1

The second dimension of the input and output (int).

shape2

The third dimension of the input and output (int).

class janus.operators.BlockDiagonalLinearOperator2D

Block-diagonal linear operator with 2D layout of the data.

Instances of this class keep a shallow copy of the array of local matrices passed to the initializer.

Parameters

(float[ (a) – , :, :, :]): The array of local matrices.

apply_transpose(self, double[:, :, :] x, double[:, :, :] y=None)

Return the result of applying the transposed operator to x.

The output is defined as follows:

y[i0, i1, i2] = sum(a[i0, i1, j2, i2] * x[i0, i1, j2], j2)

If y is None, then a new memoryview is created and returned. Otherwise, the image of x is stored in y, and a view of y is returned.

The default implementation calls the (Cython) method c_apply_transpose().

Parameters
  • (float[ (y) – , :, :]): The input vector.

  • (float[ – , :, :]): The output vector.

class janus.operators.BlockDiagonalLinearOperator3D

Block-diagonal linear operator with 3D layout of the data.

Instances of this class keep a shallow copy of the array of local matrices passed to the initializer.

Parameters

(float[ (a) – , :, :, :, :]): The array of local matrices.

apply_transpose(self, double[:, :, :, :] x, double[:, :, :, :] y=None)

Return the result of applying the transposed operator to x.

The output is defined as follows:

y[i0, i1, i2, i3] = sum(a[i0, i1, i2, j3, i3] *
                        x[i0, i1, i2, j3], j3)

If y is None, then a new memoryview is created and returned. Otherwise, the image of x is stored in y, and a view of y is returned.

The default implementation calls the (Cython) method c_apply_transpose().

Parameters
  • (float[ (y) – , :, :, :]): The input vector.

  • (float[ – , :, :, :]): The output vector.

class janus.operators.BlockDiagonalOperator2D

Block-diagonal operator with 2D layout of the (vectorial) data.

If the local operators loc allow for in-place operations, then the block-diagonal operator also allows for in-place operations.

Instances of this class keep a shallow copy of the array of local operators passed to the initializer.

Parameters

(AbstractOperator[ (loc) – , :]): The array of local operators.

class janus.operators.BlockDiagonalOperator3D

Block-diagonal operator with 3D layout of the (vectorial) data.

If the local operators loc allow for in-place operations, then the block-diagonal operator also allows for in-place operations.

Instances of this class keep a shallow copy of the array of local operators passed to the initializer.

Parameters

(AbstractOperator[ (loc) – , :, :]): The array of local operators.

class janus.operators.FourthRankCubicTensor2D
dim

The dimension of the physical space (int, read-only).

t11

The (1, 1) coefficient of the Mandel-Voigt matrix representation.

t12

The (1, 2) coefficient of the Mandel-Voigt matrix representation.

t13

The (1, 3) coefficient of the Mandel-Voigt matrix representation.

t23

The (2, 3) coefficient of the Mandel-Voigt matrix representation.

t33

The (3, 3) coefficient of the Mandel-Voigt matrix representation.

class janus.operators.FourthRankIsotropicTensor

Fourth rank, isotropic tensor with minor symmetries.

Such a tensor is defined by its spherical and deviatoric projections. Warning: this class should not be instantiated directly, as the object returned by __cinit__ would not be in a legal state. Use the function isotropic_4() instead.

Any fourth rank, isotropic tensor T is a linear combination of the spherical projection tensor J and the deviatoric projection tensor K:

T = sph * J + dev * K.

sph and dev are the two coefficients which are passed to the initializer of this class. The components of J are:

J_ijkl = δ_ij * δ_kl / d,

where δ_ij denotes the Kronecker symbol, and d is the dimension of the physical space on which the tensor operates. The components of K are found from the identity K = I - J, where I is the fourth-rank identity tensor:

I_ijkl = (δ_ik * δ_jl + δ_il * δ_jk) / 2.
Parameters
  • sph – See sph.

  • dev – See dev.

  • dim – See dim.

dev

The deviatoric projection of the tensor (float, read-only).

dim

The dimension of the physical space (int, read-only).

sph

The spherical projection of the tensor (float, read-only).

class janus.operators.FourthRankIsotropicTensor2D

Specialization of FourthRankIsotropicTensor to 2D.

The present implementation allows for in-place operations.

class janus.operators.FourthRankIsotropicTensor3D

Specialization of FourthRankIsotropicTensor to 3D.

The present implementation allows for in-place operations.

class janus.operators.LinearOperator

Matrix-based AbstractLinearOperator.

Instances of this class keep a shallow copy of the matrix that was passed to the initializer.

Parameters

(float[ (a) – , :]): The matrix of the linear operator.

apply_transpose(self, double[:] x, double[:] y=None)

Return the result of applying the transposed operator to x.

If y is None, then a new memoryview is created and returned. Otherwise, the image of x is stored in y, and a view of y is returned.

The default implementation calls the (Cython) method c_apply_transpose().

Parameters
  • (float[ (y) – ]): The input vector.

  • (float[ – ]): The output vector.

janus.operators.block_diagonal_linear_operator(a)

Create a block-diagonal, linear operator.

The array of local matrices a is a 4D or 5D memoryview of float.

The returned instance of BlockDiagonalLinearOperator2D (if a is of type float[:, :, :, :]) or BlockDiagonalLinearOperator3D (if a is of type float[:, :, :, :, :]) keeps a shallow copy of a.

janus.operators.block_diagonal_operator(loc)

Create a block-diagonal operator.

The array of local operators loc is a two- or three- dimensional memoryview of AbstractOperator.

The returned instance of BlockDiagonalOperator2D or BlockDiagonalOperator3D keeps a shallow copy of loc.

janus.operators.isotropic_4(sph, dev, dim)

Create a new instance of FourthRankIsotropicTensor.

Parameters
  • sph (float) – The spherical projection.

  • dev (float) – The deviatoric projection.

  • dim (int) – The dimension of the physical space.