今天要給你們介紹的是這本書《Programming Quantum Computers —— Essential Algorithms and Code Samples》,主要講如何在量子計算機上編程,又示例的代碼能夠跑 https://oreilly-qc.github.io./ ,這本書的理解方向是純粹計算機的,連矩陣都不多涉及,一個量子計算機就像是協處理器同樣,很像咱們如今的GPU。html
這本書一共分爲三個部分,我也將分紅三篇文章來寫,這是第一部分QPU的編程。git
這本書中對於量子的表達方式以下circle notation:github
藍色圈的面積就是這個量子態測量後是這個狀態的機率,中間的藍色短線表明他們的相位,由於全局相位也觀察不出來,因此通常\(|0\rangle\)就是朝上的。對於一個量子比特來講,重要的也就這兩個,magnitude和relative phase(可能由於重要的是機率大小,因此他其實沒有提amplitude實際上是一個複數)。編程
這兩個態其實是等價的。app
電路圖呢,通常長這樣dom
這個電路圖對應的代碼以下:(這個例子均可以在上面那個網站上跑起來)網站
qc.reset(1); // allocate one qubit qc.write(0); // write the value zero qc.had(); // place it into superposition of 0 and 1 var result = qc.read(); // read the result as a digital bit
第一步就是申請一個qubit,就像你要給變量分配空間同樣。spa
第二步寫0,其實寫0很容易,你能夠直接測量,要麼0,要麼1,若是結果是1的話,再作一個not操做就好;固然,你要是嫌麻煩,對於一個qubit,長時間的靜置他,他也會變成0,畢竟仍是基態比較穩定。code
第三步就是進行一個H門的操做htm
第四步讀,其實就是測量了
其中值得一提的是PHASE相位操做,phase操做只做用在 \(|1\rangle\) 上,由於他的效果是改變相對相位,若是你們都改變就沒有什麼用了。可能有同窗據說過繞X軸旋轉和繞Y軸旋轉,這些都是針對Bloch球的表達方式,與這裏的circle notation的方式不要弄混了。
一個操做也多是其餘幾個操做的組合,好比:
若是咱們能夠把not變成H+180°旋轉+H,那麼咱們也能夠把中間的180°旋轉變成兩個90°的旋轉,中間再加上兩個H,由於\(HH=I\),他們能夠相互抵消,這樣咱們還能夠獲得RNOT:
COPY:這是一個須要注意的操做,由於量子程序裏沒有複製,這也保障了量子傳輸的信息不會被竊聽, 由於你要竊聽,你就須要去讀,一讀就是測量,而量子比特一測量就是坍縮。因爲量子不能複製,因此,上述全部操做都是在原有的那個比特上操做的,因此操做就會被發現。
一個簡單例子:
對於這裏例子來講, \(A_1\) 和 \(A_2\) 是對qubit Hadmard門操做後測量獲得的隨機值,由於這個是真隨機,因此就不會被竊聽者提早知道或者預估,那麼當我傳輸這個被我用紅色圈出來的比特的時候,spy並不知道這個比特是否執行了H門和not操做,那他就只能猜了,25%的機率,圖裏面所示就是他猜有執行了,而後他再按照他的猜想如法炮製一個qubit繼續傳遞,當B收了這個bit後,B也隨機一個數據\(B_2\),看是否執行H門,而後測量。這個時候消息也都收到了,測量也都測量好了,那麼把 \(A_2\)的信息發過來也和竊聽沒有關係了,若是 \(B_2\) \(A_2\) 的結果同樣,那麼測量結果應該同樣,若是不同,那麼必定被竊聽了。
這樣的成功機率有多少呢? \(B_2\) \(A_2\) 同樣的機率0.5,在這種狀況下spy被發現的機率0.25。看起來不是很高,可是若是咱們有一百個比特先檢測一下這條線路,不被發現的機率將會降到百萬分之一。
如今來看一下代碼:https://oreilly-qc.github.io/?p=2-4
qc.reset(3);//申請三個qubit qc.discard(); var a = qint.new(1, 'alice'); //給其中一個變量命名爲a,可是畫出來的電路圖中顯示alice var fiber = qint.new(1, 'fiber'); var b = qint.new(1, 'bob'); function random_bit(q) {//對一個初始化爲0的比特,進行H操做,而後測量,測量結果是隨機的 q.write(0); q.had(); return q.read(); } // Generate two random bits qc.label('get two random bits'); var send_had = random_bit(a);//獲得是否執行H門的隨機值 var send_value = random_bit(a);//獲得是否not的隨機值 qc.label(''); // Prepare Alice's qubit a.write(0);//a從新賦值爲0,因此前面取隨機值的操做也能夠在a上進行 qc.label('set value'); qc.nop(); if (send_value) a.not(); qc.nop(); qc.label(''); qc.nop(); qc.label('apply had'); qc.nop(); if (send_had) a.had(); qc.nop(); qc.label(''); // Send the qubit! fiber.exchange(a); // Activate the spy var spy_is_present = true; if (spy_is_present) { var spy_had = 1; qc.nop(); qc.label('spy'); if (spy_had) fiber.had(); stolen_data = fiber.read(); fiber.write(0); if (stolen_data) fiber.not(); if (spy_had) fiber.had(); qc.label(''); qc.nop(); } // Receive the qubit! var recv_had = random_bit(b); fiber.exchange(b); qc.label('apply had'); qc.nop(); if (recv_had) b.had(); qc.nop(); qc.label(''); qc.nop(); qc.label('read value'); qc.nop(); recv_val = b.read(); qc.nop(); qc.label(''); qc.nop(); // Now Alice emails Bob to tell // him her had setting and value. // If the had setting matches and the // value does not, there's a spy! if (send_had == recv_had) if (send_value != recv_val) qc.print('Caught a spy!\n');
多量子比特的表示方法和單量子比特沒有什麼區別,下面的數字就是把他們從01的二進制換算成了咱們熟悉的十進制。0x是十六進制的表示方法,最上面的是地位,正好能夠not操做表示了出來,0就是000,1就是001,2就是010……以此類推
真要說和單量子比特的區別,那主要是兩方面,一個是糾纏;另外一個就是受控操做。
糾纏好說,兩個糾纏的量子比特就是其中一個的測量結果會影響另外一個。
具體呢,能夠看一下個人這篇文章量子糾纏1——量子比特、Bell態、EPR佯謬
受控操做就是說有兩類比特,一個是用來控制的,另外一個是被控制的。
好比你們耳熟能詳的CNOT,當控制比特是1的時候,就翻轉被控制的比特,若是控制比特是0的時候,那就不作操做。還有CCNOT門,又叫作toffli門,有兩個控制比特,只有當他們都爲1的時候才翻轉。
如今要介紹一個前面沒有提過的CPHASE受控相位門,和CNOT類似,一樣是當控制比特爲1的時候才進行,可是正如前面咱們提過,PHASE操做只操做在1上,也就是說,若是這個操做被執行其實只有一種狀況,那就是\(|11\rangle\) 。
在前面咱們表示過一個旋轉180°的相位操做能夠表示成一個 H+NOT+H figure 2-14
那麼如今受控相位操做擁有了三種表示方法:
當控制比特爲0的時候,CNOT就不會發生,兩個H又正好抵消了。
在這之因此說這麼多的受控相位操做是由於這裏面有個一頗有趣的小技巧 QPU Trick: Phase Kickback 來看下面這個電路圖
這個電路圖很容易理解,一種理解方式就是把register 1看成控制比特,register 2 看成受控比特,兩個H門使得register 1變成了等可能的四種狀況 \(\frac{1}{2}|00\rangle+\frac{1}{2}|01\rangle+\frac{1}{2}|10\rangle+\frac{1}{2}|11\rangle\) 。
如今來看看結果:
由於register 2並非疊加態,因此沒有相對相位,而絕對相位又測不出來,因此他能夠說是沒有變的,改變了的,反而是register 1 , \(|3\rangle\) 轉了135°是由於兩個都爲1,45°和90°都轉了。做爲一個受控操做,控制比特反而變了,而受控比特沒有改變。
受控操做固然也能連在一塊兒,獲得一些有用的結果,好比三個CNOT操做,他就能夠交換兩條線路。
這個的證實是一件很容易的事情,你能夠取一個任意態推一邊,專門把這個提出來講一遍是由於這個還能作一件有趣的事情,那就是驗證兩個比特是否相等。咱們須要用到的是CSWAP,即當控制比特爲1時才交換。
當咱們的output比特通過H門後,他就變成了等機率的 \(|0\rangle\) 和 \(|1\rangle\) 通過一個CSWAP,爲1狀況下的input1和input2就會交換,也就是說他們原來x機率的ab就變成了x機率的ba了,這樣的問題出在哪?
若是機率仍是原來的分佈,那麼在通過一個H門output等待率的 \(|0\rangle\) 和 \(|1\rangle\) 又會化簡成 \(|0\rangle\) ,各類各樣的 \(|1\rangle\) 的機率會相互抵消掉,那麼在經歷一個NOT操做就必定會獲得1。
那,若是這兩個數據不同,就必定得不到1嗎?不必定,只是他有機率不是1,而一旦有機率不是1,那隻要多檢測幾回就必定能檢測出來,就像上面那個竊聽同樣,明明只有四分之一的機率,但僅須要一百次,測不出來的可能性就降到了百萬分之一。
固然,代碼在這裏https://oreilly-qc.github.io/?p=3-4,這也是這本書的特點了。
受控操做固然不止這些,可是不少受控操做均可以分解成CNOT加上一些相位操做,咱們能夠本身構造本身須要的操做。
這裏的遠距離操控不是指我能扣肯定他是什麼,若是我能肯定,那就不是隨機了,而是說,我把兩個比特弄成糾纏,當我一個測出來是0的時候,另外一個以x%的機率獲得0,至於我測出來是否是0看天意,對面測出來是否是0,也看天意,其中惟一能肯定的,就只有這個x了。
這個例子是書上例子3-6 https://oreilly-qc.github.io/?p=3-6 方法很簡單,就是我H門操做後,我旋轉45°的角度,這樣再來一個H門,由於相位變了,符號對不上,因此回不去了,就有了關聯。
更強大的一點的應用是——量子隱形傳態,量子隱形傳態 Quantum Teleportation 提過了,就不在累述。