Source code for capytaine.matrices.builders

"""This module contains some helpful functions to create block matrices."""
# Copyright (C) 2017-2019 Matthieu Ancellin
# See LICENSE file at <https://github.com/mancellin/capytaine>

import logging
from itertools import accumulate

import numpy as np

from capytaine.matrices.block import BlockMatrix
from capytaine.matrices.low_rank import LowRankMatrix

LOG = logging.getLogger(__name__)


[docs] def cut_matrix(full_matrix, x_shapes, y_shapes, check=False): """Transform a numpy array into a block matrix of numpy arrays. Parameters ---------- full_matrix: numpy array The matrix to split into blocks. x_shapes: sequence of int The columns at which to split the blocks. y_shapes: sequence of int The lines at which to split the blocks. check: bool, optional Check to dimensions and type of the matrix after creation (default: False). Return ------ BlockMatrix The same matrix as the input one but in block form. """ new_block_matrix = [] for i, di in zip(accumulate([0] + x_shapes[:-1]), x_shapes): line = [] for j, dj in zip(accumulate([0] + x_shapes[:-1]), y_shapes): line.append(full_matrix[i:i+di, j:j+dj]) new_block_matrix.append(line) return BlockMatrix(new_block_matrix, check=check)
[docs] def random_block_matrix(x_shapes, y_shapes, rng=np.random.default_rng()): """A random block matrix.""" return cut_matrix(rng.uniform(size=(sum(x_shapes), sum(y_shapes))), x_shapes, y_shapes)
[docs] def full_like(A, value, dtype=np.float64): """A matrix of the same kind and shape as A but filled with a single value.""" if isinstance(A, BlockMatrix): new_matrix = [] for i in range(A._stored_nb_blocks[0]): line = [] for j in range(A._stored_nb_blocks[1]): line.append(full_like(A._stored_blocks[i, j], value, dtype=dtype)) new_matrix.append(line) return A.__class__(new_matrix) elif isinstance(A, LowRankMatrix): return LowRankMatrix(np.ones((A.shape[0], 1)), np.full((1, A.shape[1]), value)) elif isinstance(A, np.ndarray): return np.full_like(A, value, dtype=dtype)
[docs] def zeros_like(A, dtype=np.float64): """A matrix of the same kind and shape as A but filled with zeros.""" return full_like(A, 0.0, dtype=dtype)
[docs] def ones_like(A, dtype=np.float64): """A matrix of the same kind and shape as A but filled with ones.""" return full_like(A, 1.0, dtype=dtype)
[docs] def identity_like(A, dtype=np.float64): """A identity matrix of the same kind and shape as A.""" if isinstance(A, BlockMatrix): I = [] for i in range(A._stored_nb_blocks[0]): line = [] for j in range(A._stored_nb_blocks[1]): if i == j: line.append(identity_like(A._stored_blocks[i, j], dtype=dtype)) else: line.append(zeros_like(A._stored_blocks[i, j], dtype=dtype)) I.append(line) return A.__class__(I) elif isinstance(A, np.ndarray): return np.eye(A.shape[0], A.shape[1], dtype=dtype)