def test_expectation_value() -> None:
    c = Circuit(2)
    c.H(0)
    c.CX(0, 1)
    op = QubitPauliOperator({
        QubitPauliString({
            Qubit(0): Pauli.Z,
            Qubit(1): Pauli.Z
        }):
        1.0,
        QubitPauliString({
            Qubit(0): Pauli.X,
            Qubit(1): Pauli.X
        }):
        0.3,
        QubitPauliString({
            Qubit(0): Pauli.Z,
            Qubit(1): Pauli.Y
        }):
        0.8j,
        QubitPauliString({Qubit(0): Pauli.Y}):
        -0.4j,
    })
    b = MyBackend()
    b.compile_circuit(c)
    assert get_operator_expectation_value(c, op, b) == pytest.approx(1.3)
def test_sampler_expectation_value() -> None:
    c = Circuit(2)
    c.H(0)
    c.CX(0, 1)
    op = QubitPauliOperator({
        QubitPauliString({
            Qubit(0): Pauli.Z,
            Qubit(1): Pauli.Z
        }):
        1.0,
        QubitPauliString({
            Qubit(0): Pauli.X,
            Qubit(1): Pauli.X
        }):
        0.3,
        QubitPauliString({
            Qubit(0): Pauli.Z,
            Qubit(1): Pauli.Y
        }):
        0.8j,
        QubitPauliString({Qubit(0): Pauli.Y}):
        -0.4j,
    })
    b = MySampler()
    b.compile_circuit(c)
    expectation = get_operator_expectation_value(c,
                                                 op,
                                                 b,
                                                 n_shots=2000,
                                                 seed=0)
    assert (np.real(expectation), np.imag(expectation)) == pytest.approx(
        (1.3, 0.0), abs=0.1)
Exemple #3
0
def gen_pauli_measurement_circuits(state_circuit, compiler_pass, operator):
    # compile main circuit once
    state_cu = CompilationUnit(state_circuit)
    compiler_pass.apply(state_cu)
    compiled_state = state_cu.circuit
    final_map = state_cu.final_map
    # make a measurement circuit for each pauli
    pauli_circuits = []
    coeffs = []
    energy = 0
    for p, c in operator.terms.items():
        if p == ():
            # constant term
            energy += c
        else:
            # make measurement circuits and compile them
            pauli_circ = Circuit(state_circuit.n_qubits -
                                 1)  # ignore syndrome qubit
            append_pauli_measurement(qps_from_openfermion(p), pauli_circ)
            pauli_cu = CompilationUnit(pauli_circ)
            compiler_pass.apply(pauli_cu)
            pauli_circ = pauli_cu.circuit
            init_map = pauli_cu.initial_map
            # map measurements onto the placed qubits from the state
            rename_map = {
                i: final_map[o]
                for o, i in init_map.items() if o in final_map
            }
            pauli_circ.rename_units(rename_map)
            state_and_measure = compiled_state.copy()
            state_and_measure.append(pauli_circ)
            pauli_circuits.append(state_and_measure)
            coeffs.append(c)
    return pauli_circuits, coeffs, energy
Exemple #4
0
def phi(qubits, alpha, n_qubits):
    c = Circuit(n_qubits)
    for i in range(len(qubits) - 1):
        c.CX(qubits[i], qubits[i + 1])
    c.Rz(qubits[-1], alpha)
    for i in range(len(qubits) - 1):
        c.CX(qubits[-i - 2], qubits[-i - 1])
    return c
def test_bell() -> None:
    c = Circuit(2)
    c.H(0)
    c.CX(0, 1)
    b = MyBackend()
    b.compile_circuit(c)
    assert np.allclose(b.get_state(c),
                       np.asarray([1, 0, 0, 1]) * 1 / np.sqrt(2))
Exemple #6
0
def ucc(params):
    ansatz = Circuit(4)
    ansatz.X(1).X(3)
    add_excitation(ansatz, singles_a, params[0])
    add_excitation(ansatz, singles_b, params[1])
    add_excitation(ansatz, doubles, params[2])
    DecomposeBoxes().apply(ansatz)
    return ansatz
def test_basisorder() -> None:
    c = Circuit(2)
    c.X(1)
    b = MyBackend()
    b.compile_circuit(c)
    assert np.allclose(b.get_state(c), np.asarray([0, 1, 0, 0]))
    assert np.allclose(b.get_state(c, basis=BasisOrder.dlo),
                       np.asarray([0, 0, 1, 0]))
 def sq(a, b, c):
     circ = Circuit(1)
     if c != 0:
         circ.Rz(c, 0)
     if b != 0:
         circ.Rx(b, 0)
     if a != 0:
         circ.Rz(a, 0)
     return circ
Exemple #9
0
def hea(params):
    ansatz = Circuit(4)
    for i in range(4):
        ansatz.Ry(params[i], i)
    for i in range(3):
        ansatz.CX(i, i + 1)
    for i in range(4):
        ansatz.Ry(params[4 + i], i)
    return ansatz
Exemple #10
0
def approximate_with_cnots(unitary):
    n_qubits = int(math.log(unitary.shape[0], 2))
    mnots = function_to_mnots(
        matrix_to_function(suggest_cnot_unitary(unitary), n_qubits), n_qubits)
    circs = mnot_templates(n_qubits)
    c = Circuit(n_qubits)
    for mnot in mnots:
        n_controls = len(mnot[0])
        c.add_circuit(circs[n_controls - 1], mnot[0] + [mnot[1]])
    return c
def test_sampler_basisorder() -> None:
    c = Circuit(2, 2)
    c.X(1)
    c.measure_all()
    b = MySampler()
    b.compile_circuit(c)
    assert b.get_counts(c, n_shots=10, seed=0) == {(0, 1): 10}
    assert b.get_counts(c, n_shots=10, seed=0, basis=BasisOrder.dlo) == {
        (1, 0): 10
    }
Exemple #12
0
def cnot_unitary_to_circuit(u, n_qubits):
    # desc = greedy(matrix_to_function(u, n_qubits), n_qubits)  # Doesn't converge, don't run this
    desc = decompose_unitary(u)
    c = Circuit(n_qubits)
    for d in desc:
        if d[0] == "N":
            c.X(int(d[2:]))
        elif d[0] == "C":
            c.CX(int(d.split(":")[1]), int(d.split(":")[2]))
    return c
Exemple #13
0
def U(s, n_qubits):
    c = Circuit(n_qubits)
    for i in range(len(s)):
        if s[i] == "X":
            c.H(i)
        elif s[i] == "Y":
            c.Rx(i, 0.5)
        elif s[i] == "Z":
            pass
    return c
 def to_tket(self):
     if self.out_par != mat22partition(Mat2.id(self.n_qubits)):
         print(self.out_par)
         raise NotImplementedError("The linear transformation part of the phase polynomial cannot yet be transformed into a tket circuit")
     circuit = TketCircuit(self.n_qubits)
     for parity, phase in self.zphases.items():
         qubits = [i for i,s in enumerate(parity) if s == '1']
         circuit.add_pauliexpbox(PauliExpBox([Pauli.Z]*len(qubits), phase), qubits)
     # TODO add the linear combination part with CNOTs
     Transform.DecomposeBoxes().apply(circuit)
     return circuit
def add_params_to_template(template: Circuit, params: np.ndarray):
    params = params.reshape((template.n_gates * 2 + template.n_qubits, 3))
    c = Circuit(template.n_qubits)
    for i in range(template.n_gates):
        cnot_gate = template.get_commands()[i]
        c.add_operation(OpType.U3, params[2 * i], [cnot_gate.qubits[0]])
        c.add_operation(OpType.U3, params[2 * i + 1], [cnot_gate.qubits[1]])
        c.CX(cnot_gate.qubits[0], cnot_gate.qubits[1])
    for q in range(template.n_qubits):
        c.add_operation(OpType.U3, params[template.n_gates * 2 + q], [q])
    return c
Exemple #16
0
def measure_x(quantum_circuit: Circuit, qubit: int, bit: int) -> None:
    """Measures a specified qubit in the Hadamard (X) basis.

    Args:
        quantum_circuit (pytket.circuit.Circuit): The quantum circuit to apply the measurement to.
        qubit (int): The qubit to measure.
        bit (int): The bit to save the qubit measurement result into.
    """
    # Apply Hadamard gate to the qubit.
    # Measure the qubit into the bit.
    quantum_circuit.H(qubit)
    quantum_circuit.Measure(qubit, bit)
Exemple #17
0
def ucc(params):
    ansatz = Circuit(4)
    # Set initial reference state
    ansatz.X(1).X(3)
    # Evolve by excitations
    for term, coeff in singles_a.items():
        add_operator_term(ansatz, term, coeff * params[0])
    for term, coeff in singles_b.items():
        add_operator_term(ansatz, term, coeff * params[1])
    for term, coeff in doubles.items():
        add_operator_term(ansatz, term, coeff * params[2])
    return ansatz
Exemple #18
0
def get_pauli_expectation(c: Circuit,
                          initial_circuit: Circuit,
                          pauli_string: str,
                          backend,
                          shots: int = 100) -> float:
    n_qubits = len(pauli_string)
    circuit = initial_circuit.copy()
    circuit.add_circuit(c.copy(), list(range(n_qubits)))
    black_box_exp = backend.get_pauli_expectation_value(
        circuit, [(i, pauli_string[i])
                  for i in range(len(pauli_string)) if pauli_string[i] != "I"],
        shots=shots).real
    return black_box_exp
def test_sampler_compilation_pass() -> None:
    b = MySampler()
    for opt_level in range(3):
        c = Circuit(2)
        c.CX(0, 1)
        u = np.asarray([[0, 1], [-1j, 0]])
        c.add_unitary1qbox(Unitary1qBox(u), 1)
        c.CX(0, 1)
        c.add_gate(OpType.CRz, 0.35, [1, 0])
        c.measure_all()
        assert not (b.valid_circuit(c))
        b.compile_circuit(c, optimisation_level=opt_level)
        assert b.valid_circuit(c)
def instructions_to_circuit(instructions):
    c = Circuit(n_qubit)
    for inst in instructions:
        t = inst.op.get_type()
        c.add_operation(t, inst.op.get_params(), inst.qubits)
    return c


# circ = instructions_to_circuit(circ.get_commands()[:24])

# print(circ.n_gates)

# print(dag_to_circuit(tk_to_dagcircuit(circ)))
 def test_transpile_grid_circuit(self):
     c = Circuit()
     qb = pytket._tket.circuit.Qubit("grid", 0, 0)
     c.add_qubit(qb)
     c.Rz(1, qb)
     qsc = jaqal_circuit_from_tket_circuit(c)
     jcirc = CircuitBuilder()
     reg = jcirc.register("baseregister", 1)
     reg2 = jcirc.map("grid0_0", reg, slice(0, 1, 1))
     block = jcirc.block()
     block.gate("prepare_all")
     block.gate("Rz", reg2[0], pi)
     block.gate("measure_all")
     self.assertEqual(generate_jaqal_program(jcirc.build()),
                      generate_jaqal_program(qsc))
def approximate_via_cnots(unitary):
    dim = unitary.shape[0]
    n_qubits = int(math.log(dim, 2))
    converter.n_qubits = n_qubits
    r = RewriteTket(Circuit(n_qubits), [], [])
    r.set_target_unitary(unitary)
    # cnot_circuit = approximate_with_cnots(unitary)
    cnot_circuit = qft3
    # print(dag_to_circuit(tk_to_dagcircuit(cnot_circuit)))
    n_params = (cnot_circuit.n_gates * 2 + n_qubits) * 3

    def distance(params):
        f = r.fidelity(add_params_to_template(cnot_circuit, params))
        return (1 - max(0, f)**0.5)**0.5

    best_distance = 1
    best_circ = None
    for _ in range(10):
        initial = np.random.random((n_params, ))
        res = scipy.optimize.minimize(distance,
                                      initial,
                                      method='SLSQP',
                                      options={'ftol': 0.01},
                                      callback=lambda x: print(distance(x)))
        if res.success and res.fun < best_distance:
            best_distance = res.fun
            best_circ = add_params_to_template(cnot_circuit, res.x)
            if res.fun < 0.01:
                return best_circ, best_distance
    return best_circ, best_distance
def simulated_annealing(unitary, n_layers):
    dim = unitary.shape[0]
    n_qubits = int(math.log(dim, 2))
    converter.n_qubits = n_qubits
    n_cnots = (n_layers // 2) * (n_qubits // 2) + ((n_qubits - 1) // 2) * (
        (n_layers + 1) // 2)
    r = RewriteTket(Circuit(n_qubits), [], [])
    r.set_target_unitary(unitary)
    skips = []
    circuit, distance = approximate_scipy(unitary, n_layers, r, [])
    for k in range(10):
        new_skip = random.choice([i for i in range(n_cnots) if i not in skips])
        print("maybe I will skip", new_skip)
        new_circ, new_d = approximate_scipy(unitary, n_layers, r,
                                            skips + [new_skip])
        if new_d <= distance:  # or random.random() < (1 - new_d + distance) / (5 * k + 1):
            print("skipping", new_skip)
            circuit, distance, skips = new_circ, new_d, skips + [new_skip]
        else:
            print("not skipping", new_skip)
        print(circuit.n_gates, circuit.n_gates_of_type(OpType.CX))
        if distance < 0.01:
            print("returning early", distance)
            return circuit, r.fidelity(circuit)
    print(distance)
    return circuit, r.fidelity(circuit)
Exemple #24
0
def measurement_circuits(hamiltonian, n_qubits):
    all_circs = []
    for pauli, _ in hamiltonian.terms.items():
        if not pauli:
            continue  # Ignore the constant term
        measure_circ = Circuit(n_qubits, n_qubits)
        for qb, p in pauli:
            if p == 'I':
                continue  # Discard I qubits
            elif p == 'X':
                measure_circ.H(qb)
            elif p == 'Y':
                measure_circ.Rx(0.5, qb)
            measure_circ.Measure(qb, qb)
        all_circs.append(measure_circ)
    return all_circs
Exemple #25
0
def ucc(params):
    singles_params = {qps: params[0] * coeff for qps, coeff in singles.items()}
    doubles_params = {qps: params[1] * coeff for qps, coeff in doubles.items()}
    excitation_op = QubitPauliOperator({**singles_params, **doubles_params})
    reference_circ = Circuit(4).X(1).X(3)
    ansatz = gen_term_sequence_circuit(excitation_op, reference_circ)
    GuidedPauliSimp().apply(ansatz)
    FullPeepholeOptimise().apply(ansatz)
    return ansatz
def generate_hf_wavefunction_circuit(n_qubit: int, n_alpha_electron: int, n_beta_electron: int):
   """
   Args:
       n_qubit (int):
       n_alpha_electron (int):
       n_beta_electron (int):
   """
   circuit = Circuit(n_qubit)

   for i in range(n_alpha_electron):
       idx_alpha = 2 * i
       circuit.X(idx_alpha)

   for i in range(n_beta_electron):
       idx_beta = 2 * i + 1
       circuit.X(idx_beta)

   return circuit
Exemple #27
0
def measure_z(quantum_circuit: Circuit, qubit: int, bit: int) -> None:
    """Measures a specified qubit in the Computational (Z) basis.

    Args:
        quantum_circuit (pytket.circuit.Circuit): The quantum circuit to apply the measurement to.
        qubit (int): The qubit to measure.
        bit (int): The bit to save the qubit measurement result into.
    """
    # Measure the qubit into the bit.
    quantum_circuit.Measure(qubit, bit)
Exemple #28
0
def circuit_from_string(op_string: Iterable[Any],
                        *,
                        n_qubits: int = 1,
                        key: Dict[Any, Callable] = None) -> Circuit:
    if key is None:
        key = ops
    circuit = Circuit(n_qubits)
    for s in op_string[::-1]:
        key[s](circuit)
    return circuit
Exemple #29
0
def pauli_measurement(pauli_string:Iterable[Tuple[int,str]], circ:Circuit) :
    """Appends measurement instructions to a given circuit, measuring each qubit in a given basis

    
    :param pauli_string: The pauli operator to measure, as tuples of pauli name and qubit.
    :type pauli_string: Iterable[Tuple[int,str]]
    :param circ: Circuit to add measurement to.
    :type circ: Circuit
    """
    measured_qbs = []
    for qb_idx, p in pauli_string:
        measured_qbs.append(qb_idx)
        if p=='X':
            circ.H(qb_idx)
        elif p=='Y':
            circ.Sdg(qb_idx)
            circ.H(qb_idx)

    for idx in measured_qbs:
        circ.Measure(idx, idx)
Exemple #30
0
def run_multiple(n_qubits, n_iter):
    c = Circuit(n_qubits)
    rewriter = RewriteTket(c, single_noise, cnot_noise, verbose=False)
    rewriter.verbose = True
    for _ in range(n_iter):
        circuit = random_pauli_gadget(n_qubits)
        Transform.OptimisePauliGadgets().apply(circuit)
        rewriter.set_circuit_and_target(circuit)
        rewriter.reduce()
        print(rewriter.instructions)
        print("\n\n")