Esempio n. 1
0
def test_reorder_fermionic_modes():
    ref_op = get_interaction_operator(
        FermionOperator(
            """
    0.0 [] +
    1.0 [0^ 0] +
    1.0 [1^ 1] +
    1.0 [0^ 1^ 2 3] +
    1.0 [1^ 1^ 2 2]
    """
        )
    )
    reordered_op = get_interaction_operator(
        FermionOperator(
            """
    0.0 [] +
    1.0 [0^ 0] +
    1.0 [2^ 2] +
    1.0 [0^ 2^ 1 3] +
    1.0 [2^ 2^ 1 1]
    """
        )
    )
    spin_block_op = reorder_fermionic_modes(ref_op, [0, 2, 1, 3])
    assert reordered_op == spin_block_op
    spin_block_qubit_op = jordan_wigner(spin_block_op)
    interleaved_qubit_op = jordan_wigner(ref_op)
    spin_block_spectrum = eigenspectrum(spin_block_qubit_op)
    interleaved_spectrum = eigenspectrum(interleaved_qubit_op)
    assert np.allclose(spin_block_spectrum, interleaved_spectrum)
Esempio n. 2
0
def OptimizeVQEOpenFermion(u,v,t):
    '''
    Function to optimize a VQE for the hamiltonian and ansatz we are looking at by using the built in optimizer in openfermion.

    Parameters
    ----------
    U : float
        One the parameters in the Hamiltonian, see report for description.
    V : float
        One the parameters in the Hamiltonian, see report for description.
    t : float
        One the parameters in the Hamiltonian, see report for description.

    Returns
    -------
    List
        List containing 4 values: 1) theta at minimum, 2) phi at minimum, 3) energy at minimum, 4) Error in the energy w.r.t. the exact ground state energy.

    '''
    ansatz = Ansatz()
    hamiltonian = Hamiltonian(u,v,t)
    
    objective = ofc.HamiltonianObjective(hamiltonian)
    
    study = ofc.VariationalStudy(
        name='TritonToy',
        ansatz=ansatz,
        objective=objective)
        
    optimization_params = OptimizationParams(
        algorithm=COBYLA,
        initial_guess=[1,1])
    result = study.optimize(optimization_params)
        
    minimum_energy = result.optimal_value + (8*t + 3*u/4 + v/16)
    minimum_energy_error = result.optimal_value - np.amin(of.eigenspectrum(hamiltonian))
    
    minimum_theta = result.optimal_parameters[0]
    minimum_phi = result.optimal_parameters[1]
    
    text = "Minimum E = {}, at theta = {} and phi = {} error = {}.".format(minimum_energy, minimum_theta, minimum_phi, minimum_energy_error)   
    print(text)
    
    return [minimum_theta, minimum_phi, minimum_energy, minimum_energy_error]
Esempio n. 3
0
def test_operators_initialization(coefficient: float):
    # 1. Let's create some basic operator

    operator = FermionOperator('2^ 1 3 7^', coefficient)
    alternative_operator = coefficient * FermionOperator(((2, 1), (1, 0), (3, 0), (6, 1)))

    sum_of_operators = operator + alternative_operator

    identity = FermionOperator('')
    zero = FermionOperator()

    # print(f'Fermion operator: {operator}; the terms are {list(operator.terms.keys())[0]}')
    print(f'Fermion operator: {operator}; the flattened terms are {operator.flattened_terms}')
    print(f'Alternative fermion operator: {alternative_operator}')
    print(f'Sum fermion operator: {sum_of_operators}; the terms are {sum_of_operators.terms}')
    # print(operator == alternative_operator)
    print(f'Identity operator: {identity}')
    print(f'Zero operator: {zero}')

    # 2. Checking operator combinations

    lhs_operator = FermionOperator('17^')
    rhs_operator = FermionOperator('19^')

    print(describe_result(lhs_operator, rhs_operator, lambda lhs, rhs: lhs * rhs, '*'))
    print(describe_result(lhs_operator, lhs_operator, lambda lhs, rhs: lhs * rhs, '*'))

    print(describe_result(lhs_operator, rhs_operator, lambda lhs, rhs: lhs + rhs, '+'))
    print(describe_result(lhs_operator, 5, lambda lhs, rhs: lhs ** rhs, '^'))

    # print(describe_result(lhs_operator * rhs_operator, lhs_operator, lambda lhs, rhs: lhs / rhs, '/')) # Throws an exception

    # 3. Use some auxiliary functions

    print(f'Operator {lhs_operator ** 5} occupies {count_qubits(lhs_operator)} qubits')
    print(f'Operator {rhs_operator ** 2} occupies {count_qubits(rhs_operator)} qubits')
    print(f'Operator {operator} occupies {count_qubits(operator)} qubits')

    print(f'Operator {operator} is {"not " if not operator.is_normal_ordered() else ""}normal ordered')
    print(f'Operator {(lhs_operator + rhs_operator)} is {"not " if not (lhs_operator + rhs_operator).is_normal_ordered() else ""}normal ordered')
    print(f'Operator {(lhs_operator * rhs_operator)} is {"not " if not (lhs_operator * rhs_operator).is_normal_ordered() else ""}normal ordered')
    print(f'Operator {(rhs_operator * lhs_operator)} is {"not " if not (rhs_operator * lhs_operator).is_normal_ordered() else ""}normal ordered')

    print(f'Commutator of {lhs_operator} and {rhs_operator} is {commutator(lhs_operator, rhs_operator)}')

    # 4. See qubit operators

    operator = QubitOperator('X1 Z3', coefficient) + QubitOperator('X20', coefficient - 1)
    print(f'Operator {operator} occupies {count_qubits(operator)} qubits')

    # 4. Perform transformations from fermion to qubit operators

    fermion_operator = FermionOperator_('5^', 0.1 + 0.2j)
    fermion_operator += hermitian_conjugated(fermion_operator)
    jw_operator = jordan_wigner(fermion_operator)
    bk_operator = bravyi_kitaev(fermion_operator)

    print()
    print('Source fermion operator:')
    print(fermion_operator)
    print()
    print('Source fermion operator with conjugate:')
    print(fermion_operator)
    print()
    print('Source fermion operator with conjugate passed through Jordan-Wigner transformation:')
    print(jw_operator)
    print()
    print('Eigenspectrum of the obtained operator:')
    print(eigenspectrum(jw_operator))
    print()
    print('Reversed:')
    print(reverse_jordan_wigner(jw_operator))
    print()
    print('Source fermion operator with conjugate passed through Bravyi-Kitaev transformation:')
    print(bk_operator)
    print()
    print('Eigenspectrum of the obtained operator:')
    print(eigenspectrum(bk_operator))
    print()