def epc_analytical(U_dict: dict, index, dims, proj: bool): # TODO make this work with new index and dims gate = list(U_dict.keys())[0] U = U_dict[gate] num_gates = len(gate.split(':')) lvls = int(U.shape[0] ** (1/num_gates)) fid_lvls = lvls if num_gates == 1: real_cliffords = evaluate_sequences(U_dict, cliffords_decomp) elif num_gates == 2: real_cliffords = evaluate_sequences(U_dict, cliffords_decomp_xId) projection = 'fulluni' if proj: projection = 'wzeros' fid_lvls = 2 ** num_gates ideal_cliffords = perfect_cliffords( lvls, proj=projection, num_gates=num_gates ) fids = [] for C_indx in range(24): C_real = real_cliffords[C_indx] C_ideal = ideal_cliffords[C_indx] ave_fid = tf_average_fidelity(C_real, C_ideal, fid_lvls) fids.append(ave_fid) infid = 1 - tf_ave(fids) return infid
def average_infid( U_dict: dict, gate: str, index, dims, proj=True ): """ 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 ---------- U_dict : dict Contains unitary representations of the gates, identified by a key. index : int Index of the qubit(s) in the Hilbert space to be evaluated dims : list List of dimensions of qubits proj : boolean Project to computational subspace """ U = U_dict[gate] U_ideal = tf.constant( perfect_gate(gate, index, dims=[2]*len(dims)), dtype=tf.complex128 ) infid = 1 - tf_average_fidelity(U, U_ideal, lvls=dims) return infid
def average_infid_simult(U_dict: dict, gate: str, index, dims, proj=True): """ 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. Variant for simultaneous single qubit gates. Parameters ---------- U_dict : dict Contains unitary representations of the gates, identified by a key. index : int Index of the qubit(s) in the Hilbert space to be evaluated dims : list List of dimensions of qubits proj : boolean Project to computational subspace """ proj = projector(dims, index) U = proj @ U_dict[gate] @ proj.T gate_split = gate.split(":") two_qubit_gate = ":".join([gate_split[index[0]], gate_split[index[1]]]) subspace_dims = [dims[index[0]], dims[index[1]]] U_ideal = tf.constant( perfect_gate(two_qubit_gate, index=[0, 1], dims=[2, 2])) infid = 1 - tf_average_fidelity(U, U_ideal, lvls=subspace_dims) return infid
def epc_analytical(U_dict: dict, index, dims, proj: bool, cliffords=False): # TODO check this work with new index and dims (double-check) num_gates = len(dims) if cliffords: real_cliffords = evaluate_sequences(U_dict, [[C] for C in cliffords_string]) elif num_gates == 1: real_cliffords = evaluate_sequences(U_dict, cliffords_decomp) elif num_gates == 2: real_cliffords = evaluate_sequences(U_dict, cliffords_decomp_xId) ideal_cliffords = perfect_cliffords(lvls=[2] * num_gates, num_gates=num_gates) fids = [] for C_indx in range(24): C_real = real_cliffords[C_indx] C_ideal = tf.constant(ideal_cliffords[C_indx], dtype=tf.complex128) ave_fid = tf_average_fidelity(C_real, C_ideal, lvls=dims) fids.append(ave_fid) infid = 1 - tf_ave(fids) return infid
def average_infid_CZ(U_dict: dict, index, dims, eval, proj=True): """ 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. Variant for two-qubit gates. Parameters ---------- U_dict : dict Contains unitary representations of the gates, identified by a key. index : int Index of the qubit(s) in the Hilbert space to be evaluated dims : list List of dimensions of qubits proj : boolean Project to computational subspace """ proj = projector(dims, index) U = proj @ U_dict["Id:CRZp"] @ proj.T subspace_dims = [dims[index[0]], dims[index[1]]] U_ideal = tf.constant(perfect_gate("CRZp", index=[0, 1], dims=[2, 2])) infid = 1 - tf_average_fidelity(U, U_ideal, lvls=subspace_dims) return infid
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