capytaine.tools.block_circulant_matrices module

Implementation of block circulant matrices to be used for optimizing resolution with symmetries.

class capytaine.tools.block_circulant_matrices.BlockCirculantMatrix(blocks: Sequence[Any] | Any)[source]

Bases: _BlockMatrixBackendMixin

Data-sparse representation of a block matrix of the following form:

( a  d  c  b )
( b  a  d  c )
( c  b  a  d )
( d  c  b  a )

where a, b, c and d are matrices of the same shape.

Parameters:

blocks (Sequence of arrays, can be also an array of shape (nb_blocks, n, n, …)) – The first column of blocks [a, b, c, d, …] Each block should have the same shape.

block_diagonalize() → BlockDiagonalMatrix[source]
matvec(other)[source]
solve(b)[source]
class capytaine.tools.block_circulant_matrices.BlockDiagonalMatrix(blocks: Sequence[Any] | Any)[source]

Bases: _BlockMatrixBackendMixin

Data-sparse representation of a block matrix of the following form:

( a  0  0  0 )
( 0  b  0  0 )
( 0  0  c  0 )
( 0  0  0  d )

where a, b, c and d are matrices of the same shape.

Parameters:

blocks (Sequence of arrays, can be also an array of shape (nb_blocks, n, n)) – The blocks [a, b, c, d, …]

solve(b)[source]
class capytaine.tools.block_circulant_matrices.LUDecomposedBlockCirculantMatrix(bcm: BlockCirculantMatrix, *, overwrite_a: bool = False)[source]

Bases: AbstractLUDecomposedMatrix

solve(b)[source]

Solve the linear system with the decomposed matrix as left-hand side and b as right-hand side.

class capytaine.tools.block_circulant_matrices.LUDecomposedBlockDiagonalMatrix(bdm: BlockDiagonalMatrix, *, overwrite_a: bool = False)[source]

Bases: AbstractLUDecomposedMatrix

LU decomposition of a BlockDiagonalMatrix, stored as the LU decomposition of each block.

solve(b)[source]

Solve the linear system with the decomposed matrix as left-hand side and b as right-hand side.

class capytaine.tools.block_circulant_matrices.NestedBlockCirculantMatrix(blocks: Sequence[Any] | Any)[source]

Bases: _BlockMatrixBackendMixin

Data-sparse representation of a block matrix of the following form:

( a  b | e  d | c  f )
( b  a | f  c | d  e )
( ------------------ )
( c  f | a  b | e  d )
( d  e | b  a | f  c )
( ------------------ )
( e  d | c  f | a  b )
( f  c | d  e | b  a )

where a, b, c, d, e and f are matrices of the same shape, that is a block circulant matrix (here of size 3x3, but arbitrary outer sizes are supported), where diagonal blocks are 2x2 block circulant matrices and off-diagonal blocks have subblocks in common.

Reordering the lines and columns, this matrix is equivalent to the following shape:

( a  e  c | b  d  f )
( c  a  e | f  b  d )
( e  c  a | d  f  b )
( ----------------- )
( b  f  d | a  c  e )
( d  b  f | e  a  c )
( f  d  b | c  e  a )

that is a 2x2 block matrix of block circulant matrices, the block circulant matrices of the bottom row being the transpose of the block circulant matrices of the top row.

In the 2x2x2x2 limit case, the matrix is a nested block circulant matrix:

( a  b | c  d )
( b  a | d  c )
( ----------- )
( c  d | a  b )
( d  c | b  a )

The 4x4x2x2 pattern reads:

( a  b | g  d | e  f | c  h )
( b  a | h  c | f  e | d  g )
( -----|------|------|----- )
( c  h | a  b | g  d | e  f )
( d  g | b  a | h  c | f  e )
( -----|------|------|----- )
( e  f | c  h | a  b | g  d )
( f  e | d  g | b  a | h  c )
( -----|------|------|----- )
( g  d | e  f | c  h | a  b )
( h  c | f  e | d  g | b  a )
Parameters:

blocks (Sequence of arrays, can be also an array of shape (nb_blocks, n, n, …)) – The first column of blocks [a, b, c, d, …] Each block should have the same shape, and the number of blocks should be even.

block_diagonalize() → BlockDiagonalMatrix[source]
matvec(other)[source]
solve(b)[source]
to_BlockCirculantMatrix()[source]

Convert to a BlockCirculantMatrix with combined macro-blocks.

The NestedBlockCirculantMatrix with blocks [a, b, c, d, e, f, ...] (where nb_blocks = 2*n) is converted to a BlockCirculantMatrix with n macro-blocks.

Each macro-block i (for i in 0..n-1) is a 2x2 arrangement of the original blocks:

  • For i=0: [[blocks[0], blocks[1]], [blocks[1], blocks[0]]]

  • For i>0: [[blocks[2*i], blocks[2*n-2*i+1]], [blocks[2*i+1], blocks[2*n-2*i]]]

capytaine.tools.block_circulant_matrices.circular_permutation(l: List, i: int) → List[source]