Esempio n. 1
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
Esempio n. 2
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