量子計算機編程(一)——QPU編程
量子計算機編程(二)——QPU基礎函數
量子計算機編程(三)——量子應用
第二部分主要是QPU的基礎功能,第一部分就像是我們有了哪些基本的語句,第二部分就是我們能寫一些簡單基礎的函數,一些小模塊,第三部分就是他的應用了。
先來看一下一個簡單量子應用的結構:
第一步,將量子態通過H門變成疊加態,很多應用的第一步都是H門,因為量子的疊加態正是她的優越性所在,所謂n個qubit可以表達 \(2^n\) 種狀態, \(2^n\) 種可能性同時並行,這是疊加態帶來的好處,要是一直使用基態,經典的不香嗎?還便宜,量子的還需要在靠近絕對零度的溫度下進行。
第二步,在疊加態中運算。
第三步,相位操作,疊加態中運算的結果當然也是疊加態的,但我們要獲取,只能獲取經典的信息,直接讀的話,那他就是隨機坍縮,信息丟失,當然你要是打算重復多次也行,但是有的時候,我們想要的並不是這個態的全部信息,我們可能需要的僅僅是他的一些特征,可能是一個序列的周期,我並不需要這個序列具體是什么,如此的話,可能一些相位變化操作就可以直接讀取你想要的信息,這樣更為方便。所以量子算法的設計,不僅僅要考慮量子怎么加速,還要考慮量子加速完了的結果能不能讀出來。
第四步,讀取。
量子算數邏輯
在量子之前,我們有經典算數和經典的數字邏輯,那么量子和經典有什么區別呢:
- 沒有copy ,量子的信息不能復制,如果我們要把一個信息傳給另一個,我們只能swap交換一下,或者我們還可以teleportation,總之,我們只能交換,不能賦值,具體一點來說,以前我們寫程序的里面的賦值“=”是沒有的。
- 可逆,除了測量,QPU上的所有操作都是可逆的。
說到邏輯,我們已經還記得數字邏輯里面學的全加器吧,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),非常熟悉的配方的了。
關於條件判斷呢,給大家看一個例子:
這是是如果a>3那么b就自增,如果沒有,那就不用了,3不是很好的判斷標准,但是0是啊,小於他的負數,直接首位編碼就是1,所以,可以先-3,判斷完了,增加好了,在把3加回來,辦法總比問題多。
以上是量子和經典較為相似的部分,但是除此之外,量子還有新的特性,比如說:相位,接下來的篇幅都是屬於他的。
振幅放大 Amplitude Amplification
我們先來說說振幅放大是什么:
你覺得 Figure 6-1中的ABC三個qubit一樣嗎?不一樣,直接看圖很顯然的不一樣,雖然大家都是等概率的疊加態,但是他們相對相位180°的地方不一樣。可是直接讀,能讀出來嗎?即使我重復很多遍,但是他們的概率是一樣的,no difference。但是,看圖 Figure 6-3,就是可讀的不一樣了,振幅放大(AA)就是把他們從圖6-1變成圖6-3的方法。
現在我們已經只要了what和why了,接下來就是怎么進行how。
我們先來看一個單獨的AA:
前面三步,也就是在4個H門之前是將這個疊加態中的某一個態給翻轉他的相位,使他於其他態不同,接下來的幾個步驟是把這個態的概率放大,至於問什么能放大,可以來看這篇 量子搜索算法 Grover search 這篇文章里主要是矩陣的角度,現在這個正好是一個具體的表現。
一次AA結束后,我們又回到了最初的相位,除了,我們翻轉相位的那個態的振幅變大了,如果我們想要他繼續變大,那么我們就繼續AA,每一個AA都要包括將相位翻轉的步驟。
你可能會疑惑,既然我們都知道要翻轉哪一個態了,那為什么要費這么大的力氣,這里,我們的翻轉非常簡單,就是找到這個態,然后翻轉,上圖就是兩個not操作,但是在實際操作中,這可能是是一系列計算的結果。
AA一次就放大一些,再AA就再放大,那么是不是越多,就越能無線逼近1呢?
https://oreilly-qc.github.io/?p=6-2這是上面這個的實驗,大家可以變換代碼里面的 number_of_iterations,來驗證一下剛剛的猜測,其實看圖也能發現,\(B_4\)的概率是小於\(B_3\)的,why,事實上,這個概率大小是一個類似三角函數的存在:
那么如何找到自己最合適的迭代次數呢?
書上給了一個未經過證明的公式Optimal number of iterations in amplitude amplification
這本書是一本是實踐為主的書籍,他還考慮了另一個問題,如果在這個里面我不僅僅要翻轉一個態,我要翻轉的是兩個、三個又會怎么樣呢?
https://oreilly-qc.github.io/?p=6-3 同樣給大家一個連接,大家可以改變n2f這個數組的大小,和每次的迭代次數,看一看結果會有什么變化,當然這么做有些麻煩,也可以看下面的圖,分別是4個qubit的情況下翻轉2、3、7、8個態的效果長什么樣,這里我就直接公布答案,隨着翻轉的態越來越大,這我們的這個三角函數的周期會越來越小。
那么現在的最佳迭代次數又是多少呢?m是翻轉的個數。
這里,我們再總結一下AA的意義,他把不可讀的相位信息變成了可讀的振幅信息。
量子傅里葉變換
提出一個技術,必定是為了解決一個問題,這里我們要解決的問題就是周期:
對於ABC這三個態,振幅放大也並不能很好的將他們區分,但是量子傅里葉變換(QFT)可以,他能夠把上面這三個態變成下面這樣:
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()
為什么這樣就可以找到她的周期了呢?量子傅里葉變換
不過,QFT不是每次都能像現在這樣獲得這么好的結果的,像經典的傅里葉變換會有mirror-image,如下:
量子傅里葉也可能會有這種結果,我們同樣也是取前面的一半:
選擇量子傅里葉的好處在於,他很快,比快速傅里葉都還要快,他們的速度比值是這樣的:
量子處理器的內部結構長這個樣子:
量子相位估計
這個關注的對象是量子操作的信息而不是量子寄存器的信息,每一個量子操作都可以用一個酉矩陣表示,而每一個量子態也可以用一個向量來表示,如果一個操作作用的量子態正好是他的特征向量會怎么樣?
每一個操作都有自己的eigenstate和對應的eigenphase
所以相位估計究竟是做什么的呢?
假設我有一個操作U,以及操作的特征態\(u_1,u_2,u_3,...\),量子相位估計可以測出這些特征態所對應的特征相位。
一個簡單例子,cont_u是我們輸入的操作,紅框里,是這個操作的特征態,輸出結果是8,這里有4個qubit,最大的輸出結果可以是16,那么他對應的量子相位是:(8/16)*360°=180°,qubit的增加可以增加數據的精度,如果我們有最大誤差要求,那么可以通過下面這個公式知道我們最小需要多少個量子比特:
調用這個函數非常簡單:qin是特征向量,cout_u是操作,qout就是我們的結果,她的位數取決於我們需要的精度。
// Operate phase estimation primitive on registers phase_est(qin, qout, cont_u);
// Read output register
qout.read();
那么這個里面的操作又是長什么樣子呢?
雖然看起來是上面在控制下面,但是仔細想一想 \(-|0\rangle|1\rangle\)你能分清楚這個負號是0還是1的嗎?,相位信息就這樣在qout里累加,最后一個逆傅里葉變換得到我們的結果。