@@ -44,8 +44,13 @@ def get_chemist_two_body_coefficients(two_body_coefficients, spin_basis=True):
4444 giving the $g_{pqrs}$ tensor in chemist notation.
4545
4646 Raises:
47- TypeError: Input must be two-body number conserving
48- FermionOperator or InteractionOperator.
47+ ValueError: Input two-body tensor is not spin-symmetric. The LOW_RANK
48+ decomposition requires a spin-symmetric interaction when
49+ spin_basis=True. A spin-symmetric interaction satisfies
50+ h[p,q,r,s] == h[p+1,q+1,r+1,s+1] for all even p, q, r, s
51+ (i.e., the same coefficient for alpha and beta spin channels).
52+ Consider passing spin_basis=False if your Hamiltonian is not
53+ spin-symmetric.
4954 """
5055 # Initialize.
5156 n_orbitals = two_body_coefficients .shape [0 ]
@@ -57,10 +62,34 @@ def get_chemist_two_body_coefficients(two_body_coefficients, spin_basis=True):
5762 n_orbitals = n_orbitals // 2
5863 alpha_indices = list (range (0 , n_orbitals * 2 , 2 ))
5964 beta_indices = list (range (1 , n_orbitals * 2 , 2 ))
60- chemist_two_body_coefficients = chemist_two_body_coefficients [
65+ # Extract the αα→ββ block, which is the only block used by the
66+ # spatial-orbital low-rank decomposition.
67+ alpha_alpha_beta_beta = chemist_two_body_coefficients [
6168 numpy .ix_ (alpha_indices , alpha_indices , beta_indices , beta_indices )
6269 ]
6370
71+ # Validate spin-symmetry by checking that the extracted block is
72+ # symmetric when reshaped to a matrix. For a spin-symmetric interaction
73+ # the chemist tensor satisfies g[p,q,r,s] == g[r,s,p,q] (up to
74+ # permutation symmetry), which makes the reshaped matrix symmetric.
75+ # General spin-dependent interactions such as spin-exchange Hamiltonians
76+ # produce an asymmetric matrix here and cannot be handled by this
77+ # spatial-orbital downfolding approach.
78+ flat = numpy .reshape (alpha_alpha_beta_beta , (n_orbitals ** 2 , n_orbitals ** 2 ))
79+ spin_asymmetry = numpy .amax (numpy .absolute (flat - flat .T ))
80+ if spin_asymmetry > EQ_TOLERANCE :
81+ raise ValueError (
82+ 'The two-body tensor is not spin-symmetric. The LOW_RANK '
83+ 'decomposition requires a spin-symmetric interaction when '
84+ 'spin_basis=True (i.e., the same coefficients for alpha and '
85+ 'beta spin channels). Spin-dependent interactions such as '
86+ 'spin-exchange Hamiltonians violate this requirement. '
87+ 'Consider passing spin_basis=False if your Hamiltonian is '
88+ 'not spin-symmetric.'
89+ )
90+
91+ chemist_two_body_coefficients = alpha_alpha_beta_beta
92+
6493 # Determine a one body correction in the spin basis from spatial basis.
6594 one_body_correction = numpy .zeros ((2 * n_orbitals , 2 * n_orbitals ), complex )
6695 for p , q , r , s in itertools .product (range (n_orbitals ), repeat = 4 ):
@@ -106,7 +135,11 @@ def low_rank_two_body_decomposition(
106135 $\sum_{l=0}^{L-1} (\sum_{pq} |g_{lpq}|)^2 |\lambda_l| < x$
107136
108137 Raises:
109- TypeError: Invalid two-body coefficient tensor specification.
138+ ValueError: The two-body tensor failed symmetry or reality checks
139+ required for the low-rank decomposition. When spin_basis=True,
140+ the tensor must be spin-symmetric (see
141+ get_chemist_two_body_coefficients()). When spin_basis=False,
142+ the chemist-ordered tensor must be real and symmetric.
110143 """
111144 # Initialize N^2 by N^2 interaction array.
112145 one_body_correction , chemist_two_body_coefficients = get_chemist_two_body_coefficients (
@@ -117,10 +150,15 @@ def low_rank_two_body_decomposition(
117150 interaction_array = numpy .reshape (chemist_two_body_coefficients , (full_rank , full_rank ))
118151
119152 # Make sure interaction array is symmetric and real.
120- asymmetry = numpy .sum (numpy .absolute (interaction_array - interaction_array .transpose ()))
121- imaginary_norm = numpy .sum (numpy .absolute (interaction_array .imag ))
153+ asymmetry = numpy .amax (numpy .absolute (interaction_array - interaction_array .transpose ()))
154+ imaginary_norm = numpy .amax (numpy .absolute (interaction_array .imag ))
122155 if asymmetry > EQ_TOLERANCE or imaginary_norm > EQ_TOLERANCE :
123- raise TypeError ('Invalid two-body coefficient tensor specification.' )
156+ raise ValueError (
157+ 'The two-body coefficient tensor failed the symmetry or reality '
158+ 'checks required by the low-rank decomposition. If spin_basis=True, '
159+ 'ensure the Hamiltonian is spin-symmetric. If spin_basis=False, '
160+ 'ensure the chemist-ordered two-body tensor is real and symmetric.'
161+ )
124162
125163 # Decompose with exact diagonalization.
126164 eigenvalues , eigenvectors = numpy .linalg .eigh (interaction_array )
0 commit comments