Optimizations#
Enumeration#
Init for enumeration optimizations.
- ferrmion.optimize.enumeration.anneal_enumerations(template: dict, one_e_coeffs: ndarray, two_e_coeffs: ndarray, temperature: float | None = None, initial_guess=typing.Union[collections.abc.Buffer, numpy._typing._array_like._SupportsArray[numpy.dtype[typing.Any]], numpy._typing._nested_sequence._NestedSequence[numpy._typing._array_like._SupportsArray[numpy.dtype[typing.Any]]], bool, int, float, complex, str, bytes, numpy._typing._nested_sequence._NestedSequence[bool | int | float | complex | str | bytes], NoneType], coefficient_weighted: bool = False)[source]#
Optimise mode enumeration using simulated annealing.
- Parameters:
template (dict) – Encoding template dictionary.
one_e_coeffs (np.ndarray) – One-electron coefficient matrix.
two_e_coeffs (np.ndarray) – Two-electron coefficient matrix.
temperature (float | None) – Initial annealing temperature. Defaults to
n_modes.initial_guess (ArrayLike | None) – Starting permutation. Defaults to identity.
coefficient_weighted (bool) – If True, minimise coefficient-weighted Pauli weight.
- ferrmion.optimize.enumeration.lambda_plus_mu(n_modes: int, evaluate: partial[list[float]], pop_size: int, ngen: int) ndarray[tuple[int, ...], dtype[_ScalarType_co]][source]#
Reorder modes using lambda+mu evolutionary algorithm.
The values of lambda and mu are both set to half of the population size. With some tinkering this seems to work well.
- Parameters:
n_modes (int) – The number of modes in the system.
evaluate (partial[list[float]]) – A partial function which acts as the cost function. This should take a list of integers (mode labels) as input and output a list of floats.
pop_size (int) – The size of the initial population.
ngen (int) – The number of generations to evolve.
- Returns:
The best mode ordering found.
- Return type:
NDArray
Example
>>> import numpy as np >>> from functools import partial >>> from ferrmion.optimize.enumeration.evolutionary import lambda_plus_mu >>> def dummy_eval(x): return [sum(x)] >>> evaluate = partial(dummy_eval) >>> lambda_plus_mu(3, evaluate, pop_size=10, ngen=2)
Ternary Tree#
Hamiltonian-Adaptive Ternary Tree construction.
The greedy tree construction runs in native Rust (ferrmion.core.hatt); this module exposes a thin Python wrapper that takes a FermionHamiltonian and returns a fully-populated TernaryTree.
- ferrmion.optimize.hatt.hamiltonian_adaptive_ternary_tree(fham: FermionHamiltonian, n_modes: int) TernaryTree[source]#
Construct an adaptive ternary tree from a fermionic Hamiltonian.
The tree is built greedily so the resulting qubit Hamiltonian has low Pauli weight. The construction runs in native Rust (
ferrmion.core.hatt()).- Parameters:
fham (FermionHamiltonian) – The Hamiltonian whose terms drive the greedy Pauli-weight minimisation.
n_modes (int) – Number of fermionic modes in the system.
- Returns:
The constructed tree with
pauli_weightpopulated.- Return type:
Bonsai Algorithm.
- ferrmion.optimize.bonsai.bonsai_algorithm(graph: PyGraph, homogenous: bool = False, max_nodes: None | int = None) TernaryTree[source]#
Create a TernaryTree encoding using the Bonsai Algorithm.
- Parameters:
graph (rx.PyGraph) – A RustworkX graph of device qubit-connectivity.
homogenous (bool) – “homogenous” labelling if true, else “heterogenous”
max_nodes (int) – Maximum number of nodes to include in output tree.
- Returns:
A ternary tree encoding.
- Return type:
Reduced entanglement Ternary Tree.
- ferrmion.optimize.rett.reduced_entanglement_ternary_tree(mutual_information: ndarray[tuple[int, ...], dtype[_ScalarType_co]], cutoff: float = 0.5, max_branches: int | None = None, squash: bool = False) TernaryTree[source]#
Creates the reduced entanglement TernaryTree.
- Parameters:
mutual_information (NDArray) – A 2D array of mode mutual information.
cutoff (float | None) – The average MI between spatial orbitals.
max_branches (int) – The maximum allowed number of Parity branches.
squash (bool) – Whether to squash the mutual_information from spin-orbit form to spinless.
- Returns:
A new ternary tree.
- Return type:
Note
Assumes that the MI matrix gives MI between spinless spatial orbitals So that each block of four contains [[aa, ab], [ba,bb]]
Example
>>> import numpy as np >>> from ferrmion.optimize.rett import reduced_entanglement_tree >>> mi = 0.5 * np.random.random((6,6)) >>> mi = mi + mi.T >>> tree = reduced_entanglement_tree(mi) >>> tree.as_dict()
- Advanced example (with options):
>>> tree = reduced_entanglement_tree(mi, cutoff=0.1, max_branches=2, squash=False)
Huffman-code Ternary Tree.
- ferrmion.optimize.huffman.huffman_ternary_tree(one_e_coeffs: ndarray[tuple[int, ...], dtype[float]], two_e_coeffs: ndarray[tuple[int, ...], dtype[float]]) TernaryTree[source]#
Creates a Huffman-code Ternary Tree.
Li, Q. S., Liu, H. Y., Wang, Q., Wu, Y. C., & Guo, G. P. (2025). Huffman-Code-based Ternary Tree Transformation. Chinese Physics Letters.
http://iopscience.iop.org/article/10.1088/0256-307X/42/10/100001
Note: Only vaccum-preserving Huffman-trees are currently supported.
- Parameters:
one_e_coeffs (np.ndarray) – One electron coefficients.
two_e_coeffs (np.ndarray) – Two electron coefficients.
- Returns:
A Huffman-code ternary tree.
- Return type: