def test_approx_random_mixed_unitary_channel_2q(self): # run without raising any error noise1 = UnitaryGate(random_unitary(4, seed=123)) noise2 = UnitaryGate(random_unitary(4, seed=456)) noise = QuantumError([(noise1, 0.7), (noise2, 0.3)]) for opstr in ['pauli', 'reset']: approximate_quantum_error(noise, operator_string=opstr)
def check_two_qubit_weyl_decomposition(self, target_unitary, tolerance=1.e-7): """Check TwoQubitWeylDecomposition() works for a given operator""" with self.subTest(unitary=target_unitary): decomp = TwoQubitWeylDecomposition(target_unitary) q = QuantumRegister(2) decomp_circuit = QuantumCircuit(q) decomp_circuit.append(UnitaryGate(decomp.K2r), [q[0]]) decomp_circuit.append(UnitaryGate(decomp.K2l), [q[1]]) decomp_circuit.append( UnitaryGate(Ud(decomp.a, decomp.b, decomp.c)), [q[0], q[1]]) decomp_circuit.append(UnitaryGate(decomp.K1r), [q[0]]) decomp_circuit.append(UnitaryGate(decomp.K1l), [q[1]]) result = execute(decomp_circuit, UnitarySimulatorPy()).result() decomp_unitary = result.get_unitary() target_unitary *= la.det(target_unitary)**(-0.25) decomp_unitary *= la.det(decomp_unitary)**(-0.25) maxdists = [ np.max(np.abs(target_unitary + phase * decomp_unitary)) for phase in [1, 1j, -1, -1j] ] maxdist = np.min(maxdists) self.assertTrue( np.abs(maxdist) < tolerance, "Worst distance {}".format(maxdist))
def test_open_controlled_unitary_z(self, num_ctrl_qubits, ctrl_state): """Test that UnitaryGate with control returns params.""" umat = np.array([[1, 0], [0, -1]]) ugate = UnitaryGate(umat) cugate = ugate.control(num_ctrl_qubits, ctrl_state=ctrl_state) ref_mat = _compute_control_matrix(umat, num_ctrl_qubits, ctrl_state=ctrl_state) self.assertEqual(Operator(cugate), Operator(ref_mat))
def inverse(self): inverse = UnitaryGate( np.diag( [1.0, 1.0, np.exp(-1.0j * self.params[0]), np.exp(-1.0j * self.params[0])] ) ) inverse.name = "p" return inverse
def test_controlled_controlled_unitary(self): """Test that global phase in iso decomposition of unitary is handled.""" umat = np.array([[1, 0], [0, -1]]) ugate = UnitaryGate(umat) cugate = ugate.control() ccugate = cugate.control() ccugate2 = ugate.control(2) ref_mat = _compute_control_matrix(umat, 2) self.assertTrue(Operator(ccugate2).equiv(Operator(ref_mat))) self.assertTrue(Operator(ccugate).equiv(Operator(ccugate2)))
def trainSuperPosition(self): """ This function creates a superposition of dataset as described in the paper. """ for i in range(self.m): pR = QuantumRegister(self.n_total, "p") uR = QuantumRegister(2, "u") mR = QuantumRegister(self.n_total, "m") circuit = QuantumCircuit(pR, uR, mR, name="pattern" + str(i + 1)) for j in range(self.n_total): if self.pattern[i][j] == 0: circuit.initialize(self.zero_state, pR[j]) else: circuit.initialize(self.one_state, pR[j]) circuit.ccx(pR[j], uR[1], mR[j]) for j in range(self.n_total): circuit.cx(pR[j], mR[j]) circuit.x(mR[j]) circuit.mcx(mR, uR[0]) k = i + 1 data = np.array([[np.sqrt((k - 1) / k), np.sqrt(1 / k)], [-np.sqrt(1 / k), np.sqrt((k - 1) / k)]]) gate = UnitaryGate(data=data) gate = gate.control(1, ctrl_state="1") circuit.append(gate, [uR[0], uR[1]], []) circuit.mcx(mR, uR[0]) for j in range(self.n_total): circuit.x(mR[j]) circuit.cx(pR[j], mR[j]) for j in range(self.n_total): circuit.ccx(pR[j], uR[1], mR[j]) """circuit.draw(output = "mpl") plt.tight_layout() plt.show()""" self.main_circuit.append( circuit.to_instruction(), self.main_pR[:self.n_total] + self.main_uR[:2] + self.main_mR[:self.n_total]) return self.main_circuit
def test_ideal(self): """Test ideal gates are identified correctly.""" self.assertTrue(QuantumError(IGate()).ideal()) self.assertTrue(QuantumError(UnitaryGate(np.eye(2))).ideal()) self.assertTrue(QuantumError([(IGate(), 0.7), (IGate(), 0.3)]).ideal()) # up to global phase qc = QuantumCircuit(1, global_phase=0.5) qc.i(0) self.assertTrue(QuantumError(qc).ideal()) self.assertTrue(QuantumError(UnitaryGate(-1.0 * np.eye(2))).ideal())
def test_approx_random_mixed_unitary_channel_1q(self): noise1 = UnitaryGate(random_unitary(2, seed=123)) noise2 = UnitaryGate(random_unitary(2, seed=456)) noise = QuantumError([(noise1, 0.7), (noise2, 0.3)]) for opstr in ['pauli', 'reset']: new_result = approximate_quantum_error(noise, operator_string=opstr) old_result = self.old_approximate_quantum_error( noise, operator_string=opstr) self.assertEqual(new_result, old_result) for opstr in ['clifford']: # cannot compare due to error in old implementation with self.assertRaises(NoiseError): self.old_approximate_quantum_error(noise, operator_string=opstr)
def cphase00_replacement(phi: float) -> QuantumCircuit: matrix = np.array([[np.e**(1j * phi), 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]], dtype=complex) gate = UnitaryGate(matrix, label="CPHASE00") return gate
def pswap_replacement(phi: float) -> QuantumCircuit: matrix = np.array([[1, 0, 0, 0], [0, 0, np.e**(1j * phi), 0], [0, np.e**(1j * phi), 0, 0], [0, 0, 0, 1]], dtype=complex) gate = UnitaryGate(matrix, label="PSWAP") return gate
def pauli_y_root_dagger(root, label=None): return UnitaryGate(np.exp(1j * np.pi / (2 * root)) * Operator([ [np.cos(np.pi / (2 * root)), -np.sin(np.pi / (2 * root))], [np.sin(np.pi / (2 * root)), np.cos(np.pi / (2 * root))], ]), label=label)
def test_exact_supercontrolled_decompose_random(self, seeds): """Exact decomposition for random supercontrolled basis and random target""" k1 = np.kron(random_unitary(2, seed=seeds[0]).data, random_unitary(2, seed=seeds[1]).data) k2 = np.kron(random_unitary(2, seed=seeds[2]).data, random_unitary(2, seed=seeds[3]).data) basis_unitary = k1 @ Ud(np.pi / 4, 0, 0) @ k2 decomposer = TwoQubitBasisDecomposer(UnitaryGate(basis_unitary)) self.check_exact_decomposition(random_unitary(4, seed=seeds[4]).data, decomposer)
def swap_theta(theta, label=None): return UnitaryGate(Operator([ [1, 0, 0, 0], [0, 0, np.exp(1j * theta), 0], [0, np.exp(1j * theta), 0, 0], [0, 0, 0, 1], ]), label=label)
def magic_dagger(label=None): return UnitaryGate(1 / math.sqrt(2) * Operator([ [1, 0, 0, 1], [-1j, 0, 0, 1j], [0, -1j, -1j, 0], [0, 1, -1, 0], ]), label=label)
def magic(label=None): return UnitaryGate(1 / math.sqrt(2) * Operator([ [1, 1j, 0, 0], [0, 0, 1j, 1], [0, 0, 1j, -1], [1, -1j, 0, 0], ]), label=label)
def sqrt_swap_dagger(label=None): return UnitaryGate(Operator([ [1, 0, 0, 0], [0, (1 - 1j) / 2, (1 + 1j) / 2, 0], [0, (1 + 1j) / 2, (1 - 1j) / 2, 0], [0, 0, 0, 1], ]), label=label)
def w(label=None): return UnitaryGate(Operator([ [1, 0, 0, 0], [0, 1 / math.sqrt(2), 1 / math.sqrt(2), 0], [0, 1 / math.sqrt(2), -1 / math.sqrt(2), 0], [0, 0, 0, 1], ]), label=label)
def fswap(label=None): return UnitaryGate(Operator([ [1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, -1], ]), label=label)
def test_exact_supercontrolled_decompose_random(self, seed): """Exact decomposition for random supercontrolled basis and random target (seed={seed})""" # pylint: disable=invalid-name k1 = np.kron(random_unitary(2, seed=seed).data, random_unitary(2, seed=seed + 1).data) k2 = np.kron(random_unitary(2, seed=seed + 2).data, random_unitary(2, seed=seed + 3).data) basis_unitary = k1 @ Ud(np.pi / 4, 0, 0) @ k2 decomposer = TwoQubitBasisDecomposer(UnitaryGate(basis_unitary)) self.check_exact_decomposition(random_unitary(4, seed=seed + 4).data, decomposer)
def test_approx_random_mixed_unitary_channel_2q(self): noise1 = UnitaryGate(random_unitary(4, seed=123)) noise2 = UnitaryGate(random_unitary(4, seed=456)) noise = QuantumError([(noise1, 0.7), (noise2, 0.3)]) for opstr in ['pauli']: new_result = approximate_quantum_error(noise, operator_string=opstr) old_result = self.old_approximate_quantum_error( noise, operator_string=opstr) self.assertEqual(new_result, old_result) for opstr in ['reset']: new_result = approximate_quantum_error(noise, operator_string=opstr) old_result = self.old_approximate_quantum_error( noise, operator_string=opstr) self.assertGreaterEqual(process_fidelity(noise, new_result), process_fidelity(noise, old_result))
def molmer_sorensen_dagger(label=None): return UnitaryGate(1 / math.sqrt(2) * Operator([ [1, 0, 0, -1j], [0, 1, -1j, 0], [0, -1j, 1, 0], [-1j, 0, 0, 1], ]), label=label)
def givens(theta, label=None): return UnitaryGate(Operator([ [1, 0, 0, 0], [0, np.cos(theta), -np.sin(theta), 0], [0, np.sin(theta), np.cos(theta), 0], [0, 0, 0, 1], ]), label=label)
def test_exact_supercontrolled_decompose_random(self, nsamples=10): """Verify exact decomposition for random supercontrolled basis and random target""" for _ in range(nsamples): k1 = np.kron(random_unitary(2).data, random_unitary(2).data) k2 = np.kron(random_unitary(2).data, random_unitary(2).data) basis_unitary = k1 @ Ud(np.pi / 4, 0, 0) @ k2 decomposer = TwoQubitBasisDecomposer(UnitaryGate(basis_unitary)) self.check_exact_decomposition(random_unitary(4).data, decomposer)
def a(theta, phi, label=None): return UnitaryGate(Operator([ [1, 0, 0, 0], [0, np.cos(theta), np.sin(theta) * np.exp(1j * phi), 0], [0, np.sin(theta) * np.exp(-1j * phi), -np.cos(theta), 0], [0, 0, 0, 1], ]), label=label)
def swap_root_dagger(root, label=None): return UnitaryGate(np.exp(1j * np.pi / (4 * root)) * Operator([ [np.exp(-1j * np.pi / (2 * root)), 0, 0, 0], [0, np.cos(np.pi / (2 * root)), -1j * np.sin(np.pi / (2 * root)), 0], [0, -1j * np.sin(np.pi / (2 * root)), np.cos(np.pi / (2 * root)), 0], [0, 0, 0, np.exp(-1j * np.pi / (2 * root))], ]), label=label)
def berkeley_dagger(label=None): return UnitaryGate(Operator([ [np.cos(np.pi / 8), 0, 0, -1j * np.sin(np.pi / 8)], [0, np.cos(3 * np.pi / 8), -1j * np.sin(3 * np.pi / 8), 0], [0, -1j * np.sin(3 * np.pi / 8), np.cos(3 * np.pi / 8), 0], [-1j * np.sin(np.pi / 8), 0, 0, np.cos(np.pi / 8)], ]), label=label)
def test_consolidate_small_block(self): """test a small block of gates can be turned into a unitary on same wires""" qr = QuantumRegister(2, "qr") qc = QuantumCircuit(qr) qc.u1(0.5, qr[0]) qc.u2(0.2, 0.6, qr[1]) qc.cx(qr[0], qr[1]) dag = circuit_to_dag(qc) pass_ = ConsolidateBlocks(force_consolidate=True) pass_.property_set['block_list'] = [list(dag.topological_op_nodes())] new_dag = pass_.run(dag) sim = UnitarySimulatorPy() result = execute(qc, sim).result() unitary = UnitaryGate(result.get_unitary()) self.assertEqual(len(new_dag.op_nodes()), 1) fidelity = process_fidelity(new_dag.op_nodes()[0].op.to_matrix(), unitary.to_matrix()) self.assertAlmostEqual(fidelity, 1.0, places=7)
def ecp_dagger(label=None): c = np.cos(np.pi / 8) s = np.sin(np.pi / 8) return UnitaryGate(1 / 2 * Operator([ [2 * c, 0, 0, 1j * 2 * s], [0, (1 - 1j) * (c - s), (1 + 1j) * (c + s), 0], [0, (1 + 1j) * (c + s), (1 - 1j) * (c - s), 0], [1j * 2 * s, 0, 0, 2 * c], ]), label=label)
def test_unitary_sqrt(self): """Test UnitaryGate.power(1/2) method.""" expected = array([[0.5 + 0.5j, 0.5 + 0.5j], [-0.5 - 0.5j, 0.5 + 0.5j]], dtype=complex) result = UnitaryGate([[0, 1j], [-1j, 0]]).power(1 / 2) self.assertEqual(result.label, "unitary^0.5") self.assertEqual(len(result.definition), 1) self.assertIsInstance(result, Gate) self.assertEqual(Operator(result), Operator(expected))
def test_identity(self): """Test unrolling of identity gate over 3qubits.""" qr = QuantumRegister(3, "qr") circuit = QuantumCircuit(qr) gate = UnitaryGate(np.eye(2**3)) circuit.append(gate, range(3)) dag = circuit_to_dag(circuit) pass_ = Unroll3qOrMore() after_dag = pass_.run(dag) after_circ = dag_to_circuit(after_dag) self.assertTrue(Operator(circuit).equiv(Operator(after_circ)))