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)
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 )
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))
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")