|
|
import gradio as gr |
|
|
from qiskit import QuantumCircuit |
|
|
|
|
|
from qiskit_aer import AerSimulator |
|
|
from qiskit.visualization import circuit_drawer, plot_histogram |
|
|
import matplotlib.pyplot as plt |
|
|
import numpy as np |
|
|
import base64 |
|
|
from io import BytesIO |
|
|
|
|
|
|
|
|
def create_quantum_adder(a_str, b_str): |
|
|
""" |
|
|
建立一個2位元量子全加器電路。 |
|
|
""" |
|
|
a = a_str[::-1] |
|
|
b = b_str[::-1] |
|
|
qc = QuantumCircuit(4, 3) |
|
|
qc.name = "2-bit Adder" |
|
|
|
|
|
|
|
|
if a[0] == '1': qc.x(0) |
|
|
if len(a) > 1 and a[1] == '1': qc.x(1) |
|
|
if b[0] == '1': qc.x(2) |
|
|
if len(b) > 1 and b[1] == '1': qc.x(3) |
|
|
qc.barrier() |
|
|
|
|
|
|
|
|
|
|
|
qc.ccx(0, 1, 3) |
|
|
qc.cx(0, 1) |
|
|
|
|
|
|
|
|
qc.ccx(2, 3, 0) |
|
|
qc.cx(2, 3) |
|
|
|
|
|
|
|
|
qc.cx(1, 2) |
|
|
qc.cx(0, 1) |
|
|
|
|
|
|
|
|
qc.measure(1, 0) |
|
|
qc.measure(2, 1) |
|
|
qc.measure(0, 2) |
|
|
|
|
|
return qc |
|
|
|
|
|
|
|
|
def run_simulation(qc): |
|
|
"""執行量子電路模擬""" |
|
|
|
|
|
simulator = AerSimulator() |
|
|
|
|
|
transpiled_qc = simulator.run(qc, shots=1024).result() |
|
|
counts = transpiled_qc.get_counts(qc) |
|
|
return counts |
|
|
|
|
|
def plot_to_base64(plot_function, *args, **kwargs): |
|
|
"""將matplotlib繪圖轉換為Base64字串""" |
|
|
buf = BytesIO() |
|
|
fig = plot_function(*args, **kwargs) |
|
|
|
|
|
if not isinstance(fig, plt.Figure): |
|
|
fig = plt.gcf() |
|
|
|
|
|
fig.savefig(buf, format='png', bbox_inches='tight') |
|
|
plt.close(fig) |
|
|
buf.seek(0) |
|
|
return "data:image/png;base64," + base64.b64encode(buf.getvalue()).decode('utf-8') |
|
|
|
|
|
|
|
|
def quantum_add(num_a, num_b): |
|
|
a_bin = format(num_a, '02b') |
|
|
b_bin = format(num_b, '02b') |
|
|
|
|
|
|
|
|
|
|
|
qc = QuantumCircuit(4, 2) |
|
|
|
|
|
|
|
|
if num_a & 1: qc.x(1) |
|
|
if num_a & 2: qc.x(1) |
|
|
if num_b & 1: qc.x(2) |
|
|
if num_b & 2: qc.x(2) |
|
|
|
|
|
|
|
|
qc.cx(1, 3) |
|
|
qc.ccx(1, 2, 0) |
|
|
|
|
|
qc.measure([3, 0], [0, 1]) |
|
|
|
|
|
counts = run_simulation(qc) |
|
|
|
|
|
most_likely_result_str = max(counts, key=counts.get) |
|
|
result_decimal = int(most_likely_result_str[::-1], 2) |
|
|
|
|
|
circuit_b64 = plot_to_base64(circuit_drawer, qc, output='mpl') |
|
|
histogram_b64 = plot_to_base64(plot_histogram, counts, title="測量結果") |
|
|
|
|
|
return f"計算結果: {num_a} + {num_b} = {result_decimal}", circuit_b64, histogram_b64 |
|
|
|
|
|
|
|
|
with gr.Blocks(theme=gr.themes.Soft()) as demo: |
|
|
gr.Markdown("# 量子加法器展示 (Quantum Adder)") |
|
|
gr.Markdown( |
|
|
"選擇兩個數字,應用程式會建立對應的量子電路,並在模擬器上執行它來計算總和。" |
|
|
) |
|
|
|
|
|
with gr.Row(): |
|
|
with gr.Column(scale=1): |
|
|
|
|
|
num_a = gr.Dropdown([0, 1], label="第一個數字 (a)", value=1) |
|
|
num_b = gr.Dropdown([0, 1], label="第二個數字 (b)", value=1) |
|
|
submit_btn = gr.Button("開始量子計算", variant="primary") |
|
|
|
|
|
with gr.Column(scale=2): |
|
|
result_text = gr.Label(label="模擬結果") |
|
|
|
|
|
with gr.Row(): |
|
|
circuit_img = gr.Image(label="量子電路圖 (Quantum Circuit)") |
|
|
|
|
|
with gr.Row(): |
|
|
histogram_img = gr.Image(label="測量機率分佈 (Measurement Probabilities)") |
|
|
|
|
|
submit_btn.click( |
|
|
fn=quantum_add, |
|
|
inputs=[num_a, num_b], |
|
|
outputs=[result_text, circuit_img, histogram_img] |
|
|
) |
|
|
|
|
|
if __name__ == "__main__": |
|
|
demo.launch() |
|
|
|