def test_N_level_system(self): """ Test for circuit with N-level system. """ mat3 = qp.rand_unitary_haar(3) def controlled_mat3(arg_value): """ A qubit control an operator acting on a 3 level system """ control_value = arg_value dim = mat3.dims[0][0] return (tensor(fock_dm(2, control_value), mat3) + tensor(fock_dm(2, 1 - control_value), identity(dim))) qc = QubitCircuit(2, dims=[3, 2]) qc.user_gates = {"CTRLMAT3": controlled_mat3} qc.add_gate("CTRLMAT3", targets=[1, 0], arg_value=1) props = qc.propagators() final_fid = qp.average_gate_fidelity(mat3, ptrace(props[0], 0) - 1) assert pytest.approx(final_fid, 1.0e-6) == 1 init_state = basis([3, 2], [0, 1]) result = qc.run(init_state) final_fid = qp.fidelity(result, props[0] * init_state) assert pytest.approx(final_fid, 1.0e-6) == 1.
def test_user_gate(self): """ User defined gate for QubitCircuit """ def customer_gate1(arg_values): mat = np.zeros((4, 4), dtype=np.complex128) mat[0, 0] = mat[1, 1] = 1. mat[2:4, 2:4] = gates.rx(arg_values).full() return Qobj(mat, dims=[[2, 2], [2, 2]]) def customer_gate2(): mat = np.array([[1., 0], [0., 1.j]]) return Qobj(mat, dims=[[2], [2]]) qc = QubitCircuit(3) qc.user_gates = {"CTRLRX": customer_gate1, "T1": customer_gate2} qc.add_gate("CTRLRX", targets=[1, 2], arg_value=np.pi/2) qc.add_gate("T1", targets=[1]) props = qc.propagators() result1 = tensor(identity(2), customer_gate1(np.pi/2)) np.testing.assert_allclose(props[0].full(), result1.full()) result2 = tensor(identity(2), customer_gate2(), identity(2)) np.testing.assert_allclose(props[1].full(), result2.full())
def construct_circuit(self, angles): """ Construct a circuit by specifying values for each free parameter. Parameters ---------- angles: list of float A list of dimension (n,) for n free parameters in the circuit Returns ------- circ: :obj:`.QubitCircuit` """ circ = QubitCircuit(self.num_qubits) circ.user_gates = self.user_gates i = 0 for layer_num in range(self.num_layers): for block in self.blocks: if block.initial and layer_num > 0: continue if block.is_native_gate: circ.add_gate(block.operator, targets=block.targets) else: n = block.get_free_parameters_num() circ.add_gate( block.name, targets=list(range(self.num_qubits)), arg_value=angles[i:i + n] if n > 0 else None, ) i += n return circ
def test_N_level_system(self): """ Test for circuit with N-level system. """ mat3 = rand_dm(3, density=1.) def controlled_mat3(arg_value): """ A qubit control an operator acting on a 3 level system """ control_value = arg_value dim = mat3.dims[0][0] return (tensor(fock_dm(2, control_value), mat3) + tensor(fock_dm(2, 1 - control_value), identity(dim))) qc = QubitCircuit(2, dims=[3, 2]) qc.user_gates = {"CTRLMAT3": controlled_mat3} qc.add_gate("CTRLMAT3", targets=[1, 0], arg_value=1) props = qc.propagators() np.testing.assert_allclose(mat3, ptrace(props[0], 0) - 1)
def test_add_circuit(self): """ Addition of a circuit to a `QubitCircuit` """ def customer_gate1(arg_values): mat = np.zeros((4, 4), dtype=np.complex128) mat[0, 0] = mat[1, 1] = 1. mat[2:4, 2:4] = gates.rx(arg_values) return Qobj(mat, dims=[[2, 2], [2, 2]]) qc = QubitCircuit(6) qc.user_gates = {"CTRLRX": customer_gate1} qc = QubitCircuit(6) qc.add_gate("CNOT", targets=[1], controls=[0]) test_gate = Gate("SWAP", targets=[1, 4]) qc.add_gate(test_gate) qc.add_gate("TOFFOLI", controls=[0, 1], targets=[2]) qc.add_gate("SNOT", targets=[3]) qc.add_gate(test_gate, index=[3]) qc.add_measurement("M0", targets=[0], classical_store=[1]) qc.add_1q_gate("RY", start=4, end=5, arg_value=1.570796) qc.add_gate("CTRLRX", targets=[1, 2], arg_value=np.pi/2) qc1 = QubitCircuit(6) qc1.add_circuit(qc) # Test if all gates and measurements are added assert len(qc1.gates) == len(qc.gates) # Test if the definitions of user gates are added assert qc1.user_gates == qc.user_gates for i in range(len(qc1.gates)): assert (qc1.gates[i].name == qc.gates[i].name) assert (qc1.gates[i].targets == qc.gates[i].targets) if (isinstance(qc1.gates[i], Gate) and isinstance(qc.gates[i], Gate)): assert (qc1.gates[i].controls == qc.gates[i].controls) assert (qc1.gates[i].classical_controls == qc.gates[i].classical_controls) elif (isinstance(qc1.gates[i], Measurement) and isinstance(qc.gates[i], Measurement)): assert (qc1.gates[i].classical_store == qc.gates[i].classical_store) # Test exception when qubit out of range pytest.raises(NotImplementedError, qc1.add_circuit, qc, start=4) qc2 = QubitCircuit(8) qc2.add_circuit(qc, start=2) # Test if all gates are added assert len(qc2.gates) == len(qc.gates) # Test if the positions are correct for i in range(len(qc2.gates)): if qc.gates[i].targets is not None: assert (qc2.gates[i].targets[0] == qc.gates[i].targets[0]+2) if (isinstance(qc.gates[i], Gate) and qc.gates[i].controls is not None): assert (qc2.gates[i].controls[0] == qc.gates[i].controls[0]+2) # Test exception when the operators to be added are not gates or measurements qc.gates[-1] = 0 pytest.raises(TypeError, qc2.add_circuit, qc)