Skip to main content

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.

View on GitHub

Open this notebook in GitHub to run it yourself
This notebook demonstrates the capability of Classiq’s Synthesis engine to reduce depth and cx-counts when modeling a Quantum Phase Estimation (QPE) on a unitary that is hard-coded unitary matrix (of the form e2πiAe^{2\pi i A}, with AA Hermitian).
import numpy as np
import scipy

# taking a random example, rescaling and shifting the matrix to guarantee eigenvalues in [0,1)
np.random.seed(1235)
new_mat = np.random.rand(8, 8)
new_mat = (new_mat + new_mat.T) / 2

w, v = np.linalg.eig(new_mat)
w_max = np.max(np.abs(w))

mew_mat = (new_mat + w_max) / (2 * w_max)

my_unitary = scipy.linalg.expm(1j * 2 * np.pi * new_mat)

precisions = [l for l in range(1, 9)]
print("precisions:", precisions)
Output:
precisions: [1, 2, 3, 4, 5, 6, 7, 8]
  

transpilation_options = {"classiq": "custom", "qiskit": 3}

  1. Classiq’s QPE
from classiq import *

qmods = []
qprogs = []
classiq_depths = []
classiq_cx_counts = []

preferences = Preferences(
    custom_hardware_settings=CustomHardwareSettings(basis_gates=["cx", "u"]),
    transpilation_option=transpilation_options["classiq"],
)

for precision in precisions:

    @qfunc
    def main(phase: Output[QNum]):
        state = QArray("state")
        allocate(3, state)
        allocate(precision, False, precision, phase)
        qpe(
            unitary=lambda: unitary(elements=my_unitary.tolist(), target=state),
            phase=phase,
        )
        drop(state)

    qmod = create_model(main)
    qmod = set_preferences(qmod, preferences=preferences)
    qmods.append(qmod)
    qprog = synthesize(qmod)
    qprogs.append(qprog)
    depth_classiq = qprog.transpiled_circuit.depth
    classiq_depths.append(depth_classiq)
    classiq_cx_counts.append(qprog.transpiled_circuit.count_ops["cx"])

print("classiq depths:", classiq_depths)
print("classiq cx-counts:", classiq_cx_counts)
Output:
classiq depths: [180, 364, 550, 736, 922, 1108, 1294, 1480]
  classiq cx-counts: [97, 196, 297, 400, 505, 612, 721, 832]
  

  1. Comparing to Qiskit Implementations
The qiskit data was generated using qiskit version 1.
  1. To run the qiskit code uncomment the commented cells below.
qiskit_depths = [320, 950, 2206, 4706, 9694, 19658, 39574, 79394]
qiskit_cx_counts = [162, 484, 1124, 2398, 4938, 10008, 20136, 40378]

# from importlib.metadata import version
# try:
#     import qiskit
#     if version('qiskit') != "1.0.0":
#       !pip uninstall qiskit -y
#       !pip install qiskit==1.0.0
# except ImportError:
#     !pip install qiskit==1.0.0

# from qiskit import QuantumCircuit, QuantumRegister, transpile
# from qiskit.circuit.library import PhaseEstimation

# q = QuantumRegister(3, "q")
# qc = QuantumCircuit(q)
# qc.unitary(my_unitary.tolist(), q)

# qiskit_depths = []
# qiskit_cx_counts = []
# for precision in precisions:
#     qpe_qc = PhaseEstimation(precision, qc)
#     transpiled_cir = transpile(
#         qpe_qc,
#         basis_gates=["u", "cx"],
#         optimization_level=transpilation_options["qiskit"],
#     )
#     qiskit_depths.append(transpiled_cir.depth())
#     qiskit_cx_counts.append(transpiled_cir.count_ops()["cx"])

# print("qiskit depths:", qiskit_depths)
# print("qiskit cx-counts:", qiskit_cx_counts)

  1. Plotting the Data
import matplotlib.pyplot as plt

classiq_color = "#119DA4"
qiskit_color = "#bb8bff"
plt.rcParams["font.family"] = "serif"
plt.rc("savefig", dpi=300)
plt.rcParams["axes.linewidth"] = 1
plt.rcParams["xtick.major.size"] = 5
plt.rcParams["xtick.minor.size"] = 5
plt.rcParams["ytick.major.size"] = 5
plt.rcParams["ytick.minor.size"] = 5

plt.rcParams["axes.linewidth"] = 1
plt.rcParams["xtick.major.size"] = 5
plt.rcParams["xtick.minor.size"] = 5
plt.rcParams["ytick.major.size"] = 5
plt.rcParams["ytick.minor.size"] = 5


(classiq1,) = plt.semilogy(
    precisions,
    classiq_depths,
    "-o",
    label="classiq depth",
    markerfacecolor=classiq_color,
    markeredgecolor="k",
    markersize=8,
    markeredgewidth=1.5,
    linewidth=1.5,
    color=classiq_color,
)
(classiq2,) = plt.semilogy(
    precisions,
    classiq_cx_counts,
    "-*",
    label="classiq cx-counts",
    markerfacecolor=classiq_color,
    markeredgecolor="k",
    markersize=12,
    markeredgewidth=1.5,
    linewidth=1.5,
    color=classiq_color,
)
(qiskit1,) = plt.semilogy(
    precisions,
    qiskit_depths,
    "-s",
    label="qiskit depth",
    markerfacecolor=qiskit_color,
    markeredgecolor="k",
    markersize=7,
    markeredgewidth=1.5,
    linewidth=1.5,
    color=qiskit_color,
)
(qiskit2,) = plt.semilogy(
    precisions,
    qiskit_cx_counts,
    "-v",
    label="qiskit cx-counts",
    markerfacecolor=qiskit_color,
    markeredgecolor="k",
    markersize=8,
    markeredgewidth=1.5,
    linewidth=1.5,
    color=qiskit_color,
)

first_legend = plt.legend(
    handles=[qiskit1, qiskit2],
    fontsize=16,
    loc="lower left",
    bbox_to_anchor=(0.1, 0.75),
)
ax = plt.gca().add_artist(first_legend)
plt.legend(handles=[classiq1, classiq2], fontsize=16, loc="lower right")

plt.ylabel("Depth, CX-counts", fontsize=16)
plt.xlabel("QPE-precision", fontsize=16)
plt.yticks(fontsize=16)
plt.xticks(fontsize=16)
plt.text(0.9, 0.65e5, "(a)", fontsize=16)
Output:

Text(0.9, 65000.0, '(a)')
  

output