def test_partial_exchange(self): qubit_1 = 0 qubit_2 = 1 qasm_1 = QasmUtils.qasm_header(2) qasm_1 += 'x q[{}];\n'.format(qubit_1) qasm_2 = QasmUtils.qasm_header(2) qasm_2 += 'x q[{}];\n'.format(qubit_2) angles = [0, numpy.pi / 4, numpy.pi / 3, numpy.pi / 2, numpy.pi] for angle in angles: statevector_1 = QiskitSimBackend.\ statevector_from_qasm(qasm_1 + QasmUtils.partial_exchange(angle, qubit_1, qubit_2)).round(3) expected_statevector_1 = numpy.array( [0, numpy.cos(angle), -numpy.sin(angle), 0]) expected_statevector_1 = expected_statevector_1.round(3) for i in range(len(statevector_1)): self.assertEqual(statevector_1[i], expected_statevector_1[i]) statevector_2 = QiskitSimBackend.\ statevector_from_qasm(qasm_2 + QasmUtils.partial_exchange(angle, qubit_1, qubit_2)).round(3) expected_statevector_2 = numpy.array( [0, numpy.sin(angle), numpy.cos(angle), 0]) expected_statevector_2 = expected_statevector_2.round(3) for i in range(len(statevector_2)): self.assertEqual(statevector_2[i], expected_statevector_2[i])
def get_qasm(self, var_parameters): assert len(var_parameters) == 1 qasm = QasmUtils.partial_exchange(-var_parameters[0], self.qubits[0][0], self.qubits[1][0]) if {*self.qubits[0], *self.qubits[1]} != {*self.complement_qubits[0], *self.complement_qubits[1]} and \ {*self.qubits[0], *self.qubits[1]} != {*self.complement_qubits[1], *self.complement_qubits[0]}: qasm += QasmUtils.partial_exchange(-self.sign * var_parameters[0], self.complement_qubits[0][0], self.complement_qubits[1][0]) return qasm
def get_qasm(self, var_parameters): assert len(var_parameters) == self.n_var_parameters var_parameters_cycle = itertools.cycle(var_parameters) qasm = [''] for block in range(self.n_blocks): unoccupied_orbitals = list(range(self.n_electrons, self.n_orbitals)) for occupied_orbital in reversed(range(0, self.n_electrons)): if len(unoccupied_orbitals) == 0: break if occupied_orbital == self.n_electrons - 1: virtual_orbital = self.n_electrons + block else: virtual_orbital = min(unoccupied_orbitals) unoccupied_orbitals.remove(virtual_orbital) # add a phase rotation for the excited orbitals only angle = var_parameters_cycle.__next__() qasm.append('rz({}) q[{}];\n'.format(angle, virtual_orbital)) angle = var_parameters_cycle.__next__() qasm.append( QasmUtils.partial_exchange(angle, occupied_orbital, virtual_orbital)) # TODO add exchanges between the last unoccupied orbitals? return ''.join(qasm)
def double_exchange_old(angle, qubit_pair_1, qubit_pair_2): assert len(qubit_pair_1) == 2 assert len(qubit_pair_2) == 2 qasm = [''] qasm.append( QasmUtils.partial_exchange(angle, qubit_pair_1[1], qubit_pair_2[0])) qasm.append( QasmUtils.partial_exchange(-angle, qubit_pair_1[0], qubit_pair_2[1])) qasm.append('cz q[{}], q[{}];\n'.format(qubit_pair_2[0], qubit_pair_2[1])) qasm.append( QasmUtils.partial_exchange(-angle, qubit_pair_1[1], qubit_pair_2[0])) qasm.append( QasmUtils.partial_exchange(angle, qubit_pair_1[0], qubit_pair_2[1])) # corrections qasm.append('cz q[{}], q[{}];\n'.format(qubit_pair_2[0], qubit_pair_2[1])) return ''.join(qasm)
def get_qasm(self, var_parameters): var_parameters_cycle = itertools.cycle(var_parameters) count = 0 qasm = [''] # add single qubit n rotations # for qubit in range(self.n_orbitals): # qasm.append('rz ({}) q[{}];\n'.format(var_parameters_cycle.__next__(), qubit)) # count += 1 # double orbital exchanges for qubit in range(self.n_orbitals): if qubit % 4 == 0: q_0 = qubit q_1 = (qubit + 1) % self.n_orbitals q_2 = (qubit + 2) % self.n_orbitals q_3 = (qubit + 3) % self.n_orbitals q_4 = (qubit + 4) % self.n_orbitals # qasm.append(DoubleExchangeAnsatzElement.double_exchange(var_parameters_cycle.__next__(), [q_0, q_1], [q_2, q_3])) # count += 1 qasm.append( DoubleExchangeAnsatzElement.double_exchange( var_parameters_cycle.__next__(), [q_1, q_2], [q_3, q_4])) count += 1 # single orbital exchanges for qubit in range(self.n_orbitals): if qubit % 2 == 0: qasm.append( QasmUtils.partial_exchange(var_parameters_cycle.__next__(), qubit, (qubit + 1) % self.n_orbitals)) count += 1 qasm.append( QasmUtils.partial_exchange(var_parameters_cycle.__next__(), (qubit + 1) % self.n_orbitals, (qubit + 2) % self.n_orbitals)) count += 1 assert count == len(var_parameters) return ''.join(qasm)
def get_qasm(self, var_parameters): assert len(var_parameters) == 1 return QasmUtils.partial_exchange( -var_parameters[0], self.qubits[0][0], self.qubits[1][0] ) # the minus sign is important for consistence with the d_q_exc, as well obtaining the correct sign for grads...