构建模块化的量子线路¶
在比特数量比较多,量子算法比较复杂的情况下,可能我们需要把多个比较小的量子线路组成成一整个大的量子程序。
QPanda-2可以以一种比较方便的模式去构建这种模块。
用于生成量子线路(量子程序)的函数¶
QPanda中最常见的做法是用C++函数来定义一个量子线路模块。它通常具有一个QCircuit或者QProg类型的返回值。例如
QCircuit foo(Qubit* qubit1, Qubit* qubit2) { QCircuit cir; cir << H(qubit2) << CNOT(qubit1, qubit2) << H(qubit2); return cir; }
这样的一个函数代表了一个模块(如图),当以不同的qubit1和qubit2作为输入的时候,它相当于把这个模块放置在了量子线路的不同位置
Qubit分配(qAlloc)与映射¶
QPanda-2中量子比特是用一个Qubit*的指针对象进行表示的。Qubit本身不包含任何和量子态相关的数据,它只是一个用于映射物理量子比特的对象。
qAlloc这个函数可以从量子芯片未用到的量子比特池中申请一个量子比特。qAllocMany则可以申请到一批。
示例:
Qubit* q=qAlloc(); QVec qs=qAllocMany(3);
如图:

在任何时候Qubit * 类型的对象(或者Qvec容器中包含的每一个Qubit*)对象,都是映射到量子芯片上一个位置。 在一开始申请的时候,用户无需指定这种映射关系(通过allocateQubitThroughPhyAddress可以进行手动指定),程序后面可以通过自动的优化器来根据量子程序进行重新映射,以便得到最简的量子程序。
使用编写好的模块¶
前面写好的foo,就可以被用于不同的量子比特上,以构建一个更大的量子程序。例如我们可以把这一段线路作用在q和qs上:
QProg prog; prog << foo(q, qs[0]) << foo(qs[1],qs[2]) << foo(qs[2], q);
这样,这个量子程序对应了下面这个量子线路:

利用QVec(vector<Qubit*>)构建模块的方式¶
QVec继承了vector<Qubit*>类,因此它可以覆盖所有vector所包含的功能(operator[],size(),push_back,iterator……),当然也可以利用C++11的新式for循环。
下面这个程序利用了一组量子比特(数量不定)去构建一个量子线路,对这组量子比特中每一个,都作用一个Hadamard门。
QCircuit foo2(QVec qs) { QCircuit cir; for (auto qubit: qs){ cir << H(q); } return cir; }
如果qs中只有一个量子比特,那这个线路就是:

如果qs中有N个量子比特,那这个线路自然就是:

请问:下面这个量子程序代表了一个什么样的模块呢?
QCircuit foo2(QVec qs) { QCircuit cir; cir << H(q[0]); for (int i=1;i<qs.size();++i) { cir << CNOT(q[i-1], q[i]); } return cir; }
答案是如图所示:
