def _instruction_states(instructions: List[Instruction]) -> List[np.ndarray]: """Construct preparation density matrices from instructions""" states = [] num_qubits = instructions[0].num_qubits init = DensityMatrix.from_int(0, 2**num_qubits) for inst in instructions: states.append(init.evolve(inst).data) return states
def _instruction_povms(instructions: List[Instruction]) -> List[Dict[int, np.ndarray]]: """Construct measurement outcome POVMs from instructions""" basis = [] for inst in instructions: inst_inv = inst.inverse() basis_dict = { i: DensityMatrix.from_int(i, 2**inst.num_qubits).evolve(inst_inv).data for i in range(2**inst.num_qubits) } basis.append(basis_dict) return basis
def _format_povms(povms: Sequence[any]) -> Tuple[Tuple[np.ndarray, ...], ...]: """Format sequence of basis POVMs""" formatted_povms = [] # Convert from operator/channel to POVM effects for povm in povms: if isinstance(povm, (list, tuple)): # POVM is already an effect formatted_povms.append(povm) continue # Convert POVM to operator of quantum channel try: chan = Operator(povm) except QiskitError: chan = SuperOp(povm) adjoint = chan.adjoint() dims = adjoint.input_dims() dim = np.prod(dims) effects = tuple(DensityMatrix.from_int(i, dims).evolve(adjoint) for i in range(dim)) formatted_povms.append(effects) # Format POVM effects to density matrix matrices return tuple(tuple(DensityMatrix(effect).data for effect in povm) for povm in formatted_povms)