Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,16 @@
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"from matplotlib import pyplot as plt\n",
"\n",
"from classiq import *\n",
"from classiq.execution import (\n",
" ClassiqBackendPreferences,\n",
" ExecutionPreferences,\n",
" ClassiqSimulatorBackendNames,\n",
" ExecutionPreferences,\n",
")\n",
"from classiq.synthesis import set_execution_preferences\n",
"import numpy as np\n",
"from matplotlib import pyplot as plt"
"from classiq.synthesis import set_execution_preferences"
]
},
{
Expand All @@ -50,13 +51,14 @@
"metadata": {},
"outputs": [],
"source": [
"n_qbits = 7 # number of qubit to use\n",
"t = 1.0 # evolution time\n",
"tau = 1.0/32 # time step for trotterization\n",
"n_qbits = 7 # number of qubit to use\n",
"t = 1.0 # evolution time\n",
"tau = 1.0 / 32 # time step for trotterization\n",
"shots = 4096 # Number of shots to sample\n",
"\n",
"\n",
"def get_steps(t: float, tau: float) -> int:\n",
" return int(np.floor(t/tau))"
" return int(np.floor(t / tau))"
]
},
{
Expand Down Expand Up @@ -111,9 +113,10 @@
" else:\n",
" return 0\n",
"\n",
"n = 2 ** n_qbits\n",
"\n",
"n = 2**n_qbits\n",
"x_axis = np.linspace(0, 4, n)\n",
"boundary = [phi_0_x(x) for x in x_axis]\n"
"boundary = [phi_0_x(x) for x in x_axis]"
]
},
{
Expand Down Expand Up @@ -159,10 +162,11 @@
"source": [
"def step(phi: list[float], dt: float, dx: float) -> list[float]:\n",
" new_phi = np.zeros(len(phi))\n",
" for i in range(1, len(phi)-1):\n",
" new_phi[i] = phi[i] - dt * (phi[i+1] - phi[i-1]) / (2*dx)\n",
" for i in range(1, len(phi) - 1):\n",
" new_phi[i] = phi[i] - dt * (phi[i + 1] - phi[i - 1]) / (2 * dx)\n",
" return new_phi\n",
"\n",
"\n",
"def evolve(initial, t, dt, dx):\n",
" phi = initial\n",
" cur_t = dt\n",
Expand All @@ -189,7 +193,7 @@
}
],
"source": [
"dx = x_axis[1]-x_axis[0]\n",
"dx = x_axis[1] - x_axis[0]\n",
"dt = 0.001\n",
"solution = evolve(boundary, t, dt, dx)\n",
"fig, ax = plt.subplots()\n",
Expand Down Expand Up @@ -376,43 +380,46 @@
" # CNOT ladder\n",
" repeat(count=j, iteration=lambda i: CX(qbits[j], qbits[i]))\n",
"\n",
"\n",
"@qfunc\n",
"def controlled_rotate(control_qbits: QArray[QBit], target: QBit, dt: CReal):\n",
" control(ctrl=control_qbits, stmt_block=lambda: RY(2*dt, target))\n",
" control(ctrl=control_qbits, stmt_block=lambda: RY(2 * dt, target))\n",
"\n",
"\n",
"@qfunc\n",
"def step(qbits: QArray[QBit], j: CInt, dt: CReal):\n",
" within_apply(\n",
" within=lambda: u(qbits, j),\n",
" apply=lambda: controlled_rotate(qbits[0:j], qbits[j], dt)\n",
" apply=lambda: controlled_rotate(qbits[0:j], qbits[j], dt),\n",
" )\n",
"\n",
"\n",
"@qfunc\n",
"def ladder(qbits: QArray[QBit], dt: CReal):\n",
" \"\"\"Use second order approximation\n",
" \"\"\"\n",
" \"\"\"Use second order approximation\"\"\"\n",
" # W1(-$\\tau$/2)\n",
" RY(-dt, qbits[0])\n",
"\n",
" # V\n",
" RY(2*dt, qbits[0])\n",
" repeat(count=qbits.len-1, iteration=lambda i: step(qbits[0:i+2], i+1, dt))\n",
" \n",
" RY(2 * dt, qbits[0])\n",
" repeat(count=qbits.len - 1, iteration=lambda i: step(qbits[0 : i + 2], i + 1, dt))\n",
"\n",
" # W1($\\tau$/2)\n",
" RY(dt, qbits[0])\n",
"\n",
"\n",
"def model_factory(n_qbits: int, t: CReal, tau: CReal) -> QCallable:\n",
" steps = get_steps(t, tau)\n",
" initial = np.zeros(2**n_qbits)\n",
" domain_length = 4\n",
" segment_one = 2**n_qbits // domain_length\n",
" l = 1 / segment_one\n",
" initial[segment_one:2*segment_one] = np.sqrt(1/segment_one)\n",
" initial[segment_one : 2 * segment_one] = np.sqrt(1 / segment_one)\n",
"\n",
" @qfunc\n",
" def main(qbits: Output[QArray[n_qbits]]):\n",
" prepare_amplitudes(amplitudes=initial.tolist(), bound=0.01, out=qbits)\n",
" repeat(count=steps, iteration=lambda i: ladder(qbits, t/(2*l)/steps))\n",
" repeat(count=steps, iteration=lambda i: ladder(qbits, t / (2 * l) / steps))\n",
"\n",
" return main"
]
Expand All @@ -430,8 +437,12 @@
"metadata": {},
"outputs": [],
"source": [
"def create_program(n_qbits: int, t: float, tau: float, factory: callable=model_factory):\n",
" backend_preferences = ClassiqBackendPreferences(backend_name=ClassiqSimulatorBackendNames.SIMULATOR_STATEVECTOR)\n",
"def create_program(\n",
" n_qbits: int, t: float, tau: float, factory: callable = model_factory\n",
"):\n",
" backend_preferences = ClassiqBackendPreferences(\n",
" backend_name=ClassiqSimulatorBackendNames.SIMULATOR_STATEVECTOR\n",
" )\n",
" model = create_model(factory(n_qbits, t, tau))\n",
" model = set_execution_preferences(\n",
" model,\n",
Expand All @@ -456,7 +467,7 @@
"metadata": {},
"outputs": [],
"source": [
"def solve(n_qbits: int, t: float, tau: float, factory: callable=model_factory):\n",
"def solve(n_qbits: int, t: float, tau: float, factory: callable = model_factory):\n",
" qprog = create_program(n_qbits, t, tau, factory)\n",
" result = execute(qprog)\n",
" return (result.result())[0].value.model_dump(), qprog"
Expand Down Expand Up @@ -496,10 +507,10 @@
"cx_count = circuit.transpiled_circuit.count_ops[\"cx\"]\n",
"print(f\"width={width}\\ndepth={depth}\\ncx count={cx_count}\")\n",
"\n",
"position = np.linspace(0.0, 4.0, 2 ** n_qbits)\n",
"states = [f\"{i:0{n_qbits}b}\" for i in range(2 ** n_qbits)]\n",
"scale = ((2 ** n_qbits) // 4)\n",
"quantum_solution = [scale*(r[\"counts\"].get(state, 0)/shots) for state in states]"
"position = np.linspace(0.0, 4.0, 2**n_qbits)\n",
"states = [f\"{i:0{n_qbits}b}\" for i in range(2**n_qbits)]\n",
"scale = (2**n_qbits) // 4\n",
"quantum_solution = [scale * (r[\"counts\"].get(state, 0) / shots) for state in states]"
]
},
{
Expand Down Expand Up @@ -595,13 +606,15 @@
" circuit = QuantumProgram.from_qprog(qprog)\n",
" return circuit.transpiled_circuit.count_ops[\"cx\"]\n",
"\n",
"\n",
"def count_cx_ops(n_qbits: int, t: float, tau: float) -> int:\n",
" qprog = create_program(n_qbits, t, tau)\n",
" return count_cx_ops_in_qprog(qprog)\n",
"\n",
"\n",
"def count_cx_theory(n_qbits: int, t: float, tau: float) -> int:\n",
" steps = get_steps(t, tau)\n",
" return steps*((9*(n_qbits**2)) - (33*n_qbits) + 34)"
" return steps * ((9 * (n_qbits**2)) - (33 * n_qbits) + 34)"
]
},
{
Expand All @@ -627,7 +640,9 @@
"source": [
"classiq_cx_count = count_cx_ops_in_qprog(qprog_t_1)\n",
"paper_cx_estimation = count_cx_theory(n_qbits, t, tau)\n",
"print(f\"Classiq CX count: {classiq_cx_count}; Paper CX estimation: {paper_cx_estimation}\")"
"print(\n",
" f\"Classiq CX count: {classiq_cx_count}; Paper CX estimation: {paper_cx_estimation}\"\n",
")"
]
},
{
Expand Down Expand Up @@ -682,7 +697,7 @@
"outputs": [],
"source": [
"paper_cx_counts = [count_cx_theory(n_qbits, t_, tau) for t_ in times]\n",
"ratio = [cx_counts[i]/paper_cx_counts[i] for i in range(len(times))]"
"ratio = [cx_counts[i] / paper_cx_counts[i] for i in range(len(times))]"
]
},
{
Expand Down Expand Up @@ -774,26 +789,33 @@
}
],
"source": [
"qbits_range = list(range(2, n_qbits+1))\n",
"qbits_range = list(range(2, n_qbits + 1))\n",
"\n",
"\n",
"def count_cx_for_cry(n: CInt) -> int:\n",
" @qfunc\n",
" def main(control_qbits: Output[QArray], target: Output[QBit]):\n",
" allocate(n-1, control_qbits)\n",
" allocate(n - 1, control_qbits)\n",
" allocate(1, target)\n",
" hadamard_transform(control_qbits)\n",
" X(target)\n",
" control(ctrl=control_qbits, stmt_block=lambda: RY(np.pi/4, target))\n",
" control(ctrl=control_qbits, stmt_block=lambda: RY(np.pi / 4, target))\n",
"\n",
" my_model = create_model(main)\n",
" my_qprog = synthesize(my_model)\n",
" circuit = QuantumProgram.from_qprog(my_qprog)\n",
" return circuit.transpiled_circuit.count_ops[\"cx\"]\n",
"\n",
"cx_counts_for_cry = { qbits: (count_cx_for_cry(qbits), 16*qbits - 40 if qbits > 2 else 2) for qbits in qbits_range }\n",
"\n",
"cx_counts_for_cry = {\n",
" qbits: (count_cx_for_cry(qbits), 16 * qbits - 40 if qbits > 2 else 2)\n",
" for qbits in qbits_range\n",
"}\n",
"print(f\"CX count for CRY:\")\n",
"for qbits, counts in cx_counts_for_cry.items():\n",
" print(f\"[{qbits} qubits] classiq's count: {counts[0]}; paper prediction: {counts[1]}\")\n",
"\n"
" print(\n",
" f\"[{qbits} qubits] classiq's count: {counts[0]}; paper prediction: {counts[1]}\"\n",
" )"
]
},
{
Expand Down
Loading