def pauli_measurement_on_stab_list(pauli_measurement, stab_list, outcome=0): """ Updates a list of stabilizers after a measurement is performed """ if not (outcome == 0 or outcome == 1): raise ValueError("Measurement outcome value can be only 0 or 1.") if not isinstance(pauli_measurement, q.Pauli): pauli_meas = q.Pauli(pauli_measurement) else: pauli_meas = pauli_measurement for check_stab in stab_list: if not isinstance(check_stab, q.Pauli): raise ValueError( "All input stabilizers need to be qecc.Pauli objects.") new_pauli_list = copy(stab_list) for stab_ix, this_stab in enumerate(stab_list): if q.com(pauli_meas, this_stab) == 1: anticomm_pauli = this_stab anticomm_pauli.ph = (anticomm_pauli.ph + 2 * outcome) % 4 new_pauli_list[stab_ix].op = pauli_meas.op new_pauli_list[stab_ix].ph = (pauli_meas.ph + 2 * outcome) % 4 break for other_stabs_ix in range(stab_ix, len(stab_list)): this_stab = stab_list[other_stabs_ix] if q.com(pauli_meas, this_stab) == 1: new_pauli_list[other_stabs_ix] = anticomm_pauli * this_stab return new_pauli_list
def single_local_clifford(cgate, pauli, qb_idx): """ Rules for operating an individual Clifford gate on a single Pauli matrix """ if cgate not in CliffordGateList: raise ValueError("Clifford gate needs to be in:", CliffordGateList) if not isinstance(pauli, q.Pauli): raise ValueError("Pauli operator needs to be a qecc.Pauli object.") pauli_op = pauli.op[qb_idx] new_op = list(pauli.op) new_phase = pauli.ph if cgate == 'H': if pauli_op == 'X': new_op[qb_idx] = 'Z' if pauli_op == 'Z': new_op[qb_idx] = 'X' if pauli_op == 'Y': new_phase = (new_phase + 2) % 4 if cgate == "S": if pauli_op == 'X': new_op[qb_idx] = 'Y' if pauli_op == 'Y': new_op[qb_idx] = 'X' new_phase = (new_phase + 2) % 4 new_pauli = q.Pauli("".join(new_op), phase=new_phase) return new_pauli
def one_shot(): """ For the initial part of the in-class demo. Takes a single Pauli and computes one random circuit from the eps-approximate 2-design and applies it to the Pauli. """ print "\n=====================================================================" print "Choosing a single random circuit from an epsilon-approximate 2-design" print "=====================================================================\n" pauli_string = raw_input("Please enter an initial Pauli (e.g. XXYZ): ") epsilon = float(raw_input("Enter a value for epsilon: ")) pauli = q.Pauli(pauli_string) new_pauli = pauli new_circuit = [] for i in range(0, int(log(1/epsilon)) + 1): new_pauli, circuit = uniformization(new_pauli) new_circuit.extend(circuit) print "\nResultant pauli is " print new_pauli print "\nApplied circuit was " print_circuit(new_circuit, pauli.nq) print "\n\n\n"
def distribution(): print "\n=====================================================================" print "Generate statistics for the distribution of Paulis after successive " print "application of circuits chosen randomly from the 2-design" print "=====================================================================\n" pauli_string = raw_input("Please enter an initial Pauli (e.g. XXYZ): ") trials = raw_input("Please enter the number of circuits to generate: ") epsilon = float(raw_input("Enter a value for epsilon: ")) pauli = q.Pauli(pauli_string) circuit_file = open("circuit_file" + "_" + pauli.op + "_" + trials + "_" + str(epsilon) + ".out", 'w') pauli_file = open("pauli_file" + "_" + pauli.op + "_" + trials + "_" + str(epsilon) + ".out", 'w') paulis = [] pauli_counts = [] circuits = [] circuit_counts = [] for i in range(0, int(trials)): next_circuit = [] new_pauli = pauli for j in range(0, int(log(1/epsilon)) + 1): new_pauli, circuit = uniformization(new_pauli) next_circuit.extend(circuit) if next_circuit not in circuits: circuits.append(next_circuit) circuit_counts.append(1) else: circuit_counts[circuits.index(next_circuit)] += 1 if new_pauli.op not in paulis: paulis.append(new_pauli.op) pauli_counts.append(1) else: pauli_counts[paulis.index(new_pauli.op)] += 1 for i in range(0, len(circuits)): print_circuit_to_file(circuits[i], pauli.nq, circuit_file) circuit_file.write('Count: ' + str(circuit_counts[i]) + '\n\n') circuit_file.write("Total number of different circuits: " + str(len(circuits)) + '\n') pauli_probs = [pauli_counts[i]*1.0 / sum(pauli_counts) for i in range(0, len(paulis))] for i in range(0, len(paulis)): pauli_file.write(paulis[i] + "\t" + str(pauli_probs[i])) pauli_file.write('\n') pauli_file.write('\n'+"KL divergence is " + str( entropy(pauli_probs, [1.0/len(paulis)]*len(paulis)) ) )
def __init__(self, stab_generators): # stab_gens represent the n stabilizer generators defining the n-qubit stabilizer state # TODO: various checks, including that if the set in stab_gens are stabilizer but not necessarily # the set of minimal stabilizer generators, it extracts the generators (QECC has such function). # Check that stab_gens is the correct object, and ceonvert it to qecc.Pauli otherwise self.stab_gens = [] for check_stab in stab_generators: if not isinstance(check_stab, q.Pauli): self.stab_gens.append(q.Pauli(check_stab)) else: self.stab_gens.append(check_stab) self.nqbits = len(stab_generators[0])
def appl_pauli(nq, qn, g, stab): pau = ['I'] * nq pau[qn] = g return stab * qe.Pauli(''.join(pau))
def pauli_measurement_on_code(pauli_measurement, stab_gens_list, logical_ops_list, outcome=0): """ Updates stabilizers and logical operators after a measurement is performed """ if not (outcome == 0 or outcome == 1): print(outcome) raise ValueError("Measurement outcome value can be only 0 or 1.") if not isinstance(pauli_measurement, q.Pauli): pauli_meas = q.Pauli(pauli_measurement) else: pauli_meas = pauli_measurement for check_stab in stab_gens_list: if not isinstance(check_stab, q.Pauli): raise ValueError( "All input stabilizers need to be qecc.Pauli objects.") for log_op_zs in logical_ops_list[0]: if not isinstance(log_op_zs, q.Pauli): raise ValueError( "All logical Z operators need to be qecc.Pauli objects.") for log_op_xs in logical_ops_list[1]: if not isinstance(log_op_xs, q.Pauli): raise ValueError( "All logical X operators need to be qecc.Pauli objects.") check_all_comm = True new_stab_gens_list = copy(stab_gens_list) for stab_ix, this_stab in enumerate(stab_gens_list): if q.com(pauli_meas, this_stab) == 1: check_all_comm = False anticomm_pauli = this_stab anticomm_pauli.ph = (anticomm_pauli.ph + 2 * outcome) % 4 new_stab_gens_list[stab_ix].op = pauli_meas.op new_stab_gens_list[stab_ix].ph = (pauli_meas.ph + 2 * outcome) % 4 break for other_stabs_ix in range(stab_ix, len(stab_gens_list)): this_stab = stab_gens_list[other_stabs_ix] if q.com(pauli_meas, this_stab) == 1: new_stab_gens_list[other_stabs_ix] = anticomm_pauli * this_stab new_Z_log_ops_list = copy(logical_ops_list[0]) new_X_log_ops_list = copy(logical_ops_list[1]) # if measurement anticommutes with some stabilizer generator, update logical operators if not check_all_comm: for logop_ix, this_logop in enumerate(logical_ops_list[0]): if q.com(pauli_meas, this_logop) == 1: new_Z_log_ops_list[logop_ix] = anticomm_pauli * this_logop for logop_ix, this_logop in enumerate(logical_ops_list[1]): if q.com(pauli_meas, this_logop) == 1: new_X_log_ops_list[logop_ix] = anticomm_pauli * this_logop return new_stab_gens_list, [new_Z_log_ops_list, new_X_log_ops_list] # if measurement commutes with all stabilizer generators, check that it commutes with all logical operators (i.e. # the measurement is a stabilizer), and if so return the same logical operators. If instead it anticommutes with # some logical operator, it means we measured a logical operator, and thus we collapsed the whole logical state to # an eigenstate of a logical operator. In this case both te stabilizer generators and logical operators would remain # untouched, but here we also raise an error because teleportation can no longer be performed. else: for logop_ix, this_logop in enumerate(logical_ops_list[0]): if (q.com(pauli_meas, logical_ops_list[0][logop_ix]) == 1) or \ (q.com(pauli_meas, logical_ops_list[1][logop_ix]) == 1): raise ValueError( "Performed measurement in a logical operator: logical state is collapsed and " "teleportation can no longer be performed.") return new_stab_gens_list, [new_Z_log_ops_list, new_X_log_ops_list]