- 量子計算機編程:從入門到實踐
- (美)埃里克·R.約翰斯頓 (英)尼古拉斯·哈里根 (西)梅塞德絲·希梅諾?塞戈維亞
- 10449字
- 2021-07-28 17:51:30
第 2 章 單個量子比特
傳統比特僅有 1 個二進制參數,可以將其初始化為狀態 0 或狀態 1。盡管二進制的邏輯運算已足夠簡單,但是我們仍然可以用空心圓和實心圓直觀地表示狀態值,如表 2-1 所示。
表2-1:用空心圓和實心圓表示傳統比特
在某種意義上,量子比特與傳統比特非常相似:每當讀取一個量子比特的值時,總會得到 0 或 1。因此,在讀出一個量子比特之后,總是可以像表 2-1 所示的那樣來描述它。但是在 讀取之前,量子比特的值并非黑白分明,需要用更復雜的方式來描述。在讀取之前,量子比特處于疊加態(superposition)。
我們很快就會了解疊加態的含義,但首先來了解一下它的強大作用。請注意,在被讀取之前,單個量子比特存在無窮多個疊加態,表 2-2 僅列出了其中的一些。盡管最終讀出的值總會是 0 或 1,但如果善用一些技巧,這些可用的額外狀態便能幫助我們執行一些非常強大的運算任務。
表2-2:量子比特的一些可能的值
在表 2-2 中,我們將 0 和 1 分別表示為 |0? 和 |1?。這種符號被稱為狄拉克符號(bra-ket notation),通常用于量子計算。一個簡單的經驗法則是,狄拉克符號中的數字表示在讀取時可能會得到的量子比特值。當談到一個量子比特已被讀出的值時,我們只使用數字來表示。
表 2-2 中的前兩行展示了與傳統比特的狀態等價的量子態,其中完全沒有出現量子疊加態。在狀態 |0? 下制備的量子比特等價于傳統比特 0(在讀取時總是給出值 0),在狀態 |1? 下同理。如果永遠只是非 |0? 即 |1?,那么這些僅僅等價于傳統比特的量子比特可夠昂貴的。
如何才能獲得如表 2-2 中后三行所示的那些更奇妙的量子疊加態呢?為了理解量子疊加態,不妨先花上一點點時間思考量子比特到底是什么 1。
1本書盡力避免過多地解釋量子比特的含義。盡管這似乎有點令人掃興,但請記住,傳統編程指南幾乎從不講比特和字節迷人的物理特性。實際上,正是能夠從信息的物理本質中抽離出來,才使得復雜程序的編寫過程變得容易。
2.1 物理量子比特概覽
一個有助于闡釋量子疊加態的例子是單光子。為了說明這一點,讓我們先回退一步,假設要使用光子的位置來表示傳統比特。在圖 2-1 所示的設備中,帶開關的鏡子(可以通過開關調整為反射鏡或透視鏡)讓我們能夠控制光子走兩條路徑中的一條。其中,兩條路徑分別對應 0 和 1。
圖 2-1:把光子用作傳統比特
在數字通信領域,確實存在圖 2-1 所示的設備。不過顯然,單光子處理起來非常困難(一個原因是,它不會在任何地方長時間停留)。為了使用這個設備演示量子比特的某些特性,我們把決定光子路徑的那面帶開關的鏡子替換為半鍍銀的鏡子。
如圖 2-2 所示,半鍍銀的鏡子(也叫作分束器)有一個半反射的表面,它有 50% 的概率將光偏轉到值 1 相應的路徑上,同時有 50% 的概率讓光直接沿著值 0 相應的路徑向前,只有這兩種可能情況。
圖 2-2:光量子比特的一種簡單實現
當一個不可分割的光子撞擊半鍍銀的鏡子表面時,它會遭遇某種身份危機,也即出現一種不合常理的效應:光子處于一種既受路徑 0 影響、又受路徑 1 影響的狀態。我們將這種狀態稱為疊加態,意思是光子可能處于每一條路徑上。換句話說,我們擁有的不再是一個傳統比特,而是一個量子比特,它處于由 0 態和 1 態疊加的狀態。
人們很容易誤解疊加態的本質,就像許多介紹量子計算的流行文章所描述的那樣。那種認為光子同時處在路徑 0 和路徑 1 上的說法并不正確。因為光子只有一個,所以如果像圖 2-2 所示的那樣在每條路徑上都放置探測器,那么只有一個探測器會探測到光子。當這種情況出現后,量子比特將降維到數字比特,并給出確定的結果:非 0 即 1。然而,正如我們稍后將探討的那樣,在需要通過探測讀取值之前,QPU 與處于疊加態的量子比特的交互將對計算大有幫助。
圖 2-2 所示的這種疊加態對利用 QPU 的量子計算能力至關重要。因此,我們需要以量化程度更高的方式描述和控制量子疊加態。當光子處于多路徑疊加的狀態時,它與每條路徑都有一個相應的振幅(amplitude)。這些振幅有兩個重要特性——強度和相對相位。它們就像兩個旋轉開關,我們可以利用這兩個開關來改變量子疊加態的特殊配置。
● 與每條路徑相關聯的強度(magnitude)是一個模擬值,用于衡量光子在每條路徑上的擴散程度。路徑的強度與在該路徑上檢測到光子的概率有關。具體來說,強度的平方決定了在給定路徑上檢測到光子的概率。在圖 2-2 中,可以通過改變半鍍銀鏡子的反射程度來調整與每條路徑相關聯的振幅強度。
● 不同路徑之間的相對相位(relative phase)表示光子在一條路徑上相對于另一條路徑的延遲程度。相對相位也是一個模擬值,可以通過設置光子沿著路徑 0 和路徑 1 傳播的距離之差來控制。需要注意的是,改變相對相位不會影響光子在每條路徑上被檢測到的概率 2。
2雖然本書基于光的相對傳播距離來引入相對相位的概念,但這是一個普適的概念,它適用于所有類型的量子比特:光子、電子、超導體等。
再次強調,振幅包含兩個特性,即與量子疊加態的某個值相關聯的強度和相對相位。
對數學感興趣的讀者不妨了解這樣一點:與疊加態中的不同路徑相關聯的振幅通常用復數來表示。振幅的強度正好是這個復數的模(復數與其共軛復數乘積的平方根),振幅的相對相位則是復數以極坐標表示時的輻角。如果你對數學不感興趣,也不必擔心,我們很快將介紹一種圖形記法。
在計算時,強度和相對相位是可以利用的值,不妨認為它們被編碼在量子比特中。但是如果要從中讀取任何信息,就必須使光子撞擊某種探測器。此時,這兩個模擬值都消失了——量子比特的量子特性消失了。這就是量子計算的關鍵所在:找到一種方法來利用這些虛幻的值,使得在進行讀取這一破壞性行為之后,一些有用的值仍然得以保留。
在將光子用作量子比特的情況下,圖 2-2 中的設置與稍后將在示例 2-1 中介紹的代碼示例等效。
好了,用光子做的介紹就到這里了!本書是程序員指南,不是物理學教科書。讓我們從物理學中抽身,拋開光子和量子物理,看看如何描述和可視化量子比特,就像拋開電子和半導體物理去研究二進制邏輯一樣。
2.2 圓形表示法
我們現在已經知道了何謂疊加態,但目前所知的內容僅與光子的特有行為密切相關。接下來需要找到一種描述疊加態的抽象方式,從而只關注抽象的信息。
在成熟的量子物理學中,數學描述提供了這樣一種抽象,但從表 2-2 左列可以看出,這種數學描述遠不如傳統比特簡單的二進制計算直觀和方便。
幸運的是,表 2-2 右列的圓形表示法是一種更直觀的方法。由于我們的目標是在無須深入了解晦澀的數學知識的前提下,直觀地理解 QPU 的內部原理,因此從現在開始,我們將完全基于圓形表示法來思考量子比特。
我們通過光子實驗發現,在 QPU 中,量子比特的一般狀態有兩個特性需要關注:疊加振幅的強度和振幅之間的相對相位。這些參數與圓形表示法的關系如下。
● 與量子比特可能取的每個值(目前為止是 |0? 和 |1?)相關聯的振幅的強度與每個 |0? 圓和 |1? 圓中的已填充區域的半徑相關。
● 這些值的振幅之間的相對相位由 |1? 圓相對于 |0? 圓的旋轉表示(在圓中畫一條顏色較深的線,以表示旋轉)。
因為整本書都將依賴圓形表示法,所以有必要更詳細地了解如何通過圓的大小和旋轉來表示上述概念。
2.2.1 圓的大小
如前所述,與 |0? 或 |1? 相關聯的強度的平方決定了在讀取時得到該值的概率。圓的填充半徑表示強度,這意味著如果讀取量子比特,那么每個圓中的已填充面積(或者更通俗地說,圓的大小)與得到該圓所對應的值(0 或 1)的概率成正比。圖 2-3 展示了不同量子比特狀態的圓形表示法以及在每種情況下讀出值 1 的概率。
圖 2-3:從圓形表示法表示的不同疊加態中讀出值 1 的概率
讀取量子比特會破壞信息。若對圖 2-3 中的所有狀態讀取量子比特,結果將非 0 即 1。在讀取之后,量子比特會改變其狀態,以匹配所讀取的值。因此,假設一個量子比特最初處于復雜的狀態,可一旦讀出了值 1,那么即便立即再次嘗試讀取,也只會得到值 1。
請注意,|0? 圓中的已填充區域越大,讀出值 0 的概率就越大,當然這意味著得到值 1 的概率越小。在圖 2-3 的最后一個例子中,讀出值 0 的概率是 90%,讀出值 1 的概率則是 10%。3 在圓形表示法中,我們用圓的已填充區域來表示疊加態中的強度。雖然這看起來像是一個讓人煩惱的技術細節,但務必記住,強度與已填充區域的半徑相關。為了在視覺上更直觀,即使將兩者等同起來也沒有關系。
3寄存器振幅的平方之和必須總是等于 1,這個要求被稱為規范化。要了解更多信息,請參閱 9.3.1 節。
有一點很容易被忽略,但請謹記,那就是在圓形表示法中,與給定結果相關聯的圓的大小并不能完全代表疊加態的振幅,其中缺少的重要信息是疊加態的相對相位。
2.2.2 圓的旋轉
利用一些 QPU 指令,可以改變 |0? 圓和 |1? 圓的相對旋轉情況,即量子比特的相對相位。量子比特狀態的相對相位可以取 0°和 360°之間的任意值,圖 2-4 展示了幾個例子。
圖 2-4:單個量子比特的相對相位示例
本書用圓形表示法旋轉圓的慣例是,逆時針旋轉,且角度值為正,如圖 2-4 所示。
在前面的所有例子中,我們都只旋轉了 |1? 圓。為什么不旋轉 |0? 圓呢?顧名思義,只有量子比特疊加態的相對相位才彰顯不同。因此,只有圓之間的相對旋轉才有意義。4 如果 QPU 指令對兩個圓都進行旋轉,那么總是可以考慮等效的效果,即只旋轉 |1? 圓,使相對旋轉效果看起來更明顯,如圖 2-5 所示。
4基于控制量子比特的量子力學定律,只有相對相位才是重要的。
圖 2-5:在圓形表示法中,只有相對旋轉才是重要的。圖中兩種狀態是等價的,這是因為兩個圓的相對相位相同
注意,相對相位可以獨立于疊加態的強度而變化,反之亦然。比較圖 2-3 中的第 3 個和第 4 個例子,可以看到,單個量子比特的不同結果之間的相對相位對讀出某個結果的概率沒有直接影響。
由于量子比特的相對相位對疊加態的強度沒有影響,因此它不會直接影響可觀測的讀取結果。這可能會使相對相位這個特性看起來無關緊要,但事實并非如此!在涉及多個量子比特的量子計算中,可以利用旋轉來巧妙、間接地影響最終讀出不同值的概率。實際上,精心設計的相對相位可以提供驚人的計算優勢。接下來將介紹一些量子運算,特別是那些只對單個量子比特起作用的運算。我們將使用圓形表示法將運算效果可視化。
與傳統比特明顯的數字特性不同,量子比特的強度和相對相位是具有連續自由度的特性。這導致許多人誤以為,量子計算類似于命運多舛的模擬計算(analog computing)。但需要指出的是,盡管量子計算具有連續自由度,但 QPU 計算導致的誤差仍然可以用數字方式糾正。這就是 QPU 比模擬計算設備更穩健的原因。
2.3 第一批QPU指令
與 CPU 的同類運算一樣,針對單個量子比特的 QPU 運算將輸入信息轉換為目標輸出。當然,QPU 運算的輸入和輸出是量子比特,而不是傳統比特。許多 QPU 指令 5 有相應的逆指令,了解它們是有用的。這樣的 QPU 運算被稱為可逆,這意味著在進行這些運算時不會丟失或舍棄任何信息。然而,一些 QPU 運算是不可逆的,因此它們會導致信息丟失。后文會解釋,了解運算是否可逆對我們如何應用它有重要的影響。
5在本書中,“QPU 指令”和“QPU 運算”是等義的,經常交替使用。
某些 QPU 指令看上去有些奇怪,而且用法不明,但在簡單了解之后,我們將很快開始使用它們。
2.3.1 QPU指令:NOT
NOT 與傳統的邏輯非指令類似。應用它之后,0 會變為 1,反之亦然。然而,與傳統的邏輯非指令不同的是,QPU 的 NOT 指令可以對處于疊加態的量子比特進行操作。
用圓形表示法可以簡單地表示 NOT 運算的結果,只需交換 |0? 圓和 |1? 圓即可,如圖 2-6 所示。
圖 2-6:用圓形表示法表示 NOT 運算
可逆性:就像傳統的數字邏輯運算一樣,NOT 運算的逆運算是它自己。兩次應用它會將一個量子比特恢復到初始值。
2.3.2 QPU指令:HAD
HAD 是 Hadamard 的縮寫形式,該運算本質上是為某個呈 |0? 態或 |1? 態的量子比特創建相等的疊加態。它就像一把鑰匙,為我們開啟量子疊加態那既奇妙又微妙的并行性之門!與 NOT 運算不同,HAD 沒有針對傳統比特的等價運算。
在用圓形表示法表示時,HAD 輸出的 |0? 圓和 |1? 圓的已填充面積相同,如圖 2-7 所示。
圖 2-7:針對基本狀態進行 HAD 運算
HAD 運算會在量子比特中產生均勻疊加效果,即產生每個結果出現的概率相同的疊加態。注意,HAD 運算對初始狀態為 |0? 和 |1? 的量子比特稍有不同:對 |1? 態應用 HAD,會在一個圓中產生非零旋轉(相對相位),而對 |0? 態應用 HAD 則不會如此。
你可能會好奇,如果針對已經處于疊加態的量子比特應用 HAD,結果會如何。找到答案的最佳方法就是做實驗!通過實驗,你很快就會注意到以下現象。
● 根據圖 2-7 所示的規則,HAD 分別作用于 |0? 態和 |1? 態。
● 生成的 |0? 值和 |1? 值被組合起來,并根據初始疊加態的振幅加權 6。
6關于 HAD 和其他常見運算背后的數學細節,請參考第 14 章。
可逆性:與 NOT 運算類似,HAD 運算的逆運算也是它自己。兩次應用它會將一個量子比特恢復到初始值。
2.3.3 QPU指令:READ和WRITE
READ 運算是前文介紹的讀取過程的形式化表示。它在 QPU 指令集中與眾不同,這是因為它是唯一可能返回隨機結果的指令。
WRITE 運算能夠在操作 QPU 寄存器之前將它初始化,這是一個具有確定性的過程。
將 READ 指令應用于單個量子比特將返回 0 或 1,每個結果出現的概率由量子比特狀態中相應振幅的強度的平方決定(忽略相對相位)。應用 READ 指令之后,如果得到的結果為 0,那么量子比特將維持 |0? 態,反之則維持 |1? 態。換句話說,任何疊加態都將被不可逆轉地破壞。
因為圓中的已填充面積體現了相應結果出現的概率,所以在用圓形表示法表示 READ 運算的結果時,與結果對應的圓將被完全填充,而其余的變為空心圓。圖 2-8 展示了針對不同的疊加態應用 READ 指令的場景。
圖 2-8:READ 運算的隨機結果
在圖 2-8 的第 2 個示例中,READ 運算刪除了全部有意義的相對相位信息。因此,我們重新調整狀態,使圓中的線垂直。
使用 READ 和 NOT,可以編寫簡單的 WRITE 指令,從而制備目標狀態為 |0? 或 |1? 的量子比特。首先針對量子比特應用 READ 指令,之后,如果所得的值與計劃寫入的值不同,則應用 NOT 指令。請注意,WRITE 運算不能制備處于任意疊加態(具有任意強度和相對相位)的量子比特,它制備的量子比特只能處于 |0? 態或 |1? 態 7。
7我們在后文中會看到,獲得任意的疊加態很難,但很有用,在量子機器學習應用中尤其如此。第 13 章將介紹一種方法。
可逆性:READ 和 WRITE 是不可逆的。它們會破壞疊加態,并導致信息丟失。疊加態一旦遭到破壞,量子比特的模擬值(強度和相對相位)就會永遠消失。
2.3.4 實踐:完全隨機的比特
在介紹更多的單量子比特運算之前,讓我們休息片刻,來看看如何利用 HAD、READ 和 WRITE 創建一個強大的程序。該程序能夠生成真正的隨機比特,這在任何傳統計算機上都不可能實現。
縱觀計算史,人們花費了大量的時間和精力來開發 偽隨機數生成器(pseudo-random number generator,PRNG),這些系統在密碼學和天氣預報等領域有著廣泛的應用。PRNG 是偽隨機的,這是因為如果知道計算機內存的內容和 PRNG 算法,原則上就可以預測下一個要生成的數字。
根據已知的物理定律,針對處于疊加態的量子比特,讀取結果本質上是完全不可預測的。因此,借助 QPU,我們就能創建世界上最好的隨機數生成器,只需要制備一個處于 |0? 態的量子比特,對其應用 HAD 指令,然后讀取它的值。可以使用量子電路(quantum circuit)來展示 QPU 指令組合,如圖 2-9 所示。
圖 2-9:用 QPU 生成完全隨機的比特
雖然簡單得難以置信,但是我們已經有了第一個 QPU 程序:量子隨機數生成器(quantum random number generator,QRNG)。可以使用示例 2-1 中的代碼片段來模擬這個過程。如果在 QCEngine 上反復運行這 4 行代碼,就會得到一個隨機的二進制數字串。當然,像 QCEngine 這種以 CPU 驅動的 QPU 模擬器只是用 PRNG 來模擬 QRNG,但是在真正的 QPU 中運行等價的代碼將生成完全隨機的二進制數字串。
示例代碼
請在 http://oreilly-qc.github.io?p=2-1 上運行本示例。
示例2-1 隨機比特
qc.reset(1); // 分配一個量子比特 qc.write(0); // 寫入值0 qc.had(); // 使量子比特處于0和1的疊加態 var result = qc.read(); // 讀取數字比特
可以在 http://oreilly-qc.github.io 上找到本書中的所有示例代碼,這些代碼既可以在 QPU 模擬器上運行,也可以在真正的 QPU 硬件上運行。運行這些示例代碼是學習 QPU 編程的重要一環。若想了解更多信息,請參閱第 1 章。
這可能是你的第一個量子程序,祝賀你!讓我們逐行分析,了解每一行的意義。
● qc.reset(1) 設置 QPU 模擬器,請求分配一個量子比特。我們為 QCEngine 編寫的所有程序都將用類似這樣的一行代碼去初始化一個或一組量子比特。
● qc.write(0) 將單個量子比特初始化為 |0? 態,這相當于將傳統比特設置為值 0。
● qc.had() 對量子比特應用 HAD 指令,使其處于 |0? 和 |1? 的疊加態,如圖 2-7 所示。
● var result = qc.read() 在計算結束時將量子比特的值作為隨機數字比特讀出,并將該值賦給變量 result。
本例所做的一切似乎不過是用一種非常昂貴的方式拋硬幣,但是這種想法低估了 HAD 的威力。如果深入探究 HAD 的原理,就會發現這既不是偽隨機數生成器,也不是基于硬件的隨機數生成器。與它們不同,量子物理定律保證了 HAD 運算的不可預測性。在已知的宇宙中,即便知道用來生成隨機數的指令,也沒有人能夠猜出從應用了 HAD 指令的量子比特中讀出的隨機數是 0 還是 1。
雖然我們在第 3 章中才會正式學習多量子比特的內容,但是現在可以很容易地并行運行 8 次單量子比特程序,從而生成隨機字節,如圖 2-10 所示。
圖 2-10:生成隨機字節
示例 2-2 展示了用于生成隨機字節的代碼,它與示例 2-1 相差不大。
示例代碼
請在 http://oreilly-qc.github.io?p=2-2 上運行本示例。
示例2-2 隨機字節
qc.reset(8); qc.write(0); qc.had(); var result = qc.read(); qc.print(result);
請注意,我們利用了這樣一個事實:除非明確地指定要操作的量子比特,否則 QCEngine 指令(如 WRITE 和 HAD)將默認應用于所有經過初始化的量子比特。
盡管示例 2-2 用了多個量子比特,但實際上沒有進行將多個量子比特作為輸入的運算。該程序只能被序列化為針對單個量子比特運行。
2.3.5 QPU指令:PHASE(θ)
PHASE(θ) 也沒有針對傳統比特的等價運算。它使得我們能夠直接操作量子比特的相對相位,將其改變某個特定的角度。因此,除了要操作的量子比特之外,PHASE(θ) 還需要一個額外的數值參數,即旋轉角度。例如,PHASE(45) 表示進行 45° 的旋轉運算。
在使用圓形表示法表示時,PHASE(θ) 的作用就是簡單地以指定的角度旋轉 |1? 圓。圖 2-11 展示了 PHASE(45) 的效果。
圖 2-11:PHASE(45) 的效果
請注意,PHASE(θ) 僅旋轉 |1? 圓,因此它對處于 |0? 態的量子比特沒有影響。
可逆性:PHASE(θ) 是可逆的,不過逆運算通常不是它自己。通過應用與原始角度相反的 PHASE(θ),可以反轉相對相位旋轉效果。在圓形表示法中,這相當于通過反向旋轉抵消旋轉效果。
使用 HAD 和 PHASE,可以創建一些常用的單量子比特狀態,如圖 2-12 所示。這些狀態分 別被命名為 |+?、|–?、|+Y? 和 |–Y?。如果你想使用 QPU 小試身手,請看看能否用 HAD 和 PHASE 產生這些狀態(每個疊加態在 |0? 態和 |1? 態中都具有相等的強度)。
圖 2-12:十分常用的 4 種單量子比特狀態
盡管產生上述狀態的一種方法是使用 HAD 和 PHASE,但也可以將它們理解為所謂的單量子比特旋轉運算的結果。
2.3.6 QPU指令:ROTX(θ)和ROTY(θ)
我們已經了解了 PHASE(θ) 指令的用途,即旋轉量子比特的相對相位,在圓形表示法中,該指令旋轉的是 |1? 圓。另外兩個與 PHASE(θ) 相關的常見指令是 ROTX(θ) 和 ROTY(θ),它們會以稍微不同的方式旋轉量子比特。
圖 2-13 用圓形表示法展示了 ROTX(45) 和 ROTY(45) 在 |0? 態和 |1? 態上的應用效果。
圖 2-13:在 |0? 態和 |1? 態上應用 ROTX 和 ROTY
圖 2-13 中的效果不太容易理解,至少不像 PHASE 那樣直觀。這兩個指令的名稱來源于單量子比特狀態的另一種常見的可視化表示,即布洛赫球(Bloch sphere)。在布洛赫球表示法中,單個量子比特是由三維球面上的某個點表示的。本書沒有使用布洛赫球表示法,而是使用了圓形表示法,這是由于布洛赫球表示法不能很好地表示多個量子比特。但是為了滿足你的好奇心,我們簡單介紹一下。如果用布洛赫球表示一個量子比特,那么 ROTX 和 ROTY 分別表示圍繞球體的 軸和
軸旋轉量子比特。由于本書在表示量子比特時使用兩個圓而不是球體,因此 ROTX 和 ROTY 在圓形表示法中就失去了意義。實際上,PHASE 對應于繞
軸旋轉,它在布洛赫球表示法中相當于 ROTZ。
2.4 復制:缺失的指令
有一個指令可用于傳統計算機,但不能在 QPU 中實現。盡管可以通過反復創建得到一個已知狀態的多個副本 8,但是在狀態不確定的情況下,無法通過量子計算來部分復制某個狀態。這種約束是由控制量子比特的基本物理定律所導致的。
8如果狀態是 |0? 或 |1?,就可以簡單地通過 WRITE 指令來實現。
缺失復制指令無疑會帶來不便,但正如我們將在后文中了解到的,QPU 的其他能力足以彌補這一不足。
2.5 組合QPU指令
我們已經了解的指令有 NOT、HAD、READ、WRITE 和 PHASE。值得一提的是,和傳統的邏輯運算指令一樣,可以結合這些指令來實現其中每一個指令,甚至創建出全新的指令。假設某種 QPU 提供 HAD 指令和 PHASE 指令,但缺失 NOT 指令。將 PHASE(180) 與兩個 HAD 相結合,就能產生與 NOT 完全相同的結果,如圖 2-14 所示。反之,PHASE(180) 也可以通過 HAD 和 NOT 來實現。
圖 2-14:構建等效運算
QPU指令:RNOT
通過組合 QPU 指令,還可以創建出在傳統邏輯世界中根本不存在的有趣指令,RNOT(ROOT-of-NOT)就是這樣一個例子。顧名思義,它是 NOT 指令的平方根,也就是說,應用該指令兩次,相當于應用一次 NOT 指令,如圖 2-15 所示。
圖 2-15:對于傳統比特而言,這是不可能實現的運算
構建 RNOT 指令的方法不止一種,圖 2-16 給出了一種簡單的實現。
圖 2-16:實現 RNOT
可以通過模擬器驗證一下,看看應用兩次 RNOT 是否確實產生了與 NOT 相同的結果,如示例 2-3 所示。
示例代碼
請在 http://oreilly-qc.github.io?p=2-3 上運行本示例。
示例2-3 驗證 RNOT 的效果
qc.reset(1); qc.write(0); // 應用RNOT qc.had(); qc.phase(90); qc.had(); // 應用RNOT qc.had(); qc.phase(90); qc.had();
可以用圓形表示法將實現 RNOT(兩個 HAD 之間有一個 PHASE(90))所涉及的每個步驟都可視化,如圖 2-17 所示。
圖 2-17:將 RNOT 的實現過程可視化
利用圓形表示法,可以根據量子比特的演變理解 RNOT 為何是 NOT 的平方根。回顧圖 2-14,我們對一個量子比特應用 HAD,然后將其相對相位旋轉 180°,再應用一次 HAD,這一系列操作等同于應用一次 NOT。由于 RNOT 對量子比特執行一半的旋轉(PHASE(90)),因此應用兩次 RNOT 會產生 HAD-PHASE(180)-HAD 序列,等同于 NOT。乍一看,這可能有些難以理解,但是如果試著應用兩次 RNOT,就會理解上述原理。(提示:HAD 是它本身的逆指令,也就是說,應用兩次 HAD 相當于什么都不做。)
可逆性:雖然 RNOT 不是其本身的逆指令,但是圖 2-16 中的運算可以通過使用負的相位值來逆轉,如圖 2-18 所示。
圖 2-18:RNOT 的逆運算
盡管有些晦澀,但 RNOT 教給我們重要的一招:通過精心地將信息保存在量子比特的相對相位中,可以實現全新的計算類型。
2.6 實踐:量子監聽檢測
為了更實際地展現控制量子比特相對相位的優勢,我們用一個更復雜的程序來結束本章。示例 2-4 使用前面介紹的簡單的單量子比特 QPU 指令來完成簡化的量子密鑰分發(quantum key distribution,QKD)。QKD 是量子密碼學領域的核心協議,通過它能安全地傳輸信息。
假設 QPU 程序員 Alice 和 Bob 正在通過能夠傳輸量子比特的信道相互發送數據。他們偶爾會發送示例 2-4 描述的具有特殊構造的“監聽檢測”量子比特,用于測試所用的信道是否被監聽。
任何試圖讀取“監聽檢測”量子比特的監聽者都有 12.5% 的概率被發現。因此,即使 Alice 和 Bob 在整個傳輸過程中只使用了 100 個這樣的量子比特,監聽不被發現的可能性也只有約百萬分之一。
Alice 和 Bob 可以通過交換一些不需要加密的傳統數字信息來檢測他們的密鑰是否被泄露。在交換信息后,他們測試一些量子比特,方法是讀取量子比特并檢查讀取結果是否符合預期。如果出現不一致,就說明有人在監聽。該過程如圖 2-19 所示。
圖 2-19:量子監聽檢測程序
以下給出代碼。建議嘗試運行示例 2-4 中的代碼,并像探索任何其他代碼片段一樣進行調整和測試。
示例代碼
請在 http://oreilly-qc.github.io?p=2-4 上運行本示例。
示例2-4 量子監聽檢測
qc.reset(3); qc.discard(); var a = qint.new(1, 'alice'); var fiber = qint.new(1, 'fiber'); var b = qint.new(1, 'bob'); function random_bit(q) { q.write(0); q.had(); return q.read(); } // 生成2個隨機比特 var send_had = random_bit(a); var send_val = random_bit(a); // 創建Alice的量子比特 a.write(0); if (send_val) // 根據隨機比特判斷是否設置該值 a.not(); if (send_had) // 根據隨機比特判斷是否應用HAD a.had(); // 發送量子比特 fiber.exchange(a); // 監聽 var spy_is_present = true; if (spy_is_present) { var spy_had = 0; if (spy_had) fiber.had(); var stolen_data = fiber.read(); fiber.write(stolen_data); if (spy_had) fiber.had(); } // 接收量子比特 var recv_had = random_bit(b); fiber.exchange(b); if (recv_had) b.had(); var recv_val = b.read(); // 現在Alice用郵件告訴Bob她選擇的操作和值 // 如果選擇的操作匹配,但值不一樣,就說明通信被監聽 if (send_had == recv_had) if (send_val != recv_val) qc.print('Caught a spy!\n');
在示例 2-4 中,Alice 和 Bob 各自可以訪問只包含一個量子比特的簡單 QPU,并且可以沿著量子信道發送量子比特。可能會有人監聽該信道。在示例代碼中,通過變量 spy_is_present 來控制是否存在監聽者。
量子密碼可以用這么小的 QPU 來實現,這就是早在更強大的通用 QPU 出現之前,小型 QPU 就已經開始商業化應用的原因之一。
讓我們逐步分析代碼,看看 Alice 和 Bob 如何利用手頭的簡單資源實現量子監聽檢測。以下結合代碼注釋來解釋。
// 生成 2 個隨機比特
Alice 將她的單量子比特 QPU 作為一個簡單的 QRNG,正如我們在示例 2-2 中所做的那樣,生成兩個只有她知道的秘密隨機比特。本例將它們定義為 send_had 和 send_val。
// 創建 Alice 的量子比特
Alice 用她的兩個隨機比特來創建“監聽檢測”量子比特。她為其賦值,然后根據 send_had 的值判斷是否應用 HAD。實際上,她的量子比特將處于以下狀態之一:|0?、|1?、|+?、|??,不過她暫時不會告訴任何人具體是哪個狀態。如果 Alice 決定應用 HAD,并且 Bob 想通過讀取知道 Alice 發送的是 0 還是 1,那么 Bob 在讀取之前,必須應用 HAD 的逆指令(其實就是 HAD)。
// 發送量子比特
Alice 把她的量子比特發送給 Bob。為清晰起見,本例使用另一個量子比特來表示信道。
// 監聽
如果 Alice 傳輸的是傳統的數字比特,那么監聽者只需復制即可完成任務。如果用了量子比特,復制就不可行了。回憶一下,量子比特沒有復制指令,監聽者唯一能做的就是讀取 Alice 發送的量子比特,然后小心地將同樣的量子比特發送給 Bob,以免被發現。不過請記住,讀取操作將不可避免地破壞量子比特的信息,因此監聽者在讀取后只能獲得傳統比特的信息。因為監聽者并不知道 Alice 是否應用了 HAD,所以他也不知道在讀取前是否應該應用 HAD。如果僅執行讀取操作,那么監聽者并不知道他接收到的是從一個處于疊加態的量子比特中讀取的隨機值,還是實際上由 Alice 編碼的值。這意味著,監聽者不僅無法可靠地提取 Alice 的量子比特,也無法知道應該將什么狀態發送給 Bob 才能避免被發現。
// 接收量子比特
與 Alice 一樣,Bob 隨機生成一個 recv_had 比特,并根據這個值判斷在對 Alice 的量子比特應用 READ 之前是否應用 HAD。這意味著 Bob 偶爾能正確解碼 Alice 的二進制值,其他時候則不能。
// 如果選擇的操作匹配,但值不一樣,就說明通信被監聽
既然量子比特已經被接收,Alice 和 Bob 就可以公開地比較他們是否一致選擇了應用 HAD(或選擇不應用 HAD)。如果他們碰巧都應用了 HAD(概率約為 50%),那么二者的值應該一致;也就是說,Bob 能正確解碼 Alice 的消息。在正確解碼的消息中,如果值不一致,就可以得出結論:有人監聽了他們的消息,并將不正確的量子比特發送給了 Bob。
2.7 小結
本章介紹了一種描述單個量子比特的方法,以及用于操作單個量子比特的各種 QPU 指令。READ 指令的隨機性被用來構建量子隨機數生成器。通過控制量子比特的相對相位,可以實現基本的量子密碼。
后文將大量使用圓形表示法來可視化量子比特的狀態。第 3 章將擴展圓形表示法,以表示多量子比特系統,并介紹用于處理這種系統的 QPU 指令。
- Go Web編程
- Learning Cython Programming
- Drupal 8 Blueprints
- 編寫高質量代碼:改善Python程序的91個建議
- Windows Server 2016 Automation with PowerShell Cookbook(Second Edition)
- 劍指MySQL:架構、調優與運維
- 程序設計基礎教程:C語言
- The DevOps 2.5 Toolkit
- 開源項目成功之道
- Lift Application Development Cookbook
- Web Developer's Reference Guide
- Using Yocto Project with BeagleBone Black
- Game Programming using Qt 5 Beginner's Guide
- Java EE互聯網輕量級框架整合開發:SSM+Redis+Spring微服務(上下冊)
- Responsive Web Design with HTML5 and CSS3(Second Edition)