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 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
"""Tests of eigsh functions."""
import numpy as np
import pytest
from scipy.sparse import csr_array
from symfc.utils.eig_tools import (
_compr_projector,
eigh_projector,
eigh_projector_division,
eigsh_projector,
eigsh_projector_sumrule,
)
def test_eigsh_projector():
"""Test eigsh_projector and eigsh_projector_sumrule."""
# 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)
eigvecs = eigsh_projector(proj, verbose=False)
eigvecs = eigvecs.toarray()
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]))
eigvecs = eigsh_projector_sumrule(proj, verbose=False)
eigvecs = eigvecs.recover()
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 and eigh_projector_use_submatrix."""
# 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).toarray()
eigvecs = eigh_projector(proj, verbose=False)
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]))
eigvecs = eigh_projector_division(proj, verbose=False)
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_compr_projector():
"""Test compr_projector."""
row = col = [0, 2, 5]
data = [1, 1, 1]
proj = csr_array((data, (row, col)), shape=(6, 6), dtype=int)
proj_rev, compr = _compr_projector(proj)
assert proj_rev.shape == (3, 3)
np.testing.assert_allclose(proj_rev.toarray(), np.eye(3))
assert compr.shape == (6, 3)
compr_ref = np.zeros(compr.shape, dtype=int)
for icol, irow in enumerate(row):
compr_ref[irow, icol] = 1
np.testing.assert_allclose(compr.toarray(), compr_ref)
|