App下載

python怎么使用ProjectQ生成量子算法指令集

猿友 2021-08-05 15:26:37 瀏覽數(shù) (2047)
反饋

projectQ是一個(gè)開源的量子計(jì)算框架,通過projectQ我們可以生成量子算法指令集,進(jìn)而開發(fā)出量子算法。projectQ是基于python編譯運(yùn)行的,今天我們就來介紹一下python怎么使用ProjectQ生成量子算法指令集。

輸出算法操作

首先介紹一個(gè)最基本的使用方法,就是使用ProjectQ來打印量子算法中所輸入的量子門操作,這里使用到了ProjectQ中的DummyEngine后端用于保存操作的指令。比如最簡(jiǎn)單的一個(gè)Bell State的制備,可以通過如下代碼實(shí)現(xiàn),并且打印出所保存的基本操作:

from projectq import MainEngine
from projectq.cengines import DummyEngine
from projectq.ops import H, CX, All, Measure

backend = DummyEngine(save_commands=True)
eng = MainEngine(backend=backend)

qureg = eng.allocate_qureg(2)
H | qureg[0]
CX | (qureg[0], qureg[1])

All(Measure) | qureg
eng.flush(deallocate_qubits=True)

for cmd in backend.received_commands:
    print (cmd)

運(yùn)行結(jié)果如下:

Allocate | Qureg[0]
H | Qureg[0]
Allocate | Qureg[1]
CX | ( Qureg[0], Qureg[1] )
Measure | Qureg[0]
Measure | Qureg[1]
Deallocate | Qureg[0]
Deallocate | Qureg[1]

這里有一點(diǎn)需要注意的是,如果是單次運(yùn)算,我們到Measure就可以結(jié)束了。但是如果同一個(gè)線程的任務(wù)還沒有結(jié)束的話,需要在Measure之后加上一個(gè)deallocate_qubits=True的配置項(xiàng),用于解除當(dāng)前分配的量子比特所占用的內(nèi)存。

封裝的操作

在量子算法的實(shí)現(xiàn)中,我們可以用一些函數(shù)或者類來封裝一部分的量子算法操作指令,但是這可能會(huì)導(dǎo)致一個(gè)問題,那就是在ProjectQ上打印出來的操作指令沒有把封裝的模塊的內(nèi)容輸出出來,比如如下的案例:

from projectq import MainEngine
from projectq.cengines import DummyEngine
from projectq.ops import H, CX, All, Measure, TimeEvolution, QubitOperator

backend = DummyEngine(save_commands=True)
eng = MainEngine(backend=backend)

qureg = eng.allocate_qureg(3)
H | qureg[0]
CX | (qureg[0], qureg[1])
TimeEvolution(1, QubitOperator('X2 X1')) | qureg

All(Measure) | qureg
eng.flush()

for cmd in backend.received_commands:
    print (cmd)

執(zhí)行結(jié)果如下:

Allocate | Qureg[0]
H | Qureg[0]
Allocate | Qureg[1]
CX | ( Qureg[0], Qureg[1] )
Measure | Qureg[0]
Allocate | Qureg[2]
exp(-1j * (1.0 X0 X1)) | Qureg[1-2]
Measure | Qureg[1]
Measure | Qureg[2]

我們發(fā)現(xiàn)這里的含時(shí)演化的操作算符沒有被分解,而是直接打印輸出了出來。但是如果在硬件系統(tǒng)中,只能夠識(shí)別支持的指令操作,這里的含時(shí)演化操作可能并未在量子硬件體系中被實(shí)現(xiàn),因此我們就需要在將指令發(fā)送給量子硬件之前,就對(duì)其進(jìn)行分解。

含時(shí)演化算符的分解

這里我們直接調(diào)用ProjectQ的配置中的restrictedgateset方法進(jìn)行操作分解,我們將單比特門操作的范圍放寬到所有的操作,但是雙比特操作只允許CX操作,并將這個(gè)配置作為engin_list配置到ProjectQ的MainEngine中:

from projectq import MainEngine
from projectq.cengines import DummyEngine
from projectq.ops import H, CX, All, Measure, TimeEvolution, QubitOperator
from projectq.setups import restrictedgateset

engine_list = restrictedgateset.get_engine_list(one_qubit_gates="any",two_qubit_gates=(CX,))
backend = DummyEngine(save_commands=True)
eng = MainEngine(backend=backend,engine_list=engine_list)

qureg = eng.allocate_qureg(3)
H | qureg[0]
CX | (qureg[0], qureg[1])
TimeEvolution(1, QubitOperator('X2 X1')) | qureg

All(Measure) | qureg
eng.flush(deallocate_qubits=True)

for cmd in backend.received_commands:
    print (cmd)

打印輸出的結(jié)果如下:

Allocate | Qureg[0]
H | Qureg[0]
Allocate | Qureg[1]
CX | ( Qureg[0], Qureg[1] )
Measure | Qureg[0]
Allocate | Qureg[2]
H | Qureg[2]
H | Qureg[1]
CX | ( Qureg[1], Qureg[2] )
Rz(2.0) | Qureg[2]
CX | ( Qureg[1], Qureg[2] )
H | Qureg[1]
Measure | Qureg[1]
H | Qureg[2]
Measure | Qureg[2]
Deallocate | Qureg[0]
Deallocate | Qureg[1]
Deallocate | Qureg[2]

可以看到含時(shí)演化算符已經(jīng)被分解并輸出了出來。由于已知單比特量子門加上一個(gè)CX是一個(gè)完備的量子門集合,因此一般我們可以直接使用這個(gè)集合來進(jìn)行量子門操作指令集的限制。

QFT的分解

QFT是ProjectQ中所自帶支持的量子傅里葉變換的量子門操作封裝,跟上一個(gè)章節(jié)中所介紹的含時(shí)演化算符類似的,我們可以用restrictedgateset來具體分解QFT算符:

from projectq import MainEngine
from projectq.cengines import DummyEngine
from projectq.ops import H, CX, All, Measure, TimeEvolution, QubitOperator, QFT
from projectq.setups import restrictedgateset

engine_list = restrictedgateset.get_engine_list(one_qubit_gates="any",two_qubit_gates=(CX,))
backend = DummyEngine(save_commands=True)
eng = MainEngine(backend=backend,engine_list=engine_list)

qureg = eng.allocate_qureg(3)
H | qureg[0]
CX | (qureg[0], qureg[1])
QFT | qureg

All(Measure) | qureg
eng.flush(deallocate_qubits=True)

for cmd in backend.received_commands:
    print (cmd)

輸出的結(jié)果如下:

Allocate | Qureg[2]
Allocate | Qureg[1]
H | Qureg[2]
Rz(0.785398163398) | Qureg[2]
Allocate | Qureg[0]
H | Qureg[0]
CX | ( Qureg[0], Qureg[1] )
R(0.785398163398) | Qureg[1]
CX | ( Qureg[1], Qureg[2] )
Rz(11.780972450962) | Qureg[2]
CX | ( Qureg[1], Qureg[2] )
R(0.392699081698) | Qureg[0]
Rz(0.392699081698) | Qureg[2]
CX | ( Qureg[0], Qureg[2] )
H | Qureg[1]
Rz(12.173671532661) | Qureg[2]
CX | ( Qureg[0], Qureg[2] )
R(0.785398163398) | Qureg[0]
Rz(0.785398163398) | Qureg[1]
CX | ( Qureg[0], Qureg[1] )
Rz(11.780972450962) | Qureg[1]
CX | ( Qureg[0], Qureg[1] )
H | Qureg[0]
Measure | Qureg[0]
Measure | Qureg[1]
Measure | Qureg[2]
Deallocate | Qureg[1]
Deallocate | Qureg[2]
Deallocate | Qureg[0]

如果2比特門操作也不加以限制的化,ProjectQ中會(huì)自動(dòng)選取最簡(jiǎn)易的分解形式:

from projectq import MainEngine
from projectq.cengines import DummyEngine
from projectq.ops import H, CX, All, Measure, TimeEvolution, QubitOperator, QFT
from projectq.setups import restrictedgateset

engine_list = restrictedgateset.get_engine_list(one_qubit_gates="any",two_qubit_gates="any")
backend = DummyEngine(save_commands=True)
eng = MainEngine(backend=backend,engine_list=engine_list)

qureg = eng.allocate_qureg(3)
H | qureg[0]
CX | (qureg[0], qureg[1])
QFT | qureg

All(Measure) | qureg
eng.flush(deallocate_qubits=True)

for cmd in backend.received_commands:
    print (cmd)

輸出結(jié)果如下:

Allocate | Qureg[0]
Allocate | Qureg[1]
H | Qureg[0]
CX | ( Qureg[0], Qureg[1] )
Allocate | Qureg[2]
H | Qureg[2]
CR(1.570796326795) | ( Qureg[1], Qureg[2] )
CR(0.785398163397) | ( Qureg[0], Qureg[2] )
H | Qureg[1]
CR(1.570796326795) | ( Qureg[0], Qureg[1] )
H | Qureg[0]
Measure | Qureg[0]
Measure | Qureg[1]
Measure | Qureg[2]
Deallocate | Qureg[1]
Deallocate | Qureg[2]
Deallocate | Qureg[0]

可以發(fā)現(xiàn)使用了CR來替代CX之后,分解出來的線路會(huì)更加的簡(jiǎn)短。

總結(jié)概要

本文主要從工程實(shí)現(xiàn)的角度,講解在ProjectQ開源量子計(jì)算模擬器框架中,實(shí)現(xiàn)量子門操作分解與輸出的方法。通過這個(gè)方法,可以限制量子指令集的范圍,將量子算法中不被支持的量子門操作等價(jià)(或近似地)變化到量子硬件體系所支持的量子指令集上。

以上就是python怎么使用ProjectQ生成量子算法指令集的詳細(xì)內(nèi)容,更多python學(xué)習(xí)資料請(qǐng)關(guān)注W3Cschool!


0 人點(diǎn)贊