Beispiel #1
0
 def value(
     self, circuit_output: Union[cirq.TrialResult,
                                 cirq.SimulationTrialResult, numpy.ndarray]
 ) -> float:
     """The evaluation function for a circuit output."""
     if isinstance(circuit_output, numpy.ndarray):
         return openfermion.expectation(self._hamiltonian_linear_op,
                                        circuit_output).real
     elif isinstance(circuit_output, cirq.SimulationTrialResult):
         return openfermion.expectation(self._hamiltonian_linear_op,
                                        circuit_output.final_state).real
     else:
         # TODO implement this
         raise NotImplementedError(
             "Don't know how to compute the value of a TrialResult that "
             "is not an SimulationTrialResult.")
Beispiel #2
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)
Beispiel #3
0
 def value(
     self, trial_result: Union[cirq.TrialResult,
                               cirq.google.XmonSimulateTrialResult]
 ) -> float:
     # TODO implement support for TrialResult (compute energy given
     #      measurements)
     if not isinstance(trial_result, cirq.google.XmonSimulateTrialResult):
         raise NotImplementedError(
             "Don't know how to compute the value of a TrialResult that "
             "is not an XmonSimulateTrialResult.")
     return openfermion.expectation(self._hamiltonian_linear_op,
                                    trial_result.final_state).real
Beispiel #4
0
def exact_diagonalize(ham_qop, n_site, jobname=None):
    from os.path import isfile
    if jobname and (isfile(jobname + '_list_energy.npy')
                    and isfile(jobname + '_list_number.npy')
                    and isfile(jobname + '_list_2S.npy')
                    and isfile(jobname + '_eigvec.npy')):
        print(
            "Load results of exact diagonalize (jobname='{}')".format(jobname))
        list_energy = np.load(jobname + '_list_energy.npy')
        list_number = np.load(jobname + '_list_number.npy')
        list_2S = np.load(jobname + '_list_2S.npy')
        eigvec = np.load(jobname + '_eigvec.npy')
        return Result(list_energy, list_number, list_2S, eigvec)

    op_number_tensor = openfermion.get_sparse_operator(_get_op_number(n_site))
    op_S2_tensor = openfermion.get_sparse_operator(_get_op_S2(n_site))

    ham_tensor = openfermion.get_sparse_operator(ham_qop)
    list_energy, eigvec = np.linalg.eigh(ham_tensor.todense())

    nstate = len(list_energy)
    list_number = np.empty(nstate, int)
    list_2S = np.empty(nstate, float)

    for istate in range(nstate):
        list_number[istate] = round(
            openfermion.expectation(op_number_tensor, eigvec[:, istate]).real)
        list_2S[istate] = round(
            (openfermion.expectation(op_S2_tensor, eigvec[:, istate]).real +
             0.25)**0.5 * 2 - 1)

    if jobname:
        print(
            "Save results of exact diagonalize (jobname='{}')".format(jobname))
        np.save(jobname + '_list_energy.npy', list_energy)
        np.save(jobname + '_list_number.npy', list_number)
        np.save(jobname + '_list_2S.npy', list_2S)
        np.save(jobname + '_eigvec.npy', np.asarray(eigvec))

    return Result(list_energy, list_number, list_2S, np.asarray(eigvec))
Beispiel #5
0
def test_expectation_values_paulisum(qubitop, state_binary):
    """Test PauliSum and QubitOperator expectation value."""
    n_qubits = openfermion.count_qubits(qubitop)
    state = numpy.zeros(2**n_qubits, dtype='complex64')
    state[int(state_binary, 2)] = 1.0
    qubit_map = {cirq.LineQubit(i): i for i in range(n_qubits)}

    pauli_str = qubit_operator_to_pauli_sum(qubitop, list(qubit_map.keys()))
    op_mat = openfermion.get_sparse_operator(qubitop, n_qubits)

    expct_qop = openfermion.expectation(op_mat, state)
    expct_pauli = pauli_str.expectation_from_state_vector(state, qubit_map)

    numpy.testing.assert_allclose(expct_qop, expct_pauli)
Beispiel #6
0
def test_hamiltonian_objective_value():

    obj = HamiltonianObjective(test_hamiltonian)
    obj_linear_op = HamiltonianObjective(test_hamiltonian, use_linear_op=True)
    hamiltonian_sparse = openfermion.get_sparse_operator(test_hamiltonian)

    simulator = cirq.google.XmonSimulator()
    numpy.random.seed(10581)
    result = simulator.simulate(cirq.testing.random_circuit(4, 5, 0.8))
    correct_val = openfermion.expectation(hamiltonian_sparse,
                                          result.final_state)

    numpy.testing.assert_allclose(
            obj.value(result), correct_val, atol=1e-5)
    numpy.testing.assert_allclose(
            obj_linear_op.value(result), correct_val, 1e-5)
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)
Beispiel #8
0
def estimate_correlation(ham_qop,
                         state,
                         dt,
                         max_trotter_step,
                         outputter,
                         savefilename=None):
    const_term = ham_qop.terms[()]
    n_site = openfermion.count_qubits(ham_qop)
    outputter.n_qubit = n_site
    outputter.n_trott_step = max_trotter_step

    #circuit_time_evo = qulacs.QuantumCircuit(n_site)
    #trotter.trotter_step_2nd_order(circuit_time_evo, -1j * dt * ham_qop)
    trotterstep = trotter.TrotterStep(n_site, -1j * dt * ham_qop)
    circuit_time_evo = trotterstep._circuit
    outputter.ngate = trotterstep.count_gates()
    print(trotterstep)
    print(circuit_time_evo)

    ham_tensor = openfermion.get_sparse_operator(ham_qop)

    state_vec_exact = convert_state_vector(n_site, state.get_vector())

    steps = np.arange(max_trotter_step + 1)

    save_state_vec_exact = np.empty((len(steps), 2**n_site), np.complex128)
    save_state_vec_trotter = np.empty((len(steps), 2**n_site), np.complex128)
    save_time_energy_fidelity = np.empty((len(steps), 4), float)
    save_time_energy_fidelity[:, 0] = steps * dt

    time_sim = 0

    for istep, n_trotter_step in enumerate(steps):
        state_vec_trotter = convert_state_vector(n_site, state.get_vector())

        # calculate energy and fidelity
        energy_exact = openfermion.expectation(ham_tensor, state_vec_exact)
        energy_trotter = openfermion.expectation(ham_tensor, state_vec_trotter)
        fidelity = np.abs(
            np.dot(np.conjugate(state_vec_exact), state_vec_trotter))**2

        # save
        save_state_vec_exact[istep] = state_vec_exact
        save_state_vec_trotter[istep] = state_vec_trotter
        save_time_energy_fidelity[istep, 1] = energy_exact.real
        save_time_energy_fidelity[istep, 2] = energy_trotter.real
        save_time_energy_fidelity[istep, 3] = fidelity

        # time propergation
        time_bgn = time()
        circuit_time_evo.update_quantum_state(state)
        time_sim += time() - time_bgn
        state_vec_exact = scipy.sparse.linalg.expm_multiply(
            -1j * dt * ham_tensor, state_vec_exact)

    corr_exact = np.dot(save_state_vec_exact[0], save_state_vec_exact.T)
    corr_trotter = np.dot(
        save_state_vec_trotter[0],
        save_state_vec_trotter.T)  # * np.exp(-1j * dt * steps * const_term)

    outputter.time_sim = time_sim

    if savefilename:
        np.save(savefilename + '_ham_tensor', ham_tensor.todense())
        np.save(savefilename + '_corr_exact.npy', corr_exact)
        np.save(savefilename + '_corr_trotter.npy', corr_trotter)
        np.save(savefilename + '_state_vec_exact.npy', save_state_vec_exact)
        np.save(savefilename + '_state_vec_trotter.npy',
                save_state_vec_trotter)
        np.save(savefilename + '_time_energy_fidelity.npy',
                save_time_energy_fidelity)

    return EstimateCorrelationResult(corr_exact, corr_trotter,
                                     save_state_vec_exact,
                                     save_state_vec_trotter,
                                     save_time_energy_fidelity)
Beispiel #9
0
def estimate_corr_new__(ham,
                        dt,
                        max_trotter_step,
                        outputter,
                        savefilename=None):
    n_site = openfermion.count_qubits(ham.ham_qop)
    #state = ham.state
    #state_vec_exact = convert_state_vector(n_site, state.get_vector())

    steps = np.arange(max_trotter_step + 1)

    save_state_vec_exact = np.empty((len(steps), 2**n_site), np.complex128)
    save_state_vec_trotter = np.empty((len(steps), 2**n_site), np.complex128)
    save_time_energy_fidelity = np.empty((len(steps), 4), float)
    save_time_energy_fidelity[:, 0] = steps * dt

    time_sim = 0

    ham.init_propagate(dt)
    ham_tensor = openfermion.get_sparse_operator(ham.ham_qop)

    for istep, n_trotter_step in enumerate(steps):
        state_vec_trotter = convert_state_vector(n_site,
                                                 ham.state.get_vector())

        # calculate energy and fidelity
        energy_exact = openfermion.expectation(ham_tensor, state_vec_exact)
        energy_trotter = openfermion.expectation(ham_tensor, state_vec_trotter)
        fidelity = np.abs(
            np.dot(np.conjugate(state_vec_exact), state_vec_trotter))**2

        # save
        save_state_vec_exact[istep] = state_vec_exact
        save_state_vec_trotter[istep] = state_vec_trotter
        save_time_energy_fidelity[istep, 1] = energy_exact.real
        save_time_energy_fidelity[istep, 2] = energy_trotter.real
        save_time_energy_fidelity[istep, 3] = fidelity

        # time propergation
        time_bgn = time()
        ham.propagate()
        time_sim += time() - time_bgn
        state_vec_exact = scipy.sparse.linalg.expm_multiply(
            -1j * dt * ham_tensor, state_vec_exact)

    corr_exact = np.dot(save_state_vec_exact[0], save_state_vec_exact.T)
    corr_trotter = np.dot(save_state_vec_trotter[0], save_state_vec_trotter.T)

    outputter.n_qubit = n_site
    outputter.n_trott_step = max_trotter_step
    outputter.ngate = ham.trotterstep.count_gates()
    outputter.time_sim = time_sim

    if savefilename:
        np.save(savefilename + '_ham_tensor', ham_tensor.todense())
        np.save(savefilename + '_corr_exact.npy', corr_exact)
        np.save(savefilename + '_corr_trotter.npy', corr_trotter)
        np.save(savefilename + '_state_vec_exact.npy', save_state_vec_exact)
        np.save(savefilename + '_state_vec_trotter.npy',
                save_state_vec_trotter)
        np.save(savefilename + '_time_energy_fidelity.npy',
                save_time_energy_fidelity)

    return EstimateCorrelationResult(corr_exact, corr_trotter,
                                     save_state_vec_exact,
                                     save_state_vec_trotter,
                                     save_time_energy_fidelity)
Beispiel #10
0
 def get_energy(self):
     return openfermion.expectation(self.ham_tensor, self.state_vec).real
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)