symfc 1.3.2__tar.gz → 1.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {symfc-1.3.2/src/symfc.egg-info → symfc-1.3.4}/PKG-INFO +1 -1
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/utils/eig_tools.py +17 -4
- symfc-1.3.4/src/symfc/utils/matrix_tools.py +35 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/utils/matrix_tools_O2.py +127 -28
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/utils/matrix_tools_O3.py +126 -28
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/utils/matrix_tools_O4.py +170 -72
- symfc-1.3.4/src/symfc/utils/permutation_tools.py +113 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/utils/permutation_tools_O2.py +39 -21
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/utils/permutation_tools_O3.py +41 -24
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/utils/permutation_tools_O4.py +43 -25
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/version.py +1 -1
- {symfc-1.3.2 → symfc-1.3.4/src/symfc.egg-info}/PKG-INFO +1 -1
- symfc-1.3.2/src/symfc/utils/matrix_tools.py +0 -89
- symfc-1.3.2/src/symfc/utils/permutation_tools.py +0 -35
- {symfc-1.3.2 → symfc-1.3.4}/LICENSE +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/MANIFEST.in +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/README.md +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/pyproject.toml +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/setup.cfg +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/__init__.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/api_symfc.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/basis_sets/__init__.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/basis_sets/basis_sets_O1.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/basis_sets/basis_sets_O2.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/basis_sets/basis_sets_O3.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/basis_sets/basis_sets_O4.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/basis_sets/basis_sets_base.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/solvers/__init__.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/solvers/solver_O2.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/solvers/solver_O2O3.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/solvers/solver_O2O3O4.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/solvers/solver_O3.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/solvers/solver_O3O4.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/solvers/solver_O4.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/solvers/solver_base.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/spg_reps/__init__.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/spg_reps/spg_reps_O1.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/spg_reps/spg_reps_O2.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/spg_reps/spg_reps_O3.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/spg_reps/spg_reps_O4.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/spg_reps/spg_reps_base.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/utils/__init__.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/utils/cutoff_tools.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/utils/matrix_tools_O1.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/utils/rotation_dev/__init__.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/utils/rotation_dev/run_rotation_tools_O2.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/utils/rotation_dev/run_rotation_tools_O3.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/utils/rotation_dev/run_test_O2.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/utils/rotation_tools_O2.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/utils/solver_funcs.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/utils/utils.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/utils/utils_O1.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/utils/utils_O2.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/utils/utils_O3.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc/utils/utils_O4.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc.egg-info/SOURCES.txt +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc.egg-info/dependency_links.txt +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc.egg-info/requires.txt +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/src/symfc.egg-info/top_level.txt +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/NaCl-unitcell.yaml +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/basis_sets/test_basis_sets_O2.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/basis_sets/test_basis_sets_O3.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/basis_sets/test_basis_sets_O4.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/basis_sets/test_basis_sets_base.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/compact_fc_GaN_222.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/compact_fc_GaN_442.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/compact_fc_NaCl_222.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/compact_fc_SiO2_221.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/compact_fc_Si_111_fc3_2.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/compact_fc_Si_111_fc3_3.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/compact_fc_Si_111_fc4_2.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/compact_fc_Si_111_fc4_3.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/compact_fc_Si_111_fc4_4.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/compact_fc_SnO2_223.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/conftest.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/dfset_GaN_222_rd.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/dfset_GaN_442_rd.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/dfset_NaCl_222_rd.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/dfset_SiO2_221_rd.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/dfset_Si_111_fc3_rd.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/dfset_SnO2_223_rd.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/full_fc_NaCl_222.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/full_fc_Si_111_fc3_2.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/full_fc_Si_111_fc3_3.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/full_fc_Si_111_fc4_2.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/full_fc_Si_111_fc4_3.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/full_fc_Si_111_fc4_4.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/full_fc_Si_111_fc4_step_2.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/full_fc_Si_111_fc4_step_3.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/full_fc_Si_111_fc4_step_4.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/full_fc_SnO2_223.xz +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/perms_super.dat +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/phonopy_to_python.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/solvers/test_solver_utils.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/spg_reps/test_spg_reps_O1.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/spg_reps/test_spg_reps_O2.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/spg_reps/test_spg_reps_O3.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/spg_reps/test_spg_reps_O4.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/spg_reps/test_spg_reps_base.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/test_api.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/utils/test_cutoff_tools.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/utils/test_eig_tools.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/utils/test_matrix_tools_O2.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/utils/test_matrix_tools_O3.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/utils/test_matrix_tools_O4.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/utils/test_solver_funcs.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/utils/test_utils.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/utils/test_utils_O1.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/utils/test_utils_O2.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/utils/test_utils_O2_2.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/utils/test_utils_O3.py +0 -0
- {symfc-1.3.2 → symfc-1.3.4}/tests/utils/test_utils_O4.py +0 -0
|
@@ -359,10 +359,23 @@ def eigsh_projector_sumrule_large(p: csr_array, verbose: bool = True) -> np.ndar
|
|
|
359
359
|
When p = diag(A,B), Av = v, and Bw = w, p[v,0] = [v,0] and p[0,w] = [0,w]
|
|
360
360
|
are solutions.
|
|
361
361
|
|
|
362
|
-
This
|
|
363
|
-
|
|
364
|
-
block
|
|
365
|
-
|
|
362
|
+
This algorithm is optimized to solve an eigenvalue problem for
|
|
363
|
+
projection matrix p with large block submatrices.
|
|
364
|
+
The algorithm for solving each block submatrix is as follows.
|
|
365
|
+
1. Divide each block submatrix into reasonable sizes of submatrices,
|
|
366
|
+
not projectors.
|
|
367
|
+
2. Solve eigenvalue problems for these submatrices and eigenvectors
|
|
368
|
+
with eigenvalues of one are extracted. The eigenvectors with
|
|
369
|
+
eigenvalues e < 1 are used for compressing the complementary matrix
|
|
370
|
+
in the next step.
|
|
371
|
+
3. Calculate the complementary matrix, which corresponds to the complement
|
|
372
|
+
of the vector space spanned by the eigenvectors. The complementary matrix
|
|
373
|
+
is compressed using the eigenvectors with e < 1.
|
|
374
|
+
4. Solve eigenvalue problem for the complementary matrix and eigenvectors
|
|
375
|
+
with e = 1 are calculated. The eigenvalue problems are efficiently solved
|
|
376
|
+
using the compressed complementary matrix and the eigenvectors are recovered by
|
|
377
|
+
the compression matrix.
|
|
378
|
+
5. Collect all eigenvectors with e = 1.
|
|
366
379
|
"""
|
|
367
380
|
group = _find_projector_blocks(p)
|
|
368
381
|
if verbose:
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Matrix utility functions."""
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from scipy.sparse import csr_array
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def permutation_dot_lat_trans(
|
|
8
|
+
combinations_ijk: np.ndarray,
|
|
9
|
+
combinations_abc: np.ndarray,
|
|
10
|
+
atomic_decompr_idx: np.ndarray,
|
|
11
|
+
n_perms: int,
|
|
12
|
+
n_perms_group: int,
|
|
13
|
+
n_lp: int,
|
|
14
|
+
order: int,
|
|
15
|
+
natom: int,
|
|
16
|
+
) -> csr_array:
|
|
17
|
+
"""Return C_perm.T @ C_trans for permulation symmetry rules."""
|
|
18
|
+
assert combinations_ijk.shape[0] == combinations_abc.shape[0]
|
|
19
|
+
|
|
20
|
+
sum_abc = 3**order
|
|
21
|
+
sum_ijkabc = natom**order * sum_abc
|
|
22
|
+
n_combinations = combinations_ijk.shape[0] // n_perms
|
|
23
|
+
n_perms_sym = n_perms // n_perms_group
|
|
24
|
+
c_pt = csr_array(
|
|
25
|
+
(
|
|
26
|
+
np.full(n_combinations * n_perms, 1 / np.sqrt(n_perms_sym * n_lp)),
|
|
27
|
+
(
|
|
28
|
+
np.repeat(np.arange(n_combinations * n_perms_group), n_perms_sym),
|
|
29
|
+
atomic_decompr_idx[combinations_ijk] * sum_abc + combinations_abc,
|
|
30
|
+
),
|
|
31
|
+
),
|
|
32
|
+
shape=(n_combinations * n_perms_group, sum_ijkabc // n_lp),
|
|
33
|
+
dtype="double",
|
|
34
|
+
)
|
|
35
|
+
return c_pt
|
|
@@ -7,7 +7,8 @@ import scipy
|
|
|
7
7
|
from scipy.sparse import csr_array
|
|
8
8
|
|
|
9
9
|
from symfc.utils.cutoff_tools import FCCutoff
|
|
10
|
-
from symfc.utils.matrix_tools import
|
|
10
|
+
from symfc.utils.matrix_tools import permutation_dot_lat_trans
|
|
11
|
+
from symfc.utils.permutation_tools import get_combinations
|
|
11
12
|
from symfc.utils.solver_funcs import get_batch_slice
|
|
12
13
|
from symfc.utils.utils import get_indep_atoms_by_lat_trans
|
|
13
14
|
from symfc.utils.utils_O2 import _get_atomic_lat_trans_decompr_indices
|
|
@@ -103,7 +104,7 @@ def optimize_batch_size_sum_rules_O2(natom: int, n_batch: Optional[int] = None):
|
|
|
103
104
|
return batch_size
|
|
104
105
|
|
|
105
106
|
|
|
106
|
-
def
|
|
107
|
+
def compressed_projector_sum_rules_O2(
|
|
107
108
|
trans_perms: np.ndarray,
|
|
108
109
|
n_a_compress_mat: csr_array,
|
|
109
110
|
atomic_decompr_idx: Optional[np.ndarray] = None,
|
|
@@ -111,18 +112,67 @@ def compressed_projector_sum_rules_O2_index_atoms(
|
|
|
111
112
|
n_batch: int = 1,
|
|
112
113
|
use_mkl: bool = False,
|
|
113
114
|
) -> csr_array:
|
|
114
|
-
"""Return projection matrix for sum rule.
|
|
115
|
+
r"""Return projection matrix for translational sum rule.
|
|
115
116
|
|
|
116
|
-
Calculate a
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
Calculate a compressed projector for translational sum rules
|
|
118
|
+
efficiently using independent atom with respect to lattice translations.
|
|
119
|
+
This compression is achieved using C_trans and n_a_compress_mat,
|
|
120
|
+
without the need to allocate C_trans. The implementation utilizes
|
|
121
|
+
get_atomic_lat_trans_decompr_indices_O3 to ensure efficient memory usage.
|
|
120
122
|
|
|
121
123
|
Return
|
|
122
124
|
------
|
|
123
|
-
Compressed projector I - P^(c)
|
|
124
|
-
|
|
125
|
-
|
|
125
|
+
Compressed projector I - P^(c).
|
|
126
|
+
I - P^(c)
|
|
127
|
+
= n_a_compress_mat.T @ C_trans.T
|
|
128
|
+
@ [I - C_sum^(c) @ C_sum^(c).T] @ C_trans @ n_a_compress_mat
|
|
129
|
+
= I - [n_a_compress_mat.T @ C_trans.T @ C_sum^(c)]
|
|
130
|
+
@ [C_sum^(c).T @ C_trans @ n_a_compress_mat]
|
|
131
|
+
|
|
132
|
+
Algorithm
|
|
133
|
+
---------
|
|
134
|
+
1. C_sum^(c).T = [I, I, I, ...] of size (27N, 27N^2).
|
|
135
|
+
I denotes the unit matrix of size (27N, 27N).
|
|
136
|
+
C_sum^(c).T is composed of N unit matrices.
|
|
137
|
+
In this representation, the translational sum rules are given by
|
|
138
|
+
\sum_i FC2(i, j, a, b) = 0.
|
|
139
|
+
|
|
140
|
+
2. To divide the computation of a compressed projector into several batches,
|
|
141
|
+
C_sum^(c) and C_trans are permuted from the index order of (i, j, a, b)
|
|
142
|
+
to (a, b, j, i).
|
|
143
|
+
This is represented by C_sum^(c).T @ C_trans = C_sum^(c).T @ S.T @ S @ C_trans,
|
|
144
|
+
where S denotes the permutation matrix that changes the index order to
|
|
145
|
+
(a, b, j, i). Using this permutation, the translational sum rules are
|
|
146
|
+
represented as
|
|
147
|
+
C_sum^(c).T @ S.T = [
|
|
148
|
+
[1_N.T, 0_N.T, 0_N.T, ...]
|
|
149
|
+
[0_N.T, 1_N.T, 0_N.T, ...]
|
|
150
|
+
[0_N.T, 0_N.T, 1_N.T, ...]
|
|
151
|
+
...
|
|
152
|
+
],
|
|
153
|
+
where 1_N and 0_N are column vectors of size N with all elements
|
|
154
|
+
equal to one and zero, respectively.
|
|
155
|
+
(Example) C_sum^(c).T @ S.T = [
|
|
156
|
+
[1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 ...]
|
|
157
|
+
[0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 ...]
|
|
158
|
+
[0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 ...]
|
|
159
|
+
...
|
|
160
|
+
]
|
|
161
|
+
In this function, the permutation is achieved by using matrix reshapes.
|
|
162
|
+
|
|
163
|
+
3. Set C_trans.T @ C_sum^(c) @ C_sum^(c).T @ C_trans
|
|
164
|
+
= [(C_trans.T @ S.T) @ (S @ C_sum^(c))] @ [(C_sum^(c).T @ S.T) @ (S @ C_trans)]
|
|
165
|
+
= [T_1, T_2, ..., T_N33]
|
|
166
|
+
@ (S @ C_sum^(c)) @ (C_sum^(c).T @ S.T)
|
|
167
|
+
@ [T_1, T_2, ..., T_N33].T
|
|
168
|
+
= \sum_i t_i @ t_i.T,
|
|
169
|
+
where t_i = \sum_c T_i[:, c].
|
|
170
|
+
t_i is represented by c_sum_cplmt.T in this function.
|
|
171
|
+
T_i is the submatrix of size (N, n_aN33) of permuted C_trans.
|
|
172
|
+
|
|
173
|
+
4. Compute P^(c) = \sum_i (n_a_compress_mat.T @ t_i) @ (t_i.T @ n_a_compress_mat)
|
|
174
|
+
|
|
175
|
+
5. Compute P = I - P^(c)
|
|
126
176
|
"""
|
|
127
177
|
n_lp, natom = trans_perms.shape
|
|
128
178
|
NN9 = natom**2 * 9
|
|
@@ -135,14 +185,15 @@ def compressed_projector_sum_rules_O2_index_atoms(
|
|
|
135
185
|
atomic_decompr_idx = _get_atomic_lat_trans_decompr_indices(trans_perms)
|
|
136
186
|
|
|
137
187
|
decompr_idx = atomic_decompr_idx.reshape((natom, natom)).T.reshape(-1) * 9
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
188
|
+
|
|
189
|
+
indep_atoms = get_indep_atoms_by_lat_trans(trans_perms)
|
|
190
|
+
nonzero = np.zeros((natom, natom), dtype=bool)
|
|
191
|
+
nonzero[indep_atoms, :] = True
|
|
192
|
+
nonzero = nonzero.reshape(-1)
|
|
193
|
+
if fc_cutoff is not None:
|
|
194
|
+
nonzero_c = fc_cutoff.nonzero_atomic_indices_fc2()
|
|
195
|
+
nonzero_c = nonzero_c.reshape((natom, natom)).T.reshape(-1)
|
|
196
|
+
nonzero = nonzero & nonzero_c
|
|
146
197
|
|
|
147
198
|
batch_size = optimize_batch_size_sum_rules_O2(natom, n_batch=n_batch)
|
|
148
199
|
ab = np.arange(9)
|
|
@@ -171,11 +222,11 @@ def compressed_projector_sum_rules_O2_index_atoms(
|
|
|
171
222
|
c_sum_cplmt = dot_product_sparse(c_sum_cplmt, n_a_compress_mat, use_mkl=use_mkl)
|
|
172
223
|
proj_cplmt += dot_product_sparse(c_sum_cplmt.T, c_sum_cplmt, use_mkl=use_mkl)
|
|
173
224
|
|
|
174
|
-
proj_cplmt /=
|
|
225
|
+
proj_cplmt /= natom
|
|
175
226
|
return scipy.sparse.identity(proj_cplmt.shape[0]) - proj_cplmt
|
|
176
227
|
|
|
177
228
|
|
|
178
|
-
def
|
|
229
|
+
def compressed_projector_sum_rules_O2_stable(
|
|
179
230
|
trans_perms: np.ndarray,
|
|
180
231
|
n_a_compress_mat: csr_array,
|
|
181
232
|
atomic_decompr_idx: Optional[np.ndarray] = None,
|
|
@@ -183,18 +234,66 @@ def compressed_projector_sum_rules_O2(
|
|
|
183
234
|
n_batch: int = 1,
|
|
184
235
|
use_mkl: bool = False,
|
|
185
236
|
) -> csr_array:
|
|
186
|
-
"""Return projection matrix for sum rule.
|
|
237
|
+
r"""Return projection matrix for translational sum rule.
|
|
187
238
|
|
|
188
|
-
Calculate a
|
|
189
|
-
This is
|
|
190
|
-
|
|
191
|
-
|
|
239
|
+
Calculate a compressed projector for translational sum rules.
|
|
240
|
+
This compression is achieved using C_trans and n_a_compress_mat,
|
|
241
|
+
without the need to allocate C_trans. The implementation utilizes
|
|
242
|
+
get_atomic_lat_trans_decompr_indices_O3 to ensure efficient memory usage.
|
|
192
243
|
|
|
193
244
|
Return
|
|
194
245
|
------
|
|
195
|
-
Compressed projector I - P^(c)
|
|
196
|
-
|
|
197
|
-
|
|
246
|
+
Compressed projector I - P^(c).
|
|
247
|
+
I - P^(c)
|
|
248
|
+
= n_a_compress_mat.T @ C_trans.T
|
|
249
|
+
@ [I - C_sum^(c) @ C_sum^(c).T] @ C_trans @ n_a_compress_mat
|
|
250
|
+
= I - [n_a_compress_mat.T @ C_trans.T @ C_sum^(c)]
|
|
251
|
+
@ [C_sum^(c).T @ C_trans @ n_a_compress_mat]
|
|
252
|
+
|
|
253
|
+
Algorithm
|
|
254
|
+
---------
|
|
255
|
+
1. C_sum^(c).T = [I, I, I, ...] of size (27N, 27N^2).
|
|
256
|
+
I denotes the unit matrix of size (27N, 27N).
|
|
257
|
+
C_sum^(c).T is composed of N unit matrices.
|
|
258
|
+
In this representation, the translational sum rules are given by
|
|
259
|
+
\sum_i FC2(i, j, a, b) = 0.
|
|
260
|
+
|
|
261
|
+
2. To divide the computation of a compressed projector into several batches,
|
|
262
|
+
C_sum^(c) and C_trans are permuted from the index order of (i, j, a, b)
|
|
263
|
+
to (a, b, j, i).
|
|
264
|
+
This is represented by C_sum^(c).T @ C_trans = C_sum^(c).T @ S.T @ S @ C_trans,
|
|
265
|
+
where S denotes the permutation matrix that changes the index order to
|
|
266
|
+
(a, b, j, i). Using this permutation, the translational sum rules are
|
|
267
|
+
represented as
|
|
268
|
+
C_sum^(c).T @ S.T = [
|
|
269
|
+
[1_N.T, 0_N.T, 0_N.T, ...]
|
|
270
|
+
[0_N.T, 1_N.T, 0_N.T, ...]
|
|
271
|
+
[0_N.T, 0_N.T, 1_N.T, ...]
|
|
272
|
+
...
|
|
273
|
+
],
|
|
274
|
+
where 1_N and 0_N are column vectors of size N with all elements
|
|
275
|
+
equal to one and zero, respectively.
|
|
276
|
+
(Example) C_sum^(c).T @ S.T = [
|
|
277
|
+
[1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 ...]
|
|
278
|
+
[0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 ...]
|
|
279
|
+
[0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 ...]
|
|
280
|
+
...
|
|
281
|
+
]
|
|
282
|
+
In this function, the permutation is achieved by using matrix reshapes.
|
|
283
|
+
|
|
284
|
+
3. Set C_trans.T @ C_sum^(c) @ C_sum^(c).T @ C_trans
|
|
285
|
+
= [(C_trans.T @ S.T) @ (S @ C_sum^(c))] @ [(C_sum^(c).T @ S.T) @ (S @ C_trans)]
|
|
286
|
+
= [T_1, T_2, ..., T_N33]
|
|
287
|
+
@ (S @ C_sum^(c)) @ (C_sum^(c).T @ S.T)
|
|
288
|
+
@ [T_1, T_2, ..., T_N33].T
|
|
289
|
+
= \sum_i t_i @ t_i.T,
|
|
290
|
+
where t_i = \sum_c T_i[:, c].
|
|
291
|
+
t_i is represented by c_sum_cplmt.T in this function.
|
|
292
|
+
T_i is the submatrix of size (N, n_aN33) of permuted C_trans.
|
|
293
|
+
|
|
294
|
+
4. Compute P^(c) = \sum_i (n_a_compress_mat.T @ t_i) @ (t_i.T @ n_a_compress_mat)
|
|
295
|
+
|
|
296
|
+
5. Compute P = I - P^(c)
|
|
198
297
|
"""
|
|
199
298
|
n_lp, natom = trans_perms.shape
|
|
200
299
|
NN9 = natom**2 * 9
|
|
@@ -7,7 +7,8 @@ import scipy
|
|
|
7
7
|
from scipy.sparse import csr_array, vstack
|
|
8
8
|
|
|
9
9
|
from symfc.utils.cutoff_tools import FCCutoff
|
|
10
|
-
from symfc.utils.matrix_tools import
|
|
10
|
+
from symfc.utils.matrix_tools import permutation_dot_lat_trans
|
|
11
|
+
from symfc.utils.permutation_tools import get_combinations
|
|
11
12
|
from symfc.utils.solver_funcs import get_batch_slice
|
|
12
13
|
from symfc.utils.utils import get_indep_atoms_by_lat_trans
|
|
13
14
|
from symfc.utils.utils_O3 import get_atomic_lat_trans_decompr_indices_O3
|
|
@@ -308,7 +309,7 @@ def optimize_batch_size_sum_rules_O3(natom: int, n_batch: Optional[int] = None):
|
|
|
308
309
|
return batch_size
|
|
309
310
|
|
|
310
311
|
|
|
311
|
-
def
|
|
312
|
+
def compressed_projector_sum_rules_O3(
|
|
312
313
|
trans_perms: np.ndarray,
|
|
313
314
|
n_a_compress_mat: csr_array,
|
|
314
315
|
atomic_decompr_idx: Optional[np.ndarray] = None,
|
|
@@ -317,18 +318,67 @@ def compressed_projector_sum_rules_O3_indep_atoms(
|
|
|
317
318
|
use_mkl: bool = False,
|
|
318
319
|
verbose: bool = False,
|
|
319
320
|
) -> csr_array:
|
|
320
|
-
"""Return projection matrix for sum rule.
|
|
321
|
+
r"""Return projection matrix for translational sum rule.
|
|
321
322
|
|
|
322
|
-
Calculate a
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
323
|
+
Calculate a compressed projector for translational sum rules
|
|
324
|
+
efficiently using independent atom with respect to lattice translations.
|
|
325
|
+
This compression is achieved using C_trans and n_a_compress_mat,
|
|
326
|
+
without the need to allocate C_trans. The implementation utilizes
|
|
327
|
+
get_atomic_lat_trans_decompr_indices_O3 to ensure efficient memory usage.
|
|
326
328
|
|
|
327
329
|
Return
|
|
328
330
|
------
|
|
329
|
-
Compressed projector I - P^(c)
|
|
330
|
-
|
|
331
|
-
|
|
331
|
+
Compressed projector I - P^(c).
|
|
332
|
+
I - P^(c)
|
|
333
|
+
= n_a_compress_mat.T @ C_trans.T
|
|
334
|
+
@ [I - C_sum^(c) @ C_sum^(c).T] @ C_trans @ n_a_compress_mat
|
|
335
|
+
= I - [n_a_compress_mat.T @ C_trans.T @ C_sum^(c)]
|
|
336
|
+
@ [C_sum^(c).T @ C_trans @ n_a_compress_mat]
|
|
337
|
+
|
|
338
|
+
Algorithm
|
|
339
|
+
---------
|
|
340
|
+
1. C_sum^(c).T = [I, I, I, ...] of size (27N^2, 27N^3).
|
|
341
|
+
I denotes the unit matrix of size (27N^2, 27N^2).
|
|
342
|
+
C_sum^(c).T is composed of N unit matrices.
|
|
343
|
+
In this representation, the translational sum rules are given by
|
|
344
|
+
\sum_i FC3(i, j, k, a, b, c) = 0.
|
|
345
|
+
|
|
346
|
+
2. To divide the computation of a compressed projector into several batches,
|
|
347
|
+
C_sum^(c) and C_trans are permuted from the index order of (i, j, k, a, b, c)
|
|
348
|
+
to (a, b, c, j, k, i).
|
|
349
|
+
This is represented by C_sum^(c).T @ C_trans = C_sum^(c).T @ S.T @ S @ C_trans,
|
|
350
|
+
where S denotes the permutation matrix that changes the index order to
|
|
351
|
+
(a, b, c, j, k, i). Using this permutation, the translational sum rules are
|
|
352
|
+
represented as
|
|
353
|
+
C_sum^(c).T @ S.T = [
|
|
354
|
+
[1_N.T, 0_N.T, 0_N.T, ...]
|
|
355
|
+
[0_N.T, 1_N.T, 0_N.T, ...]
|
|
356
|
+
[0_N.T, 0_N.T, 1_N.T, ...]
|
|
357
|
+
...
|
|
358
|
+
],
|
|
359
|
+
where 1_N and 0_N are column vectors of size N with all elements
|
|
360
|
+
equal to one and zero, respectively.
|
|
361
|
+
(Example) C_sum^(c).T @ S.T = [
|
|
362
|
+
[1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 ...]
|
|
363
|
+
[0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 ...]
|
|
364
|
+
[0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 ...]
|
|
365
|
+
...
|
|
366
|
+
]
|
|
367
|
+
In this function, the permutation is achieved by using matrix reshapes.
|
|
368
|
+
|
|
369
|
+
3. Set C_trans.T @ C_sum^(c) @ C_sum^(c).T @ C_trans
|
|
370
|
+
= [(C_trans.T @ S.T) @ (S @ C_sum^(c))] @ [(C_sum^(c).T @ S.T) @ (S @ C_trans)]
|
|
371
|
+
= [T_1, T_2, ..., T_NN333]
|
|
372
|
+
@ (S @ C_sum^(c)) @ (C_sum^(c).T @ S.T)
|
|
373
|
+
@ [T_1, T_2, ..., T_NN333].T
|
|
374
|
+
= \sum_i t_i @ t_i.T,
|
|
375
|
+
where t_i = \sum_c T_i[:, c].
|
|
376
|
+
t_i is represented by c_sum_cplmt.T in this function.
|
|
377
|
+
T_i is the submatrix of size (N, n_aNN333) of permuted C_trans.
|
|
378
|
+
|
|
379
|
+
4. Compute P^(c) = \sum_i (n_a_compress_mat.T @ t_i) @ (t_i.T @ n_a_compress_mat)
|
|
380
|
+
|
|
381
|
+
5. Compute P = I - P^(c)
|
|
332
382
|
"""
|
|
333
383
|
n_lp, natom = trans_perms.shape
|
|
334
384
|
NNN27 = natom**3 * 27
|
|
@@ -343,14 +393,14 @@ def compressed_projector_sum_rules_O3_indep_atoms(
|
|
|
343
393
|
|
|
344
394
|
decompr_idx = atomic_decompr_idx.reshape((natom, NN)).T.reshape(-1) * 27
|
|
345
395
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
nonzero = nonzero
|
|
396
|
+
indep_atoms = get_indep_atoms_by_lat_trans(trans_perms)
|
|
397
|
+
nonzero = np.zeros((natom, natom, natom), dtype=bool)
|
|
398
|
+
nonzero[indep_atoms, :, :] = True
|
|
399
|
+
nonzero = nonzero.reshape(-1)
|
|
400
|
+
if fc_cutoff is not None:
|
|
401
|
+
nonzero_c = fc_cutoff.nonzero_atomic_indices_fc3()
|
|
402
|
+
nonzero_c = nonzero_c.reshape((natom, NN)).T.reshape(-1)
|
|
403
|
+
nonzero = nonzero & nonzero_c
|
|
354
404
|
|
|
355
405
|
batch_size = optimize_batch_size_sum_rules_O3(natom, n_batch=n_batch)
|
|
356
406
|
abc = np.arange(27)
|
|
@@ -381,11 +431,11 @@ def compressed_projector_sum_rules_O3_indep_atoms(
|
|
|
381
431
|
c_sum_cplmt = dot_product_sparse(c_sum_cplmt, n_a_compress_mat, use_mkl=use_mkl)
|
|
382
432
|
proj_cplmt += dot_product_sparse(c_sum_cplmt.T, c_sum_cplmt, use_mkl=use_mkl)
|
|
383
433
|
|
|
384
|
-
proj_cplmt /=
|
|
434
|
+
proj_cplmt /= natom
|
|
385
435
|
return scipy.sparse.identity(proj_cplmt.shape[0]) - proj_cplmt
|
|
386
436
|
|
|
387
437
|
|
|
388
|
-
def
|
|
438
|
+
def compressed_projector_sum_rules_O3_stable(
|
|
389
439
|
trans_perms: np.ndarray,
|
|
390
440
|
n_a_compress_mat: csr_array,
|
|
391
441
|
atomic_decompr_idx: Optional[np.ndarray] = None,
|
|
@@ -394,18 +444,66 @@ def compressed_projector_sum_rules_O3(
|
|
|
394
444
|
use_mkl: bool = False,
|
|
395
445
|
verbose: bool = False,
|
|
396
446
|
) -> csr_array:
|
|
397
|
-
"""Return projection matrix for sum rule.
|
|
447
|
+
r"""Return projection matrix for translational sum rule.
|
|
398
448
|
|
|
399
|
-
Calculate a
|
|
400
|
-
This is
|
|
401
|
-
|
|
402
|
-
|
|
449
|
+
Calculate a compressed projector for translational sum rules.
|
|
450
|
+
This compression is achieved using C_trans and n_a_compress_mat,
|
|
451
|
+
without the need to allocate C_trans. The implementation utilizes
|
|
452
|
+
get_atomic_lat_trans_decompr_indices_O3 to ensure efficient memory usage.
|
|
403
453
|
|
|
404
454
|
Return
|
|
405
455
|
------
|
|
406
|
-
Compressed projector I - P^(c)
|
|
407
|
-
|
|
408
|
-
|
|
456
|
+
Compressed projector I - P^(c).
|
|
457
|
+
I - P^(c)
|
|
458
|
+
= n_a_compress_mat.T @ C_trans.T
|
|
459
|
+
@ [I - C_sum^(c) @ C_sum^(c).T] @ C_trans @ n_a_compress_mat
|
|
460
|
+
= I - [n_a_compress_mat.T @ C_trans.T @ C_sum^(c)]
|
|
461
|
+
@ [C_sum^(c).T @ C_trans @ n_a_compress_mat]
|
|
462
|
+
|
|
463
|
+
Algorithm
|
|
464
|
+
---------
|
|
465
|
+
1. C_sum^(c).T = [I, I, I, ...] of size (27N^2, 27N^3).
|
|
466
|
+
I denotes the unit matrix of size (27N^2, 27N^2).
|
|
467
|
+
C_sum^(c).T is composed of N unit matrices.
|
|
468
|
+
In this representation, the translational sum rules are given by
|
|
469
|
+
\sum_i FC3(i, j, k, a, b, c) = 0.
|
|
470
|
+
|
|
471
|
+
2. To divide the computation of a compressed projector into several batches,
|
|
472
|
+
C_sum^(c) and C_trans are permuted from the index order of (i, j, k, a, b, c)
|
|
473
|
+
to (a, b, c, j, k, i).
|
|
474
|
+
This is represented by C_sum^(c).T @ C_trans = C_sum^(c).T @ S.T @ S @ C_trans,
|
|
475
|
+
where S denotes the permutation matrix that changes the index order to
|
|
476
|
+
(a, b, c, j, k, i). Using this permutation, the translational sum rules are
|
|
477
|
+
represented as
|
|
478
|
+
C_sum^(c).T @ S.T = [
|
|
479
|
+
[1_N.T, 0_N.T, 0_N.T, ...]
|
|
480
|
+
[0_N.T, 1_N.T, 0_N.T, ...]
|
|
481
|
+
[0_N.T, 0_N.T, 1_N.T, ...]
|
|
482
|
+
...
|
|
483
|
+
],
|
|
484
|
+
where 1_N and 0_N are column vectors of size N with all elements
|
|
485
|
+
equal to one and zero, respectively.
|
|
486
|
+
(Example) C_sum^(c).T @ S.T = [
|
|
487
|
+
[1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 ...]
|
|
488
|
+
[0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 ...]
|
|
489
|
+
[0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 ...]
|
|
490
|
+
...
|
|
491
|
+
]
|
|
492
|
+
In this function, the permutation is achieved by using matrix reshapes.
|
|
493
|
+
|
|
494
|
+
3. Set C_trans.T @ C_sum^(c) @ C_sum^(c).T @ C_trans
|
|
495
|
+
= [(C_trans.T @ S.T) @ (S @ C_sum^(c))] @ [(C_sum^(c).T @ S.T) @ (S @ C_trans)]
|
|
496
|
+
= [T_1, T_2, ..., T_NN333]
|
|
497
|
+
@ (S @ C_sum^(c)) @ (C_sum^(c).T @ S.T)
|
|
498
|
+
@ [T_1, T_2, ..., T_NN333].T
|
|
499
|
+
= \sum_i t_i @ t_i.T,
|
|
500
|
+
where t_i = \sum_c T_i[:, c].
|
|
501
|
+
t_i is represented by c_sum_cplmt.T in this function.
|
|
502
|
+
T_i is the submatrix of size (N, n_aNN333) of permuted C_trans.
|
|
503
|
+
|
|
504
|
+
4. Compute P^(c) = \sum_i (n_a_compress_mat.T @ t_i) @ (t_i.T @ n_a_compress_mat)
|
|
505
|
+
|
|
506
|
+
5. Compute P = I - P^(c)
|
|
409
507
|
"""
|
|
410
508
|
n_lp, natom = trans_perms.shape
|
|
411
509
|
NNN27 = natom**3 * 27
|