Exemple #1
0
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_default_initial_params_iterations_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)
    objective = HamiltonianObjective(hamiltonian)

    qubits = ansatz.qubits

    preparation_circuit = cirq.Circuit.from_ops(
            prepare_gaussian_state(
                qubits,
                openfermion.QuadraticHamiltonian(hamiltonian.one_body),
                occupied_orbitals=range(len(qubits) // 2))
    )

    simulator = cirq.google.XmonSimulator()

    # Compute value using ansatz circuit and objective
    result = simulator.simulate(
            preparation_circuit + ansatz.circuit,
            param_resolver=
                ansatz.param_resolver(ansatz.default_initial_params()),
            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
    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)
    )
    result = simulator.simulate(preparation_circuit + simulation_circuit)
    final_state = result.final_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_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)