From 2996a568befede59d0f4a7e012267a1332299455 Mon Sep 17 00:00:00 2001 From: Senzhan9 Date: Wed, 18 Feb 2026 08:23:20 -0500 Subject: [PATCH] ADD Experiment --- Experiment_hdfm.py | 370 ++++++++++++++++++ .../__pycache__/__init__.cpython-313.pyc | Bin 339 -> 339 bytes .../__pycache__/backend.cpython-313.pyc | Bin 6052 -> 6052 bytes .../__pycache__/dqc_simulator.cpython-313.pyc | Bin 66226 -> 66563 bytes src/dqc_simulator/dqc_simulator.py | 13 +- 5 files changed, 382 insertions(+), 1 deletion(-) create mode 100644 Experiment_hdfm.py diff --git a/Experiment_hdfm.py b/Experiment_hdfm.py new file mode 100644 index 0000000..d3fb196 --- /dev/null +++ b/Experiment_hdfm.py @@ -0,0 +1,370 @@ +""" +量子哈密顿量模拟 - 1D横场伊辛模型(TFIM) +使用Qiskit实现,支持分布式量子计算(DQC) +""" +# ========================= +# Python path setup +# ========================= +import sys +from pathlib import Path +sys.path.insert(0, str(Path(__file__).parent / "src")) + +import numpy as np +import time +import collections +from typing import List, Tuple +import matplotlib.pyplot as plt + +from qiskit import QuantumCircuit, ClassicalRegister, transpile +from qiskit.circuit import Instruction, CircuitInstruction +from qiskit.converters import circuit_to_dag +from qiskit.quantum_info import Statevector +from qiskit_aer import AerSimulator +from qiskit.visualization import plot_histogram +from qiskit_aer.noise import NoiseModel + +# ========================= +# Fake backends (heterogeneous QPUs) +# ========================= +from qiskit_ibm_runtime.fake_provider import ( + FakeVigoV2, + FakeLagosV2, + FakeCasablancaV2, + FakeYorktownV2, + FakeManilaV2, + FakeNairobiV2, + FakeMumbaiV2, + FakeKolkataV2, + FakeGuadalupeV2, + FakeAlmadenV2, + FakeAthensV2, + FakeCambridgeV2 +) + +# ========================= +# Distributed Quantum Computing Simulator +# ========================= +from dqc_simulator import DQCCircuit, DQCQPU, QPUManager +from dqc_simulator.backend import IonQ + +class HamiltonianSimulationQiskit: + """ + 1D横场伊辛模型(TFIM)哈密顿量模拟的Qiskit实现 + + Parameters: + ----------- + num_qubits : int + 量子比特数量 + time_step : int + 时间步长 + total_time : int + 总演化时间 + """ + + def __init__(self, num_qubits: int, time_step: int, total_time: int) -> None: + self.num_qubits = num_qubits + self.time_step = time_step + self.total_time = total_time + + def circuit(self) -> QuantumCircuit: + """ + 生成量子电路 + + Returns: + -------- + QuantumCircuit : 构建的量子电路 + """ + # 物理常数 + hbar = 0.658212 # eV*fs (约化普朗克常数) + jz = hbar * np.pi / 4 # eV, 耦合系数 + freq = 0.0048 # 1/fs, MoSe2声子频率 + + # 声子参数 + w_ph = 2 * np.pi * freq + e_ph = 3 * np.pi * hbar / (8 * np.cos(np.pi * freq)) + + # 初始化量子电路 + qc = QuantumCircuit(self.num_qubits, self.num_qubits) + + # 构建时间演化电路 + num_steps = int(self.total_time / self.time_step) + for step in range(num_steps): + t = (step + 0.5) * self.time_step + + # 单量子比特项 (横场项) + psi = -2.0 * e_ph * np.cos(w_ph * t) * self.time_step / hbar + for q in range(self.num_qubits): + qc.h(q) + qc.rz(psi, q) + qc.h(q) + + # 双量子比特耦合项 (伊辛相互作用) + psi2 = -2.0 * jz * self.time_step / hbar + for i in range(self.num_qubits - 1): + qc.cx(i, i + 1) + qc.rz(psi2, i + 1) + qc.cx(i, i + 1) + + # 添加测量 + qc.measure(range(self.num_qubits), range(self.num_qubits)) + return qc + + def _get_ideal_counts(self, circuit: QuantumCircuit) -> collections.Counter: + """ + 计算理想(无噪声)概率分布 + + Parameters: + ----------- + circuit : QuantumCircuit + 量子电路 + + Returns: + -------- + Counter : 理想概率分布 + """ + qc_no_measure = circuit.remove_final_measurements(inplace=False) + sv = Statevector.from_instruction(qc_no_measure) + probs = sv.probabilities_dict() + return collections.Counter(probs) + + def _average_magnetization(self, result: dict, shots: int) -> float: + """ + 计算平均磁化强度 + + Parameters: + ----------- + result : dict + 测量结果计数 + shots : int + 总测量次数 + + Returns: + -------- + float : 平均磁化强度 + """ + mag = 0 + for spin_str, count in result.items(): + bitstring = spin_str[::-1] + # 将比特串转换为自旋: 0→+1, 1→-1 + spin_int = [1 - 2 * int(s) for s in bitstring] + mag += (sum(spin_int) / len(spin_int)) * count + average_mag = mag / shots + return average_mag + + def score(self, counts: collections.Counter) -> float: + """ + 基于磁化强度计算保真度评分 + + Parameters: + ----------- + counts : Counter + 实验测量结果 + + Returns: + -------- + float : [0,1]范围的评分,1表示完美匹配 + """ + ideal_counts = self._get_ideal_counts(self.circuit()) + total_shots = sum(counts.values()) + + mag_ideal = self._average_magnetization(ideal_counts, 1) + mag_experimental = self._average_magnetization(counts, total_shots) + + return 1 - abs(mag_ideal - mag_experimental) / 2 + + def score2(self, counts: collections.Counter) -> float: + """ + 使用Hellinger保真度评估模拟质量 + + Parameters: + ----------- + counts : Counter + 实验测量结果 + + Returns: + -------- + float : Hellinger保真度 [0,1] + """ + # 获取电路并移除测量 + qc = self.circuit() + qc_no_measure = qc.copy() + qc_no_measure.data = [ + inst for inst in qc_no_measure.data + if inst[0].name != 'measure' + ] + + # 生成理想状态向量 + sv = Statevector.from_instruction(qc_no_measure) + ideal_probs = sv.probabilities_dict() + + # 归一化实验概率 + total_shots = sum(counts.values()) + exp_probs = {k: v / total_shots for k, v in counts.items()} + + # 计算Hellinger保真度 + fidelity = sum( + np.sqrt(ideal_probs.get(k, 0)) * np.sqrt(p) + for k, p in exp_probs.items() + ) + + return fidelity + + +def count_two_qubit_gates(circuit: QuantumCircuit) -> int: + """ + 统计电路中两比特门的数量 + + Parameters: + ----------- + circuit : QuantumCircuit + 量子电路 + + Returns: + -------- + int : 两比特门数量 + """ + dag = circuit_to_dag(circuit) + dag.remove_all_ops_named("barrier") + return len(list(dag.two_qubit_ops())) + + +def setup_qpugroup(qpu_configs: List[Tuple[int, str]], + connections: List[Tuple[int, int]], + dist: float = 0.5) -> QPUManager: + """ + 设置QPU组 + + Parameters: + ----------- + qpu_configs : List[Tuple[int, str]] + QPU配置列表,每个元素为(qpu_id, backend_name) + connections : List[Tuple[int, int]] + QPU连接列表,每个元素为(qpu1_id, qpu2_id) + dist : float + QPU间距离,默认0.5 + + Returns: + -------- + QPUManager : 配置好的QPU管理器 + """ + qpugroup = QPUManager() + + # 添加QPU + for qpu_id, backend_name in qpu_configs: + qpugroup.add_qpu(DQCQPU(qpu_id, backend_name)) + + # 添加连接 + for qpu1, qpu2 in connections: + qpugroup.add_coonnection(qpu1, qpu2, distance=dist) + + return qpugroup + + +def run_hamiltonian_dqc(ham: HamiltonianSimulationQiskit, + partition: List[int], + qpugroup: QPUManager, + numbits: int = 12) -> Tuple[float, int, int]: + """ + 运行哈密顿量DQC模拟并测量性能指标 + + Parameters: + ----------- + ham : HamiltonianSimulationQiskit + 哈密顿量模拟对象 + partition : List[int] + 量子比特分区方案 + qpugroup : QPUManager + QPU管理器 + numbits : int + 保留的比特数,默认12 + + Returns: + -------- + Tuple[float, int, int] : (保真度, 远程门数量, 两比特门总数) + """ + qc = ham.circuit() + + print(f" 电路信息: {qc.num_qubits} qubits, {qc.num_clbits} classical bits") + + try: + # 执行DQC + qc_dqc = DQCCircuit(qc) + result_qc = qc_dqc.Execution(partition, qpugroup, comm_noise=True, measure_time = True) + + # 获取噪声模型并运行仿真 + noise_model = qc_dqc.get_noise_model() + sim = AerSimulator(noise_model=noise_model) + compiled = transpile(result_qc, sim) + start_time = time.time() + job = sim.run(compiled, shots=1000) + result = job.result() + end_time = time.time() + elapsed_time = end_time - start_time + print(f"Running time: {elapsed_time:.4f} seconds") + + # 处理测量结果 + counts = result.get_counts() + + # 保留前numbits位 + new_counts = {} + for bitstring, cnt in counts.items(): + bits = bitstring[:numbits] + new_counts[bits] = new_counts.get(bits, 0) + cnt + + # 计算保真度 (Hellinger fidelity) + fidelity = ham.score2(new_counts) + + # 获取性能指标 + num_remote_gates = qc_dqc.Num_RemoteGate + num_two_qubit_gates = count_two_qubit_gates(result_qc) + + return fidelity, num_remote_gates, num_two_qubit_gates + + except Exception as e: + print(f" Error with partition {partition}: {e}") + import traceback + traceback.print_exc() + return None, None, None + + +def main(): + """ + 主函数 - 演示如何使用 + """ + # 创建12量子比特的TFIM电路 + ham = HamiltonianSimulationQiskit(num_qubits=20, time_step=1, total_time=3) + qc = ham.circuit() + qc0 = qc.copy() + + # 设置分布式量子计算 + qc_dqc = DQCCircuit(qc0) + partition = [4, 4, 4, 4, 4] # 4个QPU,每个3个量子比特 + + # 配置QPU组 + qpugroup = QPUManager() + for i in range(5): + qpugroup.add_qpu(DQCQPU(i, "FakeVigoV2")) + + # 添加QPU连接(线性拓扑) + distance = 5 + qpugroup.add_coonnection(0, 1, distance=distance) + # 可以添加更多连接以形成不同的拓扑结构 + # qpugroup.add_coonnection(0, 2, distance=distance) + qpugroup.add_coonnection(1, 2, distance=distance) + # qpugroup.add_coonnection(1, 3, distance=distance) + qpugroup.add_coonnection(2, 3, distance=distance) + qpugroup.add_coonnection(3, 4, distance=distance) + + # 运行DQC模拟 + fidelity, num_remote, num_two_qubit = run_hamiltonian_dqc( + ham, partition, qpugroup, numbits=20 + ) + + print(f"\n结果:") + print(f" Hellinger保真度: {fidelity:.4f}") + # print(f" 远程门数量: {num_remote}") + # print(f" 两比特门总数: {num_two_qubit}") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/src/dqc_simulator/__pycache__/__init__.cpython-313.pyc b/src/dqc_simulator/__pycache__/__init__.cpython-313.pyc index 30a1cf50ea21d575fd19a42394dbd0f084179148..78ae71da7a659e6307564cf7d7c296620c094860 100644 GIT binary patch delta 29 jcmcc2beW0!GcPX}0}wP;H&5h#!{!xOniL;A@oyLagdz#z delta 29 jcmcc2beW0!GcPX}0}xD0beYKghRr3=IX<{#;@>a;e;f&T diff --git a/src/dqc_simulator/__pycache__/backend.cpython-313.pyc b/src/dqc_simulator/__pycache__/backend.cpython-313.pyc index bfb26f934e70bfda62131430ec520bad4ee476cb..6673bddf6b8d0c194e529f8415e47ef906fa2ae6 100644 GIT binary patch delta 32 mcmZ3YzeJz=GcPX}0}wP;H*e(T;$!m)EKQ0J-Ym`6$q4|EqX@JB delta 32 mcmZ3YzeJz=GcPX}0}vENyKLm<;$w3ObdC=$*(}Z1$q4|5Z3rL$ diff --git a/src/dqc_simulator/__pycache__/dqc_simulator.cpython-313.pyc b/src/dqc_simulator/__pycache__/dqc_simulator.cpython-313.pyc index 74b3ab2f46c36a5c818c92f291c4f24f0f87545c..0e43b4a009075e56a7baf40f4110ec2b4f82fe29 100644 GIT binary patch delta 3691 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 diff --git a/src/dqc_simulator/dqc_simulator.py b/src/dqc_simulator/dqc_simulator.py index f14c17a..7a5941b 100644 --- a/src/dqc_simulator/dqc_simulator.py +++ b/src/dqc_simulator/dqc_simulator.py @@ -34,6 +34,7 @@ import numpy as np import copy +import time import matplotlib.pyplot as plt class RemoteGate(Instruction): @@ -336,7 +337,11 @@ def __init__(self, *args, **kwargs): self.Num_RemoteGate = 0 # 执行 - def Execution(self, config, qpugroup, comm_noise = False): + def Execution(self, config, qpugroup, comm_noise=False, measure_time=False): + # 开始计时 + if measure_time: + start_time = time.time() + self.qpugroup = qpugroup qpus = self.qpugroup.qpus @@ -359,6 +364,12 @@ def Execution(self, config, qpugroup, comm_noise = False): result_qc = self.merge_trans_circuits(comm_noise) + # 结束计时并输出 + if measure_time: + end_time = time.time() + elapsed_time = end_time - start_time + print(f"SimDisQ Execution time: {elapsed_time:.4f} seconds") + return result_qc # Get the index of a qubit in the circuit