1# Licensed under the Apache License, Version 2.0 (the "License"); 2# you may not use this file except in compliance with the License. 3# You may obtain a copy of the License at 4# 5# http://www.apache.org/licenses/LICENSE-2.0 6# 7# Unless required by applicable law or agreed to in writing, software 8# distributed under the License is distributed on an "AS IS" BASIS, 9# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10# See the License for the specific language governing permissions and 11# limitations under the License. 12"""Tests for verstraete_cirac.py.""" 13 14import unittest 15 16from openfermion.hamiltonians import fermi_hubbard 17from openfermion.linalg import get_sparse_operator, get_ground_state 18from openfermion.transforms.opconversions import verstraete_cirac_2d_square 19from openfermion.transforms.opconversions.verstraete_cirac import ( 20 coordinates_to_snake_index, snake_index_to_coordinates, 21 stabilizer_local_2d_square) 22 23 24class VerstraeteCirac2dSquareGroundStateTest(unittest.TestCase): 25 """Test that the transform preserves desired ground state properties.""" 26 27 def setUp(self): 28 self.x_dimension = 2 29 self.y_dimension = 3 30 31 # Create a Hamiltonian with nearest-neighbor hopping terms 32 self.ferm_op = fermi_hubbard(self.x_dimension, self.y_dimension, 1., 0., 33 0., 0., False, True) 34 35 # Get the ground energy and ground state 36 self.ferm_op_sparse = get_sparse_operator(self.ferm_op) 37 self.ferm_op_ground_energy, self.ferm_op_ground_state = ( 38 get_ground_state(self.ferm_op_sparse)) 39 40 # Transform the FermionOperator to a QubitOperator 41 self.transformed_op = verstraete_cirac_2d_square( 42 self.ferm_op, 43 self.x_dimension, 44 self.y_dimension, 45 add_auxiliary_hamiltonian=True, 46 snake=False) 47 48 # Get the ground energy and state of the transformed operator 49 self.transformed_sparse = get_sparse_operator(self.transformed_op) 50 self.transformed_ground_energy, self.transformed_ground_state = ( 51 get_ground_state(self.transformed_sparse)) 52 53 def test_ground_energy(self): 54 """Test that the transformation preserves the ground energy.""" 55 self.assertAlmostEqual(self.transformed_ground_energy, 56 self.ferm_op_ground_energy) 57 58 59class VerstraeteCirac2dSquareOperatorLocalityTest(unittest.TestCase): 60 """Test that the transform results in local qubit operators.""" 61 62 def setUp(self): 63 self.x_dimension = 6 64 self.y_dimension = 6 65 66 # Create a Hubbard Hamiltonian 67 self.ferm_op = fermi_hubbard(self.x_dimension, self.y_dimension, 1.0, 68 4.0, 0.0, 0.0, False, True) 69 70 # Transform the FermionOperator to a QubitOperator without including 71 # the auxiliary Hamiltonian 72 self.transformed_op_no_aux = verstraete_cirac_2d_square( 73 self.ferm_op, 74 self.x_dimension, 75 self.y_dimension, 76 add_auxiliary_hamiltonian=False, 77 snake=False) 78 self.transformed_op_no_aux.compress() 79 80 # Transform the FermionOperator to a QubitOperator, including 81 # the auxiliary Hamiltonian 82 self.transformed_op_aux = verstraete_cirac_2d_square( 83 self.ferm_op, 84 self.x_dimension, 85 self.y_dimension, 86 add_auxiliary_hamiltonian=True, 87 snake=False) 88 self.transformed_op_aux.compress() 89 90 def test_operator_locality_no_aux(self): 91 """Test that the operators without the auxiliary Hamiltonian 92 are at most 4-local.""" 93 for term in self.transformed_op_no_aux.terms: 94 self.assertTrue(len(term) <= 4) 95 96 def test_operator_locality_aux(self): 97 """Test that the operators with the auxiliary Hamiltonian 98 are at most 6-local.""" 99 for term in self.transformed_op_aux.terms: 100 self.assertTrue(len(term) <= 6) 101 102 103class ExceptionTest(unittest.TestCase): 104 """Test that exceptions are raised correctly.""" 105 106 def test_verstraete_cirac_2d_square(self): 107 ferm_op = fermi_hubbard(3, 2, 1., 0., spinless=True) 108 with self.assertRaises(NotImplementedError): 109 _ = verstraete_cirac_2d_square(ferm_op, 3, 2) 110 111 def test_stabilizer_local_2d_square(self): 112 with self.assertRaises(ValueError): 113 _ = stabilizer_local_2d_square(0, 2, 4, 4) 114 115 def test_coordinates_to_snake_index(self): 116 with self.assertRaises(ValueError): 117 _ = coordinates_to_snake_index(4, 4, 4, 5) 118 with self.assertRaises(ValueError): 119 _ = coordinates_to_snake_index(4, 4, 5, 4) 120 121 def test_snake_index_to_coordinates(self): 122 with self.assertRaises(ValueError): 123 _ = snake_index_to_coordinates(20, 4, 5) 124