def setUp(self): # Set up rotation angles self.alpha = 2.67 self.beta = 1.32 self.gamma = 0.83 # Get geometric interpretation of the rotation angles # The coordinate system is rotated by R_z(alpha)*R_y(beta)*R_z(gamma) where e.g. R_z is the elementary rotation # R_z(alpha) = [[cos(alpha), -sin(alpha), 0], [sin(alpha), cos(alpha), 0], [0,0,1]]. In the following, we calculate # the coordinate representations of the rotated z-axis and y-axis in the unrotated system. s, c = np.sin(self.gamma), np.cos(self.gamma) self.rotator = np.array([[c, -s, 0], [s, c, 0], [0, 0, 1]]) s, c = np.sin(self.beta), np.cos(self.beta) self.rotator = np.dot(np.array([[c, 0, s], [0, 1, 0], [-s, 0, c]]), self.rotator) s, c = np.sin(self.alpha), np.cos(self.alpha) self.rotator = np.dot(np.array([[c, -s, 0], [s, c, 0], [0, 0, 1]]), self.rotator) self.to_z_axis = np.dot(self.rotator, [0, 0, 1]) self.to_y_axis = np.dot(self.rotator, [0, 1, 0]) # Set up cache self.cache = pi.MatrixElementCache() # Setup states self.state_one = pi.StateOne("Rb", 61, 2, 1.5, 1.5) self.state_two = pi.StateTwo(self.state_one, self.state_one) # Build one-atom system self.system_one = pi.SystemOne(self.state_one.getSpecies(), self.cache) self.system_one.restrictEnergy(self.state_one.getEnergy() - 30, self.state_one.getEnergy() + 30) self.system_one.restrictN(self.state_one.getN() - 1, self.state_one.getN() + 1) self.system_one.restrictL(self.state_one.getL() - 1, self.state_one.getL() + 1)
def test_diagonalization_full(self): # Setup states state_one = pi.StateOne("Cs", 60, 0, 0.5, 0.5) # Build one-atom system system_one = pi.SystemOne(state_one.getSpecies(), self.cache) system_one.restrictEnergy(state_one.getEnergy() - 30, state_one.getEnergy() + 30) system_one.restrictN(state_one.getN() - 1, state_one.getN() + 1) system_one.restrictL(state_one.getL() - 1, state_one.getL() + 1) system_one.setEfield([1, 0, 0]) system_one.setBfield([5, 50, 0]) # Diagonalize using the standard approach system_one_standard = pi.SystemOne(system_one) system_one_standard.diagonalize() evecs_standard = system_one_standard.getBasisvectors() # Diagonalize using FEAST system_one.diagonalize(-1e12, 1e12) evecs_feast = system_one.getBasisvectors() # Check results overlap = np.abs(np.dot(evecs_standard.conj().T, evecs_feast))**2 np.testing.assert_allclose(overlap.diagonal(), np.ones_like(overlap.diagonal()), rtol=1e-12) self.assertAlmostEqual(np.sum(overlap), system_one.getNumBasisvectors(), places=6)
def test_basisvectors(self): one_atom_basisvectors_indices = [[0, 0], [0, 1], [1, 0], [1, 1]] # Setup states state_one = pi.StateOne("Cs", 60, 0, 0.5, 0.5) # One-atom system system_one = pi.SystemOne(state_one.getSpecies(), self.cache) system_one.restrictEnergy(state_one.getEnergy() - 30, state_one.getEnergy() + 30) system_one.restrictN(state_one.getN() - 1, state_one.getN() + 1) system_one.restrictL(state_one.getL() - 1, state_one.getL() + 1) system_one.setEfield([5, 0, 0]) system_one.diagonalize() basisvectors_one = system_one.getBasisvectors().toarray() assert basisvectors_one.shape[0] == basisvectors_one.shape[1] # Two-atom system system_two = pi.SystemTwo(system_one, system_one, self.cache) system_two.setMinimalNorm(0) system_two.setOneAtomBasisvectors(one_atom_basisvectors_indices) basisvectors_two = system_two.getBasisvectors().toarray() assert basisvectors_two.shape[0] == (basisvectors_one.shape[0])**2 assert basisvectors_two.shape[1] == len(one_atom_basisvectors_indices) # Check results for n, [a, b] in enumerate(one_atom_basisvectors_indices): np.testing.assert_allclose( np.outer(basisvectors_one[:, a], basisvectors_one[:, b]).ravel(), basisvectors_two[:, n])
def test_permutation(self): ####################################################### ### Check permutation symmetry of two atom systems #### ####################################################### # Remark: calling restrictEnergy() would cause a small # deviation # TODO figure out exact reason (in case of # symmetrized basis states, the atom-atom interaction would # add energy to the diagonal) # Define states state_one = pi.StateOne("Rb", 61, 1, 0.5, 0.5) state_two = pi.StateTwo(state_one, state_one) # Build one atom system system_one = pi.SystemOne(state_one.element, self.path_cache) system_one.restrictEnergy(state_one.energy-20, state_one.energy+20) system_one.restrictN(state_one.n-1, state_one.n+1) system_one.restrictL(state_one.l-1, state_one.l+1) system_one.restrictJ(state_one.j-1, state_one.j+1) system_one.setBfield([100, 200, 300]) system_one.setEfield([1, 2, 3]) # Build two atom system system_two = pi.SystemTwo(system_one, system_one, self.path_cache) #system_two.restrictEnergy(state_two.energy-2, state_two.energy+2) # TODO system_two.setDistance(1) system_two.setOrder(3) # Diagonalize blockwise system_two_even = pi.SystemTwo(system_two) system_two_even.setConservedParityUnderPermutation(pi.EVEN) system_two_even.diagonalize() system_two_odd = pi.SystemTwo(system_two) system_two_odd.setConservedParityUnderPermutation(pi.ODD) system_two_odd.diagonalize() system_two_combined = system_two_even system_two_combined.add(system_two_odd) # Diagonalize altogether system_two.setConservedParityUnderPermutation(pi.NA) system_two.diagonalize() # Compare results w1 = np.sort(system_two_combined.diagonal) w2 = np.sort(system_two.diagonal) maxdiff = np.abs((w1-w2)/(np.max([w1,w2],axis=0))) maxdiff[np.abs(w1-w2)<1e-14] = np.abs(w1-w2)[np.abs(w1-w2)<1e-14] maxdiff = np.max(maxdiff) print("Two-atom system with permutation symmetry, relative maximum deviation: ", maxdiff) self.assertAlmostEqual(maxdiff, 0, places=9)
def setUp(self): self.dump_new_reference_data = False self.tolerance = 1e-6 # Set up cache self.cache_path = tempfile.mkdtemp() self.cache = pi.MatrixElementCache(self.cache_path) # Setup states self.state_one = pi.StateOne("Rb", 61, 2, 1.5, 1.5) self.state_two = pi.StateTwo(self.state_one, self.state_one)
def test_rotation_hamiltonian(self): # Hamiltonian (in canonical basis) and overlaps after rotating the system with/without atom-field interactions system_one_tmp = pi.SystemOne(self.system_one) system_one_tmp.setEfield([0.2, 0, 0.3]) system_one_tmp.setBfield([0, 1, 0]) system_one_tmp.rotate(self.alpha, self.beta, self.gamma) hamiltonian1 = system_one_tmp.getHamiltonian().todense() system_one_tmp.diagonalize() overlaps1 = system_one_tmp.getOverlap(pi.StateOne("Rb", 61, 2, 1.5, 1.5)) system_one_tmp = pi.SystemOne(self.system_one) # is of no importance for the overlaps, but for the hamiltonians system_one_tmp.rotate(self.alpha, self.beta, self.gamma) system_one_tmp.setEfield(np.dot(self.rotator.T, [0.2, 0, 0.3])) system_one_tmp.setBfield(np.dot(self.rotator.T, [0, 1, 0])) hamiltonian2 = system_one_tmp.getHamiltonian().todense() system_one_tmp.diagonalize() overlaps2 = system_one_tmp.getOverlap(pi.StateOne("Rb", 61, 2, 1.5, 1.5)) system_one_tmp = pi.SystemOne(self.system_one) # is of no importance for the overlaps, but for the hamiltonians system_one_tmp.rotate(self.alpha, self.beta, self.gamma) system_one_tmp.setEfield([0.2, 0, 0.3], self.alpha, self.beta, self.gamma) system_one_tmp.setBfield([0, 1, 0], self.alpha, self.beta, self.gamma) hamiltonian3 = system_one_tmp.getHamiltonian().todense() system_one_tmp.diagonalize() overlaps3 = system_one_tmp.getOverlap(pi.StateOne("Rb", 61, 2, 1.5, 1.5)) system_one_tmp = pi.SystemOne(self.system_one) system_one_tmp.setEfield([0.2, 0, 0.3]) system_one_tmp.setBfield([0, 1, 0]) system_one_tmp.diagonalize() overlaps4 = system_one_tmp.getOverlap(pi.StateOne("Rb", 61, 2, 1.5, 1.5), -self.gamma, -self.beta, -self.alpha) # Check that everything is the same np.testing.assert_allclose(overlaps1, overlaps2, rtol=1e-4, atol=1e-6) np.testing.assert_allclose(overlaps1, overlaps3, rtol=1e-4, atol=1e-6) np.testing.assert_allclose(overlaps1, overlaps4, rtol=1e-4, atol=1e-6) np.testing.assert_allclose(hamiltonian1, hamiltonian2, rtol=1e-4, atol=1e-6) np.testing.assert_allclose(hamiltonian1, hamiltonian3, rtol=1e-4, atol=1e-6)
def test_rotation_overlap(self): states_to_calculate_overlap_with = [ pi.StateOne("Rb", 61, 2, pi.ARB, 1.5), pi.StateOne("Rb", 60, 2, 1.5, 1.5) ] # Add interaction to the Hamiltonian and diagonalize it system_one_interacting = pi.SystemOne(self.system_one) system_one_interacting.setEfield([0, 0, 0.1]) system_one_interacting.setBfield([0, 1, 0]) system_one_interacting.diagonalize() # Overlap with rotated system system_one_tmp = pi.SystemOne(system_one_interacting) system_one_tmp.rotate(self.to_z_axis, self.to_y_axis) overlap_rotated_system1 = system_one_tmp.getOverlap(states_to_calculate_overlap_with) system_one_tmp = pi.SystemOne(system_one_interacting) system_one_tmp.rotate(self.alpha, self.beta, self.gamma) overlap_rotated_system2 = system_one_tmp.getOverlap(states_to_calculate_overlap_with) system_one_tmp = pi.SystemOne(system_one_interacting) # gamma can be arbitrary, it just leads to a phase system_one_tmp.rotate(self.alpha, self.beta, self.gamma + 0.8342) overlap_rotated_system3 = system_one_tmp.getOverlap(states_to_calculate_overlap_with) # Overlap with rotated states system_one_tmp = pi.SystemOne(system_one_interacting) overlap_rotated_states1 = system_one_tmp.getOverlap( states_to_calculate_overlap_with, -self.gamma, -self.beta, -self.alpha) system_one_tmp = pi.SystemOne(system_one_interacting) overlap_rotated_states2 = system_one_tmp.getOverlap( states_to_calculate_overlap_with, -self.gamma + 0.8342, -self.beta, -self.alpha) # Check that everything is the same np.testing.assert_allclose(overlap_rotated_system1, overlap_rotated_system2, rtol=1e-6) np.testing.assert_allclose(overlap_rotated_system1, overlap_rotated_system3, rtol=1e-6) np.testing.assert_allclose(overlap_rotated_system1, overlap_rotated_states1, rtol=1e-6) np.testing.assert_allclose(overlap_rotated_system1, overlap_rotated_states2, rtol=1e-6)
def test_exception(self): one_atom_basisvectors_indices = [[0, 0], [0, 0]] # Setup states state_one = pi.StateOne("Cs", 60, 0, 0.5, 0.5) # One-atom system system_one = pi.SystemOne(state_one.getSpecies(), self.cache) system_one.restrictEnergy(state_one.getEnergy() - 30, state_one.getEnergy() + 30) system_one.restrictN(state_one.getN() - 1, state_one.getN() + 1) system_one.restrictL(state_one.getL() - 1, state_one.getL() + 1) system_one.setEfield([5, 0, 0]) system_one.diagonalize() basisvectors_one = system_one.getBasisvectors().toarray() # Two-atom system system_two = pi.SystemTwo(system_one, system_one, self.cache) system_two.setMinimalNorm(0) with self.assertRaises(RuntimeError) as context: system_two.setOneAtomBasisvectors(one_atom_basisvectors_indices) self.assertTrue('not unique' in str(context.exception))
def test_diagonalization_bounded(self): # Setup states state_one = pi.StateOne("Cs", 60, 0, 0.5, 0.5) # Build one-atom system system_one = pi.SystemOne(state_one.getSpecies(), self.cache) system_one.restrictEnergy(state_one.getEnergy() - 100, state_one.getEnergy() + 100) system_one.restrictN(state_one.getN() - 1, state_one.getN() + 1) system_one.restrictL(state_one.getL() - 1, state_one.getL() + 1) system_one.restrictM(state_one.getM(), state_one.getM()) system_one.setEfield([0, 0, 1]) system_one.setBfield([0, 0, 50]) # Determine energy bounds energy_lower_bound = state_one.getEnergy() - 20 energy_upper_bound = state_one.getEnergy() + 20 # Diagonalize using FEAST system_one.diagonalize(energy_lower_bound, energy_upper_bound, 0.01) # Check results self.assertEqual(system_one.getNumStates(), 9) self.assertEqual(system_one.getNumBasisvectors(), 4)
def test_combined(self): ####################################################### ### Check combined binary symmetries ################## ####################################################### # Remark: calling restrictEnergy() would cause a small # deviation # TODO figure out exact reason (in case of # symmetrized basis states, the atom-atom interaction would # add energy to the diagonal) # Define states state_one = pi.StateOne("Rb", 61, 1, 0.5, 0.5) state_two = pi.StateTwo(state_one, state_one) # Build one atom system system_one = pi.SystemOne(state_one.element, self.path_cache) system_one.restrictEnergy(state_one.energy-20, state_one.energy+20) system_one.restrictN(state_one.n-1, state_one.n+1) system_one.restrictL(state_one.l-1, state_one.l+1) system_one.restrictJ(state_one.j-1, state_one.j+1) system_one.setBfield([0, 100, 0]) system_one_combined = pi.SystemOne(system_one) system_one_combined.setConservedParityUnderReflection(pi.EVEN) system_one_combined.diagonalize() system_one_inverse = pi.SystemOne(system_one) system_one_inverse.setConservedParityUnderReflection(pi.ODD) system_one_inverse.diagonalize() system_one_combined.add(system_one_inverse) system_one.setConservedParityUnderReflection(pi.NA) system_one.diagonalize() # Build two atom system system_two = pi.SystemTwo(system_one, system_one, self.path_cache) system_two.setDistance(1) system_two.setOrder(3) system_two.diagonalize() # Note: it is important to use system_one_combined system_two_from_combined = pi.SystemTwo(system_one_combined, system_one_combined, self.path_cache) system_two_from_combined.setDistance(1) system_two_from_combined.setOrder(3) system_two_combined = None for sym_reflection, sym_inversion, sym_permutation in product([pi.EVEN, pi.ODD], [pi.EVEN, pi.ODD], [pi.EVEN, pi.ODD]): system_two_tmp = pi.SystemTwo(system_two_from_combined) system_two_tmp.setConservedParityUnderReflection(sym_reflection) system_two_tmp.setConservedParityUnderInversion(sym_inversion) system_two_tmp.setConservedParityUnderPermutation(sym_permutation) system_two_tmp.diagonalize() if system_two_combined is None: system_two_combined = system_two_tmp else: system_two_combined.add(system_two_tmp) system_two_combined.diagonalize() # Compare results w1 = np.sort(system_two_combined.diagonal) w2 = np.sort(system_two.diagonal) maxdiff = np.abs((w1-w2)/(np.max([w1,w2],axis=0))) maxdiff[np.abs(w1-w2)<1e-14] = np.abs(w1-w2)[np.abs(w1-w2)<1e-14] maxdiff = np.max(maxdiff) print("Two-atom system with combined binary symmetries, relative maximum deviation: ", maxdiff) self.assertAlmostEqual(maxdiff, 0, places=9)
def test_rotation(self): ####################################################### ### Check rotation symmetry of one atom systems ####### ####################################################### # Define state state_one = pi.StateOne("Rb", 61, 1, 0.5, 0.5) # Build one atom system system_one = pi.SystemOne(state_one.element, self.path_cache) system_one.restrictEnergy(state_one.energy-40, state_one.energy+40) system_one.restrictN(state_one.n-1, state_one.n+1) system_one.restrictL(state_one.l-1, state_one.l+1) system_one.restrictJ(state_one.j-1, state_one.j+1) system_one.setBfield([0, 0, 100]) system_one.setEfield([0, 0, 1]) momenta_one = np.arange(-(state_one.j+1), (state_one.j+1)+1) # Diagonalize blockwise system_one_momentum = {} for m in momenta_one: system_one_momentum[m] = pi.SystemOne(system_one) system_one_momentum[m].setConservedMomentaUnderRotation([m]) system_one_momentum[m].diagonalize() system_one_combined = pi.SystemOne(system_one_momentum[momenta_one[0]]) for m in momenta_one[1:]: system_one_combined.add(system_one_momentum[m]) # Diagonalize altogether system_one_alternative = pi.SystemOne(system_one) system_one_alternative.setConservedMomentaUnderRotation(momenta_one) system_one_alternative.diagonalize() system_one.setConservedMomentaUnderRotation([pi.ARB]) system_one.diagonalize() # Compare results w1 = np.sort(system_one_combined.diagonal) w2 = np.sort(system_one.diagonal) w3 = np.sort(system_one_alternative.diagonal) maxdiff12 = np.abs((w1-w2)/(np.max([w1,w2],axis=0))) maxdiff23 = np.abs((w3-w2)/(np.max([w3,w2],axis=0))) maxdiff12[np.abs(w1-w2)<1e-14] = np.abs(w1-w2)[np.abs(w1-w2)<1e-14] maxdiff23[np.abs(w3-w2)<1e-14] = np.abs(w3-w2)[np.abs(w3-w2)<1e-14] maxdiff12 = np.max(maxdiff12) maxdiff23 = np.max(maxdiff23) print("One-atom system with rotation symmetry, relative maximum deviation: ", maxdiff12, " (between alternatives: ", maxdiff23,")") self.assertAlmostEqual(maxdiff12, 0, places=9) self.assertAlmostEqual(maxdiff23, 0, places=9) ####################################################### ### Check rotation symmetry of two atom systems ####### ####################################################### # Define state state_two = pi.StateTwo(state_one, state_one) # Diagonalize blockwise system_two_momentum = {} for m1 in momenta_one: for m2 in momenta_one: if m1+m2 in system_two_momentum: tmp = pi.SystemTwo(system_one_momentum[m1], system_one_momentum[m2]) tmp.restrictEnergy(state_two.energy-2, state_two.energy+2) system_two_momentum[m1+m2].add(tmp) else: system_two_momentum[m1+m2] = pi.SystemTwo(system_one_momentum[m1], system_one_momentum[m2]) system_two_momentum[m1+m2].restrictEnergy(state_two.energy-2, state_two.energy+2) momenta_two = list(system_two_momentum.keys()) for m in momenta_two: system_two_momentum[m].setDistance(1) system_two_momentum[m].setOrder(5) system_two_momentum[m].diagonalize() system_two_combined = pi.SystemTwo(system_two_momentum[momenta_two[0]]) for m in momenta_two[1:]: system_two_combined.add(system_two_momentum[m]) # Diagonalize blockwise, alternative system_two_momentum_alternative = {} for m in momenta_two: system_two_momentum_alternative[m] = pi.SystemTwo(system_one, system_one) system_two_momentum_alternative[m].restrictEnergy(state_two.energy-2, state_two.energy+2) system_two_momentum_alternative[m].setConservedMomentaUnderRotation([int(m)]) system_two_momentum_alternative[m].setDistance(1) system_two_momentum_alternative[m].setOrder(5) system_two_momentum_alternative[m].diagonalize() system_two_combined_alternative = pi.SystemTwo(system_two_momentum_alternative[momenta_two[0]]) for m in momenta_two[1:]: system_two_combined_alternative.add(system_two_momentum_alternative[m]) # Diagonalize altogether system_two = pi.SystemTwo(system_one, system_one, self.path_cache) system_two.restrictEnergy(state_two.energy-2, state_two.energy+2) system_two.setDistance(1) system_two.setOrder(5) system_two.diagonalize() # Compare results w1 = np.sort(system_two_combined.diagonal) w2 = np.sort(system_two.diagonal) w3 = np.sort(system_two_combined_alternative.diagonal) maxdiff12 = np.abs((w1-w2)/(np.max([w1,w2],axis=0))) maxdiff23 = np.abs((w3-w2)/(np.max([w3,w2],axis=0))) maxdiff12[np.abs(w1-w2)<1e-14] = np.abs(w1-w2)[np.abs(w1-w2)<1e-14] maxdiff23[np.abs(w3-w2)<1e-14] = np.abs(w3-w2)[np.abs(w3-w2)<1e-14] maxdiff12 = np.max(maxdiff12) maxdiff23 = np.max(maxdiff23) print("Two-atom system with rotation symmetry, relative maximum deviation: ", maxdiff12, " (between alternatives: ", maxdiff23,")") self.assertAlmostEqual(maxdiff12, 0, places=9) self.assertAlmostEqual(maxdiff23, 0, places=9)
def test_reflection(self): ####################################################### ### Check reflection symmetry of one atom systems ##### ####################################################### # Define state state_one = pi.StateOne("Rb", 61, 1, 0.5, 0.5) # Build one atom system system_one = pi.SystemOne(state_one.element, self.path_cache) system_one.restrictEnergy(state_one.energy-20, state_one.energy+20) system_one.restrictN(state_one.n-1, state_one.n+1) system_one.restrictL(state_one.l-1, state_one.l+1) system_one.restrictJ(state_one.j-1, state_one.j+1) system_one.setBfield([0, 100, 0]) system_one.setEfield([1, 0, 2]) # Diagonalize blockwise system_one_even = pi.SystemOne(system_one) system_one_even.setConservedParityUnderReflection(pi.EVEN) system_one_even.diagonalize() system_one_odd = pi.SystemOne(system_one) system_one_odd.setConservedParityUnderReflection(pi.ODD) system_one_odd.diagonalize() system_one_combined = pi.SystemOne(system_one_even) system_one_combined.add(system_one_odd) # Diagonalize altogether system_one.setConservedParityUnderReflection(pi.NA) system_one.diagonalize() # Compare results w1 = np.sort(system_one_combined.diagonal) w2 = np.sort(system_one.diagonal) maxdiff = np.abs((w1-w2)/(np.max([w1,w2],axis=0))) maxdiff[np.abs(w1-w2)<1e-14] = np.abs(w1-w2)[np.abs(w1-w2)<1e-14] maxdiff = np.max(maxdiff) print("One-atom system with reflection symmetry, relative maximum deviation: ", maxdiff) self.assertAlmostEqual(maxdiff, 0, places=9) ####################################################### ### Check reflection symmetry of two atom systems ##### ####################################################### # Remark: calling restrictEnergy() would cause a small deviation # Define state state_two = pi.StateTwo(state_one, state_one) # Diagonalize blockwise # Note: it is called odd in order to fit to the notion of the paper system_two_odd = pi.SystemTwo(system_one_even, system_one_even, self.path_cache) system_two_odd.add(pi.SystemTwo(system_one_odd, system_one_odd, self.path_cache)) system_two_odd.setDistance(1) system_two_odd.setOrder(5) system_two_odd.diagonalize() system_two_even = pi.SystemTwo(system_one_even, system_one_odd, self.path_cache) system_two_even.add(pi.SystemTwo(system_one_odd, system_one_even, self.path_cache)) system_two_even.setDistance(1) system_two_even.setOrder(5) system_two_even.diagonalize() system_two_combined = pi.SystemTwo(system_two_even) system_two_combined.add(system_two_odd) # Diagonalize blockwise alternative # Note: it is important to use system_one_combined system_two_alternative= pi.SystemTwo(system_one_combined, system_one_combined, self.path_cache) system_two_alternative.setDistance(1) system_two_alternative.setOrder(5) system_two_even_alternative = pi.SystemTwo(system_two_alternative) system_two_even_alternative.setConservedParityUnderReflection(pi.EVEN) system_two_even_alternative.diagonalize() system_two_odd_alternative = pi.SystemTwo(system_two_alternative) system_two_odd_alternative.setConservedParityUnderReflection(pi.ODD) system_two_odd_alternative.diagonalize() # Diagonalize altogether system_two = pi.SystemTwo(system_one, system_one, self.path_cache) system_two.setDistance(1) system_two.setOrder(5) system_two.diagonalize() # Compare results w1 = np.sort(system_two_combined.diagonal) w2 = np.sort(system_two.diagonal) w3 = np.sort(system_two_even.diagonal) w4 = np.sort(system_two_odd.diagonal) w5 = np.sort(system_two_even_alternative.diagonal) w6 = np.sort(system_two_odd_alternative.diagonal) maxdiff12 = np.abs((w1-w2)/(np.max([w1,w2],axis=0))) maxdiff35 = np.abs((w3-w5)/(np.max([w3,w5],axis=0))) maxdiff46 = np.abs((w4-w6)/(np.max([w4,w6],axis=0))) maxdiff12[np.abs(w1-w2)<1e-14] = np.abs(w1-w2)[np.abs(w1-w2)<1e-14] maxdiff35[np.abs(w3-w5)<1e-14] = np.abs(w3-w5)[np.abs(w3-w5)<1e-14] maxdiff46[np.abs(w4-w6)<1e-14] = np.abs(w4-w6)[np.abs(w4-w6)<1e-14] maxdiff12 = np.max(maxdiff12) maxdiff35 = np.max(maxdiff35) maxdiff46 = np.max(maxdiff46) print("Two-atom system with reflection symmetry, relative maximum deviation: ", maxdiff12, " (between alternatives: ", maxdiff35,", ", maxdiff46, ")") self.assertAlmostEqual(maxdiff12, 0, places=9) self.assertAlmostEqual(maxdiff35, 0, places=9) self.assertAlmostEqual(maxdiff46, 0, places=9)