def lindbladian_average_infid(ideal: np.ndarray, actual: tf.constant, index=[0], dims=[2]) -> tf.constant: """ Average fidelity uses the Pauli basis to compare. Thus, perfect gates are always 2x2 (per qubit) and the actual unitary needs to be projected down. Parameters ---------- ideal: np.ndarray Contains ideal unitary representations of the gate actual: tf.Tensor Contains actual unitary representations of the gate index : int Index of the qubit(s) in the Hilbert space to be evaluated dims : list List of dimensions of qubits """ U_ideal = tf_super(ideal) actual_comp = tf_project_to_comp(actual, dims=dims, index=index, to_super=True) infid = 1 - tf_superoper_average_fidelity(actual_comp, U_ideal, lvls=dims) return infid
def lindbladian_unitary_infid(ideal: np.ndarray, actual: tf.constant, index=[0], dims=[2]) -> tf.constant: """ Variant of the unitary fidelity for the Lindbladian propagator. Parameters ---------- ideal: np.ndarray Contains ideal unitary representations of the gate actual: tf.Tensor Contains actual unitary representations of the gate index : List[int] Index of the qubit(s) in the Hilbert space to be evaluated dims : list List of dimensions of qubits Returns ------- tf.float Overlap fidelity for the Lindblad propagator. """ U_ideal = tf_super(ideal) actual_comp = tf_project_to_comp(actual, dims=dims, index=index, to_super=True) fid_lvls = 2**len(index) infid = 1 - tf_superoper_unitary_overlap( actual_comp, U_ideal, lvls=fid_lvls) return infid
def unitary_infid(ideal: np.ndarray, actual: tf.Tensor, index: List[int] = None, dims=None) -> tf.Tensor: """ Unitary overlap between ideal and actually performed gate. Parameters ---------- ideal : np.ndarray Ideal or goal unitary representation of the gate. actual : np.ndarray Actual, physical unitary representation of the gate. index : List[int] Index of the qubit(s) in the Hilbert space to be evaluated gate : str One of the keys of propagators, selects the gate to be evaluated dims : list List of dimensions of qubits Returns ------- tf.float Unitary fidelity. """ if index is None: index = list(range(len(dims))) actual_comp = tf_project_to_comp(actual, dims=dims, index=index) fid_lvls = 2**len(index) infid = 1 - tf_unitary_overlap(actual_comp, ideal, lvls=fid_lvls) return infid
def state_transfer_infid(ideal: np.ndarray, actual: tf.constant, index, dims, psi_0): """ Single gate state transfer infidelity. The dimensions of psi_0 and ideal need to be compatible and index and dims need to project actual to these same dimensions. Parameters ---------- ideal: np.ndarray Contains ideal unitary representations of the gate actual: tf.Tensor Contains actual unitary representations of the gate index : int Index of the qubit(s) in the Hilbert space to be evaluated dims : list List of dimensions of qubits psi_0: tf.Tensor Initial state Returns ------- tf.float State infidelity for the selected gate """ actual_comp = tf_project_to_comp(actual, dims=dims, index=index) psi_ideal = tf.matmul(ideal, psi_0) psi_actual = tf.matmul(actual_comp, psi_0) overlap = tf_ketket_fid(psi_ideal, psi_actual) infid = 1 - overlap return infid
def get_error_process(): """Fixture for a constant unitary Returns ------- np.array Unitary on a large Hilbert space that needs to be projected down correctly and compared to an ideal representation in the computational space. """ U_actual = ( 1 / np.sqrt(2) * np.array( [ [1, 0, 0, -1.0j, 0, 0, 0, 0, 0], [0, 1, 0, 0, -1.0j, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [-1.0j, 0, 0, 1, 0, 0, 0, 0, 0], [0, -1.0j, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 45, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], ] ) ) lvls = [3, 3] U_ideal = ( 1 / np.sqrt(2) * np.array( [[1, 0, -1.0j, 0], [0, 1, 0, -1.0j], [-1.0j, 0, 1, 0], [0, -1.0j, 0, 1]] ) ) Lambda = tf.matmul( tf.linalg.adjoint(tf_project_to_comp(U_actual, lvls, to_super=False)), U_ideal ) return Lambda
def get_ideal_gate(self, dims, index=None): if self.ideal is None: raise Exception( "C3:ERROR: No ideal representation definded for gate" f" {self.get_key()}") targets = self.targets if targets is None: targets = list(range(len(dims))) ideal_gate = insert_mat_kron( [2] * len(dims), # we compare to the computational basis targets, [self.ideal], ) if index: ideal_gate = tf_project_to_comp(ideal_gate, dims=[2] * len(dims), index=index) return ideal_gate
def average_infid(ideal: np.ndarray, actual: tf.Tensor, index: List[int] = [0], dims=[2]) -> tf.constant: """ Average fidelity uses the Pauli basis to compare. Thus, perfect gates are always 2x2 (per qubit) and the actual unitary needs to be projected down. Parameters ---------- ideal: np.ndarray Contains ideal unitary representations of the gate actual: tf.Tensor Contains actual unitary representations of the gate index : List[int] Index of the qubit(s) in the Hilbert space to be evaluated dims : list List of dimensions of qubits """ actual_comp = tf_project_to_comp(actual, dims=dims, index=index) fid_lvls = [2] * len(index) infid = 1 - tf_average_fidelity(actual_comp, ideal, lvls=fid_lvls) return infid