Fifteen factorization using Shor's algorithm¶
+This is a compiled circuit taken from reference 1804.03719. It uses information about
+the target number to simplify a lot the gates needed. We will factorize the number N = 15
, using the base a = 11
.
+The circuit is run in both a simulator and a quantum computer, courtesy of IBM's Quantum Platform. Here are the required Qiskit 1.0 imports:
from math import pi
+from qiskit import transpile, QuantumCircuit, QuantumRegister, ClassicalRegister
+from qiskit_aer import AerSimulator
+from qiskit_ibm_runtime import QiskitRuntimeService, Batch, Sampler
+from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
+from qiskit.visualization import plot_histogram
+
Circuit definition¶
+# Define quantum and classical registers
+qr = QuantumRegister(5)
+cr = ClassicalRegister(3)
+qc = QuantumCircuit(qr, cr)
+
+# Constructing the quantum circuit
+qc.h([0, 1, 2])
+qc.cx(2, 3)
+qc.cx(2, 4)
+qc.h(1)
+qc.cp(pi/2, 1, 0)
+qc.h(0)
+qc.cp(pi/4, 1, 2)
+qc.cp(pi/2, 0, 2)
+qc.h(2)
+
+# Measurement
+for i in range(3):
+ qc.measure(i, i)
+
+# Display
+qc.draw(output="mpl")
+
Run in simulator¶
+# Execute the circuit on a quantum simulator
+backend = AerSimulator()
+counts = backend.run(transpile(qc, backend)).result().get_counts()
+plot_histogram(counts, title="Qiskit Aer simulator results")
+
Run in IBM's Eagle quantum computer¶
+Circuit transpilation¶
+# Credentials and service initiation
+service = QiskitRuntimeService(
+ channel="ibm_quantum",
+ token="YOUR_API_KEY",)
+
+# Set sample and backend
+backend = service.least_busy(simulator=False, operational=True)
+print(backend.name)
+
+# Transpile circuit
+pass_manager = generate_preset_pass_manager(optimization_level=3, backend=backend)
+transpiled = pass_manager.run(qc)
+
ibm_kyoto ++
Run in the QPU¶
+# Execute using Qiskit primitives
+with Batch(service=service, backend=backend):
+ sampler = Sampler()
+ job = sampler.run(
+ circuits=transpiled,
+ skip_transpilation=True,
+ shots=1024,
+ )
+
+ # Run the transpiled circuit
+ print(f">>> Job ID: {job.job_id()}")
+ print(f">>> Job Status: {job.status()}")
+ result = job.result()
+
+# Wait for the job to complete and retrieve the results
+counts = [dist.binary_probabilities() for dist in result.quasi_dists]
+
+# Display the results
+plot_histogram(counts, title="IBM Eagle QPU results")
+
>>> Job ID: crqsved2x9jg008z2r50 +>>> Job Status: JobStatus.QUEUED ++
Judgement¶
+Both the classical simulation and the Eagle QPU results present two prominent peaks. The 0 one corresponds to the trivial
+period, but the second one 100
(4) is correct. We know that the circuit's counts peak at a number that is proportional
+to $\frac{2^n}{r}$, where $n$ is the number of qubits in the control register and $r$ is the period. We have then:
$r = \frac{2^3}{4} = 2$
+We know that for a target number $N$ and a base $a$:
+$N = \prod_{i=0}^1 \text{gcd}(a^{\frac{r}{2}} + (-1)^i, N)$
+Which means:
+$15 = \prod_{i=0}^1 \text{gcd}(11^{\frac{2}{2}} + (-1)^i, 15) = 3 \times 5$
+