> ## Documentation Index
> Fetch the complete documentation index at: https://prod-mint.classiq.io/llms.txt
> Use this file to discover all available pages before exploring further.

# PyTket code for QSVT example

<Card title="View on GitHub" icon="github" href="https://github.com/Classiq/classiq-library/blob/main/tutorials/technology_demonstrations/classiq_paper/qsvt/tket_qsvt_example.ipynb">
  Open this notebook in GitHub to run it yourself
</Card>

This notebook shows how to generate data for discrete quantum walk using `pytket` 1.34.0

Here we provide the codes for block encoding the matrix $A$, as well as the QSVT implementation. PyTket does not have an adder by a constant function. Thus, we have modified their adder functions, which is applied between two quantum registers, to include this functionality.

```python theme={null}
# import time
# from pytket.circuit import Circuit, CircBox, OpType, QControlBox
# from pytket.extensions.qiskit import AerBackend
# from pytket.passes import DecomposeBoxes, SynthesiseTket
```

```python theme={null}

# backend = AerBackend()

# from pytket.circuit import Circuit, CircBox
# import numpy as np

# def build_qft_circuit(n_qubits: int, do_swaps: True) -> Circuit:
#     circ = Circuit(n_qubits, name="QFT")
#     for i in range(n_qubits):
#         circ.H(i)
#         for j in range(i + 1, n_qubits):
#             circ.CU1(1 / 2 ** (j - i), j, i)
#     if do_swaps:
#         for k in range(0, n_qubits // 2):
#             circ.SWAP(k, n_qubits - k - 1)
#     return circ

# class DraperQFTAdderConstantPytket:
#     def __init__(self, num_state_qubits: int, constant: int) -> Circuit:
#         circuit = Circuit(num_state_qubits)

#         qft_circuit = build_qft_circuit(num_state_qubits, do_swaps=False)
#         circuit.add_gate(CircBox(qft_circuit),[k for k in range(num_state_qubits)])

#         # Apply phase rotations for the constant
#         for qubit in range(num_state_qubits):
#             angle = (constant % (2 ** (qubit + 1))) * np.pi / (2 ** qubit)
#             circuit.Rz(angle, qubit)

#         # Apply inverse QFT
#         circuit.add_gate(CircBox(qft_circuit).dagger,[k for k in range(num_state_qubits)])

#         self.circuit = circuit

#     def get_circuit(self) -> Circuit:
#         return self.circuit
```

```python theme={null}

# def get_reflect_around_zero(size):
#     qc = Circuit(size, name="reflection")
#     qc.X(0)
#     qc.H(0)
#     qc.add_gate(QControlBox(CircBox(Circuit(1).X(0)), n_controls = size-1, control_state=[0]*(size-1)), [k for k in range(size)])
#     qc.H(0)
#     qc.X(0)

#     return qc

# def get_cir_be(qc, data, block):
#     qc.H(block[0])
#     qc.H(block[2])
#     adder_2_cir = DraperQFTAdderConstantPytket(len(data)+1, 2).get_circuit()
#     adder_1_cir = DraperQFTAdderConstantPytket(len(data)+1, -1+2**(len(data)+1)).get_circuit()
#     qc.add_gate(QControlBox(CircBox(adder_2_cir), n_controls = 1, control_state=0), [block[0]]+[data[k] for k in range(len(data))]+[block[1]])
#     qc.add_gate(CircBox(adder_1_cir), [data[k] for k in range(len(data))]+[block[1]])
#     qc.add_gate(QControlBox(CircBox(get_reflect_around_zero(len(data))),n_controls=1, control_state=0),[block[2]]+[data[k] for k in range(len(data))])
#     qc.H(block[0])
#     qc.H(block[2])

#     return qc

# def apply_projector_controlled_phase(qc, phase, block_reg, aux_reg):
#     qc.add_gate(QControlBox(CircBox(Circuit(1).X(0)), n_controls = len(block_reg), control_state=[0]*len(block_reg)),
#                                          [block_reg[k] for k in range(len(block_reg))] + [aux_reg[0]]
#                                          )
#     qc.Rz(phase, aux_reg[0])

#     qc.add_gate(QControlBox(CircBox(Circuit(1).X(0)), n_controls = len(block_reg), control_state=[0]*len(block_reg)),
#                                          [block_reg[k] for k in range(len(block_reg))] + [aux_reg[0]]
#                                          )


# def apply_qsvt_step(qc, phase1, phase2, u, data, block, qsvt_aux):

#     qc.add_gate(CircBox(u), [data[l] for l in range(len(data))]+ [block[l] for l in range(len(block))])
#     apply_projector_controlled_phase(qc, phase1, block, qsvt_aux)
#     qc.add_gate(CircBox(u).dagger, [data[l] for l in range(len(data))]+ [block[l] for l in range(len(block))])
#     apply_projector_controlled_phase(qc, phase2, block, qsvt_aux)


# def get_qsvt_circuit(qsvt_phases,
#             size):

#     qsvt_cir = Circuit()
#     data = qsvt_cir.add_q_register("data", size)
#     block = qsvt_cir.add_q_register("block", 3)
#     cir_be = Circuit()
#     data = cir_be.add_q_register("data", size)
#     block = cir_be.add_q_register("block", 3)

#     qsvt_aux = qsvt_cir.add_q_register("qsvt_aux", 1)
#     cir_be = get_cir_be(cir_be,data, block)

#     qsvt_cir.H(qsvt_aux[0])
#     apply_projector_controlled_phase(qsvt_cir, qsvt_phases[0], block, qsvt_aux)
#     for i in range(int(np.floor((len(qsvt_phases) - 1) / 2))):
#         apply_qsvt_step(qsvt_cir,
#                         qsvt_phases[(2 * i) + 1], qsvt_phases[(2 * i) + 2],
#                         cir_be,
#                         data,
#                         block,
#                         qsvt_aux
#                        )
#     qsvt_cir.add_gate(CircBox(cir_be), [data[l] for l in range(len(data))]+ [block[l] for l in range(len(block))])
#     apply_projector_controlled_phase(qsvt_cir, qsvt_phases[len(qsvt_phases) - 1], block, qsvt_aux)
#     qsvt_cir.H(qsvt_aux[0])

#     return qsvt_cir
```

## run an example

```python theme={null}
# SIZE = 6
# DEGREE = 3
# QSVT_PHASES = [1.280311896404252, 8.127145628464149, 1.8439603212845617, -5.002873410775335]

# start_time = time.time()
# qc_qsvt = get_qsvt_circuit(QSVT_PHASES, SIZE)
# DecomposeBoxes().apply(qc_qsvt)
# SynthesiseTket().apply(qc_qsvt)
# compiled_circ = backend.get_compiled_circuit(qc_qsvt)
# transpilation_time = time.time()-start_time
# depth = compiled_circ.depth()
# cx_counts = compiled_circ.n_gates_of_type(OpType.CX)
# width = compiled_circ.n_qubits

# print(f"==== tket for {SIZE}==== time: {transpilation_time}")
```
