查看原文
其他

QPanda 2教程资源 | 模拟量子虚拟机的解决方案(下):单振幅和含噪声量子虚拟机

OriginQ 本源量子 2021-02-13

hi~一周又过去一半啦

继上篇推文后

小编继续为大家整理了

模拟量子虚拟机的解决方案(下)

让我们再次体验吧



在上一篇文章介绍中,小编已为大家介绍了模拟量子虚拟机的解决方案上部分全振幅量子虚拟机和部分振幅量子虚拟机。

全振幅量子虚拟机一次可模拟计算出量子态的所有振幅,计算方式支持CPU、单线程计算和GPU。部分振幅量子虚拟机的基本思想是将大比特的量子程序拆分成若干个小比特量子程序,每个小比特量子线路使用全振幅算法计算。

接下来,小编将为你继续介绍模拟量子虚拟机的解决方案(下)单振幅和含噪声量子虚拟机

单振幅量子虚拟机


单振幅与全振幅主要区别在于,全振幅一次模拟计算就能算出量子态的所有振幅,单振幅一次模拟计算只能计算出2^n个量子态分量中的一个振幅。

然而全振幅模拟量子计算时间较长,计算量随量子比特数指数增长,.在现有硬件下,无法模拟超过49量子比特。通过单振幅量子虚拟机技术可以模拟超过49比特,同时模拟速度有较大提升,且算法的计算量不随量子比特数指数提升。


使用介绍


QPanda2中设计了SingleAmplitudeQVM类用于运行单振幅模拟量子计算,同时提供了相关接口,它的使用也很简单。

首先,构建一个单振幅量子虚拟机;

auto machine = new SingleAmplitudeQVM();

然后,必须使用SingleAmplitudeQVM::init()初始化量子虚拟机环境;

machine->init();

接着,进行量子程序的构建、装载工作;

auto prog = QProg();

auto qlist = machine->allocateQubits(10);

for_each(qlist.begin(), qlist.end(), [&](Qubit *val) { prog << H(val); });

prog << CZ(qlist[1], qlist[5]) << CZ(qlist[3], qlist[5]) << CZ(qlist[2], qlist[4]);

...

machine->run(prog);

构建还可以采用另一种方式,即读取QRunes文件形式。例如

machine->run("D:\\QRunes");

最后,调用计算接口,我们设计多种返回值的接口用于满足不同的计算需求。具体见示例所述:


实例


 以下示例,展示了单振幅量子虚拟机接口的使用方式。

1、初始化虚拟机环境:构建一个单振幅量子虚拟机,向量子虚拟机申请10个量子比特;

2、构建量子程序:构建一个量子线路prog,通过 << 操作符把量子逻辑门插入到prog中;

3、运行量子程序:调用run装载量子程序,调用getQStat接口得到获取量子态所有分量的振幅。

getQStat()接口表示输出计算后的所有量子态分量的振幅,输出结果用map容器保存,key为量子态对应的字符串,value为对应的振幅,上述程序的计算结果如下

(0.040830060839653015,-9.313225746154785e-10j)

(0.040830060839653015,-9.313225746154785e-10j)

...

若使用其他接口:

PMeasure(std::string),输入的参数表示获取测量所有比特构成量子态的概率的结果集的前多少项,比如如下例子,我们获取所有量子态的概率分布结果的前6项,程序运行如下:

auto res = machine->PMeasure("6");

for (auto val :res)

{

        std::cout << val.first << " : " << val.second << std::endl;

}

结果输出如下,每个结果的序号表示量子态的下标,后面的值表示概率:

0 : 0.00333419

1 : 0.000572056

2 : 0.000572056

3 : 0.00333419

4 : 0.00333419

5 : 0.000572056

getProbDict(qvec,std::string),输入的第一个参数表示选取哪几个量子比特构成的量子态的概率,第二个参数表示选取结果的前多少项,使用示例如下:

QVec qvec;

for_each(qlist.begin(), qlist.end(), [&](Qubit *val) { qvec.emplace_back(val); });


auto res = machine->getProbDict(qvec,6);

for (auto val :res)

{

        std::cout << val.first << " : " << val.second << endl;

}

结果输出如下,每个结果的前半部分表示量子态的二进制形式,后面的值表示概率:

0000000000 : 0.00166709

0000000001 : 0.00166709

0000000010 : 0.000286028

0000000011 : 0.000286028

0000000100 : 0.000286028

0000000101 : 0.000286028

PMeasure_bin_index(std::string),输入的参数表示指定需要测量的量子态二进制形式,使用示例如下:

auto res = machine->PMeasure_bin_index("0000000001");

std::cout << res << std::endl;

结果输出如下,表示目标量子态的概率值:

0.00166709

PMeasure_dec_index(std::string),输入的参数表示指定需要测量的量子态十进制下标形式,使用示例

auto res = machine->PMeasure_bin_index("1");

std::cout << res << std::endl;

结果输出如下,表示目标量子态的概率值:

0.00166709


含噪声量子虚拟机


在真实的量子计算机中,受制于量子比特自身的物理特性,常常存在不可避免的计算误差。为了能在量子虚拟机中更好的模拟这种误差,在全振幅量子虚拟机的基础上, QPanda2带来了含噪声量子虚拟机。

含噪声量子虚拟机的模拟更贴近真实的量子计算机,我们可自定义支持的逻辑门类型。自定义逻辑门支持的噪声模型, 通过这些自定义形式,我们使用QPanda2开发量子程序的现实应用程度将更高。

接口介绍

含噪声量子虚拟机的接口和其他量子虚拟机的接口大部分是相同的,但含噪声量子虚拟机不能使用PMEASURE系列的概率测量接口。此外QPanda2给它重载了一个init成员函数, 该成员函数可接收一个rapidjson::Document类型的参数,rapidjson::Document保存的是一个Json对象,我们可以在参数中定义含噪声量子虚拟机支持的量子逻辑门类型和 噪声模型。Json的结构如下所示:

{

    “gates”:[.....],

    "noisemodel":{.....}} 

}

假设我们希望自定含噪声量子虚拟机支持的逻辑门是RX、RY、CNOT,并且希望设定RX,RY的噪声模型为DECOHERENCE_KRAUS_OPERATOR,那么我们把Json构造成以下形式:

{

“gates”:[["RX","RY"],["CNOT"]],

"noisemodel":{"RX":[DECOHERENCE_KRAUS_OPERATOR,10.0,2.0,0.03],

 "RY":[DECOHERENCE_KRAUS_OPERATOR,10.0,2.0,0.03]}} 

}

rapidjson如何使用,我们可以到Rapidjson首页学习,这里先举个集合QPanda2使用的例子:

1、设置RX门对应的噪声模型及其参数;

2、设置RY门对应的噪声模型及其参数;

3、构建含噪声量子虚拟机,并初始化量子虚拟机

rapidjson::Document doc;

doc.Parse("{}");

Value value(rapidjson::kObjectType);

Value value_rx(rapidjson::kArrayType);
value_rx.PushBack(DECOHERENCE_KRAUS_OPERATOR, doc.GetAllocator());

value_rx.PushBack(10.0, doc.GetAllocator());

value_rx.PushBack(2.0, doc.GetAllocator());

value_rx.PushBack(0.03, doc.GetAllocator());

value.AddMember("RX", value_rx, doc.GetAllocator());

Value value_ry(rapidjson::kArrayType);
value_ry.PushBack(DECOHERENCE_KRAUS_OPERATOR, doc1.GetAllocator());

value_ry.PushBack(10.0, doc1.GetAllocator());

value_ry.PushBack(2.0, doc1.GetAllocator());

value_ry.PushBack(0.03, doc1.GetAllocator());

value.AddMember("RY", value_ry, doc1.GetAllocator());
doc.AddMember("noisemodel", value, doc1.GetAllocator());

NoiseQVM qvm; 

qvm.init(doc);


噪声模型介绍


QPanda2的含噪声量子虚拟机为我们提供了丰富的噪声模型,我们可以自定义噪声模型和量子逻辑门的对应关系。噪声模型主要分为两种:单门噪声模型和双门噪声模型。

单门噪声模型

DAMPING_KRAUS_OPERATOR

DAMPING_KRAUS_OPERATOR是量子比特的弛豫过程噪声模型,它的kraus算符和表示方法如下图所示: 

我们可以看到,DAMPING_KRAUS_OPERATOR需要一个参数P,该参数是double类型的,所以我们在构造Json的时候需要用以下形式(假设设定RX的噪声模型,当然输入的参数也是假定的):

{

        ..... 

        "noisemodel":{"RX":[DAMPING_KRAUS_OPERATOR,3.0],


                                                       ......}

}

DEPHASING_KRAUS_OPERATOR

DEPHASING_KRAUS_OPERATOR是量子比特的退相位过程噪声模型,它的kraus算符和表示方法如下图所示:

我们可以看到,DEPHASING_KRAUS_OPERATOR需要一个参数P,该参数是double类型的,所以我们在构造Json的时候需要用以下形式(假设设定RX的噪声模型):

{

        .....

        "noisemodel":{"RX":[DEPHASING_KRAUS_OPERATOR,2.0],


                                                       ......}

}

DECOHERENCE_KRAUS_OPERATOR

DECOHERENCE_KRAUS_OPERATOR是上述两种噪声模型的综合,他们的关系如下图所示:

我们可以看到,DEPHASING_KRAUS_OPERATOR需要三个参数T1,T2,tgate,所有的参数是double类型的,所以我们在构造Json的时候需要用以下形式(假设设定RX的噪声模型):

{

        .....

        "noisemodel":{"RX":[DECOHERENCE_KRAUS_OPERATOR,10.0,2.0,0.03],

                                    ......}

}

双门噪声模型

双门噪声模型同样也分为三种:DOUBLE_DAMPING_KRAUS_OPERATOR、DOUBLE_DEPHASING_KRAUS_OPERATOR、DOUBLE_DECOHERENCE_KRAUS_OPERATOR。它们的输入参数与单门噪声模型一致,双门噪声模型的kraus算符和表示与单门噪声模型存在着对应关系:假设单门噪声模型为: {K1,K2}{K1,K2} ,那么对应的双门噪声模型为 {K1⊗K1,K1⊗K2,K2⊗K1,K2⊗K2}{K1⊗K1,K1⊗K2,K2⊗K1,K2⊗K2}。

★以上即为QPanda 2单振幅和含噪声量子虚拟机部分的详细内容介绍。

★感兴趣的欢迎加入"QPanda 2开发交流群"。(关注“本源量子”公众号,回复“加群”,联系小编即可)

★PC端学习量子计算请登录learn-quantum.com  

★掌上学习请下载"本源溯知APP"

★如有疑问可上量子互动论坛,与我们的大神进行交流讨论。



往期精彩回顾

模拟量子虚拟机的解决方案(上):全振幅和部分振幅量子虚拟机

QPanda 2教程资源 | 构建量子程序、QWhile与QIf的方法

QPanda 2最常用的量子计算模型——量子线路

嗨玩本源QPanda 2,从量子逻辑门实例开始学起!

QPanda更新带来4种量子虚拟机+2种开发工具

【新品】国内首款量子软件开发包QPanda 2.0 升级发布!

Origin Q发布国内首款量子软件开发包Q-Panda

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存