1. 程式人生 > >量子計算機程式設計(二)——QPU基礎函式

量子計算機程式設計(二)——QPU基礎函式

第二部分主要是QPU的基礎功能,第一部分就像是我們有了哪些基本的語句,第二部分就是我們能寫一些簡單基礎的函式,一些小模組,第三部分就是他的應用了。 先來看一下一個簡單量子應用的結構: ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312163132119-1123801841.png) 第一步,將量子態通過H門變成疊加態,很多應用的第一步都是H門,因為量子的疊加態正是她的優越性所在,所謂n個qubit可以表達 $2^n$ 種狀態, $2^n$ 種可能性同時並行,這是疊加態帶來的好處,要是一直使用基態,經典的不香嗎?還便宜,量子的還需要在靠近絕對零度的溫度下進行。 第二步,在疊加態中運算。 第三步,相位操作,疊加態中運算的結果當然也是疊加態的,但我們要獲取,只能獲取經典的資訊,直接讀的話,那他就是隨機坍縮,資訊丟失,當然你要是打算重複多次也行,但是有的時候,我們想要的並不是這個態的全部資訊,我們可能需要的僅僅是他的一些特徵,可能是一個序列的週期,我並不需要這個序列具體是什麼,如此的話,可能一些相位變化操作就可以直接讀取你想要的資訊,這樣更為方便。所以量子演算法的設計,不僅僅要考慮量子怎麼加速,還要考慮量子加速完了的結果能不能讀出來。 第四步,讀取。 ### 量子算數邏輯 在量子之前,我們有經典算數和經典的數字邏輯,那麼量子和經典有什麼區別呢: - **沒有copy** ,量子的資訊不能複製,如果我們要把一個資訊傳給另一個,我們只能swap交換一下,或者我們還可以teleportation,總之,我們只能交換,不能賦值,具體一點來說,以前我們寫程式的裡面的賦值“=”是沒有的。 - **可逆**,除了測量,QPU上的所有操作都是可逆的。 ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312163241146-1956416292.png) 說到邏輯,我們已經還記得數字邏輯裡面學的全加器吧,c=a+b之類的操作,這個簡單的加法後面是一堆的與或非門的結構,量子的也同樣如此,結構也都差不多,不同之處就兩點: $|a\rangle|b\rangle$ 的進去 $|a+b\rangle|b\rangle$ 的出來,因為量子要求可逆,他不會把a、b變成c,一旦合成了c,那就分不出a、b了,當然,你也可以 $|a\rangle|b\rangle|0\rangle$ 的進去 $|a\rangle|b\rangle|a+b\rangle$,這樣也是可以的;第二點就是疊加,這裡的a、b不再是某個具體的數,而是一個疊加態。 如果是負數,那怎麼表達呢? 和經典一樣,我們可以負數的話,首位變成1。就像 000-0 001-1 002-2 003-3 100-(-4) 101-(-3) 110-(-2) 111-(-1),非常熟悉的配方的了。 關於條件判斷呢,給大家看一個例子: ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312163310639-1788277451.png) 這是是如果a>3那麼b就自增,如果沒有,那就不用了,3不是很好的判斷標準,但是0是啊,小於他的負數,直接首位編碼就是1,所以,可以先-3,判斷完了,增加好了,在把3加回來,辦法總比問題多。 以上是量子和經典較為相似的部分,但是除此之外,量子還有新的特性,比如說:相位,接下來的篇幅都是屬於他的。 ### 振幅放大 Amplitude Amplification 我們先來說說振幅放大是什麼: ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312163354083-439312431.png) ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312163437455-1075271822.png) 你覺得 Figure 6-1中的ABC三個qubit一樣嗎?不一樣,直接看圖很顯然的不一樣,雖然大家都是等概率的疊加態,但是他們相對相位180°的地方不一樣。可是直接讀,能讀出來嗎?即使我重複很多遍,但是他們的概率是一樣的,no difference。但是,看圖 Figure 6-3,就是可讀的不一樣了,振幅放大(AA)就是把他們從圖6-1變成圖6-3的方法。 現在我們已經只要了what和why了,接下來就是怎麼進行how。 我們先來看一個單獨的AA: ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312163519323-1081533030.png) 前面三步,也就是在4個H門之前是將這個疊加態中的某一個態給翻轉他的相位,使他於其他態不同,接下來的幾個步驟是把這個態的概率放大,至於問什麼能放大,可以來看這篇 [量子搜尋演算法 Grover search](https://www.cnblogs.com/zmzzzz/p/11369637.html) 這篇文章裡主要是矩陣的角度,現在這個正好是一個具體的表現。 一次AA結束後,我們又回到了最初的相位,除了,我們翻轉相位的那個態的振幅變大了,如果我們想要他繼續變大,那麼我們就繼續AA,每一個AA都要包括將相位翻轉的步驟。 你可能會疑惑,既然我們都知道要翻轉哪一個態了,那為什麼要費這麼大的力氣,這裡,我們的翻轉非常簡單,就是找到這個態,然後翻轉,上圖就是兩個not操作,但是在實際操作中,這可能是是一系列計算的結果。 AA一次就放大一些,再AA就再放大,那麼是不是越多,就越能無線逼近1呢? ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312163552271-1517663385.png) https://oreilly-qc.github.io/?p=6-2這是上面這個的實驗,大家可以變換程式碼裡面的 number_of_iterations,來驗證一下剛剛的猜測,其實看圖也能發現,$B_4$的概率是小於$B_3$的,why,事實上,這個概率大小是一個類似三角函式的存在: ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312163656975-806397471.png) 那麼如何找到自己最合適的迭代次數呢? 書上給了一個未經過證明的公式Optimal number of iterations in amplitude amplification $$ N_{A A}=\left\lfloor\frac{\pi \sqrt{2^{n}}}{4}\right\rfloor $$ 這本書是一本是實踐為主的書籍,他還考慮了另一個問題,如果在這個裡面我不僅僅要翻轉一個態,我要翻轉的是兩個、三個又會怎麼樣呢? https://oreilly-qc.github.io/?p=6-3 同樣給大家一個連線,大家可以改變**n2f**這個陣列的大小,和每次的迭代次數,看一看結果會有什麼變化,當然這麼做有些麻煩,也可以看下面的圖,分別是4個qubit的情況下翻轉2、3、7、8個態的效果長什麼樣,這裡我就直接公佈答案,隨著翻轉的態越來越大,這我們的這個三角函式的週期會越來越小。 ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312163747622-1603918612.png) ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312163804446-1109661996.png) ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312163829447-963102160.png) ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312163842036-1448585310.png) 那麼現在的最佳迭代次數又是多少呢?m是翻轉的個數。 $$ N_{A A}=\left\lfloor\frac{\pi}{4} \sqrt{\frac{2^{n}}{m}}\right\rfloor $$ 這裡,我們再總結一下AA的意義,他把**不可讀的相位資訊**變成了**可讀的振幅資訊**。 ### 量子傅立葉變換 提出一個技術,必定是為了解決一個問題,這裡我們要解決的問題就是週期: ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312163908278-980900645.png) 對於ABC這三個態,振幅放大也並不能很好的將他們區分,但是量子傅立葉變換(QFT)可以,他能夠把上面這三個態變成下面這樣: ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312163942196-1791071308.png) A裡面的有八個這樣的週期,B裡面有四個這樣的週期,而C裡面只有2個這樣的週期,通過他們週期個數的不一樣就可以輕而易舉的把這三個態分辨出來。 量子傅立葉變換是一個封裝好了的函式,直接呼叫.QFT就可以了。 ``` var num_qubits = 4; qc.reset(num_qubits); var signal = qint.new(num_qubits, 'signal') // prepare the signal製備量子態C qc.label('prep'); signal.write(0); signal.hadamard(); signal.phase(45, 1); signal.phase(90, 2); signal.phase(180, 4); // Run the QFT直接呼叫 qc.label('QFT'); signal.QFT() ``` ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312164044593-1722761051.png) 為什麼這樣就可以找到她的週期了呢?[量子傅立葉變換](https://www.cnblogs.com/zmzzzz/p/11266656.html) 不過,QFT不是每次都能像現在這樣獲得這麼好的結果的,像經典的傅立葉變換會有mirror-image,如下: ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312164107689-278025539.png) 量子傅立葉也可能會有這種結果,我們同樣也是取前面的一半: ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312164131478-2097585197.png) 選擇量子傅立葉的好處在於,他很快,比快速傅立葉都還要快,他們的速度比值是這樣的: ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312164154303-844455383.png) 量子處理器的內部結構長這個樣子: ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312164220586-576908184.png) ### 量子相位估計 這個關注的物件是量子操作的資訊而不是量子暫存器的資訊,每一個量子操作都可以用一個酉矩陣表示,而每一個量子態也可以用一個向量來表示,如果一個操作作用的量子態正好是他的特徵向量會怎麼樣? ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312164302305-1261322701.png) 每一個操作都有自己的eigenstate和對應的eigenphase ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312164324678-630977401.png) 所以相位估計究竟是做什麼的呢? 假設我有一個操作U,以及操作的特徵態$u_1,u_2,u_3,...$,量子相位估計可以測出這些特徵態所對應的特徵相位。 ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312164346831-1761607513.png) 一個簡單例子,cont_u是我們輸入的操作,紅框裡,是這個操作的特徵態,輸出結果是8,這裡有4個qubit,最大的輸出結果可以是16,那麼他對應的量子相位是:(8/16)*360°=180°,qubit的增加可以增加資料的精度,如果我們有最大誤差要求,那麼可以通過下面這個公式知道我們最小需要多少個量子位元: $$m=p+\lceil \log \left(2+\frac{1}{\epsilon}\right)\rceil$$ 呼叫這個函式非常簡單:qin是特徵向量,cout_u是操作,qout就是我們的結果,她的位數取決於我們需要的精度。 ``` // Operate phase estimation primitive on registers phase_est(qin, qout, cont_u); // Read output register qout.read(); ``` 那麼這個裡面的操作又是長什麼樣子呢? ![](https://img2020.cnblogs.com/blog/1654058/202003/1654058-20200312164406866-581109824.png) 雖然看起來是上面在控制下面,但是仔細想一想 $-|0\rangle|1\rangle$你能分清楚這個負號是0還是1的嗎?,相位資訊就這樣在qout裡累加,最後一個逆傅立葉變換得到我們的