Source code for protis.utils.helpers

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Benjamin Vial
# This file is part of protis
# License: GPLv3
# See the documentation at protis.gitlab.io


from nannos import is_scalar as _is_scalar
from nannos.layers import is_anisotropic

from .. import backend as bk


def _allclose(a, b, tol=1e-12):
    for _a, _b in zip(a.flatten(), b.flatten()):
        if abs(_a - _b) > tol:
            return False
    return True


[docs] def is_scalar(a): return len(a.shape) == 0 if hasattr(a, "shape") else _is_scalar(a)
[docs] def block_anisotropic(a, dim=3): l = len(a[0]), len(a[1]) if l != (dim, dim): raise ValueError(f"input shape must be ({dim},{dim},N,N)") return bk.stack( [bk.array(bk.stack([bk.array(a[j][i]) for i in range(3)])) for j in range(3)] )
[docs] def block_z_anisotropic(axx, axy, ayx, ayy, azz): zer = 0 * axx a_list = [ [axx, axy, zer], [ayx, ayy, zer], [zer, zer, azz], ] return block_anisotropic(a_list)
[docs] def block(a): return bk.hstack( [ bk.array(bk.vstack([bk.array(a[i][j]) for i in range(len(a))])) for j in range(len(a)) ] )
[docs] def is_z_anisotropic(a): if not is_anisotropic(a): return False zer = 0 * a[0, 0] return ( _allclose(a[0, 2], zer) and _allclose(a[1, 2], zer) and _allclose(a[2, 0], zer) and _allclose(a[2, 1], zer) )
[docs] def is_symmetric(M): return _allclose(M, M.T)
[docs] def is_hermitian(M): return _allclose(bk.conj(M), M.T)
[docs] def invblock(A, B, C, D): invA = bk.linalg.inv(A) Q = bk.linalg.inv(D - C @ invA @ B) Mxx = invA + invA @ B @ Q @ C @ invA Mxy = -invA @ B @ Q Myx = -Q @ C @ invA Myy = Q return block([[Mxx, Mxy], [Myx, Myy]])