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_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))
Beispiel #3
0
    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
Beispiel #4
0
    def _handle_gate_import(self, circuit, instr, program,
                            qreg_mapping) -> None:
        modifiers = instr.modifiers
        if instr.name in gate_mapping_pyquil:
            # get the instruction
            if "g" in gate_mapping_pyquil[instr.name]:
                instr_qiskit_class = gate_mapping_pyquil[instr.name]["g"]
            # replacement circuit
            elif "r" in gate_mapping_pyquil[instr.name]:
                instr_qiskit_class = gate_mapping_pyquil[instr.name]["r"]
            else:
                raise NameError(
                    "Gate defined in gate mapping but neither gate nor replacement circuit is given: "
                    + str(instr))
            # TODO check if division by pi is necessary (pytket does this)
            params = instr.params
            for i, param in enumerate(params):
                # parameterized circuit --> add Qiskit Parameter Object (convert from Pyquil Parameter Object)
                if isinstance(param, pyquil_Parameter):
                    params[i] = qiskit_Parameter(param.name)

            # reverse needed, because the first operation is at the end of the list (for whatever reason)
            # and modifier are not always commutative

            instr_qiskit = instr_qiskit_class(*params)
        # custom gates
        else:
            gate_found = False
            for gate in program.defined_gates:
                if gate.name == instr.name:
                    gate_found = True
                    if gate.parameters:
                        # no possibility to bind pyquil parameter to value before execution on a device (like the qiskit equivalent assign_parameters)
                        # and no possibility to define parametric custom gates in qiskit
                        raise NotImplementedError(
                            "Cannot convert parameterized custom gates to Qiskit: "
                            + str(instr))
                        # for i, param in enumerate(instr.params):
                        # if isinstance(param, pyquil_Parameter):
                        #     raise NotImplementedError("Cannot convert parameterized custom gates (with general parameter) to Qiskit: " + str(instr))
                        # if isinstance(gate.parameters[i], pyquil_Parameter):
                        #     raise NotImplementedError("Cannot convert parameterized custom gates to Qiskit: " + str(instr))

                    else:
                        instr_qiskit = UnitaryGate(gate.matrix,
                                                   label=gate.name)

            if not gate_found:
                raise NotImplementedError("Unsupported Gate: " + str(instr))

        for modifier in reversed(modifiers):
            if modifier == "CONTROLLED":
                instr_qiskit = instr_qiskit.control(1)
            elif modifier == "DAGGER":
                instr_qiskit = instr_qiskit.inverse()
            else:
                raise NotImplementedError("Unsupported Modifier: " +
                                          str(modifier))

        # get the qubits on which the instruction operates
        qargs = [qreg_mapping[qubit.index] for qubit in instr.qubits]
        circuit.append(instr_qiskit, qargs=qargs)