量子計算機編程(從入門到實踐)_第1頁
量子計算機編程(從入門到實踐)_第2頁
量子計算機編程(從入門到實踐)_第3頁
量子計算機編程(從入門到實踐)_第4頁
量子計算機編程(從入門到實踐)_第5頁
已閱讀5頁,還剩210頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

\h量子計算機編程從入門到實踐目錄\h第1章入門\h1.1所需背景\h1.2何謂QPU\h1.3動手實踐\hQCEngine入門\h1.4原生QPU指令\h1.4.1模擬器的上限\h1.4.2硬件的上限\h1.5QPU與GPU的共同點\h第一部分QPU編程\h第2章單個量子比特\h2.1物理量子比特概覽\h2.2圓形表示法\h2.2.1圓的大小\h2.2.2圓的旋轉(zhuǎn)\h2.3第一批QPU指令\h2.3.1QPU指令:NOT\h2.3.2QPU指令:HAD\h2.3.3QPU指令:READ和WRITE\h2.3.4實踐:完全隨機的比特\h2.3.5QPU指令:PHASE(θ)\h2.3.6QPU指令:ROTX(θ)和ROTY(θ)\h2.4復(fù)制:缺失的指令\h2.5組合QPU指令\hQPU指令:RNOT\h2.6實踐:量子監(jiān)聽檢測\h2.7小結(jié)\h第3章多個量子比特\h3.1多量子比特寄存器的圓形表示法\h3.2繪制多量子比特寄存器\h3.3多量子比特寄存器中的單量子比特運算\h讀取多量子比特寄存器中的某個量子比特\h3.4可視化更多數(shù)量的量子比特\h3.5QPU指令:CNOT\h3.6實踐:利用貝爾對實現(xiàn)共享隨機性\h3.7QPU指令:CPHASE(θ)和CZ\hQPU技巧:相位反沖\h3.8QPU指令:CCNOT\h3.9QPU指令:SWAP和CSWAP\h交換測試\h3.10構(gòu)造任意的條件運算\h3.11實踐:遠(yuǎn)程控制隨機性\h3.12小結(jié)\h第4章量子隱形傳態(tài)\h4.1動手嘗試\h4.2程序步驟\h4.2.1步驟1:創(chuàng)建糾纏對\h4.2.2步驟2:準(zhǔn)備有效載荷\h4.2.3步驟3.1:將有效載荷鏈接到糾纏對\h4.2.4步驟3.2:將有效載荷置于疊加態(tài)\h4.2.5步驟3.3:讀取Alice的兩個量子比特\h4.2.6步驟4:接收和轉(zhuǎn)換\h4.2.7步驟5:驗證結(jié)果\h4.3解釋結(jié)果\h4.4如何利用隱形傳態(tài)\h4.5著名的隱形傳態(tài)事故帶來的樂趣\h第二部分QPU原語\h第5章量子算術(shù)與邏輯\h5.1奇怪的不同\h5.2QPU中的算術(shù)運算\h實踐:實現(xiàn)自增運算和自減運算\h5.3兩個量子整數(shù)相加\h5.4負(fù)整數(shù)\h5.5實踐:更復(fù)雜的數(shù)學(xué)運算\h5.6更多量子運算\h5.6.1量子條件執(zhí)行\(zhòng)h5.6.2相位編碼結(jié)果\h5.7可逆性和臨時量子比特\h5.8反計算\h5.9QPU中的邏輯運算\h基本的量子邏輯\h5.10小結(jié)\h第6章振幅放大\h6.1實踐:在相位和強度之間相互轉(zhuǎn)換\h6.2振幅放大迭代\h6.3更多迭代?\h6.4多個標(biāo)記值\h6.5使用振幅放大\h6.5.1作為和估計的AA與QFT\h6.5.2用AA加速傳統(tǒng)算法\h6.6QPU內(nèi)部\h直觀理解\h6.7小結(jié)\h第7章量子傅里葉變換\h7.1隱藏模式\h7.2QFT、DFT和FFT\h7.3QPU寄存器中的頻率\h7.4DFT\h7.4.1實數(shù)DFT輸入與復(fù)數(shù)DFT輸入\h7.4.2DFT一切\(zhòng)h7.5使用QFT\h高效的QFT\h7.6QPU內(nèi)部\h7.6.1直觀理解\h7.6.2逐步運算\h7.7小結(jié)\h第8章量子相位估計\h8.1了解QPU運算\h8.2本征相位揭示有用信息\h8.3相位估計的作用\h8.4如何使用相位估計\h8.4.1輸入\h8.4.2輸出\h8.5使用細(xì)節(jié)\h8.5.1選擇輸出寄存器的大小\h8.5.2復(fù)雜度\h8.5.3條件運算\h8.6實踐中的相位估計\h8.7QPU內(nèi)部\h8.7.1直觀理解\h8.7.2逐步運算\h8.8小結(jié)\h第三部分QPU應(yīng)用程序\h第9章真實的數(shù)據(jù)\h9.1非整型數(shù)據(jù)\h9.2QRAM\h9.3向量的編碼\h9.3.1振幅編碼的局限性\h9.3.2振幅編碼和圓形表示法\h9.4矩陣的編碼\h9.4.1QPU運算如何表示矩陣\h9.4.2量子模擬\h第10章量子搜索\h10.1相位邏輯\h10.1.1構(gòu)建基本的相位邏輯運算\h10.1.2構(gòu)建復(fù)雜的相位邏輯語句\h10.2解決邏輯謎題\h小貓和老虎\h10.3求解布爾可滿足性問題的一般方法\h10.3.1實踐:一個可滿足的3-SAT問題\h10.3.2實踐:一個不可滿足的3-SAT問題\h10.4加速傳統(tǒng)算法\h第11章量子超采樣\h11.1QPU能為計算機圖形學(xué)做什么\h11.2傳統(tǒng)超采樣\h11.3實踐:計算相位編碼圖像\h11.3.1QPU像素著色器\h11.3.2使用PHASE畫圖\h11.3.3繪制曲線\h11.4采樣相位編碼圖像\h11.5更有趣的圖像\h11.6超采樣\h11.7量子超采樣與蒙特卡羅采樣\h量子超采樣的工作原理\h11.8增加顏色\h11.9小結(jié)\h第12章舒爾分解算法\h12.1實踐:在QPU上應(yīng)用舒爾分解算法\h12.2算法說明\h12.2.1我們需要QPU嗎\h12.2.2量子方法\h12.3逐步操作:分解數(shù)字15\h12.3.1步驟1:初始化QPU寄存器\h12.3.2步驟2:擴展為量子疊加態(tài)\h12.3.3步驟3:條件乘2\h12.3.4步驟4:條件乘4\h12.3.5步驟5:QFT\h12.3.6步驟6:讀取量子結(jié)果\h12.3.7步驟7:數(shù)字邏輯\h12.3.8步驟8:檢查結(jié)果\h12.4使用細(xì)節(jié)\h12.4.1求模\h12.4.2時間與空間\h12.4.3除了2以外的互質(zhì)\h第13章量子機器學(xué)習(xí)\h13.1求解線性方程組\h13.1.1線性方程組的描述與求解\h13.1.2用QPU解線性方程組\h13.2量子主成分分析\h13.2.1傳統(tǒng)主成分分析\h13.2.2用QPU進行主成分分析\h13.3量子支持向量機\h13.3.1傳統(tǒng)支持向量機\h13.3.2用QPU實現(xiàn)支持向量機\h13.4其他機器學(xué)習(xí)應(yīng)用\h第四部分展望\h第14章保持領(lǐng)先:文獻指引\h14.1從圓形表示法到復(fù)向量\h14.2與術(shù)語有關(guān)的一些細(xì)節(jié)和注意事項\h14.3測量基\h14.4門的分解與編譯\h14.5隱形傳態(tài)門\h14.6QPU名人堂\h14.7競賽:量子計算機與傳統(tǒng)計算機\h14.8基于oracle的算法研究\h14.8.1Deutsch-Jozsa算法\h14.8.2Bernstein-Vazirani算法\h14.8.3Simon算法\h14.9量子編程語言\h14.10量子模擬的前景\h14.11糾錯與NISQ設(shè)備\h14.12進一步學(xué)習(xí)\h14.12.1出版物\h14.12.2課程講義\h14.12.3在線資源第1章入門不管你是軟件工程、計算機圖形學(xué)、數(shù)據(jù)科學(xué)等方面的專家,還是充滿好奇心的計算機愛好者,我們都希望你能通過本書開始使用量子計算機,并了解如何發(fā)揮量子計算的潛力。為了實現(xiàn)上述目標(biāo),本書不會詳細(xì)解釋量子物理(量子計算的底層定律)和量子信息理論(這些定律如何決定我們處理信息的能力),而會提供示例代碼,幫助你深入理解量子計算這一令人興奮的新技術(shù)及其用途。最重要的是,你可以調(diào)整和修改本書提供的示例代碼。這樣做可以讓你以最有效的方式學(xué)習(xí):親自動手實踐。在這個過程中,我們會在必要時解釋核心概念,但只會點到為止,目的是幫助你編寫量子計算程序,而不是精通量子力學(xué)。我們有一個微不足道的愿望:感興趣的讀者或許能夠運用這些知識,在連物理學(xué)家可能都沒有聽說過的領(lǐng)域應(yīng)用和拓展量子計算技術(shù)。誠然,希望幫助引發(fā)量子革命,這個愿望絕對不算微不足道,但是成為先驅(qū)者無疑令人興奮。1.1所需背景理解量子計算背后的物理學(xué)需要大量的數(shù)學(xué)知識,晶體管背后的物理學(xué)也是如此,但學(xué)習(xí)C++連一個物理方程都不需要涉及。本書采取所謂的以程序員為中心的方法,避開任何艱深的數(shù)學(xué)知識。下面簡要列出有助于理解書中概念的知識點。熟悉程序控制結(jié)構(gòu),例如if、while等。本書使用JavaScript提供對可以在線運行的示例的輕量級訪問。如果你對JavaScript還不熟悉,但是有一些編程經(jīng)驗,那么或許能在一小時之內(nèi)就掌握閱讀本書所需的知識。有關(guān)JavaScript的全面介紹,請參見EthanBrown的《JavaScript學(xué)習(xí)指南(第3版)》。掌握程序員應(yīng)該了解的一些相關(guān)的數(shù)學(xué)知識,它們是必需的:理解數(shù)學(xué)函數(shù)的用法;熟悉三角函數(shù);熟練地操作二進制數(shù)以及在二進制表示和十進制表示之間相互轉(zhuǎn)換;理解復(fù)數(shù)的基本含義。對如何評估算法的計算復(fù)雜度(大O記法)有最基本的理解。書中超出上述要求的部分是第13章,其中將研究量子計算在機器學(xué)習(xí)中的一些應(yīng)用。篇幅所限,那一章僅概述每種機器學(xué)習(xí)應(yīng)用,并展示量子計算機在其中有何優(yōu)勢。盡管我們試圖使內(nèi)容通俗易懂,但是如果讀者具備一些機器學(xué)習(xí)背景,在付諸實踐時將有更大的收獲。本書的側(cè)重點是量子計算機編程(不是構(gòu)建或研究量子計算機),這就是你在閱讀本書時不需要了解高等數(shù)學(xué)和量子理論的原因。不過,對于有興趣進一步探索這個主題的讀者來說,第14章提供了很好的參考,并將書中介紹的概念與量子計算研究界常用的數(shù)學(xué)符號聯(lián)系起來。1.2何謂QPU盡管人們經(jīng)常談及“量子計算機”,但這個詞具有誤導(dǎo)性。它讓人聯(lián)想到一種全新的計算機,并且這種計算機使用極具未來感的某種東西替代現(xiàn)有的一切軟件。在我們編寫本書時,這是對量子計算機的一個很大卻很常見的誤解。量子計算機的前景并不在于它是“傳統(tǒng)計算機殺手”,而在于它能夠極大地擴展計算機處理的問題種類。一些重要的計算問題很容易在量子計算機上進行運算,而這在任何標(biāo)準(zhǔn)計算設(shè)備上都是做不到的1。1關(guān)于這一點,我們常常舉這樣一個例子:假設(shè)可以將傳統(tǒng)的晶體管縮小為原子大小,即便要在質(zhì)因數(shù)分解能力上與普通的量子計算機相當(dāng),傳統(tǒng)計算機的體積也得有倉庫那么大。此外,這臺傳統(tǒng)計算機中的晶體管將組裝得如此密集,以至于產(chǎn)生一個引力奇點。引力奇點使得計算非常困難,更別說這樣的傳統(tǒng)計算機能否真的存在。重要的是,這種提升效果只適用于某些問題(后文會具體闡明)。盡管我們預(yù)計這樣的問題會越來越多,但試圖利用量子計算機解決所有的計算問題是沒有意義的。對于筆記本計算機能夠執(zhí)行的大部分任務(wù),量子計算機未必表現(xiàn)得更好。換句話說,從程序員的角度來看,量子計算機實際上是協(xié)處理器。過去,計算機使用了各種各樣的協(xié)處理器,每一種都各有所長,如進行浮點運算、信號處理和實時的圖形渲染?;谶@個思路,本書使用量子處理單元(quantumprocessingunit,QPU)來指代運行書中示例代碼的設(shè)備。我們認(rèn)為,這個術(shù)語強化了量子計算的定位。與圖形處理單元(graphicsprocessingunit,GPU)等其他協(xié)處理器一樣,對QPU的編程需要程序員編寫代碼,這些代碼主要在普通計算機的中央處理器(centralprocessingunit,CPU)上運行。CPU向QPU協(xié)處理器發(fā)送指令,只為啟動與其處理能力相匹配的任務(wù)。1.3動手實踐本書的核心是能夠動手實踐的示例代碼。但是在編寫本書時,還不存在成熟通用的QPU,那么該如何運行本書中的代碼呢?幸運的是,在編寫本書時,已經(jīng)有了一些可通過云端訪問和使用的原型QPU,這令人興奮。此外,對于較小的問題,可以在傳統(tǒng)計算機上模擬QPU的表現(xiàn)。盡管無法模擬大型QPU程序,但對于簡短的代碼片段來說,這是一種學(xué)習(xí)如何控制實際QPU的簡便方法。本書中的示例代碼符合上述要求,并且即便以后出現(xiàn)更復(fù)雜的QPU,這些代碼也將保持可用性和教學(xué)性。目前有許多可用的QPU模擬器、庫和系統(tǒng)。你可以在\hhttp://oreilly-qc.github.io上找到一份列表,其中列出了幾個具有良好支持的系統(tǒng)。在該網(wǎng)頁上,我們以多種編程語言提供了本書的示例代碼。不過,為了避免書中出現(xiàn)過多的代碼,我們僅在本書中列舉用于QCEngine的JavaScript示例。QCEngine是免費的在線量子計算模擬器,利用它,用戶可以在瀏覽器中運行示例代碼,無須額外安裝任何軟件。QCEngine由本書作者開發(fā),初衷是自用,現(xiàn)在作為本書的配套工具使用。QCEngine對我們特別有用,這不僅因為它無須下載任何軟件即可運行,還因為它集成了我們在整本書中用作可視化工具的圓形表示法。QCEngine入門由于我們將大量使用QCEngine,因此值得花點時間來了解這個模擬器的用法。你可以在\hhttp://oreilly-qc.github.io上找到它。運行代碼如圖1-1所示,利用QCEngine的Web界面,能夠輕松地實現(xiàn)所需的各種可視化效果。只需在QCEngine的代碼編輯器中輸入代碼,即可生成圖像。圖1-1:QCEngine的Web界面要運行本書中的示例代碼,請從代碼編輯器頂部的下拉列表中選擇它,然后單擊“運行程序”(RunProgram)按鈕。在屏幕上將出現(xiàn)一些新的交互式界面元素,用于將代碼的運行結(jié)果可視化,如圖1-2所示。圖1-2:用于可視化QPU結(jié)果的QCEngine界面元素量子電路可視化工具該界面元素用可視化方式表示代碼所代表的量子電路。第2章和第3章會介紹量子電路所用的表示符號??梢酝ㄟ^它交互式地單步執(zhí)行程序。圓形表示法可視化工具該界面元素以圓形表示法將QPU(或模擬器)寄存器可視化。第2章會解釋如何理解和使用圓形表示法。輸出控制臺輸出控制臺用于顯示通過命令qc.print()打印的任何文本(用于調(diào)試)。使用標(biāo)準(zhǔn)的JavaScript函數(shù)console.log()打印的任何內(nèi)容仍將在Web瀏覽器的JavaScript控制臺上輸出。調(diào)試代碼調(diào)試QPU程序有一定的難度。要理解程序背后的邏輯,最簡單的方法通常是慢慢地單步執(zhí)行,同時查看每個步驟的可視化效果。將鼠標(biāo)懸停在量子電路可視化工具上,應(yīng)該會看到一條橙色豎線出現(xiàn)在固定位置,此時若移動鼠標(biāo),還會看到一條灰色豎線跟隨鼠標(biāo)移動。橙色豎線表示圓形表示法可視化工具當(dāng)前顯示的信息在量子電路及程序中的位置。它默認(rèn)在程序的結(jié)束位置,但是通過單擊量子電路的其他部分,可以讓圓形表示法可視化工具顯示程序中單擊處的QPU配置情況。來看一個例子,圖1-3顯示了當(dāng)在默認(rèn)QCEngine程序的兩個步驟之間切換時,圓形表示法可視化工具的變化情況。圖1-3:使用量子電路可視化工具和圓形表示法可視化工具單步執(zhí)行QCEngine程序用過QPU模擬器后,你可能會忍不住開始擺弄它。請盡管嘗試!在第2章中,我們會看到越來越復(fù)雜的QPU程序。1.4原生QPU指令可以用多種工具運行和檢查QPU代碼,QCEngine就是其中之一??墒?,QPU代碼究竟是什么樣子的呢?通常使用傳統(tǒng)的高級語言來控制低級QPU指令(我們已經(jīng)在基于JavaScript的QCEngine中看到過例子)。本書將帶你在高級語言和低級指令間穿梭。一方面,學(xué)習(xí)真正的量子計算機級的QPU編程有助于掌握全新的QPU基本邏輯;另一方面,了解如何通過JavaScript、Python、C++等更高級的傳統(tǒng)編程語言執(zhí)行這些操作,有助于掌握更務(wù)實的編碼范式。對專用、新的量子編程語言的定義仍在火熱進行中。本書不會過多地闡述這個話題,若對此感興趣,請參閱第14章。為了滿足你的好奇心,表1-1列出了一些基本的QPU指令。后文將詳細(xì)地解釋其中每一條指令。表1-1:基本的QPU指令集符號名稱用法描述NOT或Xqc.not(t)邏輯非CNOTot(t,c)受控非:if(c)thenNOT(t)CCNOT(托佛利門)ot(t,c1|c2)控–控–非:if(c1ANDc2)thenNOT(t)HADqc.had(t)阿達馬門PHASEqc.phase(angle,c)相對相位旋轉(zhuǎn)Zqc.phase(180,c)相對相位旋轉(zhuǎn)180°Sqc.phase(90,c)相對相位旋轉(zhuǎn)90°Tqc.phase(45,c)相對相位旋轉(zhuǎn)45°CPHASEqc.cphase(angle,c1|c2)條件相位旋轉(zhuǎn)CZqc.cphase(180,c1|c2)條件相位旋轉(zhuǎn)180°READval=qc.read(t)讀取量子比特,返回數(shù)值WRITEqc.write(t,val)將傳統(tǒng)數(shù)據(jù)寫為量子比特RNOTqc.rootnot(t)ROOT-of-NOT運算SWAP或EXCHANGEqc.exchange(t1|t2)交換2個量子比特CSWAPqc.exchange(t1|t2,c)條件交換:if(c)thenSWAP(t1,t2)具體的指令和時序取決于QPU的品牌和架構(gòu)。不過,表1-1中的是一組基本指令,應(yīng)該在所有QPU中都可用。這些指令構(gòu)成了QPU編程的基礎(chǔ),就像MOV和ADD這樣的指令之于CPU程序員一樣。1.4.1模擬器的上限盡管模擬器在運行小型QPU程序時非常方便,但與真正的QPU相比,它們的性能仍然不夠強大。衡量QPU性能的一個指標(biāo)是在其上可操作的量子比特(qubit)的數(shù)量2。量子比特就是量子位,稍后會詳細(xì)說明。2盡管媒體很喜歡將硬件可以處理的量子比特數(shù)作為衡量量子計算機性能的基準(zhǔn),但這樣做過于簡單化。要想評估QPU的真正能力,還需考慮更微妙的因素。截至本書原版出版之時,測試得出的QPU模擬器的世界記錄是51個量子比特。在實踐中,公眾可以使用的模擬器和硬件通常能夠在停止運行之前處理約26個量子比特。本書中的示例考慮到了上述限制。對量子計算初學(xué)者來說,這些示例是很好的著手點。每向示例中添加一個量子比特,都會使運行模擬器所需的內(nèi)存加倍,速度減半。1.4.2硬件的上限在本書寫作之時,實際可用的最大QPU硬件大約有70個物理量子比特(physicalqubit),而通過Qiskit開源軟件開發(fā)工具包向公眾提供的最大QPU包含16個物理量子比特3。與邏輯量子比特(logicalqubit)不同的是,這70個物理量子比特沒有糾錯能力,易受干擾,且不穩(wěn)定。與傳統(tǒng)比特相比,量子比特要脆弱得多,與周圍環(huán)境發(fā)生輕微的相互作用,就會令計算出錯。3當(dāng)本書出版時,這個數(shù)字可能會過時!在使用邏輯量子比特時,程序員無須了解QPU硬件即可實現(xiàn)任何教科書介紹的算法,并且不必?fù)?dān)心特定的硬件限制。本書專注于用邏輯量子比特編程,書中的示例代碼都可以在較小的QPU中(比如本書出版時可用的QPU)運行。忽略物理硬件細(xì)節(jié)意味著,即使未來硬件進一步發(fā)展,你掌握的技能和擁有的經(jīng)驗也仍然極具價值。1.5QPU與GPU的共同點盡管在StackExchange網(wǎng)站上已經(jīng)有了關(guān)于QPU編程的討論區(qū),但在一種全新的處理器上編程的想法仍會令人望而卻步。下面是一些關(guān)于QPU編程的事實。一個程序完全在QPU中運行的情況十分罕見。通常是由在CPU上運行的程序發(fā)出QPU指令,然后獲取結(jié)果。有些任務(wù)非常適合在QPU中執(zhí)行,有些任務(wù)則不適合。QPU時鐘與CPU時鐘不同,QPU往往通過專用的硬件接口連接到外部設(shè)備(如光學(xué)輸出設(shè)備)。典型的QPU有專用的隨機存儲器,CPU不能高效地訪問它。簡單的QPU可以是由筆記本計算機訪問的一塊芯片,甚至可以只是芯片上的一塊區(qū)域。更先進的QPU可以是昂貴的大型附加設(shè)備,并一直需要特殊的冷卻措施。即便是簡單的類型,早期的QPU也有冰箱大小,需要特殊的大電流電源插座。當(dāng)計算完成時,QPU向CPU返回計算結(jié)果的投影,并舍棄大部分內(nèi)部工作數(shù)據(jù)。QPU調(diào)試可能非常棘手,需要特殊的工具和技術(shù)。單步執(zhí)行一個程序可能很困難,通常最好的方法是更改程序,并觀察更改對輸出的影響。對一條QPU指令的執(zhí)行速度進行優(yōu)化可能會拖慢另一條QPU指令的執(zhí)行速度。雖然聽上去似乎不太可能,但這是一個事實:對于上述每一項,都可以用GPU替換QPU,并且表述仍然成立??梢哉f,QPU是具有超能力且與眾不同的技術(shù)。盡管如此,QPU編程面臨的問題并不新鮮,軟件工程師前輩早已遇到過。的確,QPU編程與傳統(tǒng)編程存在一些細(xì)微的差別,這些差別是非常新穎的(否則本書就沒有存在的必要!),但二者有很多共同點。相信自己,你一定能掌握QPU編程!第一部分QPU編程量子比特到底是什么?如何將它可視化?它有什么用處?這些問題都很簡短,但是答案很復(fù)雜。在第一部分中,我們將通過實踐來回答這些問題。第2章首先介紹并使用單個量子比特。第3章揭示多量子比特系統(tǒng)的復(fù)雜性。在這個過程中,我們將遇到許多單量子比特操作和多量子比特操作,并在第4章中直接使用這些操作實現(xiàn)量子隱形傳態(tài)。請記住,在討論過程中出現(xiàn)的示例代碼可以在QCEngine模擬器上運行(第1章已經(jīng)介紹過)。第2章單個量子比特傳統(tǒng)比特僅有1個二進制參數(shù),可以將其初始化為狀態(tài)0或狀態(tài)1。盡管二進制的邏輯運算已足夠簡單,但是我們?nèi)匀豢梢杂每招膱A和實心圓直觀地表示狀態(tài)值,如表2-1所示。表2-1:用空心圓和實心圓表示傳統(tǒng)比特可能的值圖形表示01在某種意義上,量子比特與傳統(tǒng)比特非常相似:每當(dāng)讀取一個量子比特的值時,總會得到0或1。因此,在讀出一個量子比特之后,總是可以像表2-1所示的那樣來描述它。但是在讀取之前,量子比特的值并非黑白分明,需要用更復(fù)雜的方式來描述。在讀取之前,量子比特處于疊加態(tài)(superposition)。我們很快就會了解疊加態(tài)的含義,但首先來了解一下它的強大作用。請注意,在被讀取之前,單個量子比特存在無窮多個疊加態(tài),表2-2僅列出了其中的一些。盡管最終讀出的值總會是0或1,但如果善用一些技巧,這些可用的額外狀態(tài)便能幫助我們執(zhí)行一些非常強大的運算任務(wù)。表2-2:量子比特的一些可能的值可能的值圖形表示|0?|1?0.707|0?+0.707|1?0.95|0?+0.31|1?0.707|0?–0.707|1?在表2-2中,我們將0和1分別表示為|0?和|1?。這種符號被稱為狄拉克符號(bra-ketnotation),通常用于量子計算。一個簡單的經(jīng)驗法則是,狄拉克符號中的數(shù)字表示在讀取時可能會得到的量子比特值。當(dāng)談到一個量子比特已被讀出的值時,我們只使用數(shù)字來表示。表2-2中的前兩行展示了與傳統(tǒng)比特的狀態(tài)等價的量子態(tài),其中完全沒有出現(xiàn)量子疊加態(tài)。在狀態(tài)|0?下制備的量子比特等價于傳統(tǒng)比特0(在讀取時總是給出值0),在狀態(tài)|1?下同理。如果永遠(yuǎn)只是非|0?即|1?,那么這些僅僅等價于傳統(tǒng)比特的量子比特可夠昂貴的。如何才能獲得如表2-2中后三行所示的那些更奇妙的量子疊加態(tài)呢?為了理解量子疊加態(tài),不妨先花上一點點時間思考量子比特到底是什么1。1本書盡力避免過多地解釋量子比特的含義。盡管這似乎有點令人掃興,但請記住,傳統(tǒng)編程指南幾乎從不講比特和字節(jié)迷人的物理特性。實際上,正是能夠從信息的物理本質(zhì)中抽離出來,才使得復(fù)雜程序的編寫過程變得容易。2.1物理量子比特概覽一個有助于闡釋量子疊加態(tài)的例子是單光子。為了說明這一點,讓我們先回退一步,假設(shè)要使用光子的位置來表示傳統(tǒng)比特。在圖2-1所示的設(shè)備中,帶開關(guān)的鏡子(可以通過開關(guān)調(diào)整為反射鏡或透視鏡)讓我們能夠控制光子走兩條路徑中的一條。其中,兩條路徑分別對應(yīng)0和1。圖2-1:把光子用作傳統(tǒng)比特在數(shù)字通信領(lǐng)域,確實存在圖2-1所示的設(shè)備。不過顯然,單光子處理起來非常困難(一個原因是,它不會在任何地方長時間停留)。為了使用這個設(shè)備演示量子比特的某些特性,我們把決定光子路徑的那面帶開關(guān)的鏡子替換為半鍍銀的鏡子。如圖2-2所示,半鍍銀的鏡子(也叫作分束器)有一個半反射的表面,它有50%的概率將光偏轉(zhuǎn)到值1相應(yīng)的路徑上,同時有50%的概率讓光直接沿著值0相應(yīng)的路徑向前,只有這兩種可能情況。圖2-2:光量子比特的一種簡單實現(xiàn)當(dāng)一個不可分割的光子撞擊半鍍銀的鏡子表面時,它會遭遇某種身份危機,也即出現(xiàn)一種不合常理的效應(yīng):光子處于一種既受路徑0影響、又受路徑1影響的狀態(tài)。我們將這種狀態(tài)稱為疊加態(tài),意思是光子可能處于每一條路徑上。換句話說,我們擁有的不再是一個傳統(tǒng)比特,而是一個量子比特,它處于由0態(tài)和1態(tài)疊加的狀態(tài)。人們很容易誤解疊加態(tài)的本質(zhì),就像許多介紹量子計算的流行文章所描述的那樣。那種認(rèn)為光子同時處在路徑0和路徑1上的說法并不正確。因為光子只有一個,所以如果像圖2-2所示的那樣在每條路徑上都放置探測器,那么只有一個探測器會探測到光子。當(dāng)這種情況出現(xiàn)后,量子比特將降維到數(shù)字比特,并給出確定的結(jié)果:非0即1。然而,正如我們稍后將探討的那樣,在需要通過探測讀取值之前,QPU與處于疊加態(tài)的量子比特的交互將對計算大有幫助。圖2-2所示的這種疊加態(tài)對利用QPU的量子計算能力至關(guān)重要。因此,我們需要以量化程度更高的方式描述和控制量子疊加態(tài)。當(dāng)光子處于多路徑疊加的狀態(tài)時,它與每條路徑都有一個相應(yīng)的振幅(amplitude)。這些振幅有兩個重要特性——強度和相對相位。它們就像兩個旋轉(zhuǎn)開關(guān),我們可以利用這兩個開關(guān)來改變量子疊加態(tài)的特殊配置。與每條路徑相關(guān)聯(lián)的強度(magnitude)是一個模擬值,用于衡量光子在每條路徑上的擴散程度。路徑的強度與在該路徑上檢測到光子的概率有關(guān)。具體來說,強度的平方?jīng)Q定了在給定路徑上檢測到光子的概率。在圖2-2中,可以通過改變半鍍銀鏡子的反射程度來調(diào)整與每條路徑相關(guān)聯(lián)的振幅強度。不同路徑之間的相對相位(relativephase)表示光子在一條路徑上相對于另一條路徑的延遲程度。相對相位也是一個模擬值,可以通過設(shè)置光子沿著路徑0和路徑1傳播的距離之差來控制。需要注意的是,改變相對相位不會影響光子在每條路徑上被檢測到的概率2。2雖然本書基于光的相對傳播距離來引入相對相位的概念,但這是一個普適的概念,它適用于所有類型的量子比特:光子、電子、超導(dǎo)體等。再次強調(diào),振幅包含兩個特性,即與量子疊加態(tài)的某個值相關(guān)聯(lián)的強度和相對相位。對數(shù)學(xué)感興趣的讀者不妨了解這樣一點:與疊加態(tài)中的不同路徑相關(guān)聯(lián)的振幅通常用復(fù)數(shù)來表示。振幅的強度正好是這個復(fù)數(shù)的模(復(fù)數(shù)與其共軛復(fù)數(shù)乘積的平方根),振幅的相對相位則是復(fù)數(shù)以極坐標(biāo)表示時的輻角。如果你對數(shù)學(xué)不感興趣,也不必?fù)?dān)心,我們很快將介紹一種圖形記法。在計算時,強度和相對相位是可以利用的值,不妨認(rèn)為它們被編碼在量子比特中。但是如果要從中讀取任何信息,就必須使光子撞擊某種探測器。此時,這兩個模擬值都消失了——量子比特的量子特性消失了。這就是量子計算的關(guān)鍵所在:找到一種方法來利用這些虛幻的值,使得在進行讀取這一破壞性行為之后,一些有用的值仍然得以保留。在將光子用作量子比特的情況下,圖2-2中的設(shè)置與稍后將在示例2-1中介紹的代碼示例等效。好了,用光子做的介紹就到這里了!本書是程序員指南,不是物理學(xué)教科書。讓我們從物理學(xué)中抽身,拋開光子和量子物理,看看如何描述和可視化量子比特,就像拋開電子和半導(dǎo)體物理去研究二進制邏輯一樣。2.2圓形表示法我們現(xiàn)在已經(jīng)知道了何謂疊加態(tài),但目前所知的內(nèi)容僅與光子的特有行為密切相關(guān)。接下來需要找到一種描述疊加態(tài)的抽象方式,從而只關(guān)注抽象的信息。在成熟的量子物理學(xué)中,數(shù)學(xué)描述提供了這樣一種抽象,但從表2-2左列可以看出,這種數(shù)學(xué)描述遠(yuǎn)不如傳統(tǒng)比特簡單的二進制計算直觀和方便。幸運的是,表2-2右列的圓形表示法是一種更直觀的方法。由于我們的目標(biāo)是在無須深入了解晦澀的數(shù)學(xué)知識的前提下,直觀地理解QPU的內(nèi)部原理,因此從現(xiàn)在開始,我們將完全基于圓形表示法來思考量子比特。我們通過光子實驗發(fā)現(xiàn),在QPU中,量子比特的一般狀態(tài)有兩個特性需要關(guān)注:疊加振幅的強度和振幅之間的相對相位。這些參數(shù)與圓形表示法的關(guān)系如下。與量子比特可能取的每個值(目前為止是|0?和|1?)相關(guān)聯(lián)的振幅的強度與每個|0?圓和|1?圓中的已填充區(qū)域的半徑相關(guān)。這些值的振幅之間的相對相位由|1?圓相對于|0?圓的旋轉(zhuǎn)表示(在圓中畫一條顏色較深的線,以表示旋轉(zhuǎn))。因為整本書都將依賴圓形表示法,所以有必要更詳細(xì)地了解如何通過圓的大小和旋轉(zhuǎn)來表示上述概念。2.2.1圓的大小如前所述,與|0?或|1?相關(guān)聯(lián)的強度的平方?jīng)Q定了在讀取時得到該值的概率。圓的填充半徑表示強度,這意味著如果讀取量子比特,那么每個圓中的已填充面積(或者更通俗地說,圓的大?。┡c得到該圓所對應(yīng)的值(0或1)的概率成正比。圖2-3展示了不同量子比特狀態(tài)的圓形表示法以及在每種情況下讀出值1的概率。圖2-3:從圓形表示法表示的不同疊加態(tài)中讀出值1的概率讀取量子比特會破壞信息。若對圖2-3中的所有狀態(tài)讀取量子比特,結(jié)果將非0即1。在讀取之后,量子比特會改變其狀態(tài),以匹配所讀取的值。因此,假設(shè)一個量子比特最初處于復(fù)雜的狀態(tài),可一旦讀出了值1,那么即便立即再次嘗試讀取,也只會得到值1。請注意,|0?圓中的已填充區(qū)域越大,讀出值0的概率就越大,當(dāng)然這意味著得到值1的概率越小。在圖2-3的最后一個例子中,讀出值0的概率是90%,讀出值1的概率則是10%。3在圓形表示法中,我們用圓的已填充區(qū)域來表示疊加態(tài)中的強度。雖然這看起來像是一個讓人煩惱的技術(shù)細(xì)節(jié),但務(wù)必記住,強度與已填充區(qū)域的半徑相關(guān)。為了在視覺上更直觀,即使將兩者等同起來也沒有關(guān)系。3寄存器振幅的平方之和必須總是等于1,這個要求被稱為規(guī)范化。要了解更多信息,請參閱9.3.1節(jié)。有一點很容易被忽略,但請謹(jǐn)記,那就是在圓形表示法中,與給定結(jié)果相關(guān)聯(lián)的圓的大小并不能完全代表疊加態(tài)的振幅,其中缺少的重要信息是疊加態(tài)的相對相位。2.2.2圓的旋轉(zhuǎn)利用一些QPU指令,可以改變|0?圓和|1?圓的相對旋轉(zhuǎn)情況,即量子比特的相對相位。量子比特狀態(tài)的相對相位可以取0°和360°之間的任意值,圖2-4展示了幾個例子。圖2-4:單個量子比特的相對相位示例本書用圓形表示法旋轉(zhuǎn)圓的慣例是,逆時針旋轉(zhuǎn),且角度值為正,如圖2-4所示。在前面的所有例子中,我們都只旋轉(zhuǎn)了|1?圓。為什么不旋轉(zhuǎn)|0?圓呢?顧名思義,只有量子比特疊加態(tài)的相對相位才彰顯不同。因此,只有圓之間的相對旋轉(zhuǎn)才有意義。4如果QPU指令對兩個圓都進行旋轉(zhuǎn),那么總是可以考慮等效的效果,即只旋轉(zhuǎn)|1?圓,使相對旋轉(zhuǎn)效果看起來更明顯,如圖2-5所示。4基于控制量子比特的量子力學(xué)定律,只有相對相位才是重要的。圖2-5:在圓形表示法中,只有相對旋轉(zhuǎn)才是重要的。圖中兩種狀態(tài)是等價的,這是因為兩個圓的相對相位相同注意,相對相位可以獨立于疊加態(tài)的強度而變化,反之亦然。比較圖2-3中的第3個和第4個例子,可以看到,單個量子比特的不同結(jié)果之間的相對相位對讀出某個結(jié)果的概率沒有直接影響。由于量子比特的相對相位對疊加態(tài)的強度沒有影響,因此它不會直接影響可觀測的讀取結(jié)果。這可能會使相對相位這個特性看起來無關(guān)緊要,但事實并非如此!在涉及多個量子比特的量子計算中,可以利用旋轉(zhuǎn)來巧妙、間接地影響最終讀出不同值的概率。實際上,精心設(shè)計的相對相位可以提供驚人的計算優(yōu)勢。接下來將介紹一些量子運算,特別是那些只對單個量子比特起作用的運算。我們將使用圓形表示法將運算效果可視化。與傳統(tǒng)比特明顯的數(shù)字特性不同,量子比特的強度和相對相位是具有連續(xù)自由度的特性。這導(dǎo)致許多人誤以為,量子計算類似于命運多舛的模擬計算(analogcomputing)。但需要指出的是,盡管量子計算具有連續(xù)自由度,但QPU計算導(dǎo)致的誤差仍然可以用數(shù)字方式糾正。這就是QPU比模擬計算設(shè)備更穩(wěn)健的原因。2.3第一批QPU指令與CPU的同類運算一樣,針對單個量子比特的QPU運算將輸入信息轉(zhuǎn)換為目標(biāo)輸出。當(dāng)然,QPU運算的輸入和輸出是量子比特,而不是傳統(tǒng)比特。許多QPU指令5有相應(yīng)的逆指令,了解它們是有用的。這樣的QPU運算被稱為可逆,這意味著在進行這些運算時不會丟失或舍棄任何信息。然而,一些QPU運算是不可逆的,因此它們會導(dǎo)致信息丟失。后文會解釋,了解運算是否可逆對我們?nèi)绾螒?yīng)用它有重要的影響。5在本書中,“QPU指令”和“QPU運算”是等義的,經(jīng)常交替使用。某些QPU指令看上去有些奇怪,而且用法不明,但在簡單了解之后,我們將很快開始使用它們。2.3.1QPU指令:NOTNOT與傳統(tǒng)的邏輯非指令類似。應(yīng)用它之后,0會變?yōu)?,反之亦然。然而,與傳統(tǒng)的邏輯非指令不同的是,QPU的NOT指令可以對處于疊加態(tài)的量子比特進行操作。用圓形表示法可以簡單地表示NOT運算的結(jié)果,只需交換|0?圓和|1?圓即可,如圖2-6所示。圖2-6:用圓形表示法表示NOT運算可逆性:就像傳統(tǒng)的數(shù)字邏輯運算一樣,NOT運算的逆運算是它自己。兩次應(yīng)用它會將一個量子比特恢復(fù)到初始值。2.3.2QPU指令:HADHAD是Hadamard的縮寫形式,該運算本質(zhì)上是為某個呈|0?態(tài)或|1?態(tài)的量子比特創(chuàng)建相等的疊加態(tài)。它就像一把鑰匙,為我們開啟量子疊加態(tài)那既奇妙又微妙的并行性之門!與NOT運算不同,HAD沒有針對傳統(tǒng)比特的等價運算。在用圓形表示法表示時,HAD輸出的|0?圓和|1?圓的已填充面積相同,如圖2-7所示。圖2-7:針對基本狀態(tài)進行HAD運算HAD運算會在量子比特中產(chǎn)生均勻疊加效果,即產(chǎn)生每個結(jié)果出現(xiàn)的概率相同的疊加態(tài)。注意,HAD運算對初始狀態(tài)為|0?和|1?的量子比特稍有不同:對|1?態(tài)應(yīng)用HAD,會在一個圓中產(chǎn)生非零旋轉(zhuǎn)(相對相位),而對|0?態(tài)應(yīng)用HAD則不會如此。你可能會好奇,如果針對已經(jīng)處于疊加態(tài)的量子比特應(yīng)用HAD,結(jié)果會如何。找到答案的最佳方法就是做實驗!通過實驗,你很快就會注意到以下現(xiàn)象。根據(jù)圖2-7所示的規(guī)則,HAD分別作用于|0?態(tài)和|1?態(tài)。生成的|0?值和|1?值被組合起來,并根據(jù)初始疊加態(tài)的振幅加權(quán)6。6關(guān)于HAD和其他常見運算背后的數(shù)學(xué)細(xì)節(jié),請參考第14章。可逆性:與NOT運算類似,HAD運算的逆運算也是它自己。兩次應(yīng)用它會將一個量子比特恢復(fù)到初始值。2.3.3QPU指令:READ和WRITEREAD運算是前文介紹的讀取過程的形式化表示。它在QPU指令集中與眾不同,這是因為它是唯一可能返回隨機結(jié)果的指令。WRITE運算能夠在操作QPU寄存器之前將它初始化,這是一個具有確定性的過程。將READ指令應(yīng)用于單個量子比特將返回0或1,每個結(jié)果出現(xiàn)的概率由量子比特狀態(tài)中相應(yīng)振幅的強度的平方?jīng)Q定(忽略相對相位)。應(yīng)用READ指令之后,如果得到的結(jié)果為0,那么量子比特將維持|0?態(tài),反之則維持|1?態(tài)。換句話說,任何疊加態(tài)都將被不可逆轉(zhuǎn)地破壞。因為圓中的已填充面積體現(xiàn)了相應(yīng)結(jié)果出現(xiàn)的概率,所以在用圓形表示法表示READ運算的結(jié)果時,與結(jié)果對應(yīng)的圓將被完全填充,而其余的變?yōu)榭招膱A。圖2-8展示了針對不同的疊加態(tài)應(yīng)用READ指令的場景。圖2-8:READ運算的隨機結(jié)果在圖2-8的第2個示例中,READ運算刪除了全部有意義的相對相位信息。因此,我們重新調(diào)整狀態(tài),使圓中的線垂直。使用READ和NOT,可以編寫簡單的WRITE指令,從而制備目標(biāo)狀態(tài)為|0?或|1?的量子比特。首先針對量子比特應(yīng)用READ指令,之后,如果所得的值與計劃寫入的值不同,則應(yīng)用NOT指令。請注意,WRITE運算不能制備處于任意疊加態(tài)(具有任意強度和相對相位)的量子比特,它制備的量子比特只能處于|0?態(tài)或|1?態(tài)7。7我們在后文中會看到,獲得任意的疊加態(tài)很難,但很有用,在量子機器學(xué)習(xí)應(yīng)用中尤其如此。第13章將介紹一種方法??赡嫘裕篟EAD和WRITE是不可逆的。它們會破壞疊加態(tài),并導(dǎo)致信息丟失。疊加態(tài)一旦遭到破壞,量子比特的模擬值(強度和相對相位)就會永遠(yuǎn)消失。2.3.4實踐:完全隨機的比特在介紹更多的單量子比特運算之前,讓我們休息片刻,來看看如何利用HAD、READ和WRITE創(chuàng)建一個強大的程序。該程序能夠生成真正的隨機比特,這在任何傳統(tǒng)計算機上都不可能實現(xiàn)。縱觀計算史,人們花費了大量的時間和精力來開發(fā)偽隨機數(shù)生成器(pseudo-randomnumbergenerator,PRNG),這些系統(tǒng)在密碼學(xué)和天氣預(yù)報等領(lǐng)域有著廣泛的應(yīng)用。PRNG是偽隨機的,這是因為如果知道計算機內(nèi)存的內(nèi)容和PRNG算法,原則上就可以預(yù)測下一個要生成的數(shù)字。根據(jù)已知的物理定律,針對處于疊加態(tài)的量子比特,讀取結(jié)果本質(zhì)上是完全不可預(yù)測的。因此,借助QPU,我們就能創(chuàng)建世界上最好的隨機數(shù)生成器,只需要制備一個處于|0?態(tài)的量子比特,對其應(yīng)用HAD指令,然后讀取它的值??梢允褂昧孔与娐罚╭uantumcircuit)來展示QPU指令組合,如圖2-9所示。圖2-9:用QPU生成完全隨機的比特雖然簡單得難以置信,但是我們已經(jīng)有了第一個QPU程序:量子隨機數(shù)生成器(quantumrandomnumbergenerator,QRNG)??梢允褂檬纠?-1中的代碼片段來模擬這個過程。如果在QCEngine上反復(fù)運行這4行代碼,就會得到一個隨機的二進制數(shù)字串。當(dāng)然,像QCEngine這種以CPU驅(qū)動的QPU模擬器只是用PRNG來模擬QRNG,但是在真正的QPU中運行等價的代碼將生成完全隨機的二進制數(shù)字串。示例代碼請在\hhttp://oreilly-qc.github.io?p=2-1上運行本示例。示例2-1隨機比特qc.reset(1);//分配一個量子比特qc.write(0);//寫入值0qc.had();//使量子比特處于0和1的疊加態(tài)varresult=qc.read();//讀取數(shù)字比特可以在\hhttp://oreilly-qc.github.io上找到本書中的所有示例代碼,這些代碼既可以在QPU模擬器上運行,也可以在真正的QPU硬件上運行。運行這些示例代碼是學(xué)習(xí)QPU編程的重要一環(huán)。若想了解更多信息,請參閱第1章。這可能是你的第一個量子程序,祝賀你!讓我們逐行分析,了解每一行的意義。qc.reset(1)設(shè)置QPU模擬器,請求分配一個量子比特。我們?yōu)镼CEngine編寫的所有程序都將用類似這樣的一行代碼去初始化一個或一組量子比特。qc.write(0)將單個量子比特初始化為|0?態(tài),這相當(dāng)于將傳統(tǒng)比特設(shè)置為值0。qc.had()對量子比特應(yīng)用HAD指令,使其處于|0?和|1?的疊加態(tài),如圖2-7所示。varresult=qc.read()在計算結(jié)束時將量子比特的值作為隨機數(shù)字比特讀出,并將該值賦給變量result。本例所做的一切似乎不過是用一種非常昂貴的方式拋硬幣,但是這種想法低估了HAD的威力。如果深入探究HAD的原理,就會發(fā)現(xiàn)這既不是偽隨機數(shù)生成器,也不是基于硬件的隨機數(shù)生成器。與它們不同,量子物理定律保證了HAD運算的不可預(yù)測性。在已知的宇宙中,即便知道用來生成隨機數(shù)的指令,也沒有人能夠猜出從應(yīng)用了HAD指令的量子比特中讀出的隨機數(shù)是0還是1。雖然我們在第3章中才會正式學(xué)習(xí)多量子比特的內(nèi)容,但是現(xiàn)在可以很容易地并行運行8次單量子比特程序,從而生成隨機字節(jié),如圖2-10所示。圖2-10:生成隨機字節(jié)示例2-2展示了用于生成隨機字節(jié)的代碼,它與示例2-1相差不大。示例代碼請在\hhttp://oreilly-qc.github.io?p=2-2上運行本示例。示例2-2隨機字節(jié)qc.reset(8);qc.write(0);qc.had();varresult=qc.read();qc.print(result);請注意,我們利用了這樣一個事實:除非明確地指定要操作的量子比特,否則QCEngine指令(如WRITE和HAD)將默認(rèn)應(yīng)用于所有經(jīng)過初始化的量子比特。盡管示例2-2用了多個量子比特,但實際上沒有進行將多個量子比特作為輸入的運算。該程序只能被序列化為針對單個量子比特運行。2.3.5QPU指令:PHASE(θ)PHASE(θ)也沒有針對傳統(tǒng)比特的等價運算。它使得我們能夠直接操作量子比特的相對相位,將其改變某個特定的角度。因此,除了要操作的量子比特之外,PHASE(θ)還需要一個額外的數(shù)值參數(shù),即旋轉(zhuǎn)角度。例如,PHASE(45)表示進行45°的旋轉(zhuǎn)運算。在使用圓形表示法表示時,PHASE(θ)的作用就是簡單地以指定的角度旋轉(zhuǎn)|1?圓。圖2-11展示了PHASE(45)的效果。圖2-11:PHASE(45)的效果請注意,PHASE(θ)僅旋轉(zhuǎn)|1?圓,因此它對處于|0?態(tài)的量子比特沒有影響??赡嫘裕篜HASE(θ)是可逆的,不過逆運算通常不是它自己。通過應(yīng)用與原始角度相反的PHASE(θ),可以反轉(zhuǎn)相對相位旋轉(zhuǎn)效果。在圓形表示法中,這相當(dāng)于通過反向旋轉(zhuǎn)抵消旋轉(zhuǎn)效果。使用HAD和PHASE,可以創(chuàng)建一些常用的單量子比特狀態(tài),如圖2-12所示。這些狀態(tài)分別被命名為|+?、|–?、|+Y?和|–Y?。如果你想使用QPU小試身手,請看看能否用HAD和PHASE產(chǎn)生這些狀態(tài)(每個疊加態(tài)在|0?態(tài)和|1?態(tài)中都具有相等的強度)。圖2-12:十分常用的4種單量子比特狀態(tài)盡管產(chǎn)生上述狀態(tài)的一種方法是使用HAD和PHASE,但也可以將它們理解為所謂的單量子比特旋轉(zhuǎn)運算的結(jié)果。2.3.6QPU指令:ROTX(θ)和ROTY(θ)我們已經(jīng)了解了PHASE(θ)指令的用途,即旋轉(zhuǎn)量子比特的相對相位,在圓形表示法中,該指令旋轉(zhuǎn)的是|1?圓。另外兩個與PHASE(θ)相關(guān)的常見指令是ROTX(θ)和ROTY(θ),它們會以稍微不同的方式旋轉(zhuǎn)量子比特。圖2-13用圓形表示法展示了ROTX(45)和ROTY(45)在|0?態(tài)和|1?態(tài)上的應(yīng)用效果。圖2-13:在|0?態(tài)和|1?態(tài)上應(yīng)用ROTX和ROTY圖2-13中的效果不太容易理解,至少不像PHASE那樣直觀。這兩個指令的名稱來源于單量子比特狀態(tài)的另一種常見的可視化表示,即布洛赫球(Blochsphere)。在布洛赫球表示法中,單個量子比特是由三維球面上的某個點表示的。本書沒有使用布洛赫球表示法,而是使用了圓形表示法,這是由于布洛赫球表示法不能很好地表示多個量子比特。但是為了滿足你的好奇心,我們簡單介紹一下。如果用布洛赫球表示一個量子比特,那么ROTX和ROTY分別表示圍繞球體的軸和軸旋轉(zhuǎn)量子比特。由于本書在表示量子比特時使用兩個圓而不是球體,因此ROTX和ROTY在圓形表示法中就失去了意義。實際上,PHASE對應(yīng)于繞軸旋轉(zhuǎn),它在布洛赫球表示法中相當(dāng)于ROTZ。2.4復(fù)制:缺失的指令有一個指令可用于傳統(tǒng)計算機,但不能在QPU中實現(xiàn)。盡管可以通過反復(fù)創(chuàng)建得到一個已知狀態(tài)的多個副本8,但是在狀態(tài)不確定的情況下,無法通過量子計算來部分復(fù)制某個狀態(tài)。這種約束是由控制量子比特的基本物理定律所導(dǎo)致的。8如果狀態(tài)是|0?或|1?,就可以簡單地通過WRITE指令來實現(xiàn)。缺失復(fù)制指令無疑會帶來不便,但正如我們將在后文中了解到的,QPU的其他能力足以彌補這一不足。2.5組合QPU指令我們已經(jīng)了解的指令有NOT、HAD、READ、WRITE和PHASE。值得一提的是,和傳統(tǒng)的邏輯運算指令一樣,可以結(jié)合這些指令來實現(xiàn)其中每一個指令,甚至創(chuàng)建出全新的指令。假設(shè)某種QPU提供HAD指令和PHASE指令,但缺失NOT指令。將PHASE(180)與兩個HAD相結(jié)合,就能產(chǎn)生與NOT完全相同的結(jié)果,如圖2-14所示。反之,PHASE(180)也可以通過HAD和NOT來實現(xiàn)。圖2-14:構(gòu)建等效運算QPU指令:RNOT通過組合QPU指令,還可以創(chuàng)建出在傳統(tǒng)邏輯世界中根本不存在的有趣指令,RNOT(ROOT-of-NOT)就是這樣一個例子。顧名思義,它是NOT指令的平方根,也就是說,應(yīng)用該指令兩次,相當(dāng)于應(yīng)用一次NOT指令,如圖2-15所示。圖2-15:對于傳統(tǒng)比特而言,這是不可能實現(xiàn)的運算構(gòu)建RNOT指令的方法不止一種,圖2-16給出了一種簡單的實現(xiàn)。圖2-16:實現(xiàn)RNOT可以通過模擬器驗證一下,看看應(yīng)用兩次RNOT是否確實產(chǎn)生了與NOT相同的結(jié)果,如示例2-3所示。示例代碼請在\hhttp://oreilly-qc.github.io?p=2-3上運行本示例。示例2-3驗證RNOT的效果qc.reset(1);qc.write(0);//應(yīng)用RNOTqc.had();qc.phase(90);qc.had();//應(yīng)用RNOTqc.had();qc.phase(90);qc.had();可以用圓形表示法將實現(xiàn)RNOT(兩個HAD之間有一個PHASE(90))所涉及的每個步驟都可視化,如圖2-17所示。圖2-17:將RNOT的實現(xiàn)過程可視化利用圓形表示法,可以根據(jù)量子比特的演變理解RNOT為何是NOT的平方根。回顧圖2-14,我們對一個量子比特應(yīng)用HAD,然后將其相對相位旋轉(zhuǎn)180°,再應(yīng)用一次HAD,這一系列操作等同于應(yīng)用一次NOT。由于RNOT對量子比特執(zhí)行一半的旋轉(zhuǎn)(PHASE(90)),因此應(yīng)用兩次RNOT會產(chǎn)生HAD-PHASE(180)-HAD序列,等同于NOT。乍一看,這可能有些難以理解,但是如果試著應(yīng)用兩次RNOT,就會理解上述原理。(提示:HAD是它本身的逆指令,也就是說,應(yīng)用兩次HAD相當(dāng)于什么都不做。)可逆性:雖然RNOT不是其本身的逆指令,但是圖2-16中的運算可以通過使用負(fù)的相位值來逆轉(zhuǎn),如圖2-18所示。圖2-18:RNOT的逆運算盡管有些晦澀,但RNOT教給我們重要的一招:通過精心地將信息保存在量子比特的相對相位中,可以實現(xiàn)全新的計算類型。2.6實踐:量子監(jiān)聽檢測為了更實際地展現(xiàn)控制量子比特相對相位的優(yōu)勢,我們用一個更復(fù)雜的程序來結(jié)束本章。示例2-4使用前面介紹的簡單的單量子比特QPU指令來完成簡化的量子密鑰分發(fā)(quantumkeydistribution,QKD)。QKD是量子密碼學(xué)領(lǐng)域的核心協(xié)議,通過它能安全地傳輸信息。假設(shè)QPU程序員Alice和Bob正在通過能夠傳輸量子比特的信道相互發(fā)送數(shù)據(jù)。他們偶爾會發(fā)送示例2-4描述的具有特殊構(gòu)造的“監(jiān)聽檢測”量子比特,用于測試所用的信道是否被監(jiān)聽。任何試圖讀取“監(jiān)聽檢測”量子比特的監(jiān)聽者都有12.5%的概率被發(fā)現(xiàn)。因此,即使Alice和Bob在整個傳輸過程中只使用了100個這樣的量子比特,監(jiān)聽不被發(fā)現(xiàn)的可能性也只有約百萬分之一。Alice和Bob可以通過交換一些不需要加密的傳統(tǒng)數(shù)字信息來檢測他們的密鑰是否被泄露。在交換信息后,他們測試一些量子比特,方法是讀取量子比特并檢查讀取結(jié)果是否符合預(yù)期。如果出現(xiàn)不一致,就說明有人在監(jiān)聽。該過程如圖2-19所示。圖2-19:量子監(jiān)聽檢測程序以下給出代碼。建議嘗試運行示例2-4中的代碼,并像探索任何其他代碼片段一樣進行調(diào)整和測試。示例代碼請在\hhttp://oreilly-qc.github.io?p=2-4上運行本示例。示例2-4量子監(jiān)聽檢測qc.reset(3);qc.discard();vara=qint.new(1,'alice');varfiber=qint.new(1,'fiber');varb=qint.new(1,'bob');functionrandom_bit(q){q.write(0);q.had();returnq.read();}//生成2個隨機比特varsend_had=random_bit(a);varsend_val=random_bit(a);//創(chuàng)建Alice的量子比特a.write(0);if(send_val)//根據(jù)隨機比特判斷是否設(shè)置該值a.not();if(send_had)//根據(jù)隨機比特判斷是否應(yīng)用HADa.had();//發(fā)送量子比特fiber.exchange(a);//監(jiān)聽varspy_is_present=true;if(spy_is_present){varspy_had=0;if(spy_had)fiber.had();varstolen_data=fiber.read();fiber.write(stolen_data);if(spy_had)fiber.had();}//接收量子比特varrecv_had=random_bit(b);fiber.exchange(b);if(recv_had)b.had();varrecv_val=b.read();//現(xiàn)在Alice用郵件告訴Bob她選擇的操作和值//如果選擇的操作匹配,但值不一樣,就說明通信被監(jiān)聽if(send_had==recv_had)if(send_val!=recv_val)qc.print('Caughtaspy!\n');在示例2-4中,Alice和Bob各自可以訪問只包含一個量子比特的簡單QPU,并且可以沿著量子信道發(fā)送量子比特。可能會有人監(jiān)聽該信道。在示例代碼中,通過變量spy_is_present來控制是否存在監(jiān)聽者。量子密碼可以用這么小的QPU來實現(xiàn),這就是早在更強大的通用QPU出現(xiàn)之前,小型QPU就已經(jīng)開始商業(yè)化應(yīng)用的原因之一。讓我們逐步分析代碼,看看Alice和Bob如何利用手頭的簡單資源實現(xiàn)量子監(jiān)聽檢測。以下結(jié)合代碼注釋來解釋。//生成2個隨機比特Alice將她的單量子比特QPU作為一個簡單的QRNG,正如我們在示例2-2中所做的那樣,生成兩個只有她知道的秘密隨機比特。本例將它們定義為send_had和send_val。//創(chuàng)建Alice的量子比特Alice用她的兩個隨機比特來創(chuàng)建“監(jiān)聽檢測”量子比特。她為其賦值,然后根據(jù)send_had的值判斷是否應(yīng)用HAD。實際上,她的量子比特將處于以下狀態(tài)之一:|0?、|1?、|+?、|??,不過她暫時不會告訴任何人具體是哪個狀態(tài)。如果Alice決定應(yīng)用HAD,并且Bob想通過讀取知道Alice發(fā)送的是0還是1,那么Bob在讀取之前,必須應(yīng)用HAD的逆指令(其實就是HAD)。//發(fā)送量子比特Alice把她的量子比特發(fā)送給Bob。為清晰起見,本例使用另一個量子比特來表示信道。//監(jiān)聽如果Alice傳輸?shù)氖莻鹘y(tǒng)的數(shù)字比特,那么監(jiān)聽者只需復(fù)制即可完成任務(wù)。如果用了量子比特,復(fù)制就不可行了。回憶一下,量子比特沒有復(fù)制指令,監(jiān)聽者唯一能做的就是讀取Alice發(fā)送的量子比特,然后小心地將同樣的量子比特發(fā)送給Bob,以免被發(fā)現(xiàn)。不過請記住,讀取操作將不可避免地破壞量子比特的信息,因此監(jiān)聽者在讀取后只能獲得傳統(tǒng)比特的信息。因為監(jiān)聽者并不知道Alice是否應(yīng)用了HAD,所以他也不知道在讀取前是否應(yīng)該應(yīng)用HAD。如果僅執(zhí)行讀取操作,那么監(jiān)聽者并不知道他接收到的是從一個處于疊加態(tài)的量子比特中讀取的隨機值,還是實際上由Alice編碼的值。這意味著,監(jiān)聽者不僅無法可靠地提取Alice的量子比特,也無法知道應(yīng)該將什么狀態(tài)發(fā)送給Bob才能避免被發(fā)現(xiàn)。//接收量子比特與Alice一樣,Bob隨機生成一個recv_had比特,并根據(jù)這個值判斷在對Alice的量子比特應(yīng)用READ之前是否應(yīng)用HAD。這意味著Bob偶爾能正確解碼Alice的二進制值,其他時候則不能。//如果選擇的操作匹配,但值不一樣,就說明通信被監(jiān)聽既然量子比特已經(jīng)被接收,Alice和Bob就可以公開地比較他們是否一致選擇了應(yīng)用HAD(或選擇不應(yīng)用HAD)。如果他們碰巧都應(yīng)用了HAD(概率約為50%),那么二者的值應(yīng)該一致;也就是說,Bob能正確解碼Alice的消息。在正確解碼的消息中,如果值不一致,就可以得出結(jié)論:有人監(jiān)聽了他們的消息,并將不正確的量子比特發(fā)送給了Bob。2.7小結(jié)本章介紹了一種描述單個量子比特的方法,以及用于操作單個量子比特的各種QPU指令。READ指令的隨機性被用來構(gòu)建量子隨機數(shù)生成器。通過控制量子比特的相對相位,可以實現(xiàn)基本的量子密碼。后文將大量使用圓形表示法來可視化量子比特的狀態(tài)。第3章將擴展圓形表示法,以表示多量子比特系統(tǒng),并介紹用于處理這種系統(tǒng)的QPU指令。第3章多個量子比特盡管單個量子比特很有用,但多個量子比特在組合之后會更強大,也更有趣。我們已經(jīng)在第2章中詳細(xì)地了解了量子疊加現(xiàn)象為計算引入的新參數(shù):強度和相對相位。當(dāng)QPU可以訪問多個量子比特時,我們可以利用第2個強大的量子現(xiàn)象:量子糾纏(quantumentanglement)。量子糾纏是量子比特之間的一種非常特殊的相互作用,我們將在本章中以復(fù)雜而巧妙的方式利用它。不過,為了充分利用多個量子比特,我們首先需要用一種方法將它們可視化。3.1多量子比特寄存器的圓形表示法能否擴展圓形表示法,使之可用于表示多個量子比特呢?如果量子比特之間沒有交互,那么可以簡單地使用單個量子比特表示法的復(fù)數(shù)版本。換句話說,可以為每個量子比特準(zhǔn)備一對圓來分別表示它的|0?態(tài)和|1?態(tài)。雖然這種簡單的表示法可以表示任意單個量子比特的疊加態(tài),但它無法表示量子比特組的疊加態(tài)。如何用圓形表示法表示多量子比特寄存器的狀態(tài)呢?就像傳統(tǒng)比特的情況一樣,只需用含有N個量子比特的寄存器來表示2N個值即可。例如,處于狀態(tài)|0?|1?|1?的三量子比特寄存器可以表示十進制數(shù)3。對于多量子比特寄存器,通常用與表示單個量子比特相同的量子表示法來描述寄存器所表示的十進制數(shù)。鑒于單個量子比特可以編碼狀態(tài)|0?和|1?,雙量子比特寄存器可以對狀態(tài)|0?、|1?、|2?、|3?進行編碼。利用量子比特的特點,還可以創(chuàng)建這些狀態(tài)的疊加態(tài)。為了表示N個量子比特的疊加態(tài),我們將使用單獨的圓來表示2N個值中的每個值,如圖3-1所示。圖3-1:用圓形表示法表示不同數(shù)量的量子比特我們已經(jīng)熟悉圖3-1中表示單個量子比特的兩個圓。對于2個量子比特,有分別表示|0?、|1?、|2?、|3?的圓。我們采用的不是“每個量子比特一對圓”的表示法,而是在讀取這些量子比特時,用不同的圓來表示每個可能得到的值。對于3個量子比特,QPU寄存器的值為|0?、|1?、|2?、|3?、|4?、|5?、|6?、|7?,這是因為一旦讀取,就會得到任意3比特值。結(jié)合圖3-1來看,這意味著現(xiàn)在可以將強度和相對相位與這2N個圓關(guān)聯(lián)起來。以3個量子比特的情況為例,每個圓的強度決定了在讀取全部量子比特時得到特定3比特值的概率。你可能想知道,當(dāng)多量子比特寄存器處于疊加態(tài)時,其中的單個量子比特會處于何種狀態(tài)。在某些情況下,可以很容易地推導(dǎo)出單個量子比特的狀態(tài)。如圖3-2所示,三量子比特寄存器的狀態(tài)|0?、|2?、|4?、|6?的疊加態(tài)可以很容易地用每個量子比特的狀態(tài)來表示。圖3-2:從多量子比特寄存器的狀態(tài)推導(dǎo)出單個量子比特的狀態(tài)為了確認(rèn)圖3-2中的單個量子比特表示法和多個量子比特表示法是等價的,可以用3位二進制數(shù)寫出多量子比特狀態(tài)下的每個十進制數(shù)。實際上,這種多量子比特狀態(tài)可以簡單地使用針對單個量子比特的兩個HAD運算來生成,如示例3-1所示。示例代碼請在\hhttp://oreilly-qc.github.io?p=3-1上運行本示例。示例3-1創(chuàng)建可以用單個量子比特表示的多量子比特狀態(tài)qc.reset(3);qc.write(0);varqubit1=qint.new(1,'qubit1');varqubit2=qint.new(1,'qubit2');varqubit3=qint.new(1,'qubit3');qubit2.had();qubit3.had();示例3-1引入了一些新的QCEngine語法,用于跟蹤多個量子比特。qint對象用于標(biāo)記量子比特,有了它,就可以像使用標(biāo)準(zhǔn)變量一樣來使用量子比特。在使用qc.reset()在寄存器中設(shè)置一些量子比特后,使用qint.new()將它們分配給qint對象。qint.new()的第1個參數(shù)指定了要從qc.reset()創(chuàng)建的棧中拿多少個量子比特分配給這個qint對象。第2個參數(shù)是在量子電路可視化工具中要使用的標(biāo)簽。qint對象的許多方法讓我們可以直接將QPU指令應(yīng)用于量子比特組。在示例3-1中,我們使用qint.had()。圖3-2中的多量子比特寄存器狀態(tài)可以基于組成它的量子比特來理解。下面看看三量子比特寄存器的狀態(tài),如圖3-3所示。圖3-3:三量子比特寄存器示例圖3-3表示3個量子比特處于|0?態(tài)和|7?態(tài)相等的疊加態(tài)。能否像在圖3-2中所做的那樣,將三量子比特寄存器以單個量子比特的形式進行可視化呢?因為0和7分別對應(yīng)二進制數(shù)000和111,所以3個量子比特處于|0?|0?|0?和|1?|1?|1?的疊加態(tài)。令人驚訝的是,沒有辦法用單個量子比特來表示這種情況!注意,這3個量子比特在讀出后總是具有相同的值(得到0或1的概率各為50%)。很明顯,這3個量子比特一定有某種聯(lián)系,使得它們的結(jié)果總是相同的。這種聯(lián)系就是強大的量子糾纏現(xiàn)象。多個量子比特的糾纏態(tài)不能用其中的單個量子比特來描述,不過歡迎你大膽嘗試!這種糾纏態(tài)只能通過整個多量子比特寄存器來描述。事實證明,僅僅通過單量子比特運算不可能產(chǎn)生糾纏態(tài)。為了更深入地探討量子糾纏,需要先理解多量子比特運算。3.2繪制多量子比特寄存器我們已經(jīng)知道如何以圓形表示法用2N個圓來表示N個量子比特的情況,但是如何畫出多量子比特電路呢?根據(jù)多量子比特的圓形表示法,在長度為N的比特串中,每個量子比特占據(jù)一個位置。因此,根據(jù)其二進制值來標(biāo)記每個量子比特就很方便了。以第2章中的隨機字節(jié)為例。仿照將8個傳統(tǒng)比特稱為1字節(jié)(byte)的叫法,我們將8個量子比特稱為1量子字節(jié)(qubyte)。此前,我們只是簡單地將8個量子比特標(biāo)記為量子比特1、量子比特2等。圖3-4展示了正確標(biāo)記每個量子比特的電路圖。圖3-4:標(biāo)記量子字節(jié)中的量子比特量子比特的命名圖3-4使用諸如0x1和0x2這樣的十六進制數(shù)來標(biāo)記量子比特值。這是用于十六進制數(shù)的標(biāo)準(zhǔn)表示法,我們將在整本書中使用它來表示特定的量子比特,甚至在量子比特數(shù)量很多的情況下也會這樣做。3.3多量子比特寄存器中的單量子比特運算既然能夠畫出多個量子比特的電路圖,并用圓形表示法來表示它們,那就開始使用它們吧!若對多量子比特寄存器應(yīng)用NOT、HAD、PHASE等單量子比特指令,會如何呢?與單量子比特運算的唯一區(qū)別是,多量子比特運算所用的算子對(operatorpair)專用于該運算所對應(yīng)的量子比特。要識別出一個量子比特的算子對,請將值的差等于該量子比特值的兩個圓相匹配,如圖3-5所示。舉例來說,如果對量子比特0x4進行運算,那么每個算子對將包含值的差正好為4的那些圓。圖3-5:在多量子比特疊加態(tài)示例中,NOT運算用于交換每個量子比特算子對中的值一旦識別出算子對,就會針對每一對進行運算,就好像算子對的成員是單量子比特寄存器的|0?值和|1?值一樣。以圖3-5為例,NOT運算會交換每一對中的圓。對于單量子比特的PHASE運算,每一對中位于右手方的圓將按相位角旋轉(zhuǎn),如圖3-6所示。圖3-6:多量子比特寄存器中的單量子比特PHASE運算從算子對的角度思考有助于快速、直觀地理解針對寄存器的單量子比特運算。為了更深入地理解其工作原理,需要考慮針對給定量子比特的運算對整個寄存器的二進制表示有何影響。舉例來說,圖3-5中的NOT運算對第2個量子比特進行的圓交換動作相當(dāng)于簡單地翻轉(zhuǎn)每個值的二進制表示的第2位。同理,作用于第3個量子比特的PHASE運算會旋轉(zhuǎn)第3位為1的所有圓。針對單量子比特的PHASE運算總會導(dǎo)致寄存器中正好一半的圓被旋轉(zhuǎn),而旋轉(zhuǎn)哪一半只取決于哪個量子比特是運算對象。上述思路有助于思考在更大的多量子比特寄存器上所做的任意其他單量子比特運算。本書中的一些圖用不同的顏色來突出顯示某些圓,如圖3-5和圖3-6所示。這樣做只是為了說明哪些狀態(tài)參與了運算。讀取多量子比特寄存器中的某個量子比特若對多量子比特寄存器中的一個量子比特應(yīng)用READ指令,會發(fā)生什么呢?READ指令也可以使用算子對。針對多量子比特寄存器,要計算其中某一個量子比特為0的概率,做法是計算該量子比特算子對的|0?側(cè)(左手邊)所有圓的強度的平方和。同理,可以通過計算該量子比特算子對的|1?側(cè)(右手邊)所有圓的強度的平方和來得出單個量子比特的讀取結(jié)果為1的概率。在進行READ運算之后,多量子比特寄存器的狀態(tài)將改變,以反映運算結(jié)果。所有與結(jié)果不一致的圓都將被消除,如圖3-7所示。圖3-7:在多量子比特寄存器中讀取一個量子比特11圖中的概率省略了小數(shù)位?!幷咦⒄堊⒁?,在|1?和|3?這兩種狀態(tài)下讀取第一個量子比特(0x1)時結(jié)果都為1,這是因為1和3對應(yīng)的二進制數(shù)的第一位都是1。還需要注意,在這個消除過程之后,該狀態(tài)將剩余的值重新規(guī)范化,這使得它們的面積(

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論