矢量到量子門操作的工程化實(shí)現(xiàn))
簡介面向量子信息方向的MATLAB實(shí)用工具箱整合了量子比特操作、量子門實(shí)現(xiàn)、量子線路模擬、量子測(cè)量以及熵與糾纏度量等功能適合科研人員、工程師與相關(guān)專業(yè)學(xué)生開展量子算法仿真和量子系統(tǒng)性質(zhì)分析。壓縮包共279個(gè)文件以276個(gè).m腳本為主輔以3個(gè)txt說明文檔整體僅163KB輕量易用。核心腳本與初始化配置分別提供庫函數(shù)調(diào)用與環(huán)境預(yù)設(shè)啟動(dòng)加載模塊確保每次使用自動(dòng)生效dm、measurements、entropy_and_entanglement等目錄則按密度矩陣計(jì)算、量子測(cè)量和糾纏度量分模塊組織查閱路徑清晰。配套R(shí)EADME.txt、release_notes.txt和LICENSE.txt可幫助快速上手、獲知更新與許可條款。資源已有545人學(xué)習(xí)想深入量子信息計(jì)算模擬的讀者可由此獲得一套結(jié)構(gòu)完整、可直接調(diào)用的MATLAB基礎(chǔ)工具。1. 量子信息計(jì)算庫把態(tài)矢量演化和測(cè)量封裝成可用的 MATLAB 工具箱做量子計(jì)算仿真的人大多經(jīng)歷過這種尷尬算法流程畫在紙上很清晰一落到 MATLAB 里就開始和復(fù)數(shù)矩陣搏斗。態(tài)矢量乘法、張量積順序、測(cè)量坍縮概率每一步都是出錯(cuò)重災(zāi)區(qū)調(diào)試一個(gè)小規(guī)模量子線路常常要花掉一整個(gè)下午。這個(gè)量子信息計(jì)算庫就是為解決這類問題而生的它把量子態(tài)表示、量子門操作、測(cè)量與線路模擬封裝成一組 MATLAB 函數(shù)和類讓開發(fā)者從底層矩陣運(yùn)算中解脫出來。無論是剛接觸量子計(jì)算的初學(xué)者還是需要快速驗(yàn)證算法的研究者都能靠這份源碼把思路直接變成可運(yùn)行的仿真結(jié)果改參數(shù)、換門、加測(cè)量幾乎不用動(dòng)框架代碼。2. 總體架構(gòu)圍繞 QuantumState、QuantumGate、QuantumCircuit 的三層拆解先說結(jié)論這個(gè)庫的架構(gòu)可以概括為“兩個(gè)核心類、一個(gè)調(diào)度類、三個(gè)輔助模塊”。QuantumState負(fù)責(zé)量子態(tài)的存儲(chǔ)與基礎(chǔ)運(yùn)算QuantumGate負(fù)責(zé)門的定義與組合QuantumCircuit負(fù)責(zé)把門按時(shí)間序排成線路并執(zhí)行仿真。上層再掛測(cè)量模塊和可視化工具整套分層方式和主流量子計(jì)算框架的思路基本一致后面想遷移到別的語言也容易對(duì)照。2.1 三層職責(zé)劃分為什么把態(tài)和門拆成兩個(gè)類而不是塞進(jìn)一個(gè)對(duì)象在 MATLAB 里做量子仿真的常見做法是直接拿復(fù)數(shù)矩陣塞進(jìn)腳本然后靠一堆過程式函數(shù)操作這些矩陣。這樣做在 2 到 3 個(gè)量子比特時(shí)還好一旦超過 4 個(gè)比特就會(huì)陷入“哪個(gè)矩陣乘哪個(gè)矩陣”的黑匣子狀態(tài)。這個(gè)庫選擇了面向?qū)ο蟮姆謱観uantumState只關(guān)心“我是誰”也就是當(dāng)前系統(tǒng)的態(tài)矢量或密度矩陣QuantumGate只關(guān)心“我要做什么變換”也就是一個(gè)酉矩陣QuantumCircuit把兩者組合起來按時(shí)間序調(diào)度門的執(zhí)行。這樣拆的好處體現(xiàn)在兩個(gè)地方。第一門本身是可復(fù)用的同一個(gè) H 門可以在不同線路里反復(fù)使用不用每次重新構(gòu)造矩陣。第二態(tài)的存儲(chǔ)方式可以獨(dú)立演進(jìn)比如從態(tài)矢量改成密度矩陣表示時(shí)門和線路的代碼不用大改。我自己寫仿真代碼時(shí)也傾向于這種職責(zé)劃分否則后期加噪聲模型時(shí)會(huì)發(fā)現(xiàn)所有函數(shù)都要跟著改那種牽一發(fā)動(dòng)全身的感覺經(jīng)歷過一次就不想再來第二次。2.2 目錄結(jié)構(gòu)拿到源碼后第一眼看哪里解壓源碼包后第一件事應(yīng)該是看目錄結(jié)構(gòu)。這個(gè)庫的布局大致如下quantum-lib/ ├── QuantumState % 量子態(tài)類態(tài)矢量、密度矩陣、部分求跡 ├── QuantumGate % 量子門類單比特門、受控門、自定義門 ├── QuantumCircuit % 線路類門的追加、執(zhí)行、深度統(tǒng)計(jì) ├── Measurement % 測(cè)量類投影測(cè)量、概率采樣 ├── utils/ % 輔助函數(shù)張量積、矩陣歸一化、隨機(jī)數(shù)封裝 ├── examples/ % 示例腳本貝爾態(tài)、GHZ 態(tài)、量子隱形傳態(tài) └── docs/ % 文檔和 API 說明開頭是 MATLAB 的類文件夾語法表示該文件夾下的所有文件都屬于這個(gè)類的方法。使用類文件夾的好處是不用手動(dòng)addpath到每個(gè)子目錄MATLAB 會(huì)自動(dòng)把類定義加載進(jìn)搜索路徑。初次使用時(shí)只需要在倉庫根目錄執(zhí)行一次addpath(genpath(quantum-lib))后續(xù)所有類都能被直接調(diào)用不用每次啟動(dòng)都重新配置一遍。2.3 數(shù)據(jù)流一次仿真從輸入?yún)?shù)到輸出結(jié)果經(jīng)歷了什么把一次典型仿真的數(shù)據(jù)流理順能幫你在改代碼時(shí)快速定位到具體模塊。以制備并測(cè)量一個(gè)兩比特糾纏態(tài)為例整個(gè)流程是先創(chuàng)建兩個(gè)初始化為零態(tài)的QuantumState對(duì)象接著用QuantumGate構(gòu)造 H 門和 CNOT 門然后通過QuantumCircuit按順序把 H 門作用到比特 1、把 CNOT 門作用到比特 1 和比特 2執(zhí)行線路得到最終態(tài)最后調(diào)用測(cè)量模塊對(duì)最終態(tài)做投影測(cè)量得到坍縮后的態(tài)和對(duì)應(yīng)概率。這個(gè)流程對(duì)應(yīng)到代碼里就是三層對(duì)象各司其職出問題時(shí)可以按層排查概率算得不對(duì)先看測(cè)量模塊演化結(jié)果不符合預(yù)期先看QuantumGate的矩陣構(gòu)造如果連初始態(tài)都錯(cuò)了那就是QuantumState的問題。分層的價(jià)值在調(diào)試時(shí)體現(xiàn)得最明顯不用每次都在上千行腳本里翻來翻去。3. 核心實(shí)現(xiàn)拆解態(tài)矢量、酉變換與測(cè)量坍縮的代碼鏈路這一章挑三個(gè)最關(guān)鍵的模塊把核心代碼拉出來逐段講。代碼做了適度簡化保留了原庫的核心邏輯方便閱讀也方便直接抄走。3.1 QuantumState態(tài)矢量與密度矩陣的統(tǒng)一封裝量子態(tài)在仿真里有兩個(gè)表示層級(jí)純態(tài)用態(tài)矢量混態(tài)用密度矩陣。這個(gè)庫在設(shè)計(jì)QuantumState時(shí)做了一個(gè)實(shí)用的決定內(nèi)部data屬性統(tǒng)一存復(fù)數(shù)矩陣純態(tài)存列向量混態(tài)存方陣通過is_pure標(biāo)志區(qū)分。classdef QuantumState handle properties data; % 復(fù)數(shù)矩陣純態(tài)為列向量混態(tài)為方陣 nq; % 量子比特?cái)?shù) is_pure true; end methods function obj QuantumState(init_state) % 支持傳入態(tài)矢量或密度矩陣 if isvector(init_state) obj.data init_state(:); obj.nq log2(length(init_state)); obj.is_pure true; % 歸一化態(tài)矢量 n norm(obj.data); if abs(n - 1) 1e-12 obj.data obj.data / n; end else obj.data init_state; obj.nq log2(size(init_state, 1)); obj.is_pure false; % 密度矩陣歸一化跡等于 1 tr trace(obj.data); if abs(tr - 1) 1e-12 obj.data obj.data / tr; end end end function rho density_matrix(obj) % 純態(tài)轉(zhuǎn)密度矩陣混態(tài)直接返回 if obj.is_pure rho obj.data * obj.data; else rho obj.data; end end end end構(gòu)造函數(shù)接收一個(gè)復(fù)數(shù)向量或方陣通過取對(duì)數(shù)自動(dòng)推斷比特?cái)?shù)nq并在創(chuàng)建時(shí)就完成歸一化。這里的關(guān)鍵細(xì)節(jié)是歸一化閾值1e-12量子線路跑完一輪之后由于浮點(diǎn)誤差振幅模方和往往不是精確的 1直接做后續(xù)運(yùn)算會(huì)積累偏差所以在入口統(tǒng)一處理掉。density_matrix方法是純態(tài)和混態(tài)之間的橋梁在計(jì)算期望值或繪制布洛赫球時(shí)非常有用。注意這里繼承的是handle類而不是值類這是源碼里一個(gè)值得留意的設(shè)計(jì)選擇。handle是引用語義兩個(gè)變量可以指向同一個(gè)數(shù)據(jù)對(duì)象在構(gòu)造線路時(shí)可以避免反復(fù)復(fù)制大矩陣。但這也帶來一個(gè)副作用你改了其中一個(gè)變量另一個(gè)也會(huì)跟著變。后面避坑章節(jié)會(huì)專門講這個(gè)問題。3.2 QuantumGate從單比特門到受控門的矩陣組裝量子門的本質(zhì)是酉矩陣。這個(gè)庫的QuantumGate類把常用門Pauli 門、H 門、S 門、T 門、CNOT、CZ、SWAP預(yù)置為靜態(tài)方法也允許傳入任意酉矩陣構(gòu)造自定義門。classdef QuantumGate properties matrix; % 酉矩陣 nq; % 門作用的比特?cái)?shù) name; % 門名稱 end methods function obj QuantumGate(matrix, name) % 校驗(yàn)酉性M*M 應(yīng)接近單位陣 assert(norm(matrix * matrix - eye(size(matrix))) 1e-10, ... 輸入矩陣必須是酉矩陣); obj.matrix matrix; obj.nq log2(size(matrix, 1)); obj.name name; end end methods (Static) function g H() g QuantumGate(1/sqrt(2) * [1 1; 1 -1], H); end function g CNOT(nq, ctrl, tgt) % nq : 系統(tǒng)總比特?cái)?shù) % ctrl: 控制比特編號(hào)1 到 nq % tgt : 目標(biāo)比特編號(hào)1 到 nq且不等于 ctrl dim 2^nq; m eye(dim); for idx 0:dim-1 bits dec2bin(idx, nq) - 0; % 轉(zhuǎn)成二進(jìn)制位向量 if bits(ctrl) 1 bits(tgt) 1 - bits(tgt); % 翻轉(zhuǎn)目標(biāo)比特 new_idx bin2dec(num2str(bits)) 1; m(idx 1, :) 0; m(idx 1, new_idx) 1; end end g QuantumGate(m, sprintf(CNOT(%d,%d), ctrl, tgt)); end end end構(gòu)造方法里的酉性校驗(yàn)用的是M * M也就是共軛轉(zhuǎn)置不是普通轉(zhuǎn)置transpose。這個(gè)細(xì)節(jié)對(duì)復(fù)矩陣極其關(guān)鍵很多人自定義門時(shí)會(huì)把寫成.結(jié)果矩陣平方和算出來是復(fù)數(shù)斷言直接不通過。CNOT 構(gòu)造的邏輯是對(duì)每個(gè)計(jì)算基編號(hào)逐位判斷把編號(hào)轉(zhuǎn)成二進(jìn)制位串后檢查控制位是否為 1是的話就把目標(biāo)位翻轉(zhuǎn)再把新的編號(hào)映射到單位陣對(duì)應(yīng)行上。這個(gè)方法的時(shí)間復(fù)雜度是O(4^n)能覆蓋到 10 比特以內(nèi)的大部分教學(xué)和驗(yàn)證場景。3.3 測(cè)量模塊概率計(jì)算、隨機(jī)采樣與坍縮實(shí)現(xiàn)測(cè)量是量子線路里最容易寫錯(cuò)的部分關(guān)鍵在兩點(diǎn)概率要按振幅模平方計(jì)算坍縮要按測(cè)量結(jié)果篩選分量。這個(gè)庫的測(cè)量函數(shù)把整條邏輯封裝在一個(gè)函數(shù)里。function [outcome, probs, collapsed] measure_state(state, qubits_to_measure) % state : QuantumState 對(duì)象 % qubits_to_measure : 要測(cè)量的比特編號(hào)向量例如 [1 2] % outcome : 測(cè)量結(jié)果位串如 [0 1] % probs : 每種結(jié)果出現(xiàn)的概率 % collapsed : 坍縮后的量子態(tài)未歸一化需要再歸一化 if state.is_pure nq state.nq; psi state.data; n_meas numel(qubits_to_measure); dim_meas 2^n_meas; probs zeros(dim_meas, 1); % 第一遍對(duì)所有計(jì)算基分量按測(cè)量比特分組累加概率 for i 1:numel(psi) bits dec2bin(i - 1, nq) - 0; meas_bits bits(qubits_to_measure); group_idx bin2dec(num2str(meas_bits)) 1; probs(group_idx) probs(group_idx) abs(psi(i))^2; end % 歸一化概率 probs probs / sum(probs); % 第二遍按概率隨機(jī)采樣確定測(cè)量結(jié)果 r rand(); cumprobs cumsum(probs); chosen find(cumprobs r, 1, first); chosen_bits dec2bin(chosen - 1, n_meas) - 0; % 第三遍坍縮只保留與測(cè)量結(jié)果一致的分量 collapsed zeros(size(psi)); for i 1:numel(psi) bits dec2bin(i - 1, nq) - 0; if isequal(bits(qubits_to_measure), chosen_bits) collapsed(i) psi(i); end end outcome chosen_bits; collapsed collapsed / norm(collapsed); % 重新歸一化 else error(measure_state 暫不支持混態(tài)的測(cè)量請(qǐng)先轉(zhuǎn)為純態(tài)); end end這個(gè)函數(shù)做了三件事先遍歷所有計(jì)算基振幅按測(cè)量比特的不同取值分組累加概率相當(dāng)于做了一次“部分求跡”然后用rand()做加權(quán)隨機(jī)采樣模擬測(cè)量坍縮的隨機(jī)性最后把所有不滿足測(cè)量結(jié)果的分量清零再歸一化得到坍縮后的態(tài)。三步對(duì)應(yīng)著量子力學(xué)測(cè)量公理的三個(gè)要求少一步結(jié)果都是錯(cuò)的。rand()每次返回 0 到 1 之間的均勻隨機(jī)數(shù)find(cumprobs r, 1, first)實(shí)現(xiàn)的是概率加權(quán)抽樣哪個(gè)區(qū)間被命中就得到哪個(gè)測(cè)量結(jié)果。4. 從零跑通路徑配置、貝爾態(tài)制備和概率驗(yàn)證三步走這一章把環(huán)境配置和運(yùn)行流程完整過一遍照著做就能跑出結(jié)果。我建議在 MATLAB R2020b 及以上版本運(yùn)行低版本對(duì) classdef 的支持雖然也能跑但性能會(huì)差一些。4.1 環(huán)境準(zhǔn)備與路徑加載打開 MATLAB 后先 cd 到倉庫根目錄然后執(zhí)行一次路徑加載% 當(dāng)前目錄指向 quantum-lib 所在文件夾 addpath(genpath(pwd)); savepath; % 保存路徑下次啟動(dòng)不用重新配置genpath(pwd)會(huì)遞歸地把當(dāng)前目錄下所有子文件夾加入搜索路徑包括那些開頭的類文件夾。savepath把路徑配置寫入 MATLAB 的 pathdef 文件這樣下次重啟 MATLAB 不用重復(fù)操作。如果你用的是 MATLAB Online 或者校園機(jī)房的共享環(huán)境可能沒有寫 pathdef 的權(quán)限那每次會(huì)話開始手動(dòng)執(zhí)行一次addpath(genpath(pwd))即可。4.2 跑通一個(gè)貝爾態(tài)制備線路貝爾態(tài)是量子信息里最基礎(chǔ)的糾纏態(tài)制備線路只有兩步H 門作用到第一個(gè)比特再 CNOT 把第一個(gè)比特作為控制位、第二個(gè)比特作為目標(biāo)位。% 創(chuàng)建兩比特系統(tǒng)的初始態(tài) |00 q1 QuantumState([1; 0]); q2 QuantumState([1; 0]); psi0 kron(q1.data, q2.data); system QuantumState(psi0); % 構(gòu)建線路 circ QuantumCircuit(system); circ.add_gate(QuantumGate.H(), 1); % H 門作用到比特 1 circ.add_gate(QuantumGate.CNOT(2, 1, 2), [1, 2]); % CNOT: 控制 1 目標(biāo) 2 % 執(zhí)行線路 final_state circ.run(); % 測(cè)量兩個(gè)比特 [outcome, probs, collapsed] measure_state(final_state, [1, 2]); disp(probs); % 期待看到 [0.5; 0.5; 0; 0] 之類的結(jié)果這里kron函數(shù)按從左到右的順序做張量積對(duì)應(yīng)比特 1 在前、比特 2 在后索引順序一旦搞混后續(xù)所有結(jié)果都會(huì)亂掉。circ.add_gate的第一個(gè)參數(shù)是門對(duì)象第二個(gè)參數(shù)是門作用的比特位置位置編號(hào)從 1 開始。執(zhí)行完線路后measure_state返回的probs理論上應(yīng)該只有[0 0]和[1 1]兩種結(jié)果的概率并且各占一半。4.3 驗(yàn)證結(jié)果正確性不只看概率還要看態(tài)矢量只跑出概率還不夠建議把最終態(tài)矢量也打印出來用數(shù)學(xué)期望驗(yàn)證一下。貝爾態(tài)的標(biāo)準(zhǔn)形式是(|00? |11?) / sqrt(2)對(duì)應(yīng)到態(tài)矢量就是四個(gè)分量為[1/sqrt(2); 0; 0; 1/sqrt(2)]。你可以在線路執(zhí)行后檢查% 查看最終態(tài)矢量的非零分量 nonzero_idx find(abs(final_state.data) 1e-8); disp(nonzero_idx); disp(final_state.data(nonzero_idx));如果打印出來是第 1 個(gè)和第 4 個(gè)分量為0.7071說明線路邏輯正確。如果你發(fā)現(xiàn)翻轉(zhuǎn)了過來比如是[0; 0.7071; 0.7071; 0]不用懷疑別的就是你kron的順序或者 CNOT 的控制目標(biāo)寫反了。這是我最常遇到的翻車現(xiàn)場所以每一步都建議驗(yàn)一下。提示概率結(jié)果有隨機(jī)性單次測(cè)量看到[0 0]或[1 1]都很正常。想驗(yàn)證概率分布用一個(gè)循環(huán)跑 1000 次測(cè)量取頻率或者用rng(42)固定隨機(jī)種子再重跑。5. 避坑記錄張量積順序、測(cè)量概率與內(nèi)存爆炸的五個(gè)坑這個(gè)章節(jié)每條都是實(shí)際跑仿真時(shí)容易踩進(jìn)去的坑按“現(xiàn)象 → 原因 → 解決”的格式記錄方便你快速對(duì)照排查。5.1 張量積順序搞反所有概率對(duì)不上號(hào)現(xiàn)象跑貝爾態(tài)制備測(cè)量結(jié)果的概率分布完全對(duì)不上理論值[0 1]和[1 0]出現(xiàn)了不該有的概率。原因MATLAB 的kron是嚴(yán)格按輸入順序做張量積的而量子線路的比特編號(hào)習(xí)慣從左到右排列很多人把kron(q1.data, q2.data)寫成了kron(q2.data, q1.data)整個(gè)矢量空間里的坐標(biāo)順序全部鏡像翻轉(zhuǎn)。解決在創(chuàng)建初始態(tài)時(shí)固定寫成從左到右的編號(hào)順序并且加一行注釋標(biāo)明“比特 1 在前”。如果你覺得記號(hào)太繞可以封裝一個(gè)工具函數(shù)combine_states(varargin)內(nèi)部用kron逐個(gè)相乘并做一次維度校驗(yàn)函數(shù)返回的nq必須等于輸入?yún)?shù)個(gè)數(shù)否則直接拋錯(cuò)。5.2 測(cè)量概率與隨機(jī)數(shù)的玄學(xué)重復(fù)采樣結(jié)果總是偏向一邊現(xiàn)象同樣的線路跑很多次測(cè)量結(jié)果里[0 0]出現(xiàn)的次數(shù)明顯多于[1 1]反復(fù)重試都一樣。原因大概率是概率計(jì)算時(shí)取了psi(i)的平方而不是模平方。復(fù)數(shù)振幅a bi的平方是(abi)^2模平方才是a^2b^2。MATLAB 里abs(psi(i))^2和real(psi(i))^2是兩回事。解決檢查所有概率累加的地方統(tǒng)一用abs(...)^2另外如果你的腳本在循環(huán)里調(diào)用了rand而沒設(shè)隨機(jī)種子重復(fù)試驗(yàn)之間會(huì)有偏差感建議用rng(2024)這類固定種子復(fù)現(xiàn)排除玄學(xué)因素。5.3 超過 20 個(gè)比特后內(nèi)存開始吃緊現(xiàn)象從 20 個(gè)比特開始每次run()執(zhí)行時(shí)間越來越長到 24 個(gè)比特時(shí)直接卡出內(nèi)存不足的錯(cuò)誤。原因態(tài)矢量存儲(chǔ)空間隨比特?cái)?shù)指數(shù)增長2^24個(gè)復(fù)數(shù)的雙精度矩陣需要約 256MB 內(nèi)存而這只是一份數(shù)據(jù)如果代碼里用了值傳遞或者不小心復(fù)制了對(duì)象內(nèi)存占用直接翻倍。解決一是盡量用handle類避免對(duì)象復(fù)制二是對(duì)于只需要部分子系統(tǒng)的線路考慮用密度矩陣做部分求跡不要保留完整態(tài)空間三是可以嘗試用gpuArray把矩陣乘法挪到 GPU 上遇到 20 個(gè)比特以上的大矩陣運(yùn)算GPU 帶來的速度提升不是一點(diǎn)半點(diǎn)。5.4 自定義門報(bào)“輸入矩陣必須是酉矩陣”現(xiàn)象自己構(gòu)造了一個(gè)相位門[1 0; 0 exp(1i*theta)]傳入QuantumGate構(gòu)造函數(shù)時(shí)直接斷言失敗。原因浮點(diǎn)誤差累計(jì)導(dǎo)致M*M和單位陣的差超過了 1e-10 的容差另一類可能是把共軛轉(zhuǎn)置寫成了普通轉(zhuǎn)置復(fù)矩陣的虛部沒被正確處理矩陣乘出來不是單位陣。解決構(gòu)造自定義門前先手動(dòng)驗(yàn)證norm(M*M - eye(size(M)))如果是因?yàn)楦↑c(diǎn)誤差把構(gòu)造函數(shù)里的容差放寬到1e-8如果是因?yàn)檗D(zhuǎn)置寫錯(cuò)把.改成。從這之后我每次寫新門都會(huì)先跑一遍酉性檢查成了固定流程。5.5 handle 引用語義導(dǎo)致變量互相污染現(xiàn)象創(chuàng)建了兩個(gè)QuantumState對(duì)象只是想改其中一個(gè)結(jié)果發(fā)現(xiàn)另一個(gè)的數(shù)據(jù)也變了。原因QuantumState handle是引用語義多個(gè)變量持有同一個(gè)底層數(shù)據(jù)地址任何一處修改都會(huì)同步。這在構(gòu)造線路時(shí)省了復(fù)制開銷但對(duì)不熟悉 MATLAB 面向?qū)ο蟮娜藖碚f非常反直覺。解決如果你確實(shí)需要獨(dú)立副本自己實(shí)現(xiàn)一個(gè)copy方法把data和標(biāo)志位復(fù)制到新對(duì)象里返回MATLAB內(nèi)置的copy函數(shù)對(duì) handle 類默認(rèn)是淺拷貝使用時(shí)要注意區(qū)分。知道這個(gè)坑之后我再寫多比特仿真時(shí)都會(huì)刻意避免把一個(gè)對(duì)象反復(fù)賦值給多個(gè)變量。6. 二次開發(fā)思路自定義門、噪聲信道與性能優(yōu)化的改造點(diǎn)這個(gè)庫的擴(kuò)展方式比想象中要直接核心思路是“不修改現(xiàn)有類只新增子類或新增靜態(tài)方法”。比如要加一個(gè)自定義單比特門只需要構(gòu)造QuantumGate實(shí)例不必改動(dòng)類定義本身theta pi/3; phase_gate QuantumGate([1 0; 0 exp(1i*theta)], P(pi/3)); circ.add_gate(phase_gate, 1);加噪聲模型稍微繞一點(diǎn)但也可以獨(dú)立于框架實(shí)現(xiàn)。常見做法是在線路run()之后對(duì)最終密度矩陣做一次信道變換比如退極化信道function noisy_rho depolarizing_channel(rho, p) % rho: 輸入密度矩陣 % p : 退極化概率0 到 1 之間 d size(rho, 1); noisy_rho (1 - p) * rho p * eye(d) / d; end調(diào)用時(shí)先用density_matrix()把純態(tài)轉(zhuǎn)成密度矩陣再過一次信道。性能優(yōu)化方面我一般從三個(gè)方向入手一是把QuantumCircuit.run()里循環(huán)調(diào)用的矩陣乘法改成預(yù)先合并所有門矩陣的形式減少中間矩陣數(shù)量二是對(duì)只涉及少數(shù)比特的門用稀疏矩陣存儲(chǔ)避免單位陣撐滿內(nèi)存三是在 MATLAB 支持 GPU 的環(huán)境中把QuantumState.data轉(zhuǎn)成gpuArray大矩陣乘法直接交給 GPU 處理。每次改完記得跑一遍貝爾態(tài)和 GHZ 態(tài)的驗(yàn)證腳本確認(rèn)新模塊沒有破壞原有的酉性約束和概率歸一化。從那以后我每次加完功能都強(qiáng)制走一遍三個(gè)驗(yàn)證點(diǎn)矩陣酉性、概率歸一化、兩比特糾纏態(tài)保真度成了肌肉記憶。這個(gè)習(xí)慣幫我攔住了不少看似沒問題、實(shí)際改了索引順序的隱形 bug希望也能幫到你。本文還有配套的精品資源點(diǎn)擊獲取