def makeOracle(q0, q1, secretFunction): """ Gates implementing the secret function f(x).""" if secretFunction[0]: yield [CNOT(q0, q1), X(q1)] if secretFunction[1]: yield CNOT(q0, q1)
def __call__(self, qubits): q0, q1, q2 = qubits yield rx(sympy.Symbol("rad0")).on(q0) yield CNOT(q0, q1) yield H(q2) yield CNOT(q2, q1) yield TOFFOLI(q1, q0, q2)
def make_oracle(q0, q1, secret_function): """ Gates implementing the secret function f(x).""" # coverage: ignore if secret_function[0]: yield [CNOT(q0, q1), X(q1)] if secret_function[1]: yield CNOT(q0, q1)
def test_aqt_device_wrong_op_str(): circuit = Circuit() q0, q1 = LineQubit.range(2) circuit.append(CNOT(q0, q1)**1.0) for op in circuit.all_operations(): with pytest.raises(ValueError): _result = get_op_string(op)
def twoLevelControlledRy(circuit, l, angle, k, externalControl, reg, workReg): """ Implements two level Ry rotation from state |0> to |k>, if externalControl qubit is on for reference: http://www.physics.udel.edu/~msafrono/650/Lecture%206.pdf """ grayList = generateGrayList(l, k) # handle the case where l=0 or 1 if k == 0: return if l == 1 and k == 1: circuit.append(cirq.ry(angle).controlled().on(externalControl, reg[0])) return # swap states according to Gray Code until one step before the end for element in grayList: targetQub = element[0] number = element[1] number = number[0:targetQub] + number[targetQub + 1:] controlQub = numberControl(circuit, l - 1, number, reg[0:targetQub] + reg[targetQub + 1:], workReg) if element == grayList[-1]: # reached end circuit.append(TOFFOLI(controlQub, externalControl, workReg[l - 2]), strategy=new) circuit.append( cirq.ry(angle).controlled().on(workReg[l - 2], reg[targetQub])) circuit.append(TOFFOLI(controlQub, externalControl, workReg[l - 2]), strategy=new) else: # swap states circuit.append(CNOT(controlQub, reg[targetQub]), strategy=new) numberControlT(circuit, l - 1, number, reg[0:targetQub] + reg[targetQub + 1:], workReg) # undo for element in reverse(grayList[:-1]): targetQub = element[0] number = element[1] number = number[0:targetQub] + number[targetQub + 1:] controlQub = numberControl(circuit, l - 1, number, reg[0:targetQub] + reg[targetQub + 1:], workReg) circuit.append(CNOT(controlQub, reg[targetQub]), strategy=new) numberControlT(circuit, l - 1, number, reg[0:targetQub] + reg[targetQub + 1:], workReg) return
def U_h(circuit, l, n_i, m, n_phiReg, w_phiReg, n_aReg, w_aReg, n_bReg, w_bReg, wReg, eReg, pReg, hReg, w_hReg, P_phi, P_a, P_b): """Implement U_h from paper""" # for k in range(n_i + m): for k in range(1): countsList = generateParticleCounts( n_i, m, k) # reduce the available number of particles for counts in [countsList[0]]: n_phi, n_a, n_b = counts[0], counts[1], counts[2] # controlled R-y from |0> to |k> on all qubits with all possible angles depending on n_phi, n_a, n_b, and flavor for flavor in ['phi']: # for flavor in ['phi', 'a', 'b']: angle = U_hAngle(flavor, n_phi, n_a, n_b, P_phi, P_a, P_b) # add in x gates for checking phiControl = numberControl(circuit, l, n_phi, n_phiReg, w_phiReg) print("cirq phiControl: ", phiControl) aControl = numberControl(circuit, l, n_a, n_aReg, w_aReg) print("cirq aControl: ", aControl) # bControl = numberControl(circuit, l, n_b, n_bReg, w_bReg) print("cirq wReg[0]: ", wReg[0]) # circuit.append(TOFFOLI(phiControl, aControl, wReg[0]), strategy=new) # circuit.append(TOFFOLI(bControl, wReg[0], wReg[1]), strategy=new) flavorControl( circuit, flavor, pReg[k], wReg[2], wReg[4]) # wReg[4] is work qubit but is reset to 0 # circuit.append(TOFFOLI(wReg[1], wReg[2], wReg[3]), strategy=new) # circuit.append(TOFFOLI(eReg[0], wReg[3], wReg[4]), strategy=new) # # # print("m ", m) # # print("hReg[m]: ",hReg[m]) # # twoLevelControlledRy(circuit, l, angle, k+1, wReg[4], hReg[m], w_hReg) # # circuit.append(TOFFOLI(eReg[0], wReg[3], wReg[4]), strategy=new) # next steps undo work qubits # circuit.append(TOFFOLI(wReg[1], wReg[2], wReg[3]), strategy=new) # flavorControl(circuit, flavor, pReg[k], wReg[2], wReg[4]) # circuit.append(TOFFOLI(bControl, wReg[0], wReg[1]), strategy=new) # circuit.append(TOFFOLI(phiControl, aControl, wReg[0]), strategy=new) # numberControlT(circuit, l, n_b, n_bReg, w_bReg) # numberControlT(circuit, l, n_a, n_aReg, w_aReg) # numberControlT(circuit, l, n_phi, n_phiReg, w_phiReg) # subtract from the counts register depending on which flavor particle emitted for flavor, countReg, workReg in zip(['phi', 'a', 'b'], [n_phiReg, n_aReg, n_bReg], [w_phiReg, w_aReg, w_bReg]): flavorControl(circuit, flavor, pReg[k], wReg[0], wReg[1]) minus1(circuit, l, countReg, workReg, wReg[0], wReg[1], 0) flavorControl(circuit, flavor, pReg[k], wReg[0], wReg[1]) # apply x on eReg if hReg[m] = 0, apply another x so we essentially control on not 0 instead of 0 isZeroControl = numberControl(circuit, l, 0, hReg[m], w_hReg) circuit.append(CNOT(isZeroControl, eReg[0])) circuit.append(X(eReg[0]), strategy=new) numberControlT(circuit, l, 0, hReg[m], w_hReg)
def test_represent_operations_in_circuit_local(circuit_type: str): """Tests all operation representations are created.""" qreg = LineQubit.range(2) circ_mitiq = Circuit([CNOT(*qreg), H(qreg[0]), Y(qreg[1]), CNOT(*qreg)]) circ = convert_from_mitiq(circ_mitiq, circuit_type) reps = represent_operations_in_circuit_with_local_depolarizing_noise( ideal_circuit=circ, noise_level=0.1, ) for op in convert_to_mitiq(circ)[0].all_operations(): found = False for rep in reps: if _equal(rep.ideal, Circuit(op), require_qubit_equality=True): found = True assert found # The number of reps. should match the number of unique operations assert len(reps) == 3
def plus1(circuit, l, countReg, workReg, control, ancilla, level): """ Recursively add 1 to the LSB of a register and carries to all bits, if control == 1 l: number of qubits in count register countReg, workReg: count register and associated work register control: control qubit to determine if plus1 should be executed ancilla: extra work qubit level: current qubit we are operating on, recursively travels from qubit 0 to l-1 """ # apply X to LSB if level == 0: circuit.append(CNOT(control, countReg[0]), strategy=new) if level < l - 1: # first level uses CNOT instead of TOFFOLI gate if level == 0: # move all X gates to first step to avoid unnecesarry gates circuit.append([X(qubit) for qubit in countReg], strategy=new) circuit.append(TOFFOLI(countReg[0], control, workReg[0]), strategy=new) else: circuit.append(TOFFOLI(countReg[level], workReg[level - 1], ancilla), strategy=new) circuit.append(TOFFOLI(ancilla, control, workReg[level]), strategy=new) circuit.append(TOFFOLI(countReg[level], workReg[level - 1], ancilla), strategy=new) circuit.append(TOFFOLI(workReg[level], control, countReg[level + 1]), strategy=new) # recursively call next layer print("countReg ", countReg) plus1(circuit, l, countReg, workReg, control, ancilla, level + 1) # undo work qubits (exact opposite of first 7 lines - undoes calculation) if level == 0: circuit.append(TOFFOLI(countReg[0], control, workReg[0]), strategy=new) circuit.append([X(qubit) for qubit in countReg], strategy=new) else: circuit.append(TOFFOLI(countReg[level], workReg[level - 1], ancilla), strategy=new) circuit.append(TOFFOLI(ancilla, control, workReg[level]), strategy=new) circuit.append(TOFFOLI(countReg[level], workReg[level - 1], ancilla), strategy=new)
def get_cnot_circuit(control_line, target_line): cnot_circuit = Circuit() cnot_circuit.append([CNOT(control_line, target_line)], strategy=InsertStrategy.EARLIEST) return cnot_circuit
def oracle_method(first_param, second_param, secret_function): if secret_function[0]: yield CNOT(first_param, second_param), X(second_param) if secret_function[1]: yield CNOT(first_param, second_param)
@pytest.mark.parametrize("gate", [X, Y, Z, CNOT]) def test_sample_sequence_types(gate: Gate): num_qubits = gate.num_qubits() qreg = LineQubit.range(num_qubits) for _ in range(1000): imp_seq, sign, norm = sample_sequence(gate.on(*qreg), DECO_DICT) assert all([isinstance(op, Operation) for op in imp_seq]) assert sign in {1, -1} assert norm > 1 @pytest.mark.parametrize("seed", (1, 2, 3, 5)) @pytest.mark.parametrize("seed_type", (int, np.random.RandomState)) @pytest.mark.parametrize( "op", [X(qreg[0]), Y(qreg[0]), Z(qreg[0]), CNOT(*qreg)]) def test_sample_sequence_random_state(seed, seed_type, op): decomposition = _simple_pauli_deco_dict(0.5) if isinstance(seed_type, np.random.RandomState): seed = np.random.RandomState(seed) sequence, sign, norm = sample_sequence(op, decomposition, random_state=seed) for _ in range(20): if isinstance(seed_type, np.random.RandomState): seed = np.random.RandomState(seed) new_sequence, new_sign, new_norm = sample_sequence(op, decomposition, random_state=seed)
def makeOracle(q0, q1, secretFunction): if secretFunction[0]: yield [CNOT(q0, q1), X(q1)] if secretFunction[1]: yield CNOT(q0, q1)
def exponentiate_general_case(pauli_string, param): """ Returns a Circuit object corresponding to the exponential of the `pauli_string` object, i.e. exp(-1.0j * param * pauli_string) Parameters: ---------- pauli_string : (PauliString object) represents the Pauli term to exponentiate param : (float) scalar, non-complex, value Returns: ------- circuit : (Circuit) represents a parameterized circuit corresponding to the exponential of the input `pauli_string` and parameter `param` """ def reverse_circuit_operations(c): reverse_circuit = Circuit() operations_in_c = [] reverse_operations_in_c = [] for operation in c.all_operations(): operations_in_c.append(operation) reverse_operations_in_c = inverse(operations_in_c) for operation in reverse_operations_in_c: reverse_circuit.append( [operation], strategy=InsertStrategy.EARLIEST) return reverse_circuit circuit = Circuit() change_to_z_basis = Circuit() change_to_original_basis = Circuit() cnot_seq = Circuit() prev_qubit = None highest_target_qubit = None for qubit, pauli in pauli_string.items(): if pauli == X: change_to_z_basis.append( [H(qubit)], strategy=InsertStrategy.EARLIEST) change_to_original_basis.append( [H(qubit)], strategy=InsertStrategy.EARLIEST) elif pauli == Y: RX = Rx(np.pi/2.0) change_to_z_basis.append( [RX(qubit)], strategy=InsertStrategy.EARLIEST) RX = inverse(RX) change_to_original_basis.append( [RX(qubit)], strategy=InsertStrategy.EARLIEST) if prev_qubit is not None: cnot_seq.append([CNOT(prev_qubit, qubit)], strategy=InsertStrategy.EARLIEST) prev_qubit = qubit highest_target_qubit = qubit circuit += change_to_z_basis circuit += cnot_seq RZ = Rz(2.0 * pauli_string.coefficient * param) circuit.append([RZ(highest_target_qubit)], strategy=InsertStrategy.EARLIEST) circuit += reverse_circuit_operations(cnot_seq) circuit += change_to_original_basis return circuit
import unittest import ddt from cirq import rx, Z, CNOT from paulicirq.linear_combinations import * q0, q1, q2 = cirq.LineQubit.range(3) op_tuple_1 = (rx(sympy.Symbol("θ"))(q0), CNOT(q2, q1)) op_tuple_2 = (CNOT(q0, q2), Z(q1)) m1 = cirq.Moment(op_tuple_1) m2 = cirq.Moment(op_tuple_2) @ddt.ddt class LinearSymbolicDictTest(unittest.TestCase): """ A test class for `LinearSymbolicDict`, `LinearCombinationOfMoments`, and `LinearCombinationOfOperations` in `paulicirq.gates.linear_combinations`. """ @ddt.unpack @ddt.data([LinearCombinationOfOperations, op_tuple_1, op_tuple_2], [LinearCombinationOfMoments, m1, m2]) def test_numerical(self, _type, term1, term2): c1 = 0.123 c2 = 0.589 lc1 = _type({term1: c1, term2: c2})