Coverage for tbkit/values.py: 100%
34 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-30 11:04 +0000
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-30 11:04 +0000
1'''
2Value functions: hoppings and onsite energies given as callables of the
3sites and of named parameters, ``t(site_i, site_j, **params)`` and
4``onsite(site, **params)`` (see *System.set_hopping*, *System.set_onsite*
5and *KSpace.set_hopping*). The model stores which bonds or sites each one
6applies to; ``get_ham(**params)`` calls it once per Hamiltonian, with
7arrays of sites (one entry per bond or site).
8'''
9from __future__ import annotations
11import inspect
12from typing import Callable
14import numpy as np
15from numpy.typing import NDArray
16import tbkit.error_handling as error_handling
19def sites(pos: NDArray[np.float64], tags: NDArray, index: NDArray) -> NDArray:
20 '''
21 Private function. The sites passed to a value function: a structured
22 array with fields 'x', 'y' (and 'z' in 3D space), 'tag' and 'index'.
24 Parameters
25 ----------
26 pos : Real ndarray, shape (n, space_dim)
27 Positions.
28 tags : String ndarray, shape (n,)
29 Sublattice tags.
30 index : Integer ndarray, shape (n,)
31 Site indices.
32 '''
33 names = ('x', 'y', 'z')[:pos.shape[1]]
34 rec = np.zeros(len(pos), dtype=[(name, 'f8') for name in names] + [('tag', 'U1'), ('index', 'i8')])
35 for k, name in enumerate(names):
36 rec[name] = pos[:, k]
37 rec['tag'] = tags
38 rec['index'] = index
39 return rec
42def _kwargs(func: Callable, n_args: int, params: dict) -> dict:
43 '''
44 Private function. The entries of *params* that *func* takes (all of them
45 if it has ``**kwargs``), past its first *n_args* positional arguments.
46 '''
47 args = list(inspect.signature(func).parameters.values())
48 if any(p.kind is p.VAR_KEYWORD for p in args):
49 return dict(params)
50 named = [p for p in args[n_args:] if p.kind in (p.POSITIONAL_OR_KEYWORD, p.KEYWORD_ONLY)]
51 error_handling.value_params([p.name for p in named if p.default is p.empty], params, func)
52 return {p.name: params[p.name] for p in named if p.name in params}
55def evaluate(func: Callable, args: tuple, params: dict, size: int, spin: bool = False) -> NDArray[np.complex128]:
56 '''
57 Private function. Call the value function *func* on the site arrays
58 *args*, with the entries of *params* it takes.
60 Returns
61 -------
62 values
63 Complex ndarray, shape (size,), or (size, 2, 2) if
64 *spin* (a number per bond then multiplies the identity).
65 '''
66 val = np.asarray(func(*args, **_kwargs(func, len(args), params)), dtype='c16')
67 error_handling.value_shape(val, size, spin, func)
68 if not spin:
69 return np.broadcast_to(val, (size,))
70 if val.ndim <= 1:
71 return np.broadcast_to(val, (size,))[:, None, None] * np.eye(2, dtype='c16')
72 return np.broadcast_to(val, (size, 2, 2))
75def reversed_conj(func: Callable) -> Callable:
76 r'''
77 Private function. The value function of the reversed bonds: given
78 :math:`t(i, j) = H_{ij}`, the function :math:`(i, j) \mapsto H_{ji}^\dagger
79 = t(j, i)^\dagger` (conjugate transpose for 2x2 spin blocks).
80 '''
81 def value(site_i, site_j, **params):
82 val = np.asarray(func(site_j, site_i, **_kwargs(func, 2, params)), dtype='c16')
83 return val.conj() if val.ndim < 2 else np.swapaxes(val.conj(), -1, -2)
84 return value