UCJ
class UCJ(variant, diag_coulomb_mats, orbital_rotations, *, final_orbital_rotation=None)
Bases: FermionicGate
Implements the (local) unitary cluster Jastrow ((L)UCJ) ansatz.
A unitary cluster Jastrow operator has the form
where each is an OrbitalRotation, each is a diagonal Coulomb operator
and is an optional final orbital rotation. The number of terms is the number of ansatz repetitions.
This gate supports three spin variants (see UCJ.Variant), selected explicitly by the variant argument and validated against the shapes of the supplied tensors (mirroring ffsim’s UCJOpSpinBalanced, UCJOpSpinUnbalanced and UCJOpSpinless). The number of spatial orbitals is not a constructor argument – it is inferred from those same tensor shapes (see norb):
- spin-balanced –
diag_coulomb_matshas shape(L, 2, norb, norb)(the[alpha-alpha, alpha-beta]matrices, with beta-beta reusing alpha-alpha and beta-alpha reusing alpha-beta) andorbital_rotationshas shape(L, norb, norb)(one rotation applied to both spin sectors). Acts on2 * norbblock-spin modes. - spin-unbalanced –
diag_coulomb_matshas shape(L, 3, norb, norb)(the[alpha-alpha, alpha-beta, beta-beta]matrices) andorbital_rotationshas shape(L, 2, norb, norb)(independent[alpha, beta]rotations). Acts on2 * norbblock-spin modes. - spinless –
diag_coulomb_matsandorbital_rotationsboth have shape(L, norb, norb). Acts onnorbspinless modes. The equivalent two-register operator with a shared same-spin diagonal Coulomb matrix and no cross-spin interaction is expressible via the"balanced"variant with its alpha-beta block set to zero.
This gate builds the ansatz from exact tensors. To use ffsim’s optimized (“compressed”) double factorization, construct an ffsim UCJ operator with optimize=True and pass its diag_coulomb_mats / orbital_rotations / final_orbital_rotation into this constructor directly.
This is an early development prototype. Beware of changes to its interface without warning during the pre-release development of this package.
Initializing an instance of this gate can be done with the arguments listed below.
The number of spatial orbitals is inferred from the supplied tensor shapes (see norb).
Parameters
- variant (UCJ.Variant | str) – the spin variant, a
UCJ.Variant(or its string value"balanced","unbalanced", or"spinless"). Determines the number of modes this gate acts on (see the class docstring) and the expected tensor shapes. - diag_coulomb_mats (np.ndarray) – the diagonal Coulomb matrices, of shape
(L, 2, norb, norb)(spin-balanced),(L, 3, norb, norb)(spin-unbalanced), or(L, norb, norb)(spinless), whereLis the number of ansatz repetitions. - orbital_rotations (np.ndarray) – the orbital rotations, of shape
(L, norb, norb)(spin-balanced or spinless) or(L, 2, norb, norb)(spin-unbalanced). - final_orbital_rotation (np.ndarray | None) – an optional final orbital rotation, of shape
(norb, norb)(spin-balanced or spinless) or(2, norb, norb)(spin-unbalanced).
Raises
ValueError – if variant is not recognized, or if the tensor shapes are inconsistent with each other or with variant.
Attributes
diag_coulomb_mats
The diagonal Coulomb matrices defining each ansatz repetition.
orbital_rotations
The orbital rotations defining each ansatz repetition.
final_orbital_rotation
The optional final orbital rotation.
norb
The number of spatial orbitals, inferred from the tensor shapes.
Methods
from_parameters
classmethod from_parameters(params, norb, variant, n_reps, *, interaction_pairs=None, with_final_orbital_rotation=False)
Constructs a UCJ ansatz from a real-valued parameter vector.
Parameters
- params (ndarray) – the real-valued parameter vector.
- norb (int) – the number of spatial orbitals.
- variant (Variant | str) – the spin variant, a
UCJ.Variant(or its string value"balanced","unbalanced", or"spinless"). - n_reps (int) – the number of ansatz repetitions.
- interaction_pairs (list[tuple[int, int]] | tuple[list[tuple[int, int]] | None, ...] | None) – the allowed diagonal Coulomb interactions (see
from_t_amplitudes()for the exact per-variant shape convention).None(the default) imposes no restriction, so every block uses its full parameter count. - with_final_orbital_rotation (bool) – whether
paramsincludes a trailing final orbital rotation.
Returns
The constructed UCJ gate.
Raises
ValueError – if variant is not recognized, or if len(params) does not match num_parameters() for the given settings.
Return type
from_t_amplitudes
classmethod from_t_amplitudes(nelec, t2, *, t1=None, variant='balanced', n_reps=None, interaction_pairs=None, tol=1e-08)
Constructs a UCJ ansatz from coupled-cluster (and optional ) amplitudes.
The ansatz layers are obtained from an exact double factorization of the amplitudes (via double_factorized_t2() / double_factorized_t2_alpha_beta()) and, when is supplied, a final orbital rotation from OrbitalRotation.from_t1_amplitudes().
Only the exact factorization is supported here. To use ffsim’s optimized (“compressed”) double factorization, build an ffsim UCJ operator with optimize=True and pass its tensors into UCJ directly.
Parameters
- 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.
- t2 (ndarray |tuple[ndarray, ndarray, ndarray]) – the amplitudes. For the
"balanced"and"spinless"variants, a single array of shape(nocc, nocc, nvrt, nvrt). For the"unbalanced"variant, a tuple(t2aa, t2ab, t2bb). - t1 (ndarray |tuple[ndarray, ndarray] | None) – the optional amplitudes producing the final orbital rotation. For
"unbalanced", a pair(t1a, t1b); otherwise a single array of shape(nocc, nvrt). - variant (Variant | str) – the spin variant to build, a
UCJ.Variant(or its string value"balanced","unbalanced", or"spinless"). - n_reps (int |tuple[int, int] | None) – the number of ansatz repetitions. If
None, uses all terms of the double factorization; if larger, the ansatz is padded with identity rotations and zero diagonal Coulomb matrices. For the"unbalanced"variant a pair(n_reps_ab, n_reps_same_spin)independently sets the number of alpha-beta and same-spin terms; a tuple is only valid for that variant. - interaction_pairs (list[tuple[int, int]] | tuple[list[tuple[int, int]] | None, ...] | None) – the allowed diagonal Coulomb interactions (the “local” in LUCJ). For
"spinless"a single list of upper-triangular(i, j)pairs; for"balanced"a pair(pairs_aa, pairs_ab); for"unbalanced"a triple(pairs_aa, pairs_ab, pairs_bb). A list of pairs restricts that block to exactly those entries; the same-spin (aa/bb) masks are symmetrized while the alpha-beta (ab) mask is not. UseNone– not an empty list[]– to impose no restriction: aNoneelement (or the whole argument beingNone) leaves the block untouched, whereas an empty list allows no interactions and so zeros the entire block. - tol (float) – the double-factorization truncation tolerance.
Returns
The constructed UCJ gate.
Raises
ValueError – if variant is not recognized, or if a tuple n_reps is passed for a variant other than UCJ.Variant.UNBALANCED.
Return type
num_parameters
classmethod num_parameters(norb, variant, n_reps, *, interaction_pairs=None, with_final_orbital_rotation=False)
Returns the number of parameters of a UCJ ansatz with the given settings.
Parameters
- norb (int) – the number of spatial orbitals.
- variant (Variant | str) – the spin variant, a
UCJ.Variant(or its string value"balanced","unbalanced", or"spinless"). - n_reps (int) – the number of ansatz repetitions.
- interaction_pairs (list[tuple[int, int]] | tuple[list[tuple[int, int]] | None, ...] | None) – the allowed diagonal Coulomb interactions (see
from_t_amplitudes()for the exact per-variant shape convention).None(the default) imposes no restriction, so every block uses its full parameter count. - with_final_orbital_rotation (bool) – whether the ansatz includes a final orbital rotation.
Returns
The number of parameters.
Raises
ValueError – if variant is not recognized.
Return type
to_parameters
to_parameters(*, interaction_pairs=None)
Converts this UCJ ansatz to a real-valued parameter vector.
If interaction_pairs restricts a block, the returned parameter vector incorporates only the diagonal Coulomb matrix entries corresponding to the allowed interactions, so the original operator is not recoverable from the parameter vector alone.
The returned vector is the principal-branch representative of this ansatz’s orbital rotations: each rotation is parameterized by logm(U), which is unique only up to shifts of its eigenvalue phases. Consequently from_parameters() applied to the returned vector reproduces this operator exactly, but the reverse composition does not generally return its input – to_parameters(from_parameters(p)) equals p only when p’s generators already lie in the principal branch (all eigenvalue phases within ). Both a wrapped p and the returned vector describe the same unitary, so the operator is unaffected. Amplitudes from from_t_amplitudes() are well inside the principal branch; large hand-built parameter vectors need not be.
Parameters
interaction_pairs (list[tuple[int, int]] | tuple[list[tuple[int, int]] | None, ...] | None) – the allowed diagonal Coulomb interactions (see from_t_amplitudes() for the exact per-variant shape convention). None (the default) imposes no restriction, so every block’s full contents are included.
Returns
The real-valued parameter vector.
Return type
Protocol Methods
_apply_unitary_placed_
_apply_unitary_placed_(vec, norb, nelec, copy, freg_indices)
Applies the ansatz after placing its modes onto the vector’s global modes.
This builds the gate’s definition (the per-repetition orbital rotations and diagonal Coulomb evolutions) and applies it to vec, with the definition circuit placed onto the global modes freg_indices (each of its instructions is relabeled onto the corresponding absolute modes). See _define() for the exact gate sequence.
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.
- 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.
Returns
The transformed vector.
Return type