5. 异构量子程序设计¶
异构型量子程序并不神秘,只需要将经典程序中的参数输入到量子程序中(例如单比特的旋转角度等),再将量子程序的结果按需反馈给经典程序即可。
5.1 QCIS的异构程序示例¶
5.1.1 示例1:将经典参数带入量子线路¶
演示程序未必有实际物理意义,仅供参考编程风格。
In [ ]:
Copied!
from pyezQ import * #导入pyezQ包
import time
account = Account(login_key='554393d4e2425130b0bcf7579163ffe2', machine_name='Transponder')
#创建实例,设置用户SDK密钥,选择量子计算机
create_res = account.create_experiment('expe21000010')
if create_res == 0:
print('新建实验合集失败')
else :
print('新建实验合辑成功,ID=', create_res)
lab_id = create_res
#在线路中预置{x}表述待传入参数
qcis_circuit = '''
RX Q0 {n1}
RX Q6 {n2}
H Q0
X Q6
H Q6
CZ Q0 Q6
H Q6
M Q0
M Q6
'''
#代码中嵌入了变量['n1','n2'],利用submit_job函数,提交前进行参数带入,实现动态数据的输入。
value=0
while value < 0.5 : #经典计算的条件判断
query_id = account.submit_job(circuit=qcis_circuit, lab_id=lab_id, version=str(int(time.time())),
parameters=[['n1','n2']], values=[[(0.2*value)%3.14, (0.2*value)%3.14]], num_shots=100)
#将实时计算的经典数据带入量子程序,并运行。
#实现了经典程序数据与量子程序数据的交互。
#还可以根据经典数据作为条件,调用不同量子程序,输入不同参数。见示例2
if query_id:
result=account.query_experiment(query_id, max_wait_time=360000)
#最大等待时间单位为秒,不传递时默认为30秒。因量子程序的执行会有排队的情况,而量子计算机本身有自动校准的时间,如果想跑全自动的程序,等待时间最好大于两者。
print(result)
value = float(result[0]['probability']['00']) #将量子程序的运行结果处理,重新赋值给经典程序。
print(value)
else:
value=0.5
print(f'迭代失败,有实验未运行成功')
#以下为运算结果的使用与保存。
f = open("./results.txt",'w')
f.write('value={},next n1={},n2={}'.format(value,(0.2*value)%3.14, (0.2*value)%3.14))
f.close()
from pyezQ import * #导入pyezQ包
import time
account = Account(login_key='554393d4e2425130b0bcf7579163ffe2', machine_name='Transponder')
#创建实例,设置用户SDK密钥,选择量子计算机
create_res = account.create_experiment('expe21000010')
if create_res == 0:
print('新建实验合集失败')
else :
print('新建实验合辑成功,ID=', create_res)
lab_id = create_res
#在线路中预置{x}表述待传入参数
qcis_circuit = '''
RX Q0 {n1}
RX Q6 {n2}
H Q0
X Q6
H Q6
CZ Q0 Q6
H Q6
M Q0
M Q6
'''
#代码中嵌入了变量['n1','n2'],利用submit_job函数,提交前进行参数带入,实现动态数据的输入。
value=0
while value < 0.5 : #经典计算的条件判断
query_id = account.submit_job(circuit=qcis_circuit, lab_id=lab_id, version=str(int(time.time())),
parameters=[['n1','n2']], values=[[(0.2*value)%3.14, (0.2*value)%3.14]], num_shots=100)
#将实时计算的经典数据带入量子程序,并运行。
#实现了经典程序数据与量子程序数据的交互。
#还可以根据经典数据作为条件,调用不同量子程序,输入不同参数。见示例2
if query_id:
result=account.query_experiment(query_id, max_wait_time=360000)
#最大等待时间单位为秒,不传递时默认为30秒。因量子程序的执行会有排队的情况,而量子计算机本身有自动校准的时间,如果想跑全自动的程序,等待时间最好大于两者。
print(result)
value = float(result[0]['probability']['00']) #将量子程序的运行结果处理,重新赋值给经典程序。
print(value)
else:
value=0.5
print(f'迭代失败,有实验未运行成功')
#以下为运算结果的使用与保存。
f = open("./results.txt",'w')
f.write('value={},next n1={},n2={}'.format(value,(0.2*value)%3.14, (0.2*value)%3.14))
f.close()
5.1.2 示例2:经典参数作为判断条件,执行不同量子线路¶
演示程序未必有实际物理意义,仅供参考编程风格。
In [ ]:
Copied!
from pyezQ import * #导入pyezQ包
import time
account = Account(login_key='554393d4e2425130b0bcf7579163ffe2', machine_name='Transponder')
#创建实例,设置用户SDK密钥,选择量子计算机
create_res = account.create_experiment('expe21000009')
if create_res == 0:
print('新建实验合集失败')
else :
print('新建实验合辑成功,ID=', create_res)
lab_id = create_res
qcis_circuit_1 = '''
RX Q0 {n1}
RX Q6 {n2}
H Q0
X Q6
H Q6
CZ Q0 Q6
H Q6
M Q0
M Q6
'''
#代码中嵌入了变量['n1','n2'],利用submit_job函数,提交前进行参数带入,实现动态数据的输入。
qcis_circuit_2 = '''
H Q0
X Q6
H Q6
CZ Q0 Q6
H Q6
RX Q0 {n3}
RX Q6 {n4}
M Q0
M Q6
'''
#代码中嵌入了变量['n3','n4'],利用submit_job函数,提交前进行参数带入,实现动态数据的输入。
#经典计算一系列动作,得到一个判断变量。
value=0
if value < 0.5 : #经典计算的条件判断
query_id = account.submit_job(circuit=qcis_circuit_1, lab_id=lab_id, version="GPT4"+str(int(time.time())),
parameters=[['n1','n2']], values=[[(0.2*value)%3.14, (0.2*value)%3.14]])
#将实时计算的经典数据带入量子程序,并运行。
#实现了经典程序数据与量子程序数据的交互。
if query_id:
result=account.query_experiment(query_id, max_wait_time=360000)
#最大等待时间单位为秒,不传递时默认为30秒。因量子程序的执行会有排队的情况,而量子计算机本身有自动校准的时间,如果想跑全自动的程序,等待时间最好大于两者。
print(result)
value = float(result[0]['probability']['00']) #将量子程序的运行结果处理,重新赋值给经典程序。
print(value)
else:
print(f'迭代失败,有实验未运行成功')
else:
query_id = account.submit_job(circuit=qcis_circuit_2, lab_id=lab_id, version="GPT4"+str(int(time.time())),
parameters=[['n1','n2']], values=[[(0.2*value)%3.14, (0.2*value)%3.14]])
#将实时计算的经典数据带入量子程序,并运行。
#实现了经典程序数据与量子程序数据的交互。
if query_id:
result=account.query_experiment(query_id, max_wait_time=360000)
#最大等待时间单位为秒,不传递时默认为30秒。因量子程序的执行会有排队的情况,而量子计算机本身有自动校准的时间,如果想跑全自动的程序,等待时间最好大于两者。
print(result)
value = float(result[0]['probability']['00']) #将量子程序的运行结果处理,重新赋值给经典程序。
print(value)
else:
print(f'迭代失败,有实验未运行成功')
#以上还可以根据实验结果进行再次循环迭代等。参加示例1.
#以下为运算结果的使用与保存。
f = open("./results.txt",'w')
f.write('value={},next n1={},n2={}'.format(value,(0.2*value)%3.14, (0.2*value)%3.14))
f.close()
from pyezQ import * #导入pyezQ包
import time
account = Account(login_key='554393d4e2425130b0bcf7579163ffe2', machine_name='Transponder')
#创建实例,设置用户SDK密钥,选择量子计算机
create_res = account.create_experiment('expe21000009')
if create_res == 0:
print('新建实验合集失败')
else :
print('新建实验合辑成功,ID=', create_res)
lab_id = create_res
qcis_circuit_1 = '''
RX Q0 {n1}
RX Q6 {n2}
H Q0
X Q6
H Q6
CZ Q0 Q6
H Q6
M Q0
M Q6
'''
#代码中嵌入了变量['n1','n2'],利用submit_job函数,提交前进行参数带入,实现动态数据的输入。
qcis_circuit_2 = '''
H Q0
X Q6
H Q6
CZ Q0 Q6
H Q6
RX Q0 {n3}
RX Q6 {n4}
M Q0
M Q6
'''
#代码中嵌入了变量['n3','n4'],利用submit_job函数,提交前进行参数带入,实现动态数据的输入。
#经典计算一系列动作,得到一个判断变量。
value=0
if value < 0.5 : #经典计算的条件判断
query_id = account.submit_job(circuit=qcis_circuit_1, lab_id=lab_id, version="GPT4"+str(int(time.time())),
parameters=[['n1','n2']], values=[[(0.2*value)%3.14, (0.2*value)%3.14]])
#将实时计算的经典数据带入量子程序,并运行。
#实现了经典程序数据与量子程序数据的交互。
if query_id:
result=account.query_experiment(query_id, max_wait_time=360000)
#最大等待时间单位为秒,不传递时默认为30秒。因量子程序的执行会有排队的情况,而量子计算机本身有自动校准的时间,如果想跑全自动的程序,等待时间最好大于两者。
print(result)
value = float(result[0]['probability']['00']) #将量子程序的运行结果处理,重新赋值给经典程序。
print(value)
else:
print(f'迭代失败,有实验未运行成功')
else:
query_id = account.submit_job(circuit=qcis_circuit_2, lab_id=lab_id, version="GPT4"+str(int(time.time())),
parameters=[['n1','n2']], values=[[(0.2*value)%3.14, (0.2*value)%3.14]])
#将实时计算的经典数据带入量子程序,并运行。
#实现了经典程序数据与量子程序数据的交互。
if query_id:
result=account.query_experiment(query_id, max_wait_time=360000)
#最大等待时间单位为秒,不传递时默认为30秒。因量子程序的执行会有排队的情况,而量子计算机本身有自动校准的时间,如果想跑全自动的程序,等待时间最好大于两者。
print(result)
value = float(result[0]['probability']['00']) #将量子程序的运行结果处理,重新赋值给经典程序。
print(value)
else:
print(f'迭代失败,有实验未运行成功')
#以上还可以根据实验结果进行再次循环迭代等。参加示例1.
#以下为运算结果的使用与保存。
f = open("./results.txt",'w')
f.write('value={},next n1={},n2={}'.format(value,(0.2*value)%3.14, (0.2*value)%3.14))
f.close()
5.1.3 示例3:根据经典参数,重新合成(组装)量子线路¶
演示程序未必有实际物理意义,仅供参考编程风格。
In [ ]:
Copied!
from pyezQ import * #导入pyezQ包
import time
account = Account(login_key='554393d4e2425130b0bcf7579163ffe2', machine_name='Transponder')
#创建实例,设置用户SDK密钥,选择量子计算机
create_res = account.create_experiment('expe21000009')
if create_res == 0:
print('新建实验合集失败')
else :
print('新建实验合辑成功,ID=', create_res)
lab_id = create_res
qcis_circuit = '''
'''
#空白量子线路,等待生产
#一通经典计算
i=15
if i >10:
qcis_circuit=qcis_circuit+'\nX Q0'
else:
qcis_circuit=qcis_circuit+'\Y Q0'
#再一通经典计算
j=5
if j >10:
qcis_circuit=qcis_circuit+'\nRX Q0 {n1} \nRY Q0 {n2} \nM Q0'
else:
qcis_circuit=qcis_circuit+'\nRY Q0 {n1} \nRX Q0 {n2} \nM Q0'
#看看线路成什么样子了
print(qcis_circuit)
#又一通经典计算
value=0
#采用量子实验结果递归和经典参数带入作为下文示例。
while value < 0.5 : #经典计算的条件判断
query_id = account.submit_job(circuit=qcis_circuit, lab_id=lab_id, version="GPT4"+str(int(time.time())),parameters=[['n1','n2']], values=[[(0.2*value)%3.14, (0.2*value)%3.14]], num_shots=100)
#将实时计算的经典数据带入量子程序,并运行。
#实现了经典程序数据与量子程序数据的交互。
#还可以根据经典数据作为条件,调用不同量子程序,输入不同参数。见示例2
if query_id:
result=account.query_experiment(query_id, max_wait_time=360000)
#最大等待时间单位为秒,不传递时默认为30秒。因量子程序的执行会有排队的情况,而量子计算机本身有自动校准的时间,如果想跑全自动的程序,等待时间最好大于两者。
print(result)
value = float(result[0]['probability']['0']) #将量子程序的运行结果处理,重新赋值给经典程序。
print(value)
else:
value=0.5
print(f'迭代失败,有实验未运行成功')
#以下为运算结果的使用与保存。
f = open("./results.txt",'w')
f.write('value={},next n1={},n2={}'.format(value,(0.2*value)%3.14, (0.2*value)%3.14))
f.close()
from pyezQ import * #导入pyezQ包
import time
account = Account(login_key='554393d4e2425130b0bcf7579163ffe2', machine_name='Transponder')
#创建实例,设置用户SDK密钥,选择量子计算机
create_res = account.create_experiment('expe21000009')
if create_res == 0:
print('新建实验合集失败')
else :
print('新建实验合辑成功,ID=', create_res)
lab_id = create_res
qcis_circuit = '''
'''
#空白量子线路,等待生产
#一通经典计算
i=15
if i >10:
qcis_circuit=qcis_circuit+'\nX Q0'
else:
qcis_circuit=qcis_circuit+'\Y Q0'
#再一通经典计算
j=5
if j >10:
qcis_circuit=qcis_circuit+'\nRX Q0 {n1} \nRY Q0 {n2} \nM Q0'
else:
qcis_circuit=qcis_circuit+'\nRY Q0 {n1} \nRX Q0 {n2} \nM Q0'
#看看线路成什么样子了
print(qcis_circuit)
#又一通经典计算
value=0
#采用量子实验结果递归和经典参数带入作为下文示例。
while value < 0.5 : #经典计算的条件判断
query_id = account.submit_job(circuit=qcis_circuit, lab_id=lab_id, version="GPT4"+str(int(time.time())),parameters=[['n1','n2']], values=[[(0.2*value)%3.14, (0.2*value)%3.14]], num_shots=100)
#将实时计算的经典数据带入量子程序,并运行。
#实现了经典程序数据与量子程序数据的交互。
#还可以根据经典数据作为条件,调用不同量子程序,输入不同参数。见示例2
if query_id:
result=account.query_experiment(query_id, max_wait_time=360000)
#最大等待时间单位为秒,不传递时默认为30秒。因量子程序的执行会有排队的情况,而量子计算机本身有自动校准的时间,如果想跑全自动的程序,等待时间最好大于两者。
print(result)
value = float(result[0]['probability']['0']) #将量子程序的运行结果处理,重新赋值给经典程序。
print(value)
else:
value=0.5
print(f'迭代失败,有实验未运行成功')
#以下为运算结果的使用与保存。
f = open("./results.txt",'w')
f.write('value={},next n1={},n2={}'.format(value,(0.2*value)%3.14, (0.2*value)%3.14))
f.close()
5.2 Quingo的异构程序示例¶
以下示例代码节选自Quingo开源库的示例,https://gitee.com/quingo/quingo-runtime/tree/master/src/examples/H2_VQE
In [ ]:
Copied!
#核心带参数的量子算法在kernel.qu文件中
#下面将其展示出给大家讲解,注释为本教程讲解需要所添加,仅供参考。
quingo_circuit='''
opaque X(q: qubit) : unit;
opaque X2P(q: qubit) : unit;
opaque X2M(q: qubit) : unit;
opaque Y2P(q: qubit) : unit;
opaque Y2M(q: qubit) : unit;
opaque RZ(q: qubit, angle: double) : unit;
opaque CZ(q1: qubit, q2: qubit) : unit;
opaque measure(q: qubit): bool;
#自定义的CNOT门
operation CNOT(a: qubit, b: qubit) : unit {
Y2M(b);
CZ(a, b);
Y2P(b);
}
#自定义比特的初始化操作
operation init(q: qubit): unit{
X(q);
}
#自定义含参数的Ansatz函数,angle为经典变量引入到量子程序。
operation ansatz(angle: double): unit {
using(q0: qubit, q1: qubit) {
init(q0);
X2M(q0);
Y2P(q1);
CNOT(q1, q0);
RZ(q0, angle);
CNOT(q1, q0);
X2P(q0);
Y2M(q1);
}
}
'''
#核心带参数的量子算法在kernel.qu文件中
#下面将其展示出给大家讲解,注释为本教程讲解需要所添加,仅供参考。
quingo_circuit='''
opaque X(q: qubit) : unit;
opaque X2P(q: qubit) : unit;
opaque X2M(q: qubit) : unit;
opaque Y2P(q: qubit) : unit;
opaque Y2M(q: qubit) : unit;
opaque RZ(q: qubit, angle: double) : unit;
opaque CZ(q1: qubit, q2: qubit) : unit;
opaque measure(q: qubit): bool;
#自定义的CNOT门
operation CNOT(a: qubit, b: qubit) : unit {
Y2M(b);
CZ(a, b);
Y2P(b);
}
#自定义比特的初始化操作
operation init(q: qubit): unit{
X(q);
}
#自定义含参数的Ansatz函数,angle为经典变量引入到量子程序。
operation ansatz(angle: double): unit {
using(q0: qubit, q1: qubit) {
init(q0);
X2M(q0);
Y2P(q1);
CNOT(q1, q0);
RZ(q0, angle);
CNOT(q1, q0);
X2P(q0);
Y2M(q1);
}
}
'''
经典程序位于host.py文件内,以下对部分代码做异构程序讲解。
In [ ]:
Copied!
#与量子相关的局部调用关系为eval_all() --> energy_theta(theta, g) --> get_ansatz("ansatz", theta) --> qi.call_quingo(qu_file, circ_name, theta)
#原示例最终由get_ansatz函数返回,带角度参数的量子线路仿真结果。
#只需要在get_ansatz函数中将由仿真器获得的结果替换为由物理机替换的结果即可。
#本模块请勿执行
def get_ansatz(circ_name, theta):
if not qi.call_quingo(qu_file, circ_name, theta):
print("Failed to call {}".format(circ_name))
res = qi.read_result()
return res
def energy_theta(theta: np.double, g):
'''Return the calculated energy for the given parameter theta.
'''
ansatz_state = get_ansatz("ansatz", theta)
h = hamiltonian(g)
energy = expectation(h, ansatz_state)
return energy
def eval_all():
bond_length = []
lowest_energies = []
# theta = -np.pi/2
for b in bond_h_decompose:
bond_length.append(b[0])
g = b[1:]
# --------------- brute-force scanning - --------------
# angles = np.linspace(-np.pi/2, np.pi/2, 50)
# tmp_lowest_energies = [energy_theta(theta, g) for theta in angles]
# ele_tmp_lowest_energies = (min(tmp_lowest_energies)).A[0][0]
# lowest_energies.append(ele_tmp_lowest_energies)
# # --------------- optimization based on searching ---------------
minimum = minimize_scalar(
lambda theta: (energy_theta(theta, g)).A[0][0])
lowest_energies.append(minimum.fun)
plt.plot(bond_length, lowest_energies, "b.-")
plt.xlabel("Bond Length")
plt.title("Variational Quantum Eigensolver")
plt.ylabel("Energy")
plt.show()
#与量子相关的局部调用关系为eval_all() --> energy_theta(theta, g) --> get_ansatz("ansatz", theta) --> qi.call_quingo(qu_file, circ_name, theta)
#原示例最终由get_ansatz函数返回,带角度参数的量子线路仿真结果。
#只需要在get_ansatz函数中将由仿真器获得的结果替换为由物理机替换的结果即可。
#本模块请勿执行
def get_ansatz(circ_name, theta):
if not qi.call_quingo(qu_file, circ_name, theta):
print("Failed to call {}".format(circ_name))
res = qi.read_result()
return res
def energy_theta(theta: np.double, g):
'''Return the calculated energy for the given parameter theta.
'''
ansatz_state = get_ansatz("ansatz", theta)
h = hamiltonian(g)
energy = expectation(h, ansatz_state)
return energy
def eval_all():
bond_length = []
lowest_energies = []
# theta = -np.pi/2
for b in bond_h_decompose:
bond_length.append(b[0])
g = b[1:]
# --------------- brute-force scanning - --------------
# angles = np.linspace(-np.pi/2, np.pi/2, 50)
# tmp_lowest_energies = [energy_theta(theta, g) for theta in angles]
# ele_tmp_lowest_energies = (min(tmp_lowest_energies)).A[0][0]
# lowest_energies.append(ele_tmp_lowest_energies)
# # --------------- optimization based on searching ---------------
minimum = minimize_scalar(
lambda theta: (energy_theta(theta, g)).A[0][0])
lowest_energies.append(minimum.fun)
plt.plot(bond_length, lowest_energies, "b.-")
plt.xlabel("Bond Length")
plt.title("Variational Quantum Eigensolver")
plt.ylabel("Energy")
plt.show()
与量子相关的局部调用关系为eval_all() --> energy_theta(theta, g) --> get_ansatz("ansatz", theta) --> qi.call_quingo(qu_file, circ_name, theta)
原示例最终由get_ansatz函数返回,带角度参数的量子线路仿真结果。
只需要在get_ansatz函数中将由仿真器获得的结果替换为由物理机替换的结果即可。
In [ ]:
Copied!
#本模块请勿执行
from pyezQ import * #导入pyezQ包
account = Account(login_key='4f90473cc1cf4fa3d9a7b146c1524e7f', machine_name='应答机A')
#创建实例,设置用户SDK密钥,选择量子计算机
create_res = account.create_experiment('expe21000009')
if create_res == 0:
print('新建实验合集失败')
else :
print('新建实验合辑成功,ID=', create_res)
lab_id = create_res
def get_ansatz(circ_name, theta):
if not qi.call_quingo(qu_file, circ_name, theta):
print("Failed to call {}".format(circ_name))
f = open("./build/{}.qcis".format(circ_name),'r')
quingo_qcis=f.read(100000)#确保读取长度超过文件总长度。
f.close()
print(quingo_qcis)
query_id_quingo = account.submit_job(circuit=quingo_qcis, version=circ_name)
if query_id_quingo:
result=account.query_experiment(query_id_quingo, max_wait_time=360000)
#最大等待时间单位为秒,不传递时默认为30秒。因量子程序的执行会有排队的情况,而量子计算机本身有自动校准的时间,如果想跑全自动的程序,等待时间最好大于两者。
#res = qi.read_result()
res = result #注意这里需要的res的形式,本处理未必正确
return res
#本模块请勿执行
from pyezQ import * #导入pyezQ包
account = Account(login_key='4f90473cc1cf4fa3d9a7b146c1524e7f', machine_name='应答机A')
#创建实例,设置用户SDK密钥,选择量子计算机
create_res = account.create_experiment('expe21000009')
if create_res == 0:
print('新建实验合集失败')
else :
print('新建实验合辑成功,ID=', create_res)
lab_id = create_res
def get_ansatz(circ_name, theta):
if not qi.call_quingo(qu_file, circ_name, theta):
print("Failed to call {}".format(circ_name))
f = open("./build/{}.qcis".format(circ_name),'r')
quingo_qcis=f.read(100000)#确保读取长度超过文件总长度。
f.close()
print(quingo_qcis)
query_id_quingo = account.submit_job(circuit=quingo_qcis, version=circ_name)
if query_id_quingo:
result=account.query_experiment(query_id_quingo, max_wait_time=360000)
#最大等待时间单位为秒,不传递时默认为30秒。因量子程序的执行会有排队的情况,而量子计算机本身有自动校准的时间,如果想跑全自动的程序,等待时间最好大于两者。
#res = qi.read_result()
res = result #注意这里需要的res的形式,本处理未必正确
return res
因VQE实验调用物理机次数较多,需要时间较长,这里不做整体演示,有兴趣的朋友可以修改代码,做对比实验。
至此,Quingo的异构编程应用氢分子VQE实验即在量子计算物理机上运行完成。
其他需求的程序也可以使用类似的参数引入环节,进行设计。
In [ ]:
Copied!
from isq import LocalDevice
isq_code = '''
qbit q[2];
RX(theta, q[0]);
CNOT(q[0],q[1]);
M(q[0,1]);
'''
#获得QCIS代码
ld = LocalDevice()
ir = ld.compile_to_ir(isq_code, target = 'qcis', theta = 1.234)
print(ir)
from isq import LocalDevice
isq_code = '''
qbit q[2];
RX(theta, q[0]);
CNOT(q[0],q[1]);
M(q[0,1]);
'''
#获得QCIS代码
ld = LocalDevice()
ir = ld.compile_to_ir(isq_code, target = 'qcis', theta = 1.234)
print(ir)
基于变分量子算法(VQE),使用isQ求氢分子的最低能量示例代码如下:(注意,直接执行以下代码可能需要几十秒,根据经典计算机情况而定,并不是程序故障,请稍等待结果。)
In [ ]:
Copied!
from isq import LocalDevice
isq_code = '''
qbit q[2];
X(q[1]);
RY(1.57,q[0]);
RX(4.71, q[1]);
CNOT(q[0],q[1]);
RZ(theta,q[1]);
CNOT(q[0],q[1]);
RY(4.71, q[0]);
RX(1.57, q[1]);
if(e_n == 0){
M(q[0]);
}
if(e_n==1){
M(q[1]);
}
if(e_n==2){
M(q[0,1]);
}
if(e_n==3){
RX(1.57, q[0]);
RX(1.57, q[1]);
M(q[0,1]);
}
if(e_n==4){
H(q[0,1]);
M(q[0,1]);
}
'''
ld = LocalDevice()
def get_exception(theta)->float :
'''
thetas制备时角度
e_n<= E_N,测量第n个能量e
'''
theta = float(theta)
E_N=5
exceptions = list()
hs=[-0.4804,+0.3435,-0.4347,+0.5716,+0.0910,+0.0910]
exceptions.append(hs[0])
for e_n in range(E_N) :
test_res=ld.run(isq_code,theta=theta, e_n=e_n)
exception = 0
for measure_res in test_res :
frequency = test_res[measure_res]/100
#频率代替概率
parity = (-1)**(measure_res.count('1')%2)
#奇偶校验
exception += parity*frequency
exceptions.append(hs[e_n+1]*exception)
return sum(exceptions)
# nelder-mead optimization of a convex function
from scipy.optimize import minimize
from numpy.random import rand
# define range for theta
theta_min, theta_max = -3.14, 3.14
# define the starting point as a random sample from the domain
pt = theta_min + rand(1) * (theta_max - theta_min)
# perform the search
result = minimize(get_exception, pt, method='nelder-mead')
# summarize the result
print(f"Status : {result['message']}")
print(f"Total Evaluations: {result['nfev']}")
# evaluate solution
solution = result['x']
evaluation = get_exception(solution)
print(f"Solution: H_2({solution}) = {evaluation} Eh")
from isq import LocalDevice
isq_code = '''
qbit q[2];
X(q[1]);
RY(1.57,q[0]);
RX(4.71, q[1]);
CNOT(q[0],q[1]);
RZ(theta,q[1]);
CNOT(q[0],q[1]);
RY(4.71, q[0]);
RX(1.57, q[1]);
if(e_n == 0){
M(q[0]);
}
if(e_n==1){
M(q[1]);
}
if(e_n==2){
M(q[0,1]);
}
if(e_n==3){
RX(1.57, q[0]);
RX(1.57, q[1]);
M(q[0,1]);
}
if(e_n==4){
H(q[0,1]);
M(q[0,1]);
}
'''
ld = LocalDevice()
def get_exception(theta)->float :
'''
thetas制备时角度
e_n<= E_N,测量第n个能量e
'''
theta = float(theta)
E_N=5
exceptions = list()
hs=[-0.4804,+0.3435,-0.4347,+0.5716,+0.0910,+0.0910]
exceptions.append(hs[0])
for e_n in range(E_N) :
test_res=ld.run(isq_code,theta=theta, e_n=e_n)
exception = 0
for measure_res in test_res :
frequency = test_res[measure_res]/100
#频率代替概率
parity = (-1)**(measure_res.count('1')%2)
#奇偶校验
exception += parity*frequency
exceptions.append(hs[e_n+1]*exception)
return sum(exceptions)
# nelder-mead optimization of a convex function
from scipy.optimize import minimize
from numpy.random import rand
# define range for theta
theta_min, theta_max = -3.14, 3.14
# define the starting point as a random sample from the domain
pt = theta_min + rand(1) * (theta_max - theta_min)
# perform the search
result = minimize(get_exception, pt, method='nelder-mead')
# summarize the result
print(f"Status : {result['message']}")
print(f"Total Evaluations: {result['nfev']}")
# evaluate solution
solution = result['x']
evaluation = get_exception(solution)
print(f"Solution: H_2({solution}) = {evaluation} Eh")
该核函数使用模拟器运行,如需使用量子硬件,可采用2.3方式获取编译后ir,然后调用平台接口使用即可