def __init__(self, data, input_dims=None, output_dims=None): """Initialize a Chi quantum channel operator.""" if issubclass(data.__class__, BaseOperator): # If not a channel we use `to_operator` method to get # the unitary-representation matrix for input if not issubclass(data.__class__, QuantumChannel): data = data.to_operator() input_dim, output_dim = data.dim chi_mat = _to_chi(data.rep, data._data, input_dim, output_dim) if input_dims is None: input_dims = data.input_dims() if output_dims is None: output_dims = data.output_dims() elif isinstance(data, (list, np.ndarray)): chi_mat = np.array(data, dtype=complex) # Determine input and output dimensions dim_l, dim_r = chi_mat.shape if dim_l != dim_r: raise QiskitError('Invalid Choi-matrix input.') if input_dims: input_dim = np.product(input_dims) if output_dims: output_dim = np.product(input_dims) if output_dims is None and input_dims is None: output_dim = int(np.sqrt(dim_l)) input_dim = dim_l // output_dim elif input_dims is None: input_dim = dim_l // output_dim elif output_dims is None: output_dim = dim_l // input_dim # Check dimensions if input_dim * output_dim != dim_l: raise QiskitError("Invalid shape for Chi-matrix input.") else: raise QiskitError("Invalid input data format for Chi") nqubits = int(np.log2(input_dim)) if 2**nqubits != input_dim: raise QiskitError("Input is not an n-qubit Chi matrix.") # Check and format input and output dimensions input_dims = self._automatic_dims(input_dims, input_dim) output_dims = self._automatic_dims(output_dims, output_dim) super().__init__('Chi', chi_mat, input_dims, output_dims)
def __init__(self, data, input_dims=None, output_dims=None): """Initialize a quantum channel Chi-matrix operator. Args: data (QuantumCircuit or Instruction or BaseOperator or matrix): data to initialize superoperator. input_dims (tuple): the input subsystem dimensions. [Default: None] output_dims (tuple): the output subsystem dimensions. [Default: None] Raises: QiskitError: if input data is not an N-qubit channel or cannot be initialized as a Chi-matrix. Additional Information ---------------------- If the input or output dimensions are None, they will be automatically determined from the input data. The Chi matrix representation is only valid for N-qubit channels. """ # If the input is a raw list or matrix we assume that it is # already a Chi matrix. if isinstance(data, (list, np.ndarray)): # Initialize from raw numpy or list matrix. chi_mat = np.array(data, dtype=complex) # Determine input and output dimensions dim_l, dim_r = chi_mat.shape if dim_l != dim_r: raise QiskitError('Invalid Chi-matrix input.') if input_dims: input_dim = np.product(input_dims) if output_dims: output_dim = np.product(input_dims) if output_dims is None and input_dims is None: output_dim = int(np.sqrt(dim_l)) input_dim = dim_l // output_dim elif input_dims is None: input_dim = dim_l // output_dim elif output_dims is None: output_dim = dim_l // input_dim # Check dimensions if input_dim * output_dim != dim_l: raise QiskitError("Invalid shape for Chi-matrix input.") else: # Otherwise we initialize by conversion from another Qiskit # object into the QuantumChannel. if isinstance(data, (QuantumCircuit, Instruction)): # If the input is a Terra QuantumCircuit or Instruction we # convert it to a SuperOp data = SuperOp._instruction_to_superop(data) else: # We use the QuantumChannel init transform to intialize # other objects into a QuantumChannel or Operator object. data = self._init_transformer(data) input_dim, output_dim = data.dim # Now that the input is an operator we convert it to a Chi object chi_mat = _to_chi(data.rep, data._data, input_dim, output_dim) if input_dims is None: input_dims = data.input_dims() if output_dims is None: output_dims = data.output_dims() # Check input is N-qubit channel n_qubits = int(np.log2(input_dim)) if 2**n_qubits != input_dim: raise QiskitError("Input is not an n-qubit Chi matrix.") # Check and format input and output dimensions input_dims = self._automatic_dims(input_dims, input_dim) output_dims = self._automatic_dims(output_dims, output_dim) super().__init__('Chi', chi_mat, input_dims, output_dims)