Exemple #1
0
    def call_interactive(
        self,
        qureg: tqureg,
        qubits: Sequence[int],
        operators: Sequence[np.ndarray],
    ) -> None:
        r"""Interactive call of PyQuest-cffi

        Args:
            qureg: a qureg containing a density matrix
            qubits: The qubits the Kraus operators are acting on
            operators: The Kraus operators

        Raises:
            RuntimeError: Number of target qubits and dimension of Kraus operators mismatch
            RuntimeError: Not a valid Kraus map
        """
        for op in operators:
            if 2**len(qubits) != op.shape[0] or 2**len(qubits) != op.shape[1]:
                raise RuntimeError(
                    "Number of target qubits" +
                    " and dimension of Kraus operators mismatch")
        operator_sum = np.sum([op.conjugate().T @ op for op in operators],
                              axis=0)
        if not np.isclose(operator_sum, np.eye(operators[0].shape[0])).all():
            raise RuntimeError("Not a valid Kraus map")
        operator_pointers = ffi_quest.new("ComplexMatrixN[{}]".format(
            len(operators)))
        for co, op in enumerate(operators):
            operator_pointers[co] = quest.createComplexMatrixN(
                qureg.numQubitsRepresented)
            for i in range(op.shape[0]):
                for j in range(op.shape[0]):
                    operator_pointers[co].real[i][j] = np.real(op[i, j])
                    operator_pointers[co].imag[i][j] = np.imag(op[i, j])
        pointer_q = ffi_quest.new("int[{}]".format(len(qubits)))
        for co, qubit in enumerate(qubits):
            pointer_q[co] = qubit
        quest.mixMultiQubitKrausMap(qureg, pointer_q, len(qubits),
                                    operator_pointers, len(operators))
        for p in operator_pointers:
            quest.destroyComplexMatrixN(p)
    def call_interactive(
        self,
        qureg: tqureg,
        reals: Union[np.ndarray, List[List[float]]],
        imags: Union[np.ndarray, List[List[float]]],
    ) -> None:
        r"""Interactive call of PyQuest-cffi

        Args:
            qureg: The quantum register of a density matrix
            reals: the new real values of the elements of the density matrix
                between startind and startind+numamps
            imags: the new imaginary values of the elements of the density matrix
                between startind and startind+numamps

        Raises:
            RuntimeError: Qureg has to be a density matrix qureg but wavefunction qureg was used
        """
        reals = list(reals)
        imags = list(imags)
        num_amps = cheat.getNumAmps()(qureg=qureg)

        if not qureg.isDensityMatrix:
            raise RuntimeError("Qureg has to be a density matrix qureg but " +
                               "wavefunction qureg was used")
        for i in range(num_amps):
            j = num_amps * i
            reals_flat = [real[i] for real in reals]
            imags_flat = [imag[i] for imag in imags]
            pointer_reals = ffi_quest.new("{}[{}]".format(
                qreal, len(reals_flat)))
            for co, c in enumerate(reals_flat):
                pointer_reals[co] = c
            pointer_imags = ffi_quest.new("{}[{}]".format(
                qreal, len(imags_flat)))
            for co, c in enumerate(imags_flat):
                pointer_imags[co] = c
            quest.statevec_setAmps(qureg, j, pointer_reals, pointer_imags,
                                   num_amps)
Exemple #3
0
    def call_interactive(self,
                         qureg: tqureg,
                         qubits: Sequence[int],
                         paulis: Sequence[Sequence[int]],
                         workspace: tqureg
                         ) -> float:
        r"""Interactive call of PyQuest-cffi

        Args:
            qureg: quantum register that is measured
            qubits: target qubits
            paulis: List of Pauli operators in the product
                    encoded as int via IDENTITY=0, PAULI_X=1, PAULI_Y=2, PAULI_Z=3
            workspace: A qureg of same type and size as input qureg, is used as temporary
                    work qureg

        Returns:
            float

        Raises:
            RuntimeError: Need the number of qubits and pauli products to be equal
        """
        if not len(qubits) == len(paulis):
            raise RuntimeError("Need the number of qubits and pauli products to be equal")
        flat_list = [p for p in paulis]
        pointer_paulis = ffi_quest.new("enum pauliOpType[{}]".format(len(flat_list)))
        for co, p in enumerate(flat_list):
            pointer_paulis[co] = p
        pointer_q = ffi_quest.new("int[{}]".format(len(qubits)))
        for co, q in enumerate(qubits):
            pointer_q[co] = q
        return quest.calcExpecPauliProd(qureg,
                                        pointer_q,
                                        pointer_paulis,
                                        len(qubits),
                                        workspace
                                        )
Exemple #4
0
    def call_interactive(
        self,
        qureg: tqureg,
        qubit: int,
        operators: Sequence[np.ndarray],
    ) -> None:
        r"""Interactive call of PyQuest-cffi

        Args:
            qureg: a qureg containing a density matrix
            qubit: The qubit the Kraus operators are acting on
            operators: The Kraus operators

        Raises:
            RuntimeError: Qureg has to be a density matrix qureg but wavefunction qureg was used
            RuntimeError: Target qubit is not in the Qureg
            RuntimeError: Too many operators given, must be in [1, 4]
            RuntimeError: Number of target qubits and dimension of Kraus operators mismatch
            RecursionError: Not a valid Kraus map
        """
        if not qureg.isDensityMatrix:
            raise RuntimeError("Qureg has to be a density matrix qureg but " +
                               "wavefunction qureg was used")
        if qubit not in list(range(qureg.numQubitsRepresented)):
            raise RuntimeError("Target qubit is not in the Qureg")
        if len(operators) < 1 or len(operators) > 4:
            raise RuntimeError("Too many operators given, must be in [1, 4]")
        for op in operators:
            if op.shape[0] != 2 or op.shape[1] != 2:
                raise RuntimeError(
                    "Number of target qubits" +
                    " and dimension of Kraus operators mismatch")

        operator_sum = np.sum([op.conjugate().T @ op for op in operators],
                              axis=0)
        if not np.isclose(operator_sum, np.eye(2)).all():
            raise RecursionError("Not a valid Kraus map")
        operator_pointers = ffi_quest.new("ComplexMatrix2[{}]".format(
            len(operators)))
        for co, op in enumerate(operators):
            for i in range(2):
                for j in range(2):
                    operator_pointers[co].real[i][j] = float(np.real(op[i][j]))
                    operator_pointers[co].imag[i][j] = float(np.imag(op[i][j]))

        quest.mixKrausMap(qureg, qubit, operator_pointers, len(operators))
    def call_interactive(
        self,
        qureg: tqureg,
        target_qubit_1: Sequence[int],
        target_qubit_2: Sequence[int],
        operators: Sequence[np.ndarray],
    ) -> None:
        r"""Interactive call of PyQuest-cffi

        Args:
            qureg: a qureg containing a density matrix
            target_qubit_1: The least significant qubit the Kraus operators are acting on
            target_qubit_2: The most significant qubit the Kraus operators are acting on
            operators: The Kraus operators

        Raises:
            RuntimeError: Number of target qubits and dimension of Kraus operators mismatch
            RuntimeError: Not a valid Kraus map
        """
        for op in operators:
            if op.shape[0] != 4 or op.shape[1] != 4:
                raise RuntimeError(
                    "Number of target qubits" +
                    " and dimension of Kraus operators mismatch")
        operator_sum = np.sum([op.conjugate().T @ op for op in operators],
                              axis=0)
        if not np.array_equal(operator_sum, np.eye(4)):
            raise RuntimeError("Not a valid Kraus map")
        operator_pointers = ffi_quest.new("ComplexMatrix4[{}]".format(
            len(operators)))
        for co, op in enumerate(operators):
            for i in range(4):
                for j in range(4):
                    operator_pointers[co].real[i][j] = np.real(op[i, j])
                    operator_pointers[co].imag[i][j] = np.imag(op[i, j])
        quest.mixTwoQubitKrausMap(qureg, target_qubit_1, target_qubit_2,
                                  operator_pointers, len(operators))
Exemple #6
0
 def call_interactive(
     self,
     qureg: tqureg,
     qubit: int,
     operators: Sequence[np.ndarray],
 ) -> None:
     """Interactive call of QuEST function"""
     for op in operators:
         if op.shape[0] != 2 or op.shape[1] != 2:
             raise RuntimeError(
                 "Number of target qubits" +
                 " and dimension of Kraus operators mismatch")
     operator_sum = np.sum([op.conjugate().T @ op for op in operators],
                           axis=0)
     if not np.array_equal(operator_sum, np.eye(2)):
         raise RecursionError("Not a valid Kraus map")
     operator_pointers = ffi_quest.new("ComplexMatrix2[{}]".format(
         len(operators)))
     for co, op in enumerate(operators):
         for i in range(2):
             for j in range(2):
                 operator_pointers[co].real[i][j] = np.real(op[i, j])
                 operator_pointers[co].imag[i][j] = np.imag(op[i, j])
     quest.mixKrausMap(qureg, qubit, operator_pointers, len(operators))
    def call_interactive(self, qureg: tqureg, reals: Union[np.ndarray,
                                                           List[float]],
                         imags: Union[np.ndarray, List[float]]) -> None:
        r"""Interactive call of PyQuest-cffi

        Args:
            qureg: the quantum register
            reals: The real parts of the statevector
            imags: The imaginary parts of the statevector

        Raises:
            RuntimeError: Size of reals and imags needs to match
            RuntimeError: Shape of reals and imags for wavefunction should be: (1, 2**qubits)
            RuntimeError: Shape of reals and imags for density matrix should be:
                (2**qubits, 2**qubits) OR (4**qubits, 1)
            RuntimeError: Shape of reals and imags for density matrix should be:
                (2**qubits, 2**qubits) OR (4**qubits, 1)
            RuntimeError: Need to set real and imaginary amplitudes for each qubit:
                2**qubits for wavefunction qureg, 4**qubits for density matrix qureg
        """
        reals = list(reals)
        imags = list(imags)
        assert len(reals) == np.max(np.shape(reals))
        assert len(imags) == np.max(np.shape(imags))
        size_amps = np.size(np.array(reals))
        if not size_amps == np.size(np.array(imags)):
            raise RuntimeError("Size of reals and imags needs to match")
        num_qubits = cheat.getNumQubits()(qureg=qureg)

        if size_amps == 2**num_qubits:
            if qureg.isDensityMatrix:
                raise RuntimeError(
                    "Shape of reals and imags for wavefunction should be: " +
                    "(1, 2**qubits)")
            pointer_reals = ffi_quest.new("{}[{}]".format(qreal, len(reals)))
            for co, c in enumerate(reals):
                pointer_reals[co] = c
            pointer_imags = ffi_quest.new("{}[{}]".format(qreal, len(imags)))
            for co, c in enumerate(imags):
                pointer_imags[co] = c
            quest.initStateFromAmps(qureg, pointer_reals, pointer_imags)
        elif size_amps == 4**num_qubits:
            if not qureg.isDensityMatrix:
                raise RuntimeError(
                    "Shape of reals and imags for density matrix should be:" +
                    "(2**qubits, 2**qubits) OR (4**qubits, 1)")
            size_amps_rows = np.size(np.array(reals), 0)
            size_amps_columns = np.size(np.array(reals), 1)
            if (not (size_amps_rows == np.size(np.array(imags), 0))
                    or not (size_amps_columns == np.size(np.array(imags), 1))):
                raise RuntimeError("Size of reals and imags needs to match")
            cheat.initZeroState()(qureg=qureg)
            if (size_amps_rows == size_amps_columns == 2**num_qubits):
                cheat.setDensityAmps()(qureg=qureg, reals=reals, imags=imags)
            elif size_amps_rows == 4**num_qubits:
                reals = np.array(reals).reshape((2**num_qubits, 2**num_qubits))
                imags = np.array(imags).reshape((2**num_qubits, 2**num_qubits))
                cheat.setDensityAmps()(qureg=qureg, reals=reals, imags=imags)
            else:
                raise RuntimeError(
                    "Shape of reals and imags should be (2**qubits, 2**qubits) OR "
                    + "(4**qubits, 1)")
        else:
            raise RuntimeError(
                "Need to set real and imaginary amplitudes for each qubit: " +
                "2**qubits for wavefunction, 4**qubits for density matrix")