@@ -304,23 +304,43 @@ def _push_eigenvalues(self, eigenvalues):
304304 if "conjugate_pairs" in self ._eig_constraints :
305305 num_eigs = len (eigenvalues )
306306 new_eigs = np .empty (num_eigs , dtype = "complex" )
307+
308+ # Set of indices -- keeps track of indices of eigenvalues that
309+ # still need to be paired with their complex conjugate.
307310 unassigned_inds = set (np .arange (num_eigs ))
311+
308312 # If given an odd number of eigenvalues, find the eigenvalue with
309313 # the smallest imaginary part and take it to be a real eigenvalue.
310314 if num_eigs % 2 == 1 :
311315 ind_0 = np .argmin (np .abs (eigenvalues .imag ))
312316 new_eigs [ind_0 ] = eigenvalues [ind_0 ].real
313317 unassigned_inds .remove (ind_0 )
318+
314319 # Assign complex conjugate pairs until all eigenvalues are paired.
315320 while unassigned_inds :
316321 # Randomly grab the next unassigned eigenvalue.
317322 ind_1 = unassigned_inds .pop ()
318323 eig_1 = eigenvalues [ind_1 ]
324+
319325 # Get the index of the eigenvalue that's closest to being the
320326 # complex conjugate of the randomly selected eigenvalue.
321327 ind_2 = np .argmin (np .abs (eigenvalues - np .conj (eig_1 )))
328+
329+ # Alert the user if an error occurs while pairing.
330+ # Complex conjugate pairs should be unique in theory.
331+ if ind_2 not in unassigned_inds :
332+ msg = (
333+ "Error occurred while finding conjugate pairs. "
334+ "Please remove the \" conjugate pairs\" constraint and "
335+ "check that your system eigenvalues approximately "
336+ "consist of complex conjugate pairs."
337+ )
338+ raise ValueError (msg )
339+
340+ # Uniquely pair eig_1 and eig_2.
322341 eig_2 = eigenvalues [ind_2 ]
323342 unassigned_inds .remove (ind_2 )
343+
324344 # Average their real and imaginary components together.
325345 a = 0.5 * (eig_1 .real + eig_2 .real )
326346 b = 0.5 * (np .abs (eig_1 .imag ) + np .abs (eig_2 .imag ))
0 commit comments