FermiSimplex 0.1.0__cp311-cp311-win_amd64.whl

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.
@@ -0,0 +1,31 @@
1
+ from __future__ import annotations
2
+
3
+ from .certification import (
4
+ CertificateStatus,
5
+ MuInterval,
6
+ OccupationBounds,
7
+ SimplexCertificate,
8
+ certify_simplex,
9
+ )
10
+ from .mesh import (
11
+ ChargeResult,
12
+ DensityMatrixResult,
13
+ FermiSurfaceResult,
14
+ FermiSurfaceStats,
15
+ IntegrationStats,
16
+ SpectralMesh,
17
+ )
18
+
19
+ __all__ = [
20
+ "CertificateStatus",
21
+ "ChargeResult",
22
+ "DensityMatrixResult",
23
+ "FermiSurfaceResult",
24
+ "FermiSurfaceStats",
25
+ "IntegrationStats",
26
+ "MuInterval",
27
+ "OccupationBounds",
28
+ "SimplexCertificate",
29
+ "SpectralMesh",
30
+ "certify_simplex",
31
+ ]
Binary file
@@ -0,0 +1,45 @@
1
+ from __future__ import annotations
2
+
3
+ import numpy as np
4
+
5
+ from ._native import (
6
+ CertificateStatus,
7
+ MuInterval,
8
+ OccupationBounds,
9
+ SimplexCertificate,
10
+ certify_simplex as _certify_simplex,
11
+ )
12
+
13
+
14
+ def certify_simplex(
15
+ eigenvalues,
16
+ eigenvectors,
17
+ *,
18
+ linearization_error_bound: float,
19
+ mu: float = 0.0,
20
+ tolerance: float = 1e-14,
21
+ ) -> SimplexCertificate:
22
+ """Certify a simplex from trusted vertex eigensystems.
23
+
24
+ ``eigenvalues`` must be finite and sorted in ascending order at every
25
+ vertex. The columns of each ``eigenvectors`` matrix must form a finite
26
+ orthonormal basis. These numerical preconditions are not checked.
27
+ """
28
+ values = np.ascontiguousarray(np.asarray(eigenvalues, dtype=np.float64))
29
+ vectors = np.ascontiguousarray(np.asarray(eigenvectors, dtype=np.complex128))
30
+ return _certify_simplex(
31
+ values,
32
+ vectors,
33
+ float(linearization_error_bound),
34
+ float(mu),
35
+ float(tolerance),
36
+ )
37
+
38
+
39
+ __all__ = [
40
+ "CertificateStatus",
41
+ "MuInterval",
42
+ "OccupationBounds",
43
+ "SimplexCertificate",
44
+ "certify_simplex",
45
+ ]
@@ -0,0 +1,108 @@
1
+ from __future__ import annotations
2
+
3
+ import inspect
4
+ import operator
5
+ from collections.abc import Callable, Mapping
6
+
7
+ import numpy as np
8
+
9
+ from ._native import SpectralMesh as _NativeSpectralMesh
10
+
11
+
12
+ Matrix = np.ndarray
13
+ Point = np.ndarray
14
+
15
+
16
+ def _coordinate_count(function: Callable[..., Matrix]) -> int:
17
+ try:
18
+ parameters = tuple(inspect.signature(function).parameters.values())
19
+ except (TypeError, ValueError) as exc:
20
+ raise TypeError("function must have an inspectable signature") from exc
21
+
22
+ positional = (
23
+ inspect.Parameter.POSITIONAL_ONLY,
24
+ inspect.Parameter.POSITIONAL_OR_KEYWORD,
25
+ )
26
+ if not parameters or any(
27
+ parameter.kind not in positional
28
+ or parameter.default is not inspect.Parameter.empty
29
+ for parameter in parameters
30
+ ):
31
+ raise TypeError(
32
+ "function must accept one or more required positional coordinates"
33
+ )
34
+ return len(parameters)
35
+
36
+
37
+ def _coordinates_array(coordinates, ndim: int) -> Point:
38
+ result = np.ascontiguousarray(np.asarray(coordinates, dtype=np.float64))
39
+ if result.shape != (ndim,):
40
+ raise ValueError(f"expected {ndim} coordinates")
41
+ if not np.all(np.isfinite(result)):
42
+ raise ValueError("coordinates must be finite")
43
+ return result
44
+
45
+
46
+ def _callable_dimensions(function: Callable[..., Matrix]) -> tuple[int, int]:
47
+ ndim = _coordinate_count(function)
48
+ matrix = np.asarray(function(*np.zeros(ndim)), dtype=np.complex128)
49
+ if matrix.ndim != 2 or matrix.shape[0] != matrix.shape[1] or not matrix.shape[0]:
50
+ raise ValueError("Hamiltonian must return a non-empty square matrix")
51
+ return ndim, int(matrix.shape[0])
52
+
53
+
54
+ def _tight_binding_arrays(
55
+ hoppings: Mapping[tuple[int, ...], Matrix],
56
+ ) -> tuple[np.ndarray, np.ndarray]:
57
+ if not hoppings:
58
+ raise ValueError("hoppings must not be empty")
59
+
60
+ try:
61
+ lattice_vectors = [
62
+ tuple(operator.index(component) for component in vector)
63
+ for vector in hoppings
64
+ ]
65
+ except TypeError as exc:
66
+ raise TypeError("hopping lattice vectors must contain only integers") from exc
67
+ ndim = len(lattice_vectors[0])
68
+ if ndim < 1 or any(len(vector) != ndim for vector in lattice_vectors):
69
+ raise ValueError("lattice vectors must have one common positive dimension")
70
+
71
+ matrices = [np.asarray(matrix) for matrix in hoppings.values()]
72
+ shape = matrices[0].shape
73
+ if len(shape) != 2 or shape[0] != shape[1] or shape[0] < 1:
74
+ raise ValueError("hopping matrices must be non-empty and square")
75
+ if any(matrix.shape != shape for matrix in matrices):
76
+ raise ValueError("hopping matrices must all have the same shape")
77
+
78
+ return (
79
+ np.ascontiguousarray(np.asarray(lattice_vectors, dtype=np.int64)),
80
+ np.ascontiguousarray(np.asarray(matrices, dtype=np.complex128)),
81
+ )
82
+
83
+
84
+ def _create_spectral_mesh(
85
+ hamiltonian,
86
+ tolerance: float,
87
+ root_level: int,
88
+ ) -> _NativeSpectralMesh:
89
+ if isinstance(hamiltonian, Mapping):
90
+ lattice_vectors, matrices = _tight_binding_arrays(hamiltonian)
91
+ return _NativeSpectralMesh(
92
+ lattice_vectors,
93
+ matrices,
94
+ tolerance,
95
+ root_level,
96
+ )
97
+ if callable(hamiltonian):
98
+ ndim, ndof = _callable_dimensions(hamiltonian)
99
+ return _NativeSpectralMesh(
100
+ hamiltonian,
101
+ ndim,
102
+ ndof,
103
+ tolerance,
104
+ root_level,
105
+ )
106
+ raise TypeError(
107
+ "hamiltonian must be a callable or a tight-binding mapping"
108
+ )
Binary file