OrbitalRotation
class OrbitalRotation(rotation_unitary)
Bases: FermionicGate
Implements an orbital rotation.
Given an unitary matrix (rotation_unitary), this gate implements the single-particle basis change that maps the creation operators as
which is equivalent to applying the many-body unitary
The number of fermionic modes the gate acts on is the dimension of rotation_unitary.
Initializing an instance of this gate can be done with the arguments listed below.
Parameters
rotation_unitary (np.ndarray) – the unitary matrix defining the orbital rotation via . It must be square and unitary; this is the caller’s responsibility and is not verified.
Attributes
rotation_unitary
The unitary matrix representing the orbital rotation coefficients.
Methods
from_t1_amplitudes
classmethod from_t1_amplitudes(t1)
Constructs an orbital rotation from (singles) amplitudes.
The rotation is the unitary , where the amplitude matrix is embedded into the anti-Hermitian generator over all orbitals
with the occupied orbitals ordered before the virtual ones. This is the single-excitation orbital rotation entering the (L)UCJ ansatz when it is initialized from coupled-cluster amplitudes; see UCJ.
Parameters
t1 (ndarray) – the amplitudes of shape (nocc, nvrt), where nocc is the number of occupied orbitals and nvrt is the number of virtual orbitals.
Returns
An OrbitalRotation acting on modes, whose rotation_unitary is .
Return type
Protocol Methods
_apply_unitary_placed_
_apply_unitary_placed_(vec, norb, nelec, copy, freg_indices)
Applies the orbital rotation after placing it onto the vector’s global modes.
The gate’s local rotation_unitary (an matrix acting on the gate’s num_modes modes) is first embedded into the full register: an identity matrix of the state vector’s mode count with rotation_unitary written into the rows/columns picked out by freg_indices.
In the spinful case the embedded matrix must be block-diagonal across the alpha/beta split. A rotation with nonzero alpha/beta off-diagonal blocks mixes the spin sectors, which does not conserve the individual alpha/beta electron counts and hence maps amplitude out of the fixed (n_alpha, n_beta) sector – an operation the fixed-sector state vector cannot represent. Such a rotation is rejected with a ValueError.
The embedded matrix is then applied in one of two ways:
- Fast path (only when
ffsimis installed): the embedded matrix is applied viaffsim.apply_orbital_rotation()’s Givens-rotation kernel. Under the spinful block-spin convention (modes0..norbare alpha orbitals, modesnorb..2*norbare beta orbitals) the two diagonal blocks are the per-spin rotations passed to ffsim as(mat_a, mat_b). - General path: otherwise (i.e. when
ffsimis unavailable) the rotation is applied as the evolution under its generator , where is the embedded matrix. is turned into ascipyLinearOperatorvialinear_operator()(backed by the native FCI matrix-vector kernel) and applied viascipy.sparse.linalg.expm_multiply(). This mirrorsEvolution._apply_unitary_placed_().
Parameters
- vec (ndarray) – the state vector to act on.
- norb (int) – the number of spatial orbitals of the global state vector.
- nelec (int |tuple[int, int]) – either a single integer for a spinless system, or a pair of integers storing the numbers of spin alpha and spin beta fermions. An integer selects the spinless mode interpretation (the
norbmodes are orbitals); a pair selects the spinful(orb, spin)block-spin interpretation of the2 * norbmodes. - copy (bool) – whether to copy the vector before operating on it.
- freg_indices (list[int]) – the absolute (global) mode indices that this gate’s local modes map onto. The rotation is embedded onto these global modes before being applied.
Returns
The transformed vector.
Raises
ValueError – if nelec is a spinful pair and the (placed) rotation mixes the alpha and beta spin sectors.
Return type