symfc 1.3.0__tar.gz → 1.3.2__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.0/src/symfc.egg-info → symfc-1.3.2}/PKG-INFO +1 -1
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/api_symfc.py +4 -2
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/solvers/solver_O2O3.py +1 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/utils/eig_tools.py +1 -241
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/utils/matrix_tools_O2.py +38 -39
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/utils/matrix_tools_O3.py +45 -59
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/utils/matrix_tools_O4.py +46 -55
- symfc-1.3.2/src/symfc/utils/rotation_dev/__init__.py +1 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/version.py +1 -1
- {symfc-1.3.0 → symfc-1.3.2/src/symfc.egg-info}/PKG-INFO +1 -1
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc.egg-info/SOURCES.txt +4 -3
- {symfc-1.3.0 → symfc-1.3.2}/tests/basis_sets/test_basis_sets_O2.py +32 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/basis_sets/test_basis_sets_O3.py +2 -86
- {symfc-1.3.0 → symfc-1.3.2}/tests/conftest.py +87 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/utils/test_matrix_tools_O2.py +22 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/utils/test_matrix_tools_O3.py +1 -1
- {symfc-1.3.0 → symfc-1.3.2}/LICENSE +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/MANIFEST.in +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/README.md +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/pyproject.toml +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/setup.cfg +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/__init__.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/basis_sets/__init__.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/basis_sets/basis_sets_O1.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/basis_sets/basis_sets_O2.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/basis_sets/basis_sets_O3.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/basis_sets/basis_sets_O4.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/basis_sets/basis_sets_base.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/solvers/__init__.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/solvers/solver_O2.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/solvers/solver_O2O3O4.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/solvers/solver_O3.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/solvers/solver_O3O4.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/solvers/solver_O4.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/solvers/solver_base.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/spg_reps/__init__.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/spg_reps/spg_reps_O1.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/spg_reps/spg_reps_O2.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/spg_reps/spg_reps_O3.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/spg_reps/spg_reps_O4.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/spg_reps/spg_reps_base.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/utils/__init__.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/utils/cutoff_tools.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/utils/matrix_tools.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/utils/matrix_tools_O1.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/utils/permutation_tools.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/utils/permutation_tools_O2.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/utils/permutation_tools_O3.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/utils/permutation_tools_O4.py +0 -0
- {symfc-1.3.0/src/symfc/utils → symfc-1.3.2/src/symfc/utils/rotation_dev}/run_rotation_tools_O2.py +0 -0
- {symfc-1.3.0/src/symfc/utils → symfc-1.3.2/src/symfc/utils/rotation_dev}/run_rotation_tools_O3.py +0 -0
- {symfc-1.3.0/src/symfc/utils → symfc-1.3.2/src/symfc/utils/rotation_dev}/run_test_O2.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/utils/rotation_tools_O2.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/utils/solver_funcs.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/utils/utils.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/utils/utils_O1.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/utils/utils_O2.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/utils/utils_O3.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc/utils/utils_O4.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc.egg-info/dependency_links.txt +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc.egg-info/requires.txt +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/src/symfc.egg-info/top_level.txt +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/NaCl-unitcell.yaml +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/basis_sets/test_basis_sets_O4.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/basis_sets/test_basis_sets_base.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/compact_fc_GaN_222.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/compact_fc_GaN_442.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/compact_fc_NaCl_222.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/compact_fc_SiO2_221.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/compact_fc_Si_111_fc3_2.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/compact_fc_Si_111_fc3_3.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/compact_fc_Si_111_fc4_2.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/compact_fc_Si_111_fc4_3.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/compact_fc_Si_111_fc4_4.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/compact_fc_SnO2_223.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/dfset_GaN_222_rd.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/dfset_GaN_442_rd.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/dfset_NaCl_222_rd.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/dfset_SiO2_221_rd.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/dfset_Si_111_fc3_rd.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/dfset_SnO2_223_rd.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/full_fc_NaCl_222.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/full_fc_Si_111_fc3_2.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/full_fc_Si_111_fc3_3.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/full_fc_Si_111_fc4_2.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/full_fc_Si_111_fc4_3.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/full_fc_Si_111_fc4_4.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/full_fc_Si_111_fc4_step_2.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/full_fc_Si_111_fc4_step_3.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/full_fc_Si_111_fc4_step_4.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/full_fc_SnO2_223.xz +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/perms_super.dat +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/phonopy_to_python.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/solvers/test_solver_utils.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/spg_reps/test_spg_reps_O1.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/spg_reps/test_spg_reps_O2.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/spg_reps/test_spg_reps_O3.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/spg_reps/test_spg_reps_O4.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/spg_reps/test_spg_reps_base.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/test_api.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/utils/test_cutoff_tools.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/utils/test_eig_tools.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/utils/test_matrix_tools_O4.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/utils/test_solver_funcs.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/utils/test_utils.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/utils/test_utils_O1.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/utils/test_utils_O2.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/utils/test_utils_O2_2.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/utils/test_utils_O3.py +0 -0
- {symfc-1.3.0 → symfc-1.3.2}/tests/utils/test_utils_O4.py +0 -0
|
@@ -286,6 +286,7 @@ class Symfc:
|
|
|
286
286
|
basis_set_o2 = FCBasisSetO2(
|
|
287
287
|
self._supercell,
|
|
288
288
|
spacegroup_operations=self._spacegroup_operations,
|
|
289
|
+
cutoff=self._cutoff[2],
|
|
289
290
|
use_mkl=self._use_mkl,
|
|
290
291
|
log_level=self._log_level,
|
|
291
292
|
).run()
|
|
@@ -341,6 +342,7 @@ class Symfc:
|
|
|
341
342
|
basis_size_estimates[order] = FCBasisSetO2(
|
|
342
343
|
self._supercell,
|
|
343
344
|
spacegroup_operations=self._spacegroup_operations,
|
|
345
|
+
cutoff=self._cutoff[2],
|
|
344
346
|
use_mkl=self._use_mkl,
|
|
345
347
|
log_level=self._log_level,
|
|
346
348
|
).estimate_basis_size()
|
|
@@ -409,9 +411,9 @@ class Symfc:
|
|
|
409
411
|
|
|
410
412
|
def _prepare_cutoff(self, cutoff):
|
|
411
413
|
if cutoff is None:
|
|
412
|
-
self._cutoff = {3: None, 4: None}
|
|
414
|
+
self._cutoff = {2: None, 3: None, 4: None}
|
|
413
415
|
else:
|
|
414
416
|
self._cutoff = cutoff
|
|
415
|
-
for order in (3, 4):
|
|
417
|
+
for order in (2, 3, 4):
|
|
416
418
|
if order not in self._cutoff:
|
|
417
419
|
self._cutoff[order] = None
|
|
@@ -308,6 +308,7 @@ def prepare_normal_equation_O2O3(
|
|
|
308
308
|
if verbose:
|
|
309
309
|
print("Solver_block:", end, "/", disps.shape[0], flush=True)
|
|
310
310
|
print(" - Time:", "{:.3f}".format(t2 - t1), flush=True)
|
|
311
|
+
del X3
|
|
311
312
|
|
|
312
313
|
if verbose:
|
|
313
314
|
print("Solver:", "Calculate X.T @ X and X.T @ y", flush=True)
|
|
@@ -7,7 +7,7 @@ from typing import Optional
|
|
|
7
7
|
import numpy as np
|
|
8
8
|
import scipy
|
|
9
9
|
from scipy.linalg import get_lapack_funcs
|
|
10
|
-
from scipy.sparse import csr_array
|
|
10
|
+
from scipy.sparse import csr_array
|
|
11
11
|
|
|
12
12
|
from symfc.utils.solver_funcs import get_batch_slice
|
|
13
13
|
|
|
@@ -385,243 +385,3 @@ def eigsh_projector_sumrule_large(p: csr_array, verbose: bool = True) -> np.ndar
|
|
|
385
385
|
eigvecs_full[ids, col_id:col_end] = eigvecs
|
|
386
386
|
col_id = col_end
|
|
387
387
|
return eigvecs_full[:, :col_id]
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
def _find_smaller_block(p1: np.ndarray, target_size: int = 3000, random: bool = True):
|
|
391
|
-
"""Find a reasonable block in matrix p1."""
|
|
392
|
-
if random:
|
|
393
|
-
# algorithm 2 (random choice)
|
|
394
|
-
total_size = p1.shape[0]
|
|
395
|
-
ids = np.random.choice(
|
|
396
|
-
range(total_size),
|
|
397
|
-
min(target_size, total_size),
|
|
398
|
-
replace=False,
|
|
399
|
-
)
|
|
400
|
-
bools = np.zeros(p1.shape[0], dtype=bool)
|
|
401
|
-
bools[ids] = True
|
|
402
|
-
return bools
|
|
403
|
-
|
|
404
|
-
# algorithm 1
|
|
405
|
-
n_data = np.count_nonzero(np.abs(p1) > 1e-15, axis=1)
|
|
406
|
-
rep_id = np.abs(n_data - target_size).argmin()
|
|
407
|
-
return np.abs(p1[rep_id]) > 1e-15
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
def _iterative_eigsh_projector(
|
|
411
|
-
p_block: np.ndarray,
|
|
412
|
-
max_iter: int = 50,
|
|
413
|
-
size_terminate: int = 2000,
|
|
414
|
-
use_mkl: bool = False,
|
|
415
|
-
verbose: bool = False,
|
|
416
|
-
use_sparse: bool = True,
|
|
417
|
-
):
|
|
418
|
-
if use_sparse:
|
|
419
|
-
return _iterative_eigsh_projector_use_sparse(
|
|
420
|
-
p_block=p_block,
|
|
421
|
-
max_iter=max_iter,
|
|
422
|
-
size_terminate=size_terminate,
|
|
423
|
-
use_mkl=use_mkl,
|
|
424
|
-
verbose=verbose,
|
|
425
|
-
)
|
|
426
|
-
return _iterative_eigsh_projector_use_dense(
|
|
427
|
-
p_block=p_block,
|
|
428
|
-
max_iter=max_iter,
|
|
429
|
-
size_terminate=size_terminate,
|
|
430
|
-
verbose=verbose,
|
|
431
|
-
)
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
def _iterative_eigsh_projector_use_dense(
|
|
435
|
-
p_block: np.ndarray,
|
|
436
|
-
max_iter: int = 50,
|
|
437
|
-
size_terminate: int = 2000,
|
|
438
|
-
verbose: bool = False,
|
|
439
|
-
):
|
|
440
|
-
"""Solve eigenvalue problem partially for matrix p."""
|
|
441
|
-
if verbose:
|
|
442
|
-
print(" - Use iterative projector solver.", flush=True)
|
|
443
|
-
|
|
444
|
-
if p_block.shape[0] < size_terminate:
|
|
445
|
-
return None, p_block, None
|
|
446
|
-
|
|
447
|
-
eigvecs_block = np.zeros(p_block.shape, dtype="double")
|
|
448
|
-
compr = None
|
|
449
|
-
col_id = 0
|
|
450
|
-
|
|
451
|
-
for j in range(max_iter):
|
|
452
|
-
if verbose:
|
|
453
|
-
print(" * iteration:", j + 1, flush=True)
|
|
454
|
-
if p_block.shape[0] < size_terminate:
|
|
455
|
-
if verbose:
|
|
456
|
-
print(" iteration stopped. p.shape <", size_terminate, flush=True)
|
|
457
|
-
break
|
|
458
|
-
|
|
459
|
-
bool_small = _find_smaller_block(p_block, target_size=3000)
|
|
460
|
-
bool_const = np.logical_not(bool_small)
|
|
461
|
-
n_const = np.count_nonzero(bool_const)
|
|
462
|
-
if verbose:
|
|
463
|
-
print(
|
|
464
|
-
" - Solving projector of size",
|
|
465
|
-
np.count_nonzero(bool_small),
|
|
466
|
-
flush=True,
|
|
467
|
-
)
|
|
468
|
-
|
|
469
|
-
if np.count_nonzero(bool_small) / p_block.shape[0] > 0.95:
|
|
470
|
-
if verbose:
|
|
471
|
-
print(" iteration stopped (> 0.95).", flush=True)
|
|
472
|
-
break
|
|
473
|
-
|
|
474
|
-
p_small = p_block[np.ix_(bool_small, bool_small)]
|
|
475
|
-
rank = int(round(np.trace(p_small)))
|
|
476
|
-
if rank == 0:
|
|
477
|
-
break
|
|
478
|
-
|
|
479
|
-
eigvecs, (cmplt_eigvals, cmplt_small) = eigh_projector(
|
|
480
|
-
p_small,
|
|
481
|
-
return_complement=True,
|
|
482
|
-
verbose=verbose,
|
|
483
|
-
)
|
|
484
|
-
if eigvecs.shape[1] == 0:
|
|
485
|
-
if verbose:
|
|
486
|
-
print(" No eigenvectors are found.", flush=True)
|
|
487
|
-
break
|
|
488
|
-
|
|
489
|
-
compr_size = n_const + cmplt_small.shape[1]
|
|
490
|
-
if verbose:
|
|
491
|
-
print(" - Compressing matrix:", flush=True)
|
|
492
|
-
print(" ", p_block.shape[0], "->", compr_size, flush=True)
|
|
493
|
-
|
|
494
|
-
col_end = col_id + eigvecs.shape[1]
|
|
495
|
-
if j == 0:
|
|
496
|
-
compr = np.zeros((p_block.shape[0], compr_size))
|
|
497
|
-
row_ids = np.where(bool_const)[0]
|
|
498
|
-
compr[(row_ids, np.arange(n_const))] = 1.0
|
|
499
|
-
|
|
500
|
-
row_ids = np.where(bool_small)[0]
|
|
501
|
-
compr[row_ids, n_const:] = cmplt_small
|
|
502
|
-
eigvecs_block[row_ids, col_id:col_end] = eigvecs
|
|
503
|
-
else:
|
|
504
|
-
compr_slice = compr[:, bool_small]
|
|
505
|
-
prod = compr_slice @ cmplt_small
|
|
506
|
-
eigvecs_block[:, col_id:col_end] = compr_slice @ eigvecs
|
|
507
|
-
"""Time consuming part."""
|
|
508
|
-
compr = np.hstack([compr[:, bool_const], prod])
|
|
509
|
-
col_id = col_end
|
|
510
|
-
|
|
511
|
-
"""
|
|
512
|
-
cmplt_small.T @ p_small @ cmplt_small
|
|
513
|
-
= (cmplt_small.T @ cmplt_small
|
|
514
|
-
@ np.diag(cmplt_eigvals) @ cmplt_small.T @ cmplt_small)
|
|
515
|
-
= np.diag(cmplt_eigvals)
|
|
516
|
-
"""
|
|
517
|
-
mat12 = p_block[np.ix_(bool_const, bool_small)] @ cmplt_small
|
|
518
|
-
p_block = np.block(
|
|
519
|
-
[
|
|
520
|
-
[p_block[np.ix_(bool_const, bool_const)], mat12],
|
|
521
|
-
[mat12.T, np.diag(cmplt_eigvals)],
|
|
522
|
-
]
|
|
523
|
-
)
|
|
524
|
-
|
|
525
|
-
if col_id == 0:
|
|
526
|
-
return None, p_block, None
|
|
527
|
-
return eigvecs_block[:, :col_id], p_block, compr
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
def _iterative_eigsh_projector_use_sparse(
|
|
531
|
-
p_block: np.ndarray,
|
|
532
|
-
max_iter: int = 50,
|
|
533
|
-
size_terminate: int = 2000,
|
|
534
|
-
use_mkl: bool = False,
|
|
535
|
-
verbose: bool = True,
|
|
536
|
-
):
|
|
537
|
-
"""Solve eigenvalue problem partially for matrix p."""
|
|
538
|
-
if p_block.shape[0] < size_terminate:
|
|
539
|
-
return None, p_block, None
|
|
540
|
-
|
|
541
|
-
if verbose:
|
|
542
|
-
print(" - Use iterative projector solver.", flush=True)
|
|
543
|
-
|
|
544
|
-
eigvecs_block = np.zeros(p_block.shape, dtype="double")
|
|
545
|
-
compr = None
|
|
546
|
-
col_id = 0
|
|
547
|
-
|
|
548
|
-
for j in range(max_iter):
|
|
549
|
-
if verbose:
|
|
550
|
-
print(" * iteration:", j + 1, flush=True)
|
|
551
|
-
if p_block.shape[0] < size_terminate:
|
|
552
|
-
if verbose:
|
|
553
|
-
print(" iteration stopped. p.shape <", size_terminate, flush=True)
|
|
554
|
-
break
|
|
555
|
-
|
|
556
|
-
bool_small = _find_smaller_block(p_block, target_size=3000)
|
|
557
|
-
bool_const = np.logical_not(bool_small)
|
|
558
|
-
n_const = np.count_nonzero(bool_const)
|
|
559
|
-
if verbose:
|
|
560
|
-
print(
|
|
561
|
-
" - Solving projector of size",
|
|
562
|
-
np.count_nonzero(bool_small),
|
|
563
|
-
flush=True,
|
|
564
|
-
)
|
|
565
|
-
|
|
566
|
-
if np.count_nonzero(bool_small) / p_block.shape[0] > 0.95:
|
|
567
|
-
if verbose:
|
|
568
|
-
print(" iteration stopped (> 0.95).", flush=True)
|
|
569
|
-
break
|
|
570
|
-
|
|
571
|
-
p_small = p_block[np.ix_(bool_small, bool_small)]
|
|
572
|
-
rank = int(round(np.trace(p_small)))
|
|
573
|
-
if rank == 0:
|
|
574
|
-
break
|
|
575
|
-
|
|
576
|
-
eigvecs, (cmplt_eigvals, cmplt_small) = eigh_projector(
|
|
577
|
-
p_small,
|
|
578
|
-
return_complement=True,
|
|
579
|
-
verbose=verbose,
|
|
580
|
-
)
|
|
581
|
-
cmplt_small_sp = csr_array(cmplt_small)
|
|
582
|
-
if eigvecs.shape[1] == 0:
|
|
583
|
-
if verbose:
|
|
584
|
-
print(" No eigenvectors are found.", flush=True)
|
|
585
|
-
break
|
|
586
|
-
|
|
587
|
-
compr_size = n_const + cmplt_small.shape[1]
|
|
588
|
-
if verbose:
|
|
589
|
-
print(" - Compressing matrix:", flush=True)
|
|
590
|
-
print(" ", p_block.shape[0], "->", compr_size, flush=True)
|
|
591
|
-
|
|
592
|
-
col_end = col_id + eigvecs.shape[1]
|
|
593
|
-
if j == 0:
|
|
594
|
-
compr1 = csr_array(
|
|
595
|
-
(np.ones(n_const), (np.where(bool_const)[0], np.arange(n_const))),
|
|
596
|
-
shape=(p_block.shape[0], n_const),
|
|
597
|
-
dtype="double",
|
|
598
|
-
)
|
|
599
|
-
compr2 = lil_array((p_block.shape[0], cmplt_small.shape[1]), dtype="double")
|
|
600
|
-
row_ids = np.where(bool_small)[0]
|
|
601
|
-
compr2[row_ids] = cmplt_small_sp.tolil()
|
|
602
|
-
compr = hstack([compr1, compr2.tocsr()])
|
|
603
|
-
eigvecs_block[row_ids, col_id:col_end] = eigvecs
|
|
604
|
-
else:
|
|
605
|
-
compr_slice = compr[:, bool_small]
|
|
606
|
-
prod = dot_product_sparse(compr_slice, cmplt_small_sp, use_mkl=use_mkl)
|
|
607
|
-
compr = hstack([compr[:, bool_const], prod])
|
|
608
|
-
eigvecs_block[:, col_id:col_end] = compr_slice.toarray() @ eigvecs
|
|
609
|
-
col_id = col_end
|
|
610
|
-
|
|
611
|
-
"""
|
|
612
|
-
cmplt_small.T @ p_small @ cmplt_small
|
|
613
|
-
= (cmplt_small.T @ cmplt_small
|
|
614
|
-
@ np.diag(cmplt_eigvals) @ cmplt_small.T @ cmplt_small)
|
|
615
|
-
= np.diag(cmplt_eigvals)
|
|
616
|
-
"""
|
|
617
|
-
mat12 = p_block[np.ix_(bool_const, bool_small)] @ cmplt_small
|
|
618
|
-
p_block = np.block(
|
|
619
|
-
[
|
|
620
|
-
[p_block[np.ix_(bool_const, bool_const)], mat12],
|
|
621
|
-
[mat12.T, np.diag(cmplt_eigvals)],
|
|
622
|
-
]
|
|
623
|
-
)
|
|
624
|
-
|
|
625
|
-
if col_id == 0:
|
|
626
|
-
return None, p_block, None
|
|
627
|
-
return eigvecs_block[:, :col_id], p_block, compr.toarray()
|
|
@@ -95,7 +95,15 @@ def projector_permutation_lat_trans_O2(
|
|
|
95
95
|
return proj_pt
|
|
96
96
|
|
|
97
97
|
|
|
98
|
-
def
|
|
98
|
+
def optimize_batch_size_sum_rules_O2(natom: int, n_batch: Optional[int] = None):
|
|
99
|
+
"""Calculate batch size for constructing projector for sum rules."""
|
|
100
|
+
if n_batch > natom:
|
|
101
|
+
raise ValueError("n_batch must be smaller than N.")
|
|
102
|
+
batch_size = natom * (natom // n_batch)
|
|
103
|
+
return batch_size
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def compressed_projector_sum_rules_O2_index_atoms(
|
|
99
107
|
trans_perms: np.ndarray,
|
|
100
108
|
n_a_compress_mat: csr_array,
|
|
101
109
|
atomic_decompr_idx: Optional[np.ndarray] = None,
|
|
@@ -123,23 +131,20 @@ def compressed_projector_sum_rules_O2(
|
|
|
123
131
|
proj_size = n_a_compress_mat.shape[1]
|
|
124
132
|
proj_cplmt = csr_array((proj_size, proj_size), dtype="double")
|
|
125
133
|
|
|
126
|
-
if n_batch > natom:
|
|
127
|
-
raise ValueError("n_batch must be smaller than N.")
|
|
128
|
-
batch_size = natom * (natom // n_batch)
|
|
129
|
-
|
|
130
134
|
if atomic_decompr_idx is None:
|
|
131
135
|
atomic_decompr_idx = _get_atomic_lat_trans_decompr_indices(trans_perms)
|
|
132
136
|
|
|
133
137
|
decompr_idx = atomic_decompr_idx.reshape((natom, natom)).T.reshape(-1) * 9
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
nonzero = nonzero
|
|
138
|
+
if fc_cutoff is None:
|
|
139
|
+
indep_atoms = get_indep_atoms_by_lat_trans(trans_perms)
|
|
140
|
+
nonzero = np.zeros((natom, natom), dtype=bool)
|
|
141
|
+
nonzero[indep_atoms, :] = True
|
|
142
|
+
nonzero = nonzero.reshape(-1)
|
|
143
|
+
else:
|
|
144
|
+
nonzero = fc_cutoff.nonzero_atomic_indices_fc2()
|
|
145
|
+
nonzero = nonzero.reshape((natom, natom)).T.reshape(-1)
|
|
142
146
|
|
|
147
|
+
batch_size = optimize_batch_size_sum_rules_O2(natom, n_batch=n_batch)
|
|
143
148
|
ab = np.arange(9)
|
|
144
149
|
for begin, end in zip(*get_batch_slice(NN, batch_size)):
|
|
145
150
|
size = end - begin
|
|
@@ -148,31 +153,29 @@ def compressed_projector_sum_rules_O2(
|
|
|
148
153
|
|
|
149
154
|
nonzero_b = nonzero[begin:end]
|
|
150
155
|
size_data = np.count_nonzero(nonzero_b) * 9
|
|
151
|
-
if size_data
|
|
152
|
-
|
|
153
|
-
|
|
156
|
+
if size_data == 0:
|
|
157
|
+
continue
|
|
158
|
+
|
|
159
|
+
decompr_idx_b = decompr_idx[begin:end][nonzero_b]
|
|
160
|
+
c_sum_cplmt = csr_array(
|
|
161
|
+
(
|
|
162
|
+
np.ones(size_data, dtype="double"),
|
|
154
163
|
(
|
|
155
|
-
np.
|
|
156
|
-
(
|
|
157
|
-
np.repeat(np.arange(size_row), natom)[np.tile(nonzero_b, 9)],
|
|
158
|
-
(decompr_idx_b[nonzero_b][None, :] + ab[:, None]).reshape(-1),
|
|
159
|
-
),
|
|
164
|
+
np.repeat(np.arange(size_row), natom)[np.tile(nonzero_b, 9)],
|
|
165
|
+
(ab[:, None] + decompr_idx_b[None, :]).reshape(-1),
|
|
160
166
|
),
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
proj_cplmt += dot_product_sparse(
|
|
168
|
-
c_sum_cplmt.T, c_sum_cplmt, use_mkl=use_mkl
|
|
169
|
-
)
|
|
167
|
+
),
|
|
168
|
+
shape=(size_row, NN9 // n_lp),
|
|
169
|
+
dtype="double",
|
|
170
|
+
)
|
|
171
|
+
c_sum_cplmt = dot_product_sparse(c_sum_cplmt, n_a_compress_mat, use_mkl=use_mkl)
|
|
172
|
+
proj_cplmt += dot_product_sparse(c_sum_cplmt.T, c_sum_cplmt, use_mkl=use_mkl)
|
|
170
173
|
|
|
171
174
|
proj_cplmt /= n_lp * natom
|
|
172
175
|
return scipy.sparse.identity(proj_cplmt.shape[0]) - proj_cplmt
|
|
173
176
|
|
|
174
177
|
|
|
175
|
-
def
|
|
178
|
+
def compressed_projector_sum_rules_O2(
|
|
176
179
|
trans_perms: np.ndarray,
|
|
177
180
|
n_a_compress_mat: csr_array,
|
|
178
181
|
atomic_decompr_idx: Optional[np.ndarray] = None,
|
|
@@ -200,10 +203,6 @@ def compressed_projector_sum_rules_O2_stable(
|
|
|
200
203
|
proj_size = n_a_compress_mat.shape[1]
|
|
201
204
|
proj_cplmt = csr_array((proj_size, proj_size), dtype="double")
|
|
202
205
|
|
|
203
|
-
if n_batch > natom:
|
|
204
|
-
raise ValueError("n_batch must be smaller than N.")
|
|
205
|
-
batch_size = natom * (natom // n_batch)
|
|
206
|
-
|
|
207
206
|
if atomic_decompr_idx is None:
|
|
208
207
|
atomic_decompr_idx = _get_atomic_lat_trans_decompr_indices(trans_perms)
|
|
209
208
|
|
|
@@ -212,6 +211,7 @@ def compressed_projector_sum_rules_O2_stable(
|
|
|
212
211
|
nonzero = fc_cutoff.nonzero_atomic_indices_fc2()
|
|
213
212
|
nonzero = nonzero.reshape((natom, natom)).T.reshape(-1)
|
|
214
213
|
|
|
214
|
+
batch_size = optimize_batch_size_sum_rules_O2(natom, n_batch=n_batch)
|
|
215
215
|
ab = np.arange(9)
|
|
216
216
|
for begin, end in zip(*get_batch_slice(NN, batch_size)):
|
|
217
217
|
size = end - begin
|
|
@@ -224,7 +224,7 @@ def compressed_projector_sum_rules_O2_stable(
|
|
|
224
224
|
np.ones(size_vector, dtype="double"),
|
|
225
225
|
(
|
|
226
226
|
np.repeat(np.arange(size_row), natom),
|
|
227
|
-
(decompr_idx[begin:end][None, :]
|
|
227
|
+
(ab[:, None] + decompr_idx[begin:end][None, :]).reshape(-1),
|
|
228
228
|
),
|
|
229
229
|
),
|
|
230
230
|
shape=(size_row, NN9 // n_lp),
|
|
@@ -232,15 +232,14 @@ def compressed_projector_sum_rules_O2_stable(
|
|
|
232
232
|
)
|
|
233
233
|
else:
|
|
234
234
|
nonzero_b = nonzero[begin:end]
|
|
235
|
+
decompr_idx_b = decompr_idx[begin:end][nonzero_b]
|
|
235
236
|
size_data = np.count_nonzero(nonzero_b) * 9
|
|
236
237
|
c_sum_cplmt = csr_array(
|
|
237
238
|
(
|
|
238
239
|
np.ones(size_data, dtype="double"),
|
|
239
240
|
(
|
|
240
241
|
np.repeat(np.arange(size_row), natom)[np.tile(nonzero_b, 9)],
|
|
241
|
-
(
|
|
242
|
-
decompr_idx[begin:end][nonzero_b][None, :] + ab[:, None]
|
|
243
|
-
).reshape(-1),
|
|
242
|
+
(ab[:, None] + decompr_idx_b[None, :]).reshape(-1),
|
|
244
243
|
),
|
|
245
244
|
),
|
|
246
245
|
shape=(size_row, NN9 // n_lp),
|
|
@@ -294,7 +294,21 @@ def projector_permutation_lat_trans_O3(
|
|
|
294
294
|
return proj_pt
|
|
295
295
|
|
|
296
296
|
|
|
297
|
-
def
|
|
297
|
+
def optimize_batch_size_sum_rules_O3(natom: int, n_batch: Optional[int] = None):
|
|
298
|
+
"""Calculate batch size for constructing projector for sum rules."""
|
|
299
|
+
if n_batch is None:
|
|
300
|
+
if natom < 256:
|
|
301
|
+
n_batch = natom // min(natom, 16)
|
|
302
|
+
else:
|
|
303
|
+
n_batch = natom // 4
|
|
304
|
+
|
|
305
|
+
if n_batch > natom:
|
|
306
|
+
raise ValueError("n_batch must be smaller than N.")
|
|
307
|
+
batch_size = natom**2 * (natom // n_batch)
|
|
308
|
+
return batch_size
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
def compressed_projector_sum_rules_O3_indep_atoms(
|
|
298
312
|
trans_perms: np.ndarray,
|
|
299
313
|
n_a_compress_mat: csr_array,
|
|
300
314
|
atomic_decompr_idx: Optional[np.ndarray] = None,
|
|
@@ -324,31 +338,21 @@ def compressed_projector_sum_rules_O3(
|
|
|
324
338
|
proj_size = n_a_compress_mat.shape[1]
|
|
325
339
|
proj_cplmt = csr_array((proj_size, proj_size), dtype="double")
|
|
326
340
|
|
|
327
|
-
if n_batch is None:
|
|
328
|
-
if natom < 256:
|
|
329
|
-
n_batch = natom // min(natom, 64)
|
|
330
|
-
else:
|
|
331
|
-
n_batch = natom // 4
|
|
332
|
-
|
|
333
|
-
if n_batch > natom:
|
|
334
|
-
raise ValueError("n_batch must be smaller than N.")
|
|
335
|
-
batch_size = natom**2 * (natom // n_batch)
|
|
336
|
-
|
|
337
341
|
if atomic_decompr_idx is None:
|
|
338
342
|
atomic_decompr_idx = get_atomic_lat_trans_decompr_indices_O3(trans_perms)
|
|
339
343
|
|
|
340
|
-
"""Bottleneck part when using cutoff distance"""
|
|
341
344
|
decompr_idx = atomic_decompr_idx.reshape((natom, NN)).T.reshape(-1) * 27
|
|
342
345
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
nonzero = nonzero
|
|
346
|
+
if fc_cutoff is None:
|
|
347
|
+
indep_atoms = get_indep_atoms_by_lat_trans(trans_perms)
|
|
348
|
+
nonzero = np.zeros((natom, natom, natom), dtype=bool)
|
|
349
|
+
nonzero[indep_atoms, :, :] = True
|
|
350
|
+
nonzero = nonzero.reshape(-1)
|
|
351
|
+
else:
|
|
352
|
+
nonzero = fc_cutoff.nonzero_atomic_indices_fc3()
|
|
353
|
+
nonzero = nonzero.reshape((natom, NN)).T.reshape(-1)
|
|
351
354
|
|
|
355
|
+
batch_size = optimize_batch_size_sum_rules_O3(natom, n_batch=n_batch)
|
|
352
356
|
abc = np.arange(27)
|
|
353
357
|
for begin, end in zip(*get_batch_slice(NNN, batch_size)):
|
|
354
358
|
size = end - begin
|
|
@@ -357,39 +361,31 @@ def compressed_projector_sum_rules_O3(
|
|
|
357
361
|
|
|
358
362
|
nonzero_b = nonzero[begin:end]
|
|
359
363
|
size_data = np.count_nonzero(nonzero_b) * 27
|
|
364
|
+
if size_data == 0:
|
|
365
|
+
continue
|
|
366
|
+
|
|
360
367
|
if verbose:
|
|
361
|
-
print(
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
size_data,
|
|
366
|
-
flush=True,
|
|
367
|
-
)
|
|
368
|
-
if size_data > 0:
|
|
369
|
-
decompr_idx_b = decompr_idx[begin:end]
|
|
370
|
-
c_sum_cplmt = csr_array(
|
|
368
|
+
print("Complementary P (Sum rule):", str(end) + "/" + str(NNN), flush=True)
|
|
369
|
+
decompr_idx_b = decompr_idx[begin:end][nonzero_b]
|
|
370
|
+
c_sum_cplmt = csr_array(
|
|
371
|
+
(
|
|
372
|
+
np.ones(size_data, dtype="double"),
|
|
371
373
|
(
|
|
372
|
-
np.
|
|
373
|
-
(
|
|
374
|
-
np.repeat(np.arange(size_row), natom)[np.tile(nonzero_b, 27)],
|
|
375
|
-
(decompr_idx_b[nonzero_b][None, :] + abc[:, None]).reshape(-1),
|
|
376
|
-
),
|
|
374
|
+
np.repeat(np.arange(size_row), natom)[np.tile(nonzero_b, 27)],
|
|
375
|
+
(abc[:, None] + decompr_idx_b[None, :]).reshape(-1),
|
|
377
376
|
),
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
proj_cplmt += dot_product_sparse(
|
|
385
|
-
c_sum_cplmt.T, c_sum_cplmt, use_mkl=use_mkl
|
|
386
|
-
)
|
|
377
|
+
),
|
|
378
|
+
shape=(size_row, NNN27 // n_lp),
|
|
379
|
+
dtype="double",
|
|
380
|
+
)
|
|
381
|
+
c_sum_cplmt = dot_product_sparse(c_sum_cplmt, n_a_compress_mat, use_mkl=use_mkl)
|
|
382
|
+
proj_cplmt += dot_product_sparse(c_sum_cplmt.T, c_sum_cplmt, use_mkl=use_mkl)
|
|
387
383
|
|
|
388
384
|
proj_cplmt /= n_lp * natom
|
|
389
385
|
return scipy.sparse.identity(proj_cplmt.shape[0]) - proj_cplmt
|
|
390
386
|
|
|
391
387
|
|
|
392
|
-
def
|
|
388
|
+
def compressed_projector_sum_rules_O3(
|
|
393
389
|
trans_perms: np.ndarray,
|
|
394
390
|
n_a_compress_mat: csr_array,
|
|
395
391
|
atomic_decompr_idx: Optional[np.ndarray] = None,
|
|
@@ -419,16 +415,6 @@ def compressed_projector_sum_rules_O3_stable(
|
|
|
419
415
|
proj_size = n_a_compress_mat.shape[1]
|
|
420
416
|
proj_cplmt = csr_array((proj_size, proj_size), dtype="double")
|
|
421
417
|
|
|
422
|
-
if n_batch is None:
|
|
423
|
-
if natom < 256:
|
|
424
|
-
n_batch = natom // min(natom, 16)
|
|
425
|
-
else:
|
|
426
|
-
n_batch = natom // 4
|
|
427
|
-
|
|
428
|
-
if n_batch > natom:
|
|
429
|
-
raise ValueError("n_batch must be smaller than N.")
|
|
430
|
-
batch_size = natom**2 * (natom // n_batch)
|
|
431
|
-
|
|
432
418
|
if atomic_decompr_idx is None:
|
|
433
419
|
atomic_decompr_idx = get_atomic_lat_trans_decompr_indices_O3(trans_perms)
|
|
434
420
|
|
|
@@ -437,6 +423,7 @@ def compressed_projector_sum_rules_O3_stable(
|
|
|
437
423
|
nonzero = fc_cutoff.nonzero_atomic_indices_fc3()
|
|
438
424
|
nonzero = nonzero.reshape((natom, NN)).T.reshape(-1)
|
|
439
425
|
|
|
426
|
+
batch_size = optimize_batch_size_sum_rules_O3(natom, n_batch=n_batch)
|
|
440
427
|
abc = np.arange(27)
|
|
441
428
|
for begin, end in zip(*get_batch_slice(NNN, batch_size)):
|
|
442
429
|
if verbose:
|
|
@@ -451,7 +438,7 @@ def compressed_projector_sum_rules_O3_stable(
|
|
|
451
438
|
np.ones(size_vector, dtype="double"),
|
|
452
439
|
(
|
|
453
440
|
np.repeat(np.arange(size_row), natom),
|
|
454
|
-
(decompr_idx[begin:end][None, :]
|
|
441
|
+
(abc[:, None] + decompr_idx[begin:end][None, :]).reshape(-1),
|
|
455
442
|
),
|
|
456
443
|
),
|
|
457
444
|
shape=(size_row, NNN27 // n_lp),
|
|
@@ -459,15 +446,14 @@ def compressed_projector_sum_rules_O3_stable(
|
|
|
459
446
|
)
|
|
460
447
|
else:
|
|
461
448
|
nonzero_b = nonzero[begin:end]
|
|
449
|
+
decompr_idx_b = decompr_idx[begin:end][nonzero_b]
|
|
462
450
|
size_data = np.count_nonzero(nonzero_b) * 27
|
|
463
451
|
c_sum_cplmt = csr_array(
|
|
464
452
|
(
|
|
465
453
|
np.ones(size_data, dtype="double"),
|
|
466
454
|
(
|
|
467
455
|
np.repeat(np.arange(size_row), natom)[np.tile(nonzero_b, 27)],
|
|
468
|
-
(
|
|
469
|
-
decompr_idx[begin:end][nonzero_b][None, :] + abc[:, None]
|
|
470
|
-
).reshape(-1),
|
|
456
|
+
(abc[:, None] + decompr_idx_b[None, :]).reshape(-1),
|
|
471
457
|
),
|
|
472
458
|
),
|
|
473
459
|
shape=(size_row, NNN27 // n_lp),
|