def test_simulate_trotter_bad_hamiltonian_type_raises_error(): qubits = cirq.LineQubit.range(2) hamiltonian = openfermion.FermionOperator() time = 1.0 with pytest.raises(TypeError): _ = next(simulate_trotter(qubits, hamiltonian, time, algorithm=None)) with pytest.raises(TypeError): _ = next(simulate_trotter(qubits, hamiltonian, time, algorithm=LINEAR_SWAP_NETWORK))
def kevin_hubbard_cirq(self): # Create Hubbard model Hamiltonian # -------------------------------- x_dim = 3 y_dim = 2 n_sites = x_dim * y_dim n_modes = 2 * n_sites tunneling = 1.0 coulomb = 4.0 hubbard_model = of.fermi_hubbard(x_dim, y_dim, tunneling, coulomb) # Reorder indices hubbard_model = of.reorder(hubbard_model, of.up_then_down) # Convert to DiagonalCoulombHamiltonian hubbard_hamiltonian = of.get_diagonal_coulomb_hamiltonian( hubbard_model) # Create qubits qubits = cirq.LineQubit.range(n_modes) # State preparation circuit for eigenstate of one-body term # --------------------------------------------------------- # Set the pseudo-particle orbitals to fill up_orbitals = range(n_sites // 2) down_orbitals = range(n_sites // 2) # Create the circuit hubbard_state_preparation_circuit = cirq.Circuit.from_ops( ofc.prepare_gaussian_state( qubits, of.QuadraticHamiltonian(hubbard_hamiltonian.one_body), occupied_orbitals=(up_orbitals, down_orbitals)), strategy=cirq.InsertStrategy.EARLIEST) # Trotter simulation circuit # -------------------------- n_steps = 10 order = 0 hubbard_simulation_circuit = cirq.Circuit.from_ops( ofc.simulate_trotter(qubits, hubbard_hamiltonian, time=1.0, n_steps=n_steps, order=order, algorithm=ofc.trotter.LINEAR_SWAP_NETWORK), strategy=cirq.InsertStrategy.EARLIEST) t0 = time.time() self.kevin_optimize_circuit(hubbard_state_preparation_circuit) self.kevin_optimize_circuit(hubbard_simulation_circuit) t1 = time.time() # print('Optimizing circuits took {} seconds'.format(t1 - t0)) # print(hubbard_state_preparation_circuit.to_text_diagram(transpose=True)) return hubbard_state_preparation_circuit, hubbard_simulation_circuit
def test_trotter_ansatzes_default_initial_params_iterations_1( ansatz_factory, trotter_algorithm, order, hamiltonian, atol): """Check that a Trotter ansatz with one iteration and default parameters is consistent with time evolution with one Trotter step.""" ansatz = ansatz_factory(hamiltonian, iterations=1) objective = HamiltonianObjective(hamiltonian) qubits = ansatz.qubits if isinstance(hamiltonian, openfermion.DiagonalCoulombHamiltonian): one_body = hamiltonian.one_body elif isinstance(hamiltonian, openfermion.InteractionOperator): one_body = hamiltonian.one_body_tensor preparation_circuit = cirq.Circuit.from_ops( prepare_gaussian_state(qubits, openfermion.QuadraticHamiltonian(one_body), occupied_orbitals=range(len(qubits) // 2))) # Compute value using ansatz circuit and objective circuit = (preparation_circuit + ansatz.circuit).with_parameters_resolved_by( ansatz.param_resolver(ansatz.default_initial_params())) result = circuit.apply_unitary_effect_to_state( qubit_order=ansatz.qubit_permutation(qubits)) obj_val = objective.value(result) # Compute value using study study = VariationalStudy('study', ansatz, objective, preparation_circuit=preparation_circuit) study_val = study.value_of(ansatz.default_initial_params()) # Compute value by simulating time evolution if isinstance(hamiltonian, openfermion.DiagonalCoulombHamiltonian): half_way_hamiltonian = openfermion.DiagonalCoulombHamiltonian( one_body=hamiltonian.one_body, two_body=0.5 * hamiltonian.two_body) elif isinstance(hamiltonian, openfermion.InteractionOperator): half_way_hamiltonian = openfermion.InteractionOperator( constant=hamiltonian.constant, one_body_tensor=hamiltonian.one_body_tensor, two_body_tensor=0.5 * hamiltonian.two_body_tensor) simulation_circuit = cirq.Circuit.from_ops( simulate_trotter(qubits, half_way_hamiltonian, time=ansatz.adiabatic_evolution_time, n_steps=1, order=order, algorithm=trotter_algorithm)) final_state = (preparation_circuit + simulation_circuit).apply_unitary_effect_to_state() correct_val = openfermion.expectation(objective._hamiltonian_linear_op, final_state).real numpy.testing.assert_allclose(obj_val, study_val, atol=atol) numpy.testing.assert_allclose(obj_val, correct_val, atol=atol)
def test_trotter_ansatzes_evaluate_order_2(ansatz_factory, trotter_algorithm, hamiltonian, atol): """Check that a Trotter ansatz with two iterations and default parameters is consistent with time evolution with two Trotter steps.""" ansatz = ansatz_factory(hamiltonian, iterations=2) qubits = ansatz.qubits preparation_circuit = cirq.Circuit.from_ops( prepare_gaussian_state(qubits, openfermion.QuadraticHamiltonian( hamiltonian.one_body), occupied_orbitals=range(len(qubits) // 2))) study = HamiltonianVariationalStudy( 'study', ansatz, hamiltonian, preparation_circuit=preparation_circuit) simulator = cirq.google.XmonSimulator() # Compute value using ansatz val = study.evaluate(study.default_initial_params()) # Compute value by simulating time evolution quarter_way_hamiltonian = openfermion.DiagonalCoulombHamiltonian( one_body=hamiltonian.one_body, two_body=0.25 * hamiltonian.two_body) three_quarters_way_hamiltonian = openfermion.DiagonalCoulombHamiltonian( one_body=hamiltonian.one_body, two_body=0.75 * hamiltonian.two_body) simulation_circuit = cirq.Circuit.from_ops( simulate_trotter(qubits, quarter_way_hamiltonian, time=0.5 * ansatz.adiabatic_evolution_time, n_steps=1, order=1, algorithm=trotter_algorithm), simulate_trotter(qubits, three_quarters_way_hamiltonian, time=0.5 * ansatz.adiabatic_evolution_time, n_steps=1, order=1, algorithm=trotter_algorithm)) circuit = preparation_circuit + simulation_circuit result = simulator.simulate(circuit) final_state = result.final_state correct_val = openfermion.expectation(study._hamiltonian_linear_op, final_state).real numpy.testing.assert_allclose(val, correct_val, atol=atol)
def test_simulate_trotter_unsupported_trotter_step_raises_error(): qubits = cirq.LineQubit.range(2) control = cirq.LineQubit(-1) hamiltonian = openfermion.random_diagonal_coulomb_hamiltonian(2, seed=0) time = 1.0 class EmptyTrotterAlgorithm(TrotterAlgorithm): supported_types = {openfermion.DiagonalCoulombHamiltonian} algorithm = EmptyTrotterAlgorithm() with pytest.raises(ValueError): _ = next(simulate_trotter(qubits, hamiltonian, time, order=0, algorithm=algorithm)) with pytest.raises(ValueError): _ = next(simulate_trotter(qubits, hamiltonian, time, order=1, algorithm=algorithm)) with pytest.raises(ValueError): _ = next(simulate_trotter(qubits, hamiltonian, time, order=0, algorithm=algorithm, control_qubit=control)) with pytest.raises(ValueError): _ = next(simulate_trotter(qubits, hamiltonian, time, order=1, algorithm=algorithm, control_qubit=control))
def test_simulate_trotter_omit_final_swaps(): n_qubits = 5 qubits = cirq.LineQubit.range(n_qubits) hamiltonian = openfermion.DiagonalCoulombHamiltonian( one_body=numpy.ones((n_qubits, n_qubits)), two_body=numpy.ones((n_qubits, n_qubits))) time = 1.0 circuit_with_swaps = cirq.Circuit.from_ops( simulate_trotter( qubits, hamiltonian, time, order=0, algorithm=LINEAR_SWAP_NETWORK)) circuit_without_swaps = cirq.Circuit.from_ops( simulate_trotter( qubits, hamiltonian, time, order=0, algorithm=LINEAR_SWAP_NETWORK, omit_final_swaps=True)) assert len(circuit_without_swaps) < len(circuit_with_swaps) circuit_with_swaps = cirq.Circuit.from_ops( simulate_trotter( qubits, hamiltonian, time, order=1, n_steps=3, algorithm=SPLIT_OPERATOR), strategy=cirq.InsertStrategy.NEW) circuit_without_swaps = cirq.Circuit.from_ops( simulate_trotter( qubits, hamiltonian, time, order=1, n_steps=3, algorithm=SPLIT_OPERATOR, omit_final_swaps=True), strategy=cirq.InsertStrategy.NEW) assert len(circuit_without_swaps) < len(circuit_with_swaps) hamiltonian = lih_hamiltonian qubits = cirq.LineQubit.range(4) circuit_with_swaps = cirq.Circuit.from_ops( simulate_trotter( qubits, hamiltonian, time, order=0, algorithm=LOW_RANK)) circuit_without_swaps = cirq.Circuit.from_ops( simulate_trotter( qubits, hamiltonian, time, order=0, algorithm=LOW_RANK, omit_final_swaps=True)) assert len(circuit_without_swaps) < len(circuit_with_swaps)
def test_simulate_trotter_simulate(hamiltonian, time, initial_state, exact_state, order, n_steps, algorithm, result_fidelity): n_qubits = openfermion.count_qubits(hamiltonian) qubits = cirq.LineQubit.range(n_qubits) start_state = initial_state circuit = cirq.Circuit( simulate_trotter(qubits, hamiltonian, time, n_steps, order, algorithm)) final_state = circuit.apply_unitary_effect_to_state(start_state) correct_state = exact_state assert fidelity(final_state, correct_state) > result_fidelity # Make sure the time wasn't too small assert fidelity(final_state, start_state) < 0.95 * result_fidelity
def test_simulate_trotter_simulate_controlled( hamiltonian, time, initial_state, exact_state, order, n_steps, algorithm, result_fidelity): n_qubits = openfermion.count_qubits(hamiltonian) qubits = cirq.LineQubit.range(n_qubits) control = cirq.LineQubit(-1) zero = [1, 0] one = [0, 1] start_state = (numpy.kron(zero, initial_state) + numpy.kron(one, initial_state)) / numpy.sqrt(2) circuit = cirq.Circuit.from_ops(simulate_trotter( qubits, hamiltonian, time, n_steps, order, algorithm, control)) final_state = circuit.apply_unitary_effect_to_state(start_state) correct_state = (numpy.kron(zero, initial_state) + numpy.kron(one, exact_state)) / numpy.sqrt(2) assert fidelity(final_state, correct_state) > result_fidelity # Make sure the time wasn't too small assert fidelity(final_state, start_state) < 0.95 * result_fidelity
def kevin_lih_cirq(self): x_dim = 3 y_dim = 2 n_sites = x_dim * y_dim n_modes = 2 * n_sites # Create LiH Hamiltonian # ---------------------- bond_length = 1.45 geometry = [('Li', (0., 0., 0.)), ('H', (0., 0., bond_length))] n_active_electrons = 4 n_active_orbitals = 4 lih_hamiltonian = of.load_molecular_hamiltonian( geometry, 'sto-3g', 1, format(bond_length), n_active_electrons, n_active_orbitals) # Generate qubits n_qubits = of.count_qubits(lih_hamiltonian) qubits = cirq.LineQubit.range(n_qubits) # State preparation circuit for eigenstate of one-body term # --------------------------------------------------------- # Set the pseudo-particle orbitals to fill occupied_orbitals = range(n_qubits // 2) # State preparation circuit for eigenstate of one-body term # --------------------------------------------------------- # Set the pseudo-particle orbitals to fill up_orbitals = range(n_sites // 2) down_orbitals = range(n_sites // 2) # Create the circuit lih_state_preparation_circuit = cirq.Circuit.from_ops( ofc.prepare_gaussian_state( qubits, of.QuadraticHamiltonian(lih_hamiltonian.one_body_tensor), occupied_orbitals=(up_orbitals, down_orbitals)), strategy=cirq.InsertStrategy.EARLIEST) # Trotter simulation circuit # -------------------------- n_steps = 10 order = 0 lih_simulation_circuit = cirq.Circuit.from_ops( ofc.simulate_trotter(qubits, lih_hamiltonian, time=1.0, n_steps=n_steps, order=order, algorithm=ofc.trotter.LOW_RANK), strategy=cirq.InsertStrategy.EARLIEST) t0 = time.time() self.kevin_optimize_circuit(lih_state_preparation_circuit) self.kevin_optimize_circuit(lih_simulation_circuit) t1 = time.time() # print('Optimizing circuits took {} seconds'.format(t1 - t0)) # print(lih_state_preparation_circuit.to_text_diagram(transpose=True)) return lih_state_preparation_circuit, lih_simulation_circuit
def test_simulate_trotter_bad_order_raises_error(): qubits = cirq.LineQubit.range(2) hamiltonian = openfermion.random_diagonal_coulomb_hamiltonian(2, seed=0) time = 1.0 with pytest.raises(ValueError): _ = next(simulate_trotter(qubits, hamiltonian, time, order=-1))
print( "\nThe latter Hamiltoian mapped to a qubit Hamiltonian in through the Bravyi-kitaev transformation is:\n " ) print(h2_qubit_hamiltonian) # Circuit generation: import cirq import openfermioncirq as ofc qubits = cirq.LineQubit.range(4) circuit = cirq.Circuit( ofc.simulate_trotter(qubits, H2_molecular_hamiltonian, time=1.0, n_steps=1, order=0, algorithm=ofc.trotter.LOW_RANK, omit_final_swaps=True)) cirq.merge_single_qubit_gates_into_phased_x_z(circuit) print("\nThe corresponding quantum circuit, obtained with cirq:\n") circuit_cirq_string = circuit.to_text_diagram(use_unicode_characters=True) circuit_array = circuit_cirq_string.split('\n') for x in range(4): inf_lim = 0 + x * 125 sup_lim = inf_lim + 125 if sup_lim > 514: sup_lim = 514
def test_trotter_ansatzes_default_initial_params_iterations_2( ansatz, trotter_algorithm, order, hamiltonian, atol): """Check that a Trotter ansatz with two iterations and default parameters is consistent with time evolution with two Trotter steps.""" objective = HamiltonianObjective(hamiltonian) qubits = ansatz.qubits if isinstance(hamiltonian, openfermion.DiagonalCoulombHamiltonian): one_body = hamiltonian.one_body elif isinstance(hamiltonian, openfermion.InteractionOperator): one_body = hamiltonian.one_body_tensor if isinstance(ansatz, SwapNetworkTrotterHubbardAnsatz): occupied_orbitals = (range(len(qubits) // 4), range(len(qubits) // 4)) else: occupied_orbitals = range(len(qubits) // 2) preparation_circuit = cirq.Circuit( prepare_gaussian_state(qubits, openfermion.QuadraticHamiltonian(one_body), occupied_orbitals=occupied_orbitals)) # Compute value using ansatz circuit and objective circuit = cirq.resolve_parameters( preparation_circuit + ansatz.circuit, ansatz.param_resolver(ansatz.default_initial_params())) result = circuit.final_wavefunction( qubit_order=ansatz.qubit_permutation(qubits)) obj_val = objective.value(result) # Compute value using study study = VariationalStudy('study', ansatz, objective, preparation_circuit=preparation_circuit) study_val = study.value_of(ansatz.default_initial_params()) # Compute value by simulating time evolution if isinstance(hamiltonian, openfermion.DiagonalCoulombHamiltonian): quarter_way_hamiltonian = openfermion.DiagonalCoulombHamiltonian( one_body=hamiltonian.one_body, two_body=0.25 * hamiltonian.two_body) three_quarters_way_hamiltonian = openfermion.DiagonalCoulombHamiltonian( one_body=hamiltonian.one_body, two_body=0.75 * hamiltonian.two_body) elif isinstance(hamiltonian, openfermion.InteractionOperator): quarter_way_hamiltonian = openfermion.InteractionOperator( constant=hamiltonian.constant, one_body_tensor=hamiltonian.one_body_tensor, two_body_tensor=0.25 * hamiltonian.two_body_tensor) three_quarters_way_hamiltonian = openfermion.InteractionOperator( constant=hamiltonian.constant, one_body_tensor=hamiltonian.one_body_tensor, two_body_tensor=0.75 * hamiltonian.two_body_tensor) simulation_circuit = cirq.Circuit( simulate_trotter(qubits, quarter_way_hamiltonian, time=0.5 * ansatz.adiabatic_evolution_time, n_steps=1, order=order, algorithm=trotter_algorithm), simulate_trotter(qubits, three_quarters_way_hamiltonian, time=0.5 * ansatz.adiabatic_evolution_time, n_steps=1, order=order, algorithm=trotter_algorithm)) final_state = (preparation_circuit + simulation_circuit).final_wavefunction() correct_val = openfermion.expectation(objective._hamiltonian_linear_op, final_state).real numpy.testing.assert_allclose(obj_val, study_val, atol=atol) numpy.testing.assert_allclose(obj_val, correct_val, atol=atol)
def test_simulate_trotter_omit_final_swaps(): n_qubits = 5 qubits = cirq.LineQubit.range(n_qubits) hamiltonian = openfermion.DiagonalCoulombHamiltonian(one_body=numpy.ones( (n_qubits, n_qubits)), two_body=numpy.ones( (n_qubits, n_qubits))) time = 1.0 circuit_with_swaps = cirq.Circuit.from_ops( simulate_trotter(qubits, hamiltonian, time, order=0, algorithm=LINEAR_SWAP_NETWORK)) circuit_without_swaps = cirq.Circuit.from_ops( simulate_trotter(qubits, hamiltonian, time, order=0, algorithm=LINEAR_SWAP_NETWORK, omit_final_swaps=True)) assert (circuit_with_swaps.to_text_diagram(transpose=True).strip() == ( circuit_without_swaps.to_text_diagram(transpose=True).strip() + """ │ ×ᶠ─────────×ᶠ ×ᶠ─────────×ᶠ │ │ │ │ │ ×ᶠ───────×ᶠ ×ᶠ─────────×ᶠ │ │ │ │ │ │ │ ×ᶠ─────────×ᶠ ×ᶠ─────────×ᶠ │ │ │ │ │ ×ᶠ───────×ᶠ ×ᶠ─────────×ᶠ │ │ │ │ │ │ │ ×ᶠ─────────×ᶠ ×ᶠ─────────×ᶠ │ │ │ │ │ """).strip()) circuit_with_swaps = cirq.Circuit.from_ops( simulate_trotter(qubits, hamiltonian, time, order=1, n_steps=3, algorithm=SPLIT_OPERATOR), strategy=cirq.InsertStrategy.NEW) circuit_without_swaps = cirq.Circuit.from_ops( simulate_trotter(qubits, hamiltonian, time, order=1, n_steps=3, algorithm=SPLIT_OPERATOR, omit_final_swaps=True), strategy=cirq.InsertStrategy.NEW) assert (circuit_with_swaps.to_text_diagram(transpose=True).strip() == ( circuit_without_swaps.to_text_diagram(transpose=True).strip() + """ │ │ │ ×────────────× │ │ │ │ │ │ ×───────────× │ │ │ │ │ │ │ │ │ ×───────────× │ │ │ │ │ │ ×─────────× │ │ │ │ │ │ │ │ │ │ │ ×────────────× │ │ │ │ │ │ ×───────────× │ │ │ │ │ │ │ │ │ ×───────────× │ │ │ │ │ │ ×─────────× │ │ │ │ │ │ │ │ │ │ │ ×────────────× │ │ │ │ │ │ ×───────────× │ │ │ │ │ │ │ """).strip()) hamiltonian = random_interaction_operator(n_qubits, seed=0) circuit_with_swaps = cirq.Circuit.from_ops( simulate_trotter(qubits, hamiltonian, time, order=0, algorithm=LOW_RANK)) circuit_without_swaps = cirq.Circuit.from_ops( simulate_trotter(qubits, hamiltonian, time, order=0, algorithm=LOW_RANK, omit_final_swaps=True)) assert len(circuit_without_swaps) < len(circuit_with_swaps)