量子算法入门——5.Qiskit库介绍与简单应用(1)
参考资料:
【【零基础入门量子计算】】
来自b站up:溴锑锑跃迁
建议关注他的更多高质量文章:CSDN:【溴锑锑跃迁】
(实际上只带一点点原创,绝大部分资料来自这位大佬)
跟着视频我手打了一遍notebook的内容,文件随附(为了创作分哈哈),为了绕开CSDN下载资源的种种手段,再附【下载链接】: 密码:depven
简述jupyter notebook的使用流程
- 找到任意一个python文件,即后缀为.py的文件,鼠标右键点击,然后选择在终端中打开
- 在终端中输入:jupyter notebook 然后回车,等待打开网页后自动跳转到notebook的主页
格子的状态:
-
蓝色:选中格子,此时无法在格子内部编辑代码或文本,无光标闪动,但是可以对格子进行插入、删除等操作
-
绿色:编写状态
jupyter notebook的一些快捷键
- 选中格子+a:在格子上方插入一个空白格子
- 选中格子+b:在格子下方插入一个空白格子
- 选中格子+m:将该格子作为注释使用,执行markdown语法,无法运行代码
- 选中格子+enter:进入格子内部,右侧线框颜色提示变绿,进入编写状态
- 编写状态:ctrl+enter:运行格子中的代码;如果是注释格子,会运行markdown语法
- 编写状态:esc:退出到选中格子状态,右侧线框颜色提示变蓝
示例
import numpy as np
from qiskit import *circ = QuantumCircuit(3) #创建一个有三量子比特的量子电路
circ.h(0) #给第0个比特加一个H门
circ.cx(0, 1) #给第0和第1个比特加一个cx门
circ.cx(0, 2)#选择一个用于执行的后端,此处是态矢后端
backend = Aer.get_backend('statevector_simulator')
job = execute(circ, backend) #execute()z专门用于执行电路
result = job.result()output = result.get_statevector(circ, decimals=3)#保留三位数字
print(output)
执行结果,可能需要pip install qiskit-aer
量子电路与量子门
一般而言,电路的初始量子态均为|0>,当然Qiskit也支持我们使用任意长度为1的向量来初始化:
import math
desired_vector = [1 / math.sqrt(16) * complex(0, 1),1 / math.sqrt(8) * complex(1, 0),1 / math.sqrt(16) * complex(1, 1),0,0,1 / math.sqrt(8) * complex(1, 2),1 / math.sqrt(16) * complex(1, 0),0
]desired_vector_equal = [#与上面desired_vector等效的写法1 / math.sqrt(16) * 1j,1 / math.sqrt(8) * 1,1 / math.sqrt(16) * 1 + 1j,0,0,1 / math.sqrt(8) * 1 + 2j,1 / math.sqrt(16) * 1,0
]q = QuantumRegister(3)qc = QuantumCircuit(q)qc.initialize(desired_vector, [q[0],q[1],q[2]])qc.draw('mpl')
其中使用到了函数initialize(目标向量,初始化位置)
注意到初始态矢量为 ∣ ψ ⟩ = i 4 ∣ 000 ⟩ + 1 4 ∣ 001 ⟩ + 1 + i 4 ∣ 010 ⟩ + 1 + 2 i 8 ∣ 101 ⟩ + 1 4 ∣ 110 ⟩ |\psi\rangle=\frac{i}{4}|000\rangle+\frac{1}{\sqrt4}|001\rangle+\frac{1+i}{4}|010\rangle+\frac{1+2i}{\sqrt8}|101\rangle+\frac{1}{4}|110\rangle ∣ψ⟩=4i∣000⟩+41∣001⟩+41+i∣010⟩+81+2i∣101⟩+41∣110⟩
下面更改q = QuantumRegister(4),会有:
import math
desired_vector = [1 / math.sqrt(16) * complex(0, 1),1 / math.sqrt(8) * complex(1, 0),1 / math.sqrt(16) * complex(1, 1),0,0,1 / math.sqrt(8) * complex(1, 2),1 / math.sqrt(16) * complex(1, 0),0
]desired_vector_equal = [#与上面desired_vector等效的写法1 / math.sqrt(16) * 1j,1 / math.sqrt(8) * 1,1 / math.sqrt(16) * 1 + 1j,0,0,1 / math.sqrt(8) * 1 + 2j,1 / math.sqrt(16) * 1, 0
]q = QuantumRegister(4)qc = QuantumCircuit(q)qc.initialize(desired_vector, [q[0],q[1],q[3]])qc.draw('mpl')
结果如下,可以看到q[2]没被编号,因为qc.initialize(desired_vector, [q[0],q[1],q[3]])
认识后端
所有后端都存放在qiskit.Aer库当中,我们可以使用以下语句导入该库.当然也可以使用iskit.BasicAer库,它包含了Aer的基本功能
通用的后端调用流程是:
- 首先利用Aer.get_backend(后端名称)或BasicAer.get backend(后端名称)获取指定后端
- 然后使用qiskit.execute(电路,后端)执行电路,并将结果保存在job变量当中
- 随后使用iob.result()函数**获取执行结果
- 最后从中调用相应函数(如get statevector(电路,参数))获取最终结果
态矢后端
态矢后端对应的模拟器名称为statevector_simulator,用于计算在总量子态经过电路演化后得到的最终量子态
backend = Aer.get_backend('statevector_simulator') #获取指定后端
job = execute(circ, backend) #执行电路
result = job.result() #获取执行结果
output = result.get_statevector(circ, decimals=3) #调用相应函数
print(output)
执行结果:
依上所见,态天后端的相应函数为get_statevector(电路,参数)
酉后端
酉后端对应的模拟器名称为unitary_simulator,用于计算电路本身对应的矩阵
如果将该矩阵记为 U = [ u 11 u 12 ⋯ u 21 u 22 ⋯ ⋮ ⋮ ⋱ ] \left.U=\left[\begin{array}{ccc}u_{11}&u_{12}&\cdots\\u_{21}&u_{22}&\cdots\\\vdots&\vdots&\ddots\end{array}\right.\right] U= u11u21⋮u12u22⋮⋯⋯⋱
而态矢后端计算出的最终态为 ∣ 最终 ⟩ = [ a 1 a 2 ⋮ ] \left.|\text{最终}\rangle=\left[\begin{array}{c}a_1\\a_2\\\vdots\end{array}\right.\right] ∣最终⟩= a1a2⋮
则整个电路可以写成如下的数学形式: ∣ 最终 ⟩ = U ∣ 初始 ⟩ |\text{最终}\rangle=U|\text{初始}\rangle ∣最终⟩=U∣初始⟩
backend = Aer.get_backend('unitary_simulator')#获取指定后端
job = execute(circ, backend) #执行电路
result = job.result() #获取执行结果
output = result.get_unitary(circ, decimals=3) #调用相应函数
print(output)
get_unitary(circ, decimals=3)返回电路对应的大矩阵,operator类型即操作符
大矩阵维数是2,2,2;