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)
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]
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()