1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
"""Tests of core functions in eigenvalue problem solvers."""
import numpy as np
import pytest
from scipy.sparse import csr_array
from symfc.utils.eig_tools_core import (
EigenvectorResult,
_divide_eigenvectors,
eigh_projector,
find_projector_blocks,
)
from symfc.utils.matrix import root_block_matrix
def _set_projector():
"""Set projector."""
# Atomic permutations of four atoms
row = np.repeat(np.arange(12), 4)
col = np.array([i + j for j in range(3) for i in range(0, 12, 3)])
col = np.tile(col, 4)
data = np.full(len(col), 0.25)
proj = csr_array((data, (row, col)), shape=(12, 12), dtype=float)
return proj
def _assert_eigvecs(eigvecs):
"""Assert eigenvectors."""
assert eigvecs.shape[1] == 3
assert np.linalg.norm(eigvecs[:, 0]) == pytest.approx(1.0)
assert np.linalg.norm(eigvecs[:, 1]) == pytest.approx(1.0)
assert np.linalg.norm(eigvecs[:, 2]) == pytest.approx(1.0)
assert eigvecs[:, 0] @ eigvecs[:, 1] == pytest.approx(0.0)
assert eigvecs[:, 1] @ eigvecs[:, 2] == pytest.approx(0.0)
assert eigvecs[:, 2] @ eigvecs[:, 0] == pytest.approx(0.0)
for i in range(3):
nonzero = np.where(np.abs(eigvecs[:, i]) > 1e-12)[0]
assert np.all(np.isclose(eigvecs[:, i][nonzero], eigvecs[nonzero[0], i]))
def test_eigh_projector():
"""Test eigh_projector."""
proj = _set_projector()
eigvecs = eigh_projector(proj, verbose=False).eigvecs
_assert_eigvecs(eigvecs)
def test_eigenvector_result():
"""Test EigenvectorResult."""
eigvecs = np.random.random((5, 3))
res = EigenvectorResult(eigvecs)
assert res.n_eigvecs == 3
block = res.block_eigvecs
block_root = root_block_matrix(shape=(5, 3), first_child=block)
mat = np.random.random((3, 3))
np.testing.assert_allclose(block_root.dot(mat), eigvecs @ mat)
res = EigenvectorResult(block_root)
assert res.n_eigvecs == 3
def test_eigenvector_result_with_compress():
"""Test EigenvectorResult with compression matrix."""
eigvecs = np.random.random((3, 2))
compress = np.random.random((5, 3))
res = EigenvectorResult(eigvecs, compress=compress)
assert res.n_eigvecs == 2
block = res.block_eigvecs
block_root = root_block_matrix(shape=(5, 2), first_child=block)
np.testing.assert_allclose(block_root.recover(), compress @ eigvecs)
def test_divide_eigenvectors():
"""Test _divide_eigenvectors."""
eigvecs = np.random.random((10, 5))
eigvals = np.array([1.0, 1.0, 1.0, 0.5, 0.5])
res = _divide_eigenvectors(eigvals, eigvecs)
assert res.eigvecs.shape == (10, 3)
assert res.cmplt_eigvecs.shape == (10, 2)
np.testing.assert_allclose(res.cmplt_eigvals, [0.5, 0.5])
def test_find_projector_blocks():
"""Test find_projector_blocks."""
proj = _set_projector()
group = find_projector_blocks(proj)
assert group[0] == [0, 3, 6, 9]
assert group[1] == [1, 4, 7, 10]
assert group[2] == [2, 5, 8, 11]
|