def test_open_controlled_gate(self):
        """
        Test controlled gates with control on '0'
        """
        base_gate = XGate()
        base_mat = base_gate.to_matrix()
        num_ctrl_qubits = 3

        ctrl_state = 5
        cgate = base_gate.control(num_ctrl_qubits, ctrl_state=ctrl_state)
        target_mat = _compute_control_matrix(base_mat, num_ctrl_qubits, ctrl_state=ctrl_state)
        self.assertEqual(Operator(cgate), Operator(target_mat))

        ctrl_state = None
        cgate = base_gate.control(num_ctrl_qubits, ctrl_state=ctrl_state)
        target_mat = _compute_control_matrix(base_mat, num_ctrl_qubits, ctrl_state=ctrl_state)
        self.assertEqual(Operator(cgate), Operator(target_mat))

        ctrl_state = 0
        cgate = base_gate.control(num_ctrl_qubits, ctrl_state=ctrl_state)
        target_mat = _compute_control_matrix(base_mat, num_ctrl_qubits, ctrl_state=ctrl_state)
        self.assertEqual(Operator(cgate), Operator(target_mat))

        ctrl_state = 7
        cgate = base_gate.control(num_ctrl_qubits, ctrl_state=ctrl_state)
        target_mat = _compute_control_matrix(base_mat, num_ctrl_qubits, ctrl_state=ctrl_state)
        self.assertEqual(Operator(cgate), Operator(target_mat))

        ctrl_state = '110'
        cgate = base_gate.control(num_ctrl_qubits, ctrl_state=ctrl_state)
        target_mat = _compute_control_matrix(base_mat, num_ctrl_qubits, ctrl_state=ctrl_state)
        self.assertEqual(Operator(cgate), Operator(target_mat))
    def test_multi_control_toffoli_matrix_advanced_dirty_ancillas(
            self, num_controls):
        """Test the multi-control Toffoli gate with dirty ancillas (advanced).

        Based on the test moved here from Aqua:
        https://github.com/Qiskit/qiskit-aqua/blob/769ca8f/test/aqua/test_mct.py
        """
        q_controls = QuantumRegister(num_controls)
        q_target = QuantumRegister(1)
        qc = QuantumCircuit(q_controls, q_target)

        q_ancillas = None
        if num_controls <= 4:
            num_ancillas = 0
        else:
            num_ancillas = 1
            q_ancillas = QuantumRegister(num_ancillas)
            qc.add_register(q_ancillas)

        qc.mct(q_controls, q_target[0], q_ancillas, mode='advanced')

        simulated = execute(
            qc,
            BasicAer.get_backend('unitary_simulator')).result().get_unitary(qc)
        if num_ancillas > 0:
            simulated = simulated[:2**(num_controls + 1), :2**(num_controls +
                                                               1)]

        base = XGate().to_matrix()
        expected = _compute_control_matrix(base, num_controls)
        self.assertTrue(matrix_equal(simulated, expected, atol=1e-8))
 def test_single_controlled_rotation_gates(self, gate, cgate):
     """Test the controlled rotation gates controlled on one qubit."""
     if gate.name == 'rz':
         iden = Operator.from_label('I')
         zgen = Operator.from_label('Z')
         op_mat = (np.cos(0.5 * self.theta) * iden -
                   1j * np.sin(0.5 * self.theta) * zgen).data
     else:
         op_mat = Operator(gate).data
     ref_mat = Operator(cgate).data
     cop_mat = _compute_control_matrix(op_mat, self.num_ctrl)
     self.assertTrue(matrix_equal(cop_mat, ref_mat, ignore_phase=True))
     cqc = QuantumCircuit(self.num_ctrl + self.num_target)
     cqc.append(cgate, cqc.qregs[0])
     dag = circuit_to_dag(cqc)
     unroller = Unroller(['u3', 'cx'])
     uqc = dag_to_circuit(unroller.run(dag))
     self.log.info('%s gate count: %d', cgate.name, uqc.size())
     self.log.info('\n%s', str(uqc))
     # these limits could be changed
     if gate.name == 'ry':
         self.assertTrue(uqc.size() <= 32)
     elif gate.name == 'rz':
         self.assertTrue(uqc.size() <= 40)
     else:
         self.assertTrue(uqc.size() <= 20)
예제 #4
0
    def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None):
        """Return controlled version of gate

        Args:
            num_ctrl_qubits (int): number of controls to add to gate (default=1)
            label (str): optional gate label
            ctrl_state (int or str or None): The control state in decimal or as a
                bit string (e.g. '1011'). If None, use 2**num_ctrl_qubits-1.

        Returns:
            UnitaryGate: controlled version of gate.

        Raises:
            QiskitError: Invalid ctrl_state.
            ExtensionError: Non-unitary controlled unitary.
        """
        mat = self.to_matrix()
        cmat = _compute_control_matrix(mat, num_ctrl_qubits, ctrl_state=None)
        iso = isometry.Isometry(cmat, 0, 0)
        return ControlledGate(
            "c-unitary",
            num_qubits=self.num_qubits + num_ctrl_qubits,
            params=[mat],
            label=label,
            num_ctrl_qubits=num_ctrl_qubits,
            definition=iso.definition,
            ctrl_state=ctrl_state,
            base_gate=self.copy(),
        )
예제 #5
0
    def test_multi_control_u3(self):
        """Test the matrix representation of the controlled and controlled-controlled U3 gate."""
        import qiskit.extensions.standard.u3 as u3

        num_ctrl = 3
        # U3 gate params
        alpha, beta, gamma = 0.2, 0.3, 0.4

        # cnu3 gate
        u3gate = u3.U3Gate(alpha, beta, gamma)
        cnu3 = u3gate.control(num_ctrl)
        width = cnu3.num_qubits
        qr = QuantumRegister(width)
        qcnu3 = QuantumCircuit(qr)
        qcnu3.append(cnu3, qr, [])

        # U3 gate
        qu3 = QuantumCircuit(1)
        qu3.u3(alpha, beta, gamma, 0)

        # CU3 gate
        qcu3 = QuantumCircuit(2)
        qcu3.cu3(alpha, beta, gamma, 0, 1)

        # c-cu3 gate
        width = 3
        qr = QuantumRegister(width)
        qc_cu3 = QuantumCircuit(qr)
        cu3gate = u3.CU3Gate(alpha, beta, gamma)

        c_cu3 = cu3gate.control(1)
        qc_cu3.append(c_cu3, qr, [])

        job = execute([qcnu3, qu3, qcu3, qc_cu3], BasicAer.get_backend('unitary_simulator'),
                      basis_gates=['u1', 'u2', 'u3', 'id', 'cx'])
        result = job.result()

        # Circuit unitaries
        mat_cnu3 = result.get_unitary(0)

        mat_u3 = result.get_unitary(1)
        mat_cu3 = result.get_unitary(2)
        mat_c_cu3 = result.get_unitary(3)

        # Target Controlled-U3 unitary
        target_cnu3 = _compute_control_matrix(mat_u3, num_ctrl)
        target_cu3 = np.kron(mat_u3, np.diag([0, 1])) + np.kron(np.eye(2), np.diag([1, 0]))
        target_c_cu3 = np.kron(mat_cu3, np.diag([0, 1])) + np.kron(np.eye(4), np.diag([1, 0]))

        tests = [('check unitary of u3.control against tensored unitary of u3',
                  target_cu3, mat_cu3),
                 ('check unitary of cu3.control against tensored unitary of cu3',
                  target_c_cu3, mat_c_cu3),
                 ('check unitary of cnu3 against tensored unitary of u3',
                  target_cnu3, mat_cnu3)]
        for itest in tests:
            info, target, decomp = itest[0], itest[1], itest[2]
            with self.subTest(i=info):
                self.log.info(info)
                self.assertTrue(matrix_equal(target, decomp, ignore_phase=True))
    def test_multi_controlled_u1_matrix(self, num_controls):
        """Test the matrix representation of the multi-controlled CU1 gate.

        Based on the test moved here from Aqua:
        https://github.com/Qiskit/qiskit-aqua/blob/769ca8f/test/aqua/test_mcu1.py
        """

        # registers for the circuit
        q_controls = QuantumRegister(num_controls)
        q_target = QuantumRegister(1)

        # iterate over all possible combinations of control qubits
        for ctrl_state in range(2 ** num_controls):
            bitstr = bin(ctrl_state)[2:].zfill(num_controls)[::-1]
            lam = 0.3165354 * pi
            qc = QuantumCircuit(q_controls, q_target)
            for idx, bit in enumerate(bitstr):
                if bit == '0':
                    qc.x(q_controls[idx])

            qc.mcu1(lam, q_controls, q_target[0])

            # for idx in subset:
            for idx, bit in enumerate(bitstr):
                if bit == '0':
                    qc.x(q_controls[idx])

            backend = BasicAer.get_backend('unitary_simulator')
            simulated = execute(qc, backend).result().get_unitary(qc)

            base = U1Gate(lam).to_matrix()
            expected = _compute_control_matrix(base, num_controls, ctrl_state=ctrl_state)
            with self.subTest(msg='control state = {}'.format(ctrl_state)):
                self.assertTrue(matrix_equal(simulated, expected))
    def test_relative_phase_toffoli_gates(self, num_ctrl_qubits):
        """Test the relative phase Toffoli gates.

        This test compares the matrix representation of the relative phase gate classes
        (i.e. RCCXGate().to_matrix()), the matrix obtained from the unitary simulator,
        and the exact version of the gate as obtained through `_compute_control_matrix`.
        """
        # get target matrix (w/o relative phase)
        base_mat = XGate().to_matrix()
        target_mat = _compute_control_matrix(base_mat, num_ctrl_qubits)

        # build the matrix for the relative phase toffoli using the unitary simulator
        circuit = QuantumCircuit(num_ctrl_qubits + 1)
        if num_ctrl_qubits == 2:
            circuit.rccx(0, 1, 2)
        else:  # num_ctrl_qubits == 3:
            circuit.rcccx(0, 1, 2, 3)
        simulator = BasicAer.get_backend('unitary_simulator')
        simulated_mat = execute(circuit, simulator).result().get_unitary()

        # get the matrix representation from the class itself
        if num_ctrl_qubits == 2:
            repr_mat = RCCXGate().to_matrix()
        else:  # num_ctrl_qubits == 3:
            repr_mat = RC3XGate().to_matrix()

        # test up to phase
        # note, that all entries may have an individual phase! (as opposed to a global phase)
        self.assertTrue(matrix_equal(np.abs(simulated_mat), target_mat))

        # compare simulated matrix with the matrix representation provided by the class
        self.assertTrue(matrix_equal(simulated_mat, repr_mat))
예제 #8
0
    def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None):
        r"""Return controlled version of gate

        Args:
            num_ctrl_qubits (int): number of controls to add to gate (default=1)
            label (str): optional gate label
            ctrl_state (int or str or None): The control state in decimal or as a
                bit string (e.g. '1011'). If None, use 2**num_ctrl_qubits-1.

        Returns:
            UnitaryGate: controlled version of gate.

        Raises:
            QiskitError: invalid ctrl_state
        """
        cmat = _compute_control_matrix(self.to_matrix(), num_ctrl_qubits)
        iso = isometry.Isometry(cmat, 0, 0)
        cunitary = ControlledGate('c-unitary',
                                  self.num_qubits + num_ctrl_qubits,
                                  cmat,
                                  definition=iso.definition,
                                  label=label)
        cunitary.base_gate = self.copy()
        cunitary.base_gate.label = self.label
        return cunitary
 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 test_multi_control_u1(self):
        """Test the matrix representation of the controlled and controlled-controlled U1 gate."""
        import qiskit.circuit.library.standard_gates.u1 as u1

        num_ctrl = 3
        # U1 gate params
        theta = 0.2

        # cnu1 gate
        u1gate = u1.U1Gate(theta)
        cnu1 = u1gate.control(num_ctrl)
        width = cnu1.num_qubits
        qr = QuantumRegister(width)
        qcnu1 = QuantumCircuit(qr)
        qcnu1.append(cnu1, qr, [])

        # U1 gate
        qu1 = QuantumCircuit(1)
        qu1.u1(theta, 0)

        # CU1 gate
        qcu1 = QuantumCircuit(2)
        qcu1.cu1(theta, 0, 1)

        # c-cu1 gate
        width = 3
        qr = QuantumRegister(width)
        qc_cu1 = QuantumCircuit(qr)
        cu1gate = u1.CU1Gate(theta)
        c_cu1 = cu1gate.control(1)
        qc_cu1.append(c_cu1, qr, [])

        job = execute([qcnu1, qu1, qcu1, qc_cu1], BasicAer.get_backend('unitary_simulator'),
                      basis_gates=['u1', 'u2', 'u3', 'id', 'cx'])
        result = job.result()

        # Circuit unitaries
        mat_cnu1 = result.get_unitary(0)
        # trace out ancillae

        mat_u1 = result.get_unitary(1)
        mat_cu1 = result.get_unitary(2)
        mat_c_cu1 = result.get_unitary(3)

        # Target Controlled-U1 unitary
        target_cnu1 = _compute_control_matrix(mat_u1, num_ctrl)
        target_cu1 = np.kron(mat_u1, np.diag([0, 1])) + np.kron(np.eye(2), np.diag([1, 0]))
        target_c_cu1 = np.kron(mat_cu1, np.diag([0, 1])) + np.kron(np.eye(4), np.diag([1, 0]))

        tests = [('check unitary of u1.control against tensored unitary of u1',
                  target_cu1, mat_cu1),
                 ('check unitary of cu1.control against tensored unitary of cu1',
                  target_c_cu1, mat_c_cu1),
                 ('check unitary of cnu1 against tensored unitary of u1',
                  target_cnu1, mat_cnu1)]
        for itest in tests:
            info, target, decomp = itest[0], itest[1], itest[2]
            with self.subTest(i=info):
                self.log.info(info)
                self.assertTrue(matrix_equal(target, decomp, ignore_phase=True))
예제 #11
0
    def test_multi_control_toffoli_matrix_clean_ancillas(self, num_controls):
        """Test the multi-control Toffoli gate with clean ancillas.

        Based on the test moved here from Aqua:
        https://github.com/Qiskit/qiskit-aqua/blob/769ca8f/test/aqua/test_mct.py
        """
        # set up circuit
        q_controls = QuantumRegister(num_controls)
        q_target = QuantumRegister(1)
        qc = QuantumCircuit(q_controls, q_target)

        if num_controls > 2:
            num_ancillas = num_controls - 2
            q_ancillas = QuantumRegister(num_controls)
            qc.add_register(q_ancillas)
        else:
            num_ancillas = 0
            q_ancillas = None

        # apply hadamard on control qubits and toffoli gate
        qc.mct(q_controls, q_target[0], q_ancillas, mode='basic')

        # execute the circuit and obtain statevector result
        backend = BasicAer.get_backend('unitary_simulator')
        simulated = execute(qc, backend).result().get_unitary(qc)

        # compare to expectation
        if num_ancillas > 0:
            simulated = simulated[:2**(num_controls + 1), :2**(num_controls +
                                                               1)]

        base = XGate().to_matrix()
        expected = _compute_control_matrix(base, num_controls)
        self.assertTrue(matrix_equal(simulated, expected))
예제 #12
0
 def __array__(self, dtype=None):
     """Return a numpy.array for the C4X gate."""
     mat = _compute_control_matrix(self.base_gate.to_matrix(),
                                   self.num_ctrl_qubits,
                                   ctrl_state=self.ctrl_state)
     if dtype:
         return numpy.asarray(mat, dtype=dtype)
     return mat
예제 #13
0
 def test_controlled_random_unitary(self, num_ctrl_qubits):
     """Test the matrix data of an Operator based on a random UnitaryGate."""
     num_target = 2
     base_gate = random_unitary(2**num_target).to_instruction()
     base_mat = base_gate.to_matrix()
     cgate = base_gate.control(num_ctrl_qubits)
     test_op = Operator(cgate)
     cop_mat = _compute_control_matrix(base_mat, num_ctrl_qubits)
     self.assertTrue(matrix_equal(cop_mat, test_op.data, ignore_phase=True))
예제 #14
0
    def test_multi_controlled_y_rotation_matrix_basic_mode(
            self, num_controls, use_basis_gates):
        """Test the multi controlled Y rotation using the mode 'basic'.

        Based on the test moved here from Aqua:
        https://github.com/Qiskit/qiskit-aqua/blob/769ca8f/test/aqua/test_mcr.py
        """

        # get the number of required ancilla qubits
        if num_controls <= 2:
            num_ancillas = 0
        else:
            num_ancillas = num_controls - 2

        q_controls = QuantumRegister(num_controls)
        q_target = QuantumRegister(1)

        for ctrl_state in range(2**num_controls):
            bitstr = bin(ctrl_state)[2:].zfill(num_controls)[::-1]
            theta = 0.871236 * pi
            if num_ancillas > 0:
                q_ancillas = QuantumRegister(num_ancillas)
                qc = QuantumCircuit(q_controls, q_target, q_ancillas)
            else:
                qc = QuantumCircuit(q_controls, q_target)
                q_ancillas = None

            for idx, bit in enumerate(bitstr):
                if bit == '0':
                    qc.x(q_controls[idx])

            qc.mcry(theta,
                    q_controls,
                    q_target[0],
                    q_ancillas,
                    mode='basic',
                    use_basis_gates=use_basis_gates)

            for idx, bit in enumerate(bitstr):
                if bit == '0':
                    qc.x(q_controls[idx])

            rot_mat = RYGate(theta).to_matrix()

            backend = BasicAer.get_backend('unitary_simulator')
            simulated = execute(qc, backend).result().get_unitary(qc)
            if num_ancillas > 0:
                simulated = simulated[:2**(num_controls +
                                           1), :2**(num_controls + 1)]

            expected = _compute_control_matrix(rot_mat,
                                               num_controls,
                                               ctrl_state=ctrl_state)

            with self.subTest(msg='control state = {}'.format(ctrl_state)):
                self.assertTrue(matrix_equal(simulated, expected))
 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 test_multi_control_u3(self):
        """Test the matrix representation of the controlled and controlled-controlled U3 gate."""
        import qiskit.circuit.library.standard_gates.u3 as u3

        num_ctrl = 3
        # U3 gate params
        alpha, beta, gamma = 0.2, 0.3, 0.4

        # cnu3 gate
        u3gate = u3.U3Gate(alpha, beta, gamma)
        cnu3 = u3gate.control(num_ctrl)
        width = cnu3.num_qubits
        qr = QuantumRegister(width)
        qcnu3 = QuantumCircuit(qr)
        qcnu3.append(cnu3, qr, [])

        # U3 gate
        qu3 = QuantumCircuit(1)
        qu3.u3(alpha, beta, gamma, 0)

        # CU3 gate
        qcu3 = QuantumCircuit(2)
        qcu3.cu3(alpha, beta, gamma, 0, 1)

        # c-cu3 gate
        width = 3
        qr = QuantumRegister(width)
        qc_cu3 = QuantumCircuit(qr)
        cu3gate = u3.CU3Gate(alpha, beta, gamma)

        c_cu3 = cu3gate.control(1)
        qc_cu3.append(c_cu3, qr, [])

        # Circuit unitaries
        mat_cnu3 = Operator(qcnu3).data
        mat_u3 = Operator(qu3).data
        mat_cu3 = Operator(qcu3).data
        mat_c_cu3 = Operator(qc_cu3).data

        # Target Controlled-U3 unitary
        target_cnu3 = _compute_control_matrix(mat_u3, num_ctrl)
        target_cu3 = np.kron(mat_u3, np.diag([0, 1])) + np.kron(np.eye(2), np.diag([1, 0]))
        target_c_cu3 = np.kron(mat_cu3, np.diag([0, 1])) + np.kron(np.eye(4), np.diag([1, 0]))

        tests = [('check unitary of u3.control against tensored unitary of u3',
                  target_cu3, mat_cu3),
                 ('check unitary of cu3.control against tensored unitary of cu3',
                  target_c_cu3, mat_c_cu3),
                 ('check unitary of cnu3 against tensored unitary of u3',
                  target_cnu3, mat_cnu3)]
        for itest in tests:
            info, target, decomp = itest[0], itest[1], itest[2]
            with self.subTest(i=info):
                self.assertTrue(matrix_equal(target, decomp, ignore_phase=True,
                                             atol=1e-8, rtol=1e-5))
예제 #17
0
    def test_multi_controlled_rotation_gate_matrices(self, num_controls,
                                                     base_gate_name,
                                                     use_basis_gates):
        """Test the multi controlled rotation gates without ancillas.

        Based on the test moved here from Aqua:
        https://github.com/Qiskit/qiskit-aqua/blob/769ca8f/test/aqua/test_mcr.py
        """
        q_controls = QuantumRegister(num_controls)
        q_target = QuantumRegister(1)

        # iterate over all possible combinations of control qubits
        for ctrl_state in range(2**num_controls):
            bitstr = bin(ctrl_state)[2:].zfill(num_controls)[::-1]
            theta = 0.871236 * pi
            qc = QuantumCircuit(q_controls, q_target)
            for idx, bit in enumerate(bitstr):
                if bit == '0':
                    qc.x(q_controls[idx])

            # call mcrx/mcry/mcrz
            if base_gate_name == 'y':
                qc.mcry(theta,
                        q_controls,
                        q_target[0],
                        None,
                        mode='noancilla',
                        use_basis_gates=use_basis_gates)
            else:  # case 'x' or 'z' only support the noancilla mode and do not have this keyword
                getattr(qc, 'mcr' + base_gate_name)(
                    theta,
                    q_controls,
                    q_target[0],
                    use_basis_gates=use_basis_gates)

            for idx, bit in enumerate(bitstr):
                if bit == '0':
                    qc.x(q_controls[idx])

            backend = BasicAer.get_backend('unitary_simulator')
            simulated = execute(qc, backend).result().get_unitary(qc)

            if base_gate_name == 'x':
                rot_mat = RXGate(theta).to_matrix()
            elif base_gate_name == 'y':
                rot_mat = RYGate(theta).to_matrix()
            else:  # case 'z'
                rot_mat = U1Gate(theta).to_matrix()

            expected = _compute_control_matrix(rot_mat,
                                               num_controls,
                                               ctrl_state=ctrl_state)
            with self.subTest(msg='control state = {}'.format(ctrl_state)):
                self.assertTrue(matrix_equal(simulated, expected))
예제 #18
0
 def test_controlled_global_phase(self, num_ctrl_qubits):
     """
     Test controlled global phase on base gate.
     """
     theta = pi / 4
     circ = QuantumCircuit(2, global_phase=theta)
     base_gate = circ.to_gate()
     base_mat = Operator(base_gate).data
     target = _compute_control_matrix(base_mat, num_ctrl_qubits)
     cgate = base_gate.control(num_ctrl_qubits)
     ccirc = circ.control(num_ctrl_qubits)
     self.assertEqual(Operator(cgate), Operator(target))
     self.assertEqual(Operator(ccirc), Operator(target))
예제 #19
0
 def test_rz_composite_global_phase(self, num_ctrl_qubits):
     """
     Test controlling CX with global phase
     """
     theta = pi / 4
     circ = QuantumCircuit(2, global_phase=theta)
     circ.rz(0.1, 0)
     circ.rz(0.2, 1)
     ccirc = circ.control(num_ctrl_qubits)
     base_gate = circ.to_gate()
     cgate = base_gate.control(num_ctrl_qubits)
     base_mat = Operator(base_gate).data
     target = _compute_control_matrix(base_mat, num_ctrl_qubits)
     self.assertEqual(Operator(cgate), Operator(target))
     self.assertEqual(Operator(ccirc), Operator(target))
예제 #20
0
    def test_controlled_standard_gates(self, num_ctrl_qubits, gate_class):
        """Test controlled versions of all standard gates."""
        theta = pi / 2
        ctrl_state_ones = 2**num_ctrl_qubits - 1
        ctrl_state_zeros = 0
        ctrl_state_mixed = ctrl_state_ones >> int(num_ctrl_qubits / 2)

        numargs = len(_get_free_params(gate_class))
        args = [theta] * numargs
        if gate_class in [MSGate, Barrier]:
            args[0] = 2
        elif gate_class in [MCU1Gate]:
            args[1] = 2
        elif issubclass(gate_class, MCXGate):
            args = [5]

        gate = gate_class(*args)
        for ctrl_state in {
                ctrl_state_ones, ctrl_state_zeros, ctrl_state_mixed
        }:
            with self.subTest(i='{0}, ctrl_state={1}'.format(
                    gate_class.__name__, ctrl_state)):
                if hasattr(
                        gate,
                        'num_ancilla_qubits') and gate.num_ancilla_qubits > 0:
                    # skip matrices that include ancilla qubits
                    continue
                try:
                    cgate = gate.control(num_ctrl_qubits,
                                         ctrl_state=ctrl_state)
                except (AttributeError, QiskitError):
                    # 'object has no attribute "control"'
                    # skipping Id and Barrier
                    continue
                if gate.name == 'rz':
                    iden = Operator.from_label('I')
                    zgen = Operator.from_label('Z')
                    base_mat = (np.cos(0.5 * theta) * iden -
                                1j * np.sin(0.5 * theta) * zgen).data
                else:
                    base_mat = Operator(gate).data
                target_mat = _compute_control_matrix(base_mat,
                                                     num_ctrl_qubits,
                                                     ctrl_state=ctrl_state)
                self.assertTrue(
                    matrix_equal(Operator(cgate).data,
                                 target_mat,
                                 ignore_phase=True))
    def test_multi_control_toffoli_matrix_noancilla_dirty_ancillas(self, num_controls):
        """Test the multi-control Toffoli gate with dirty ancillas (noancilla).

        Based on the test moved here from Aqua:
        https://github.com/Qiskit/qiskit-aqua/blob/769ca8f/test/aqua/test_mct.py
        """
        q_controls = QuantumRegister(num_controls)
        q_target = QuantumRegister(1)
        qc = QuantumCircuit(q_controls, q_target)

        qc.mct(q_controls, q_target[0], None, mode='noancilla')

        simulated = execute(qc, BasicAer.get_backend('unitary_simulator')).result().get_unitary(qc)

        base = XGate().to_matrix()
        expected = _compute_control_matrix(base, num_controls)
        self.assertTrue(matrix_equal(simulated, expected, atol=1e-8))
예제 #22
0
    def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None):
        r"""Return controlled version of gate

        Args:
            num_ctrl_qubits (int): number of controls to add to gate (default=1)
            label (str): optional gate label
            ctrl_state (int or str or None): The control state in decimal or as a
                bit string (e.g. '1011'). If None, use 2**num_ctrl_qubits-1.

        Returns:
            UnitaryGate: controlled version of gate.

        Raises:
            QiskitError: invalid ctrl_state
        """
        cmat = _compute_control_matrix(self.to_matrix(), num_ctrl_qubits)
        return UnitaryGate(cmat, label=label)
예제 #23
0
 def test_controlled_unitary(self, num_ctrl_qubits):
     """Test the matrix data of an Operator, which is based on a controlled gate."""
     num_target = 1
     q_target = QuantumRegister(num_target)
     qc1 = QuantumCircuit(q_target)
     # for h-rx(pi/2)
     theta, phi, lamb = 1.57079632679490, 0.0, 4.71238898038469
     qc1.u3(theta, phi, lamb, q_target[0])
     base_gate = qc1.to_gate()
     # get UnitaryGate version of circuit
     base_op = Operator(qc1)
     base_mat = base_op.data
     cgate = base_gate.control(num_ctrl_qubits)
     test_op = Operator(cgate)
     cop_mat = _compute_control_matrix(base_mat, num_ctrl_qubits)
     self.assertTrue(is_unitary_matrix(base_mat))
     self.assertTrue(matrix_equal(cop_mat, test_op.data, ignore_phase=True))
 def test_open_controlled_to_matrix(self, gate_class, ctrl_state):
     """Test open controlled to_matrix."""
     num_free_params = len(_get_free_params(gate_class.__init__,
                                            ignore=['self']))
     free_params = [0.1 * i for i in range(1, num_free_params + 1)]
     if gate_class in [MCU1Gate]:
         free_params[1] = 3
     elif gate_class in [MCXGate]:
         free_params[0] = 3
     cgate = gate_class(*free_params)
     cgate.ctrl_state = ctrl_state
     base_mat = Operator(cgate.base_gate).data
     target = _compute_control_matrix(base_mat, cgate.num_ctrl_qubits,
                                      ctrl_state=ctrl_state)
     try:
         actual = cgate.to_matrix()
     except CircuitError as cerr:
         self.skipTest(cerr)
     self.assertTrue(np.allclose(actual, target))
예제 #25
0
    def test_cx_global_phase(self):
        """
        Test controlling CX with global phase
        """
        theta = pi / 2
        circ = QuantumCircuit(2, global_phase=theta)
        circ.cx(0, 1)
        cx = circ.to_gate()
        self.assertNotEqual(Operator(CXGate()), Operator(cx))

        ccx = cx.control(1)
        base_mat = Operator(cx).data
        target = _compute_control_matrix(base_mat, 1)
        self.assertEqual(Operator(ccx), Operator(target))

        expected = QuantumCircuit(*ccx.definition.qregs)
        expected.ccx(0, 1, 2)
        expected.u1(theta, 0)
        self.assertEqual(ccx.definition, expected)
 def test_single_controlled_composite_gate(self):
     """Test a singly controlled composite gate."""
     num_ctrl = 1
     # create composite gate
     sub_q = QuantumRegister(2)
     cgate = QuantumCircuit(sub_q, name='cgate')
     cgate.h(sub_q[0])
     cgate.cx(sub_q[0], sub_q[1])
     num_target = cgate.width()
     gate = cgate.to_gate()
     cont_gate = gate.control(num_ctrl_qubits=num_ctrl)
     control = QuantumRegister(num_ctrl, 'control')
     target = QuantumRegister(num_target, 'target')
     qc = QuantumCircuit(control, target)
     qc.append(cont_gate, control[:] + target[:])
     op_mat = Operator(cgate).data
     cop_mat = _compute_control_matrix(op_mat, num_ctrl)
     ref_mat = Operator(qc).data
     self.assertTrue(matrix_equal(cop_mat, ref_mat, ignore_phase=True))
예제 #27
0
    def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None):
        r"""Return controlled version of gate

        Args:
            num_ctrl_qubits (int): number of controls to add to gate (default=1)
            label (str): optional gate label
            ctrl_state (int or str or None): The control state in decimal or as a
                bit string (e.g. '1011'). If None, use 2**num_ctrl_qubits-1.

        Returns:
            UnitaryGate: controlled version of gate.

        Raises:
            QiskitError: Invalid ctrl_state.
            ExtensionError: Non-unitary controlled unitary.
        """
        cmat = _compute_control_matrix(self.to_matrix(),
                                       num_ctrl_qubits,
                                       ctrl_state=ctrl_state)
        iso = isometry.Isometry(cmat, 0, 0)
        cunitary = ControlledGate('c-unitary',
                                  num_qubits=self.num_qubits + num_ctrl_qubits,
                                  params=[cmat],
                                  label=label,
                                  num_ctrl_qubits=num_ctrl_qubits,
                                  definition=iso.definition,
                                  ctrl_state=ctrl_state)

        from qiskit.quantum_info import Operator
        # hack to correct global phase; should fix to prevent need for correction here
        pmat = (Operator(iso.inverse()).data @ cmat)
        diag = numpy.diag(pmat)
        if not numpy.allclose(diag, diag[0]):
            raise ExtensionError('controlled unitary generation failed')
        phase = numpy.angle(diag[0])
        if phase:
            qreg = cunitary.definition.qregs[0]
            cunitary.definition.u3(numpy.pi, phase, phase - numpy.pi, qreg[0])
            cunitary.definition.u3(numpy.pi, 0, numpy.pi, qreg[0])
        cunitary.base_gate = self.copy()
        cunitary.base_gate.label = self.label
        return cunitary
예제 #28
0
 def test_single_controlled_composite_gate(self):
     """Test a singly controlled composite gate."""
     num_ctrl = 1
     # create composite gate
     sub_q = QuantumRegister(2)
     cgate = QuantumCircuit(sub_q, name='cgate')
     cgate.h(sub_q[0])
     cgate.cx(sub_q[0], sub_q[1])
     num_target = cgate.width()
     gate = cgate.to_gate()
     cont_gate = gate.control(num_ctrl_qubits=num_ctrl)
     control = QuantumRegister(num_ctrl, 'control')
     target = QuantumRegister(num_target, 'target')
     qc = QuantumCircuit(control, target)
     qc.append(cont_gate, control[:] + target[:])
     simulator = BasicAer.get_backend('unitary_simulator')
     op_mat = execute(cgate, simulator).result().get_unitary(0)
     cop_mat = _compute_control_matrix(op_mat, num_ctrl)
     ref_mat = execute(qc, simulator).result().get_unitary(0)
     self.assertTrue(matrix_equal(cop_mat, ref_mat, ignore_phase=True))
예제 #29
0
    def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None):
        """Return controlled version of gate

        Args:
            num_ctrl_qubits (int): number of controls to add to gate (default=1)
            label (str): optional gate label
            ctrl_state (int or str or None): The control state in decimal or as a
                bit string (e.g. '1011'). If None, use 2**num_ctrl_qubits-1.

        Returns:
            UnitaryGate: controlled version of gate.

        Raises:
            QiskitError: Invalid ctrl_state.
            ExtensionError: Non-unitary controlled unitary.
        """
        mat = self.to_matrix()
        cmat = _compute_control_matrix(mat, num_ctrl_qubits, ctrl_state=None)
        iso = isometry.Isometry(cmat, 0, 0)
        cunitary = ControlledGate(
            "c-unitary",
            num_qubits=self.num_qubits + num_ctrl_qubits,
            params=[mat],
            label=label,
            num_ctrl_qubits=num_ctrl_qubits,
            definition=iso.definition,
            ctrl_state=ctrl_state,
            base_gate=self.copy(),
        )
        from qiskit.quantum_info import Operator

        # hack to correct global phase; should fix to prevent need for correction here
        pmat = Operator(iso.inverse()).data @ cmat
        diag = numpy.diag(pmat)
        if not numpy.allclose(diag, diag[0]):
            raise ExtensionError("controlled unitary generation failed")
        phase = numpy.angle(diag[0])
        if phase:
            # need to apply to _definition since open controls creates temporary definition
            cunitary._definition.global_phase = phase
        return cunitary
예제 #30
0
    def control(self, num_ctrl_qubits=1, label=None, ctrl_state=None):
        r"""Return controlled version of gate

        Args:
            num_ctrl_qubits (int): number of controls to add to gate (default=1)
            label (str): optional gate label
            ctrl_state (int or str or None): The control state in decimal or as a
                bit string (e.g. '1011'). If None, use 2**num_ctrl_qubits-1.

        Returns:
            UnitaryGate: controlled version of gate.

        Raises:
            QiskitError: invalid ctrl_state
        """
        from qiskit.extensions.quantum_initializer.isometry import Isometry
        cmat = _compute_control_matrix(self.to_matrix(), num_ctrl_qubits)
        iso = Isometry(cmat, 0, 0)
        return ControlledGate('c-unitary',
                              self.num_qubits + num_ctrl_qubits,
                              cmat,
                              definition=iso.definition,
                              label=label)