def test_double_exchange_extended(self): angles = [-0.2, 0.2] for angle in angles: qasm = [''] qasm.append(QasmUtils.qasm_header(6)) # qasm_1.append('x q[3];\n') qasm.append('h q[4];\n') qasm.append('x q[2];\n') qasm.append('x q[0];\n') qasm.append( DFExc([0, 2], [3, 5], rescaled_parameter=True, parity_dependence=True).get_qasm([angle])) statevector = QiskitSimBackend.statevector_from_qasm(''.join(qasm)) self.assertEqual(statevector[56].real.round(5), -statevector[40].real.round(5)) qasm = [''] qasm.append(QasmUtils.qasm_header(6)) # qasm_1.append('x q[3];\n') qasm.append('h q[4];\n') qasm.append('x q[2];\n') qasm.append('x q[0];\n') qasm.append( DFExc([0, 2], [3, 5], rescaled_parameter=True).get_qasm([angle])) statevector = QiskitSimBackend.statevector_from_qasm(''.join(qasm)) self.assertEqual(statevector[56].real.round(5), statevector[40].real.round(5))
def get_statevector(self, ansatz, var_parameters, init_state_qasm=None): assert len(var_parameters) == len(ansatz) if self.var_parameters is not None and var_parameters == self.var_parameters: # this condition is not neccessarily sufficient assert self.sparse_statevector is not None else: if self.init_sparse_statevector is not None: sparse_statevector = self.init_sparse_statevector.transpose( ).conj() else: if init_state_qasm is not None: # TODO check qasm = QasmUtils.qasm_header( self.n_qubits) + init_state_qasm statevector = QiskitSimBackend.statevector_from_qasm(qasm) else: statevector = self.hf_statevector() sparse_statevector = scipy.sparse.csr_matrix( statevector).transpose().conj() for i, excitation in enumerate(ansatz): parameter = var_parameters[i] excitation_matrices = self.get_ansatz_element_excitations_matrices( excitation, parameter) excitation_matrix = self.identity for exc_matrix in excitation_matrices[:: -1]: # the first should be the right most (confusing) excitation_matrix *= exc_matrix sparse_statevector = excitation_matrix.dot(sparse_statevector) self.sparse_statevector = sparse_statevector.transpose().conj() self.var_parameters = var_parameters return self.sparse_statevector
def __init__(self, q_system, excited_state=0): self.q_system = q_system H_sparse_matrix = get_sparse_operator(q_system.jw_qubit_ham) if excited_state > 0: # H_sparse_matrix = backend. ham_sparse_matrix(q_system, excited_state=excited_state) H_sparse_matrix = get_sparse_operator(q_system.jw_qubit_ham) if excited_state > 0: H_lower_state_terms = q_system.H_lower_state_terms assert H_lower_state_terms is not None assert len(H_lower_state_terms) >= excited_state for i in range(excited_state): term = H_lower_state_terms[i] state = term[1] statevector = QiskitSimBackend.statevector_from_ansatz(state.ansatz_elements, state.parameters, state.n_qubits, state.n_electrons, init_state_qasm=state.init_state_qasm) # add the outer product of the lower lying state to the Hamiltonian H_sparse_matrix += scipy.sparse.csr_matrix(term[0] * numpy.outer(statevector, statevector)) if H_sparse_matrix.data.nbytes > config.matrix_size_threshold: # decrease the size of the matrix. Typically it will have a lot of insignificant very small (~1e-19) # elements that do not contribute to the accuracy but inflate the size of the matrix (~200 MB for Lih) logging.warning('Hamiltonian sparse matrix accuracy decrease!!!') H_sparse_matrix = scipy.sparse.csr_matrix(H_sparse_matrix.todense().round(config.floating_point_accuracy_digits)) super(GlobalCache, self).__init__(H_sparse_matrix=H_sparse_matrix, n_qubits=q_system.n_qubits, n_electrons=q_system.n_electrons, commutators_sparse_matrices_dict=None)
def test_energies(self): molecule = q_system.H2() molecule_data = openfermion.hamiltonians.MolecularData( geometry=molecule.get_geometry({'distance': 0.735}), basis='sto-3g', multiplicity=molecule.multiplicity, charge=molecule.charge) molecule_psi4 = openfermionpsi4.run_psi4(molecule_data) # Get a qubit representation of the molecule hamiltonian molecule_ham = molecule_psi4.get_molecular_hamiltonian() fermion_ham = openfermion.transforms.get_fermion_operator(molecule_ham) h = openfermion.transforms.jordan_wigner(fermion_ham) ansatz_elements = UCCSD(molecule.n_orbitals, molecule.n_electrons).get_excitations() var_parameters = numpy.zeros(len(ansatz_elements)) var_parameters[-1] = 0.11 energy_qiskit_sim = QiskitSimBackend.ham_expectation_value( h, ansatz_elements, var_parameters, molecule.n_orbitals, molecule.n_electrons)[0].real energy_matrix_mult = ExcStateSim.get_energy( h, ansatz_elements, var_parameters, molecule.n_orbitals, molecule.n_electrons)[0].real self.assertEqual(round(energy_qiskit_sim, 3), round(energy_matrix_mult, 3))
def test_pauli_gates_circuit_statevector(self): qubit_operator = openfermion.QubitOperator('X0 Y1') qasm_circuit = QasmUtils.qasm_header(2) qasm_circuit += QasmUtils.pauli_word_qasm(qubit_operator) statevector = QiskitSimBackend.statevector_from_qasm(qasm_circuit) expected_statevector = numpy.array([0, 0, 0, 1j]) self.assertEqual(len(expected_statevector), len(statevector)) for i in range(len(statevector)): self.assertEqual(statevector[i], expected_statevector[i])
def test_controlled_y_gate_1(self): control = 0 target = 1 # case 1 qasm = QasmUtils.qasm_header(2) qasm += 'x q[{}];\n'.format(control) qasm += QasmUtils.controlled_y_rotation(numpy.pi / 2, control, target) statevector = QiskitSimBackend.statevector_from_qasm(qasm).round(3) expected_statevector = numpy.array([0, 1, 0, 1]) / numpy.sqrt(2) expected_statevector = expected_statevector.round(3) for i in range(len(statevector)): self.assertEqual(statevector[i], expected_statevector[i])
def test_exponent_statevector(self): exp_operator = ((0, 'X'), (1, 'Z'), (2, 'Z')) qasm = QasmUtils.qasm_header(3) qasm += QasmUtils.exponent_qasm(exp_operator, -numpy.pi / 2) statevector = QiskitSimBackend.statevector_from_qasm(qasm) expected_statevector = numpy.zeros(8) expected_statevector[1] = 1 self.assertEqual(len(expected_statevector), len(statevector)) for i in range(len(statevector)): self.assertEqual(statevector[i].round(3), expected_statevector[i].round(3))
def test_hf_states(self): n_qubits = 5 n_electrons = 3 qasm = QasmUtils.qasm_header(n_qubits) qasm += QasmUtils.hf_state(n_electrons) qasm += QasmUtils.reverse_qubits_qasm(n_qubits) qiskit_statevector = QiskitSimBackend.statevector_from_qasm(qasm) sparse_statevector = scipy.sparse.csr_matrix( openfermion.utils.jw_hartree_fock_state(n_electrons, n_qubits)) array_statevector = numpy.array(sparse_statevector.todense())[0] for i in range(len(qiskit_statevector)): self.assertEqual(qiskit_statevector[i], array_statevector[i])
def test_exponent_statevectors(self): qubit_operators = [] # only symetric qubit operators will works, because qiskit and openfermion use different qubit orderings qubit_operators.append(openfermion.QubitOperator('Z0 Y1 Z2')) qubit_operators.append(openfermion.QubitOperator('X0 Y1 X2')) qubit_operators.append(openfermion.QubitOperator('Y0 X1 X2 Y3')) for qubit_operator in qubit_operators: qubit_operator_tuple = list(qubit_operator.terms.keys())[0] n_qubits = len(qubit_operator_tuple) for angle in range(10): angle = 2 * numpy.pi / 10 # <<< create a statevector using QiskitSimulation.get_exponent_qasm >>> qasm = QasmUtils.qasm_header(n_qubits) qasm += QasmUtils.exponent_qasm(qubit_operator_tuple, angle) qiskit_statevector = QiskitSimBackend.statevector_from_qasm( qasm) qiskit_statevector = qiskit_statevector * numpy.exp( 1j * angle) # correct for a global phase qiskit_statevector = qiskit_statevector.round( 2) # round for the purpose of testing # <<< create a statevector using MatrixCalculation.get_qubit_operator_exponent_matrix >>> exp_matrix = MatrixUtils.get_excitation_matrix( 1j * qubit_operator, n_qubits, angle).todense() # prepare initial statevector corresponding to state |0> array_statevector = numpy.zeros(2**n_qubits) array_statevector[0] = 1 # update statevector array_statevector = numpy.array( exp_matrix.dot(array_statevector))[0].round( 2) # round for the purpose of testing # <<<< compare both state vectors >>>> self.assertEqual(len(array_statevector), len(qiskit_statevector)) # check the components of the two vectors are equal for i in range(len(qiskit_statevector)): self.assertEqual(qiskit_statevector[i], array_statevector[i])
excitation = SpinCompDFExc([0, 2], [3, 5], n_qubits) # excitation = SpinCompDFExc([0, 1], [2, 3], n_qubits) excitation_gen_matrices = [get_sparse_operator(excitation.excitations_generators[0], n_qubits), get_sparse_operator(excitation.excitations_generators[1], n_qubits)] excitation_matrix_1 = scipy.sparse.linalg.expm(parameter * excitation_gen_matrices[1]) *\ scipy.sparse.linalg.expm(parameter * excitation_gen_matrices[0]) excitation_matrix_2 = identity for exc_gen_mat in excitation_gen_matrices[::-1]: term1 = numpy.sin(parameter)*exc_gen_mat term2 = (1 - numpy.cos(parameter)) * exc_gen_mat*exc_gen_mat excitation_matrix_2 *= identity + term1 + term2 # excitation_matrix_0 = get_circuit_matrix(QasmUtils.qasm_header(n_qubits) + SpinCompDFExc([5, 3], [2, 0], n_qubits).get_qasm([parameter])) statevector_0 = QiskitSimBackend.statevector_from_ansatz([excitation], [parameter], n_qubits, n_electrons).round(10) statevector_1 = excitation_matrix_1.dot(scipy.sparse.csr_matrix(hf_statevector).transpose().conj()).\ transpose().conj().todense().round(10) statevector_2 = excitation_matrix_2.dot(scipy.sparse.csr_matrix(hf_statevector).transpose().conj()).\ transpose().conj().todense().round(10) exc_gen_sparse_matrices_dict = {str(excitation.excitations_generators): excitation_gen_matrices} sqr_exc_gen_sparse_matrices_dict = {str(excitation.excitations_generators): [x*x for x in excitation_gen_matrices]} global_cache = Cache(None, 6, 3, exc_gen_sparse_matrices_dict=exc_gen_sparse_matrices_dict, sqr_exc_gen_sparse_matrices_dict=sqr_exc_gen_sparse_matrices_dict) statevector_3 = numpy.array(global_cache.get_statevector([excitation], [parameter]).todense()) print(statevector_0) print(statevector_1)