Ejemplo n.º 1
0
def test_spin_symmetric_bogoliubov_transform(
        n_spatial_orbitals,
        conserves_particle_number,
        atol=5e-5):
    n_qubits = 2*n_spatial_orbitals
    qubits = LineQubit.range(n_qubits)

    # Initialize a random quadratic Hamiltonian
    quad_ham = random_quadratic_hamiltonian(
            n_spatial_orbitals,
            conserves_particle_number,
            real=True,
            expand_spin=True,
            seed=28166)

    # Reorder the Hamiltonian and get sparse matrix
    quad_ham = openfermion.get_quadratic_hamiltonian(
            openfermion.reorder(
                openfermion.get_fermion_operator(quad_ham),
                openfermion.up_then_down)
    )
    quad_ham_sparse = get_sparse_operator(quad_ham)

    # Compute the orbital energies and transformation_matrix
    up_orbital_energies, _, _ = (
            quad_ham.diagonalizing_bogoliubov_transform(spin_sector=0))
    down_orbital_energies, _, _ = (
            quad_ham.diagonalizing_bogoliubov_transform(spin_sector=1))
    _, transformation_matrix, _ = (
            quad_ham.diagonalizing_bogoliubov_transform())

    # Pick some orbitals to occupy
    up_orbitals = list(range(2))
    down_orbitals = [0, 2, 3]
    energy = sum(up_orbital_energies[up_orbitals]) + sum(
            down_orbital_energies[down_orbitals]) + quad_ham.constant

    # Construct initial state
    initial_state = (
            sum(2**(n_qubits - 1 - int(i)) for i in up_orbitals)
            + sum(2**(n_qubits - 1 - int(i+n_spatial_orbitals))
                  for i in down_orbitals)
    )

    # Apply the circuit
    circuit = cirq.Circuit.from_ops(
            bogoliubov_transform(
                qubits, transformation_matrix, initial_state=initial_state))
    state = circuit.apply_unitary_effect_to_state(initial_state)

    # Check that the result is an eigenstate with the correct eigenvalue
    numpy.testing.assert_allclose(
            quad_ham_sparse.dot(state), energy * state, atol=atol)
Ejemplo n.º 2
0
def test_prepare_gaussian_state_with_spin_symmetry(n_spatial_orbitals,
                                                   conserves_particle_number,
                                                   occupied_orbitals,
                                                   initial_state,
                                                   atol=1e-5):

    n_qubits = 2 * n_spatial_orbitals
    qubits = LineQubit.range(n_qubits)

    # Initialize a random quadratic Hamiltonian
    quad_ham = random_quadratic_hamiltonian(
            n_spatial_orbitals,
            conserves_particle_number,
            real=True,
            expand_spin=True,
            seed=639)

    # Reorder the Hamiltonian and get sparse matrix
    quad_ham = openfermion.get_quadratic_hamiltonian(
            openfermion.reorder(
                openfermion.get_fermion_operator(quad_ham),
                openfermion.up_then_down)
    )
    quad_ham_sparse = get_sparse_operator(quad_ham)

    # Compute the energy of the desired state
    energy = 0.0
    for spin_sector in range(2):
        orbital_energies, _, _ = (
            quad_ham.diagonalizing_bogoliubov_transform(
                spin_sector=spin_sector)
        )
        energy += sum(orbital_energies[i]
                      for i in occupied_orbitals[spin_sector])
    energy += quad_ham.constant

    # Get the state using a circuit simulation
    circuit = cirq.Circuit.from_ops(
            prepare_gaussian_state(
                qubits, quad_ham, occupied_orbitals,
                initial_state=initial_state))

    if isinstance(initial_state, list):
        initial_state = sum(1 << (n_qubits - 1 - i) for i in initial_state)
    state = circuit.apply_unitary_effect_to_state(initial_state)

    # Check that the result is an eigenstate with the correct eigenvalue
    numpy.testing.assert_allclose(
            quad_ham_sparse.dot(state), energy * state, atol=atol)