def test_excitation_preserving(self): """Test the excitation preserving wavefunction on a chemistry example.""" driver = HDF5Driver(self.get_resource_path('test_driver_hdf5.hdf5')) fermionic_transformation = FermionicTransformation( qubit_mapping=QubitMappingType.PARITY, two_qubit_reduction=False) qubit_op, _ = fermionic_transformation.transform(driver) optimizer = SLSQP(maxiter=100) initial_state = HartreeFock( fermionic_transformation.molecule_info['num_orbitals'], fermionic_transformation.molecule_info['num_particles'], qubit_mapping=fermionic_transformation._qubit_mapping, two_qubit_reduction=fermionic_transformation._two_qubit_reduction) wavefunction = ExcitationPreserving(qubit_op.num_qubits) wavefunction.compose(initial_state, front=True, inplace=True) solver = VQE(var_form=wavefunction, optimizer=optimizer, quantum_instance=QuantumInstance( BasicAer.get_backend('statevector_simulator'), seed_simulator=aqua_globals.random_seed, seed_transpiler=aqua_globals.random_seed)) gsc = GroundStateEigensolver(fermionic_transformation, solver) result = gsc.solve(driver) self.assertAlmostEqual(result.total_energies[0], self.reference_energy, places=4)
def test_fsim_circuit(self): """Test a ExcitationPreserving circuit in fsim mode.""" num_qubits = 3 reps = 2 entanglement = 'linear' # need the parameters in the entanglement blocks to be the same because the order # can get mixed up in ExcitationPreserving (since parameters are not ordered in circuits) parameters = [1] * (num_qubits * (reps + 1) + reps * (1 + num_qubits)) param_iter = iter(parameters) expected = QuantumCircuit(3) for _ in range(reps): for i in range(num_qubits): expected.rz(next(param_iter), i) shared_param = next(param_iter) expected.rxx(shared_param, 0, 1) expected.ryy(shared_param, 0, 1) expected.cp(next(param_iter), 0, 1) shared_param = next(param_iter) expected.rxx(shared_param, 1, 2) expected.ryy(shared_param, 1, 2) expected.cp(next(param_iter), 1, 2) for i in range(num_qubits): expected.rz(next(param_iter), i) library = ExcitationPreserving(num_qubits, reps=reps, mode='fsim', entanglement=entanglement).assign_parameters(parameters) self.assertCircuitEqual(library, expected)
def test_swaprz_circuit(self): """Test a ExcitationPreserving circuit in iswap mode.""" num_qubits = 3 reps = 2 entanglement = 'linear' parameters = ParameterVector('theta', num_qubits * (reps + 1) + reps * (num_qubits - 1)) param_iter = iter(parameters) expected = QuantumCircuit(3) for _ in range(reps): for i in range(num_qubits): expected.rz(next(param_iter), i) shared_param = next(param_iter) expected.rxx(shared_param, 0, 1) expected.ryy(shared_param, 0, 1) shared_param = next(param_iter) expected.rxx(shared_param, 1, 2) expected.ryy(shared_param, 1, 2) for i in range(num_qubits): expected.rz(next(param_iter), i) library = ExcitationPreserving(num_qubits, reps=reps, entanglement=entanglement).assign_parameters(parameters) self.assertCircuitEqual(library, expected)
def test_swaprz(self, mode): """ SwapRZ variational form test """ driver = HDF5Driver(self.get_resource_path('test_driver_hdf5.hdf5')) qmolecule = driver.run() operator = Hamiltonian(qubit_mapping=QubitMappingType.JORDAN_WIGNER, two_qubit_reduction=False) qubit_op, _ = operator.run(qmolecule) optimizer = SLSQP(maxiter=100) initial_state = HartreeFock( operator.molecule_info['num_orbitals'], operator.molecule_info['num_particles'], qubit_mapping=operator._qubit_mapping, two_qubit_reduction=operator._two_qubit_reduction) if mode == 'wrapped': warnings.filterwarnings('ignore', category=DeprecationWarning) wavefunction = SwapRZ(qubit_op.num_qubits, initial_state=initial_state) else: wavefunction = ExcitationPreserving(qubit_op.num_qubits, initial_state=initial_state) algo = VQE(qubit_op, wavefunction, optimizer) if mode == 'wrapped': warnings.filterwarnings('always', category=DeprecationWarning) result = algo.run( QuantumInstance(BasicAer.get_backend('statevector_simulator'), seed_simulator=aqua_globals.random_seed, seed_transpiler=aqua_globals.random_seed)) result = operator.process_algorithm_result(result) self.assertAlmostEqual(result.energy, self.reference_energy, places=6)
def test_excitation_preserving(self): """Test the excitation preserving wavefunction on a chemistry example.""" driver = HDF5Driver(self.get_resource_path('test_driver_hdf5.hdf5')) qmolecule = driver.run() operator = Hamiltonian(qubit_mapping=QubitMappingType.JORDAN_WIGNER, two_qubit_reduction=False) qubit_op, _ = operator.run(qmolecule) optimizer = SLSQP(maxiter=100) initial_state = HartreeFock( operator.molecule_info['num_orbitals'], operator.molecule_info['num_particles'], qubit_mapping=operator._qubit_mapping, two_qubit_reduction=operator._two_qubit_reduction) wavefunction = ExcitationPreserving(qubit_op.num_qubits, initial_state=initial_state) algo = VQE(qubit_op, wavefunction, optimizer) result = algo.run( QuantumInstance(BasicAer.get_backend('statevector_simulator'), seed_simulator=aqua_globals.random_seed, seed_transpiler=aqua_globals.random_seed)) result = operator.process_algorithm_result(result) self.assertAlmostEqual(result.energy, self.reference_energy, places=6)
def test_excitation_preserving(self): """Test the excitation preserving wavefunction on a chemistry example.""" driver = HDF5Driver( self.get_resource_path("test_driver_hdf5.hdf5", "second_q/drivers/hdf5d")) converter = QubitConverter(ParityMapper()) problem = ElectronicStructureProblem(driver) _ = problem.second_q_ops() particle_number = cast( ParticleNumber, problem.grouped_property_transformed.get_property(ParticleNumber)) num_particles = (particle_number.num_alpha, particle_number.num_beta) num_spin_orbitals = particle_number.num_spin_orbitals optimizer = SLSQP(maxiter=100) initial_state = HartreeFock(num_spin_orbitals, num_particles, converter) wavefunction = ExcitationPreserving(num_spin_orbitals) wavefunction.compose(initial_state, front=True, inplace=True) solver = VQE( ansatz=wavefunction, optimizer=optimizer, quantum_instance=QuantumInstance( BasicAer.get_backend("statevector_simulator"), seed_simulator=algorithm_globals.random_seed, seed_transpiler=algorithm_globals.random_seed, ), ) gsc = GroundStateEigensolver(converter, solver) result = gsc.solve(problem) self.assertAlmostEqual(result.total_energies[0], self.reference_energy, places=4)
def test_fsim_circuit(self): """Test a ExcitationPreserving circuit in fsim mode.""" num_qubits = 3 reps = 2 entanglement = "linear" # need the parameters in the entanglement blocks to be the same because the order # can get mixed up in ExcitationPreserving (since parameters are not ordered in circuits) parameters = [1] * (num_qubits * (reps + 1) + reps * (1 + num_qubits)) param_iter = iter(parameters) # ┌───────┐┌─────────┐┌─────────┐ ┌───────┐ » # q_0: ┤ Rz(1) ├┤0 ├┤0 ├─■──────┤ Rz(1) ├───────────────────» # ├───────┤│ Rxx(1) ││ Ryy(1) │ │P(1) ┌┴───────┴┐┌─────────┐ » # q_1: ┤ Rz(1) ├┤1 ├┤1 ├─■─────┤0 ├┤0 ├─■─────» # ├───────┤└─────────┘└─────────┘ │ Rxx(1) ││ Ryy(1) │ │P(1) » # q_2: ┤ Rz(1) ├─────────────────────────────┤1 ├┤1 ├─■─────» # └───────┘ └─────────┘└─────────┘ » # « ┌─────────┐┌─────────┐ ┌───────┐ » # «q_0: ─────────┤0 ├┤0 ├─■──────┤ Rz(1) ├───────────────────» # « ┌───────┐│ Rxx(1) ││ Ryy(1) │ │P(1) ┌┴───────┴┐┌─────────┐ » # «q_1: ┤ Rz(1) ├┤1 ├┤1 ├─■─────┤0 ├┤0 ├─■─────» # « ├───────┤└─────────┘└─────────┘ │ Rxx(1) ││ Ryy(1) │ │P(1) » # «q_2: ┤ Rz(1) ├─────────────────────────────┤1 ├┤1 ├─■─────» # « └───────┘ └─────────┘└─────────┘ » # « # «q_0: ───────── # « ┌───────┐ # «q_1: ┤ Rz(1) ├ # « ├───────┤ # «q_2: ┤ Rz(1) ├ # « └───────┘ expected = QuantumCircuit(3) for _ in range(reps): for i in range(num_qubits): expected.rz(next(param_iter), i) shared_param = next(param_iter) expected.rxx(shared_param, 0, 1) expected.ryy(shared_param, 0, 1) expected.cp(next(param_iter), 0, 1) shared_param = next(param_iter) expected.rxx(shared_param, 1, 2) expected.ryy(shared_param, 1, 2) expected.cp(next(param_iter), 1, 2) for i in range(num_qubits): expected.rz(next(param_iter), i) library = ExcitationPreserving( num_qubits, reps=reps, mode="fsim", entanglement=entanglement).assign_parameters(parameters) self.assertCircuitEqual(library, expected)
def test_swaprz_circuit(self): """Test a ExcitationPreserving circuit in iswap mode.""" num_qubits = 3 reps = 2 entanglement = "linear" parameters = ParameterVector( "theta", num_qubits * (reps + 1) + reps * (num_qubits - 1)) param_iter = iter(parameters) # ┌──────────┐┌────────────┐┌────────────┐ ┌──────────┐ » # q_0: ┤ Rz(θ[0]) ├┤0 ├┤0 ├─┤ Rz(θ[5]) ├───────────────» # ├──────────┤│ Rxx(θ[3]) ││ Ryy(θ[3]) │┌┴──────────┴┐┌────────────┐» # q_1: ┤ Rz(θ[1]) ├┤1 ├┤1 ├┤0 ├┤0 ├» # ├──────────┤└────────────┘└────────────┘│ Rxx(θ[4]) ││ Ryy(θ[4]) │» # q_2: ┤ Rz(θ[2]) ├────────────────────────────┤1 ├┤1 ├» # └──────────┘ └────────────┘└────────────┘» # « ┌────────────┐┌────────────┐┌───────────┐ » # «q_0: ────────────┤0 ├┤0 ├┤ Rz(θ[10]) ├───────────────» # « ┌──────────┐│ Rxx(θ[8]) ││ Ryy(θ[8]) │├───────────┴┐┌────────────┐» # «q_1: ┤ Rz(θ[6]) ├┤1 ├┤1 ├┤0 ├┤0 ├» # « ├──────────┤└────────────┘└────────────┘│ Rxx(θ[9]) ││ Ryy(θ[9]) │» # «q_2: ┤ Rz(θ[7]) ├────────────────────────────┤1 ├┤1 ├» # « └──────────┘ └────────────┘└────────────┘» # « # «q_0: ───────────── # « ┌───────────┐ # «q_1: ┤ Rz(θ[11]) ├ # « ├───────────┤ # «q_2: ┤ Rz(θ[12]) ├ # « └───────────┘ expected = QuantumCircuit(3) for _ in range(reps): for i in range(num_qubits): expected.rz(next(param_iter), i) shared_param = next(param_iter) expected.rxx(shared_param, 0, 1) expected.ryy(shared_param, 0, 1) shared_param = next(param_iter) expected.rxx(shared_param, 1, 2) expected.ryy(shared_param, 1, 2) for i in range(num_qubits): expected.rz(next(param_iter), i) library = ExcitationPreserving( num_qubits, reps=reps, entanglement=entanglement).assign_parameters(parameters) self.assertCircuitEqual(library, expected)
def test_swaprz_blocks(self): """Test that the ExcitationPreserving circuit is instantiated correctly.""" two = ExcitationPreserving(5) with self.subTest(msg='test rotation gate'): self.assertEqual(len(two.rotation_blocks), 1) self.assertIsInstance(two.rotation_blocks[0].data[0][0], RZGate) with self.subTest(msg='test entanglement gate'): self.assertEqual(len(two.entanglement_blocks), 1) block = two.entanglement_blocks[0] self.assertEqual(len(block.data), 2) self.assertIsInstance(block.data[0][0], RXXGate) self.assertIsInstance(block.data[1][0], RYYGate) with self.subTest(msg='test parameter bounds'): expected = [(-np.pi, np.pi)] * two.num_parameters np.testing.assert_almost_equal(two.parameter_bounds, expected)
def sz_conserved_ansatz(num_qubits, insert_barriers=False, entanglement='sca', reps=1, total_spindn=-1, spindn_cluster='balanced', seed='999999'): """ Creates a parameterized Quantum Circuit to feed into the VQE and VVQE optimization algorithms. Starts with placing spin-flip (X) gates in an unparameterized manner, then applies an ExcitationPreserving circuit to parameterize the system without changing the total number of spin ups/downs. Args: num_qubits: The number of qubits in the circuit insert_barriers: Whether a barrier should be placed between the X gates and ExcitationPreserving gates (Default: False) total_spindn: How many X gates should be applied initially - if set to -1, will apply floor(num_qubits/2) gates (Default: -1) spindn_cluster: Where the X gates should be applied (Default: 'balanced'): 'balanced': Attempts to distribute the gates evenly along the circuit 'left_clustered': Places the gates on the first (total_spindn) qubits 'random': Distributes the gates randomly without applying two gates to the same qubit seed: The random seed to use if spindn_cluster = 'random' (Default: 999999) entanglement: The type of entanglement that the ExcitationPreserving ansatz should use (Default: 'sca') reps: The number of layers of repeating gates that the ExcitationPreserving ansatz should use (Default: 1) Returns: A parameterized QuantumCircuit """ ansatz = ExcitationPreserving(num_qubits, insert_barriers=insert_barriers, entanglement=entanglement, reps=reps) ansatz_circuit = QuantumCircuit(num_qubits) if total_spindn == -1: total_spindn = math.floor(num_qubits / 2.) if total_spindn > num_qubits: print("WARNING: total Sz {0} exceeds qubit number {1}".format( total_spindn, num_qubits)) total_spindn = num_qubits if spindn_cluster == 'left_clustered': #Flips all the spins on one side of the circuit ansatz_circuit.x(range(total_spindn)) if spindn_cluster == 'balanced': #Attempts to distribute the spin flips as evenly as possible spindn_interval = num_qubits / total_spindn ansatz_circuit.x( [math.floor(i * spindn_interval) for i in range(total_spindn)]) if spindn_cluster == 'random': #Flips the spin at random positions (no double flips) random.seed(seed) spindn_choices = random.sample(range(num_qubits), total_spindn) ansatz_circuit.x(spindn_choices) if insert_barriers: #Adds a barrier between the spin setup gates and the parameterized gates ansatz_circuit.barrier() ansatz_circuit.compose(ansatz, inplace=True) return ansatz_circuit