pyqpanda_alg.QAOA.default_circuits

Module Contents

Functions

parity_partition_xy_mixer(qlist, beta)

Quantum circuits to approximate a parity-partition XY mixer.

complete_xy_mixer(qlist, angle)

Quantum circuits to approximate a complete XY mixer.

xy_mixer(domains[, mixer_type])

Generate XY mixer circuit.

init_d_state(domains[, k, compress])

Prepare Dicke state.

prepare_dicke_state(q_list, k[, compress])

Prepare Dicke state.

linear_w_state(q_list[, compress])

Prepare W state with a divide-and-conquer algorithm on the linear architecture device.

pyqpanda_alg.QAOA.default_circuits.parity_partition_xy_mixer(qlist, beta)

Quantum circuits to approximate a parity-partition XY mixer.

Parameters

qlist : list

Qubits list.

beta : float

angle \(t\) of \(e^{-iHt}\)

Return

cir : pq.QCircuit

Circuit of simulation a parity-partition XY mixer \(e^{-iHt}\).

Examples

Generate a circuit of simulation a parity-partition XY mixer \(e^{-iH\pi/2}\).

>>> import pyqpanda as pq
>>> import numpy as np
>>> from pyqpanda_alg.QAOA import default_circuits
>>> machine = pq.CPUQVM()
>>> machine.initQVM()
>>> qubits = machine.qAlloc_many(4)
>>> circuit = default_circuits.parity_partition_xy_mixer(qubits, np.pi/2)
>>> print(circuit)
q_0:  |0>─X X─
          │ │
q_1:  |0>─X ┼X
            ││
q_2:  |0>─X ┼X
          │ │
q_3:  |0>─X X─
Note

For a given XY mixer Hamiltonian

\[H_{XY,v} = \frac{1}{2} \sum_{c,c'\in K} (\sigma_{v,c}^x \sigma_{v',c}^x + \sigma_{v,c}^y \sigma_{v',c}^y)\]

When the mixer-set \(K\) takes a one dimensional structure: \(c'=c+1\), and periodic boundary condition, it is termed a ring mixer. In order to simulate a ring mixer in quantum circuit, a one-order approximation by applying local XY-Hamiltonian on even paris first and local pairs next is used, which is called parity-partition XY mixer. The leading error term is in order of the number of qubits in the domain. See details in [1]

Reference

[1] WANG Z, RUBIN N C, DOMINY J M, et. XY-mixers: analytical and numerical results for QAOA[J/OL]. Physical Review A, 2020, 101(1): 012320. DOI:10.1103/PhysRevA.101.012320.

pyqpanda_alg.QAOA.default_circuits.complete_xy_mixer(qlist, angle)

Quantum circuits to approximate a complete XY mixer.

Parameters

qlist : list

Qubits list.

angle : float

beta \(t\) of \(e^{-iHt}\)

Return

cir : pq.QCircuit

Circuit of simulation a complete XY mixer \(e^{-iHt}\).

Examples

Generate a circuit of simulation a complete XY mixer \(e^{-iH\pi/2}\).

>>> import pyqpanda as pq
>>> import numpy as np
>>> from pyqpanda_alg.QAOA import default_circuits
>>> machine = pq.CPUQVM()
>>> machine.initQVM()
>>> qubits = machine.qAlloc_many(4)
>>> circuit = default_circuits.complete_xy_mixer(qubits, np.pi/2)
>>> print(circuit)
q_0:  |0>─X X─ X─
          │ │  │
q_1:  |0>─X ┼X ┼X
            ││ ││
q_2:  |0>─X X┼ ┼X
          │  │ │
q_3:  |0>─X ─X X─
Note

For a given XY mixer Hamiltonian

\[H_{XY,v}=\frac{1}{2}\sum_{c,c'\in K} (\sigma_{v,c}^x \sigma_{v',c}^x + \sigma_{v,c}^y \sigma_{v',c}^y)\]

When the mixer-set \(K\) includes all pairs, it is termed a complete mixer. In order to simulate a complete mixer in quantum circuit, a partition of \(\kappa - 1, \kappa=\lceil \log_2 n \rceil\) is applied, where \(n\) is the number of qubits. See details in [1]

Reference

[1] WANG Z, RUBIN N C, DOMINY J M, et. XY-mixers: analytical and numerical results for QAOA[J/OL].

Physical Review A, 2020, 101(1): 012320. DOI:10.1103/PhysRevA.101.012320.

pyqpanda_alg.QAOA.default_circuits.xy_mixer(domains, mixer_type='PXY')

Generate XY mixer circuit.

Parameters

domains : integer or list[list]

Nodes of each XY mixer to be applied. If an integer n is given, the qubit list is divided into n parts. If a list is given, the mixer is applied to each domain.

mixer_type: string

How the mixer is implemented. Should be one of

  • PXY : Parity partition XY mixer.

    See ‘parity_partition_xy_mixer’

  • CXY : Complete XY mixer

    See ‘complete_xy_mixer’

If not given, default by PXY.

Return

mixer_circuit : func(pq.QCircuit)

A function which use qubit list and angles as input, output a circuit of simulation a XY mixer \(e^{-iHt}\).

Examples

Generate a circuit of simulation a complete XY mixer \(e^{-iH\pi/2}\) in qubits [0, 1] and [2, 3].

>>> import pyqpanda as pq
>>> import numpy as np
>>> from pyqpanda_alg.QAOA import default_circuits
>>> machine = pq.CPUQVM()
>>> machine.initQVM()
>>> qubits = machine.qAlloc_many(4)
>>> circuit1 = pq.QCircuit()
>>> circuit2 = pq.QCircuit()
>>> circuit1 << default_circuits.xy_mixer(2, 'PXY')(qubits, np.pi/2)
>>> circuit2 << default_circuits.xy_mixer([[0,1], [2,3]], 'PXY')(qubits, np.pi/2)
>>> print(circuit1)
>>> print(circuit2)
q_0:  |0>─X
          │
q_1:  |0>─X

q_2:  |0>─X
          │
q_3:  |0>─X


q_0:  |0>─X
          │
q_1:  |0>─X

q_2:  |0>─X
          │
q_3:  |0>─X
Note

A XY mixer can enforce the state evolution in a feasible subspace which keep the hamming weight (total spin) of the state to be conserved.

For example, in one-hot coding problem, a W state as initial state combine with the XY mixer can keep all solutions remain in one-hot form. See details in [1].

Reference

[1] WANG Z, RUBIN N C, DOMINY J M, et. XY-mixers: analytical and numerical results for QAOA[J/OL]. Physical Review A, 2020, 101(1): 012320. DOI:10.1103/PhysRevA.101.012320.

pyqpanda_alg.QAOA.default_circuits.init_d_state(domains, k=1, compress=True)

Prepare Dicke state.

The Dicke state is defined as \(D_{n}^{(k)} = \sum_{hmw(i)=k} |i \rangle\), which is equally superposition state of all states with the same Hamming weight. The method prepare an initial state, which is the product state of Dicke state in each domain, with in \(O(k*log(n/k))\) depth in all-to-all connectivity architecture.

Parameters

domains : integer or list[list]

Nodes of each XY mixer to be applied. If an integer n is given, the qubit list is divided into n parts. If a list is given, the mixer is applied to each domain.

k : integer, \(k>0\)

The target Hamming weight of the Dicke state to be prepared, i.e., the \(k\) of \(D_{n}^{(k)}\).

compress : bool, optional

If True, compress the basic gate implementation with simulated control gates otherwise using basic gate implementation; default is True.

Return

init_state_circuit : function

Return a function, which takes qubit list as input, and output a pyqpanda QCircuit which assumes the input state is all 0.

Raises

ValueError

If the target Hamming weight is larger than the input qubit number (\(k<n\)), or k is invalid (\(k<0\)), or qubit number is 0 (\(n=0\)).

Reference

Bärtschi A, Eidenbenz S. Short-depth circuits for dicke state preparation[C]

2022 IEEE International Conference on Quantum Computing and Engineering (QCE). IEEE, 2022: 87-96. https://doi.org/10.1109/QCE53715.2022.00027

Examples

The given example illustrates how to prepare the state \(D_4^{(2)}\).

>>> import pyqpanda as pq
>>> from pyqpanda_alg.QAOA import default_circuits
>>> n = 6
>>> k = 2
>>> machine = pq.CPUQVM()
>>> machine.initQVM()
>>> qubits = machine.qAlloc_many(n)
>>> prog = pq.QProg()
>>> domain = [[0,1,2],[3,4,5]]
>>> init_circuit = default_circuits.init_d_state(domain, k)
>>> prog << init_circuit(qubits)
>>> print(pq.draw_qprog(prog, output='text'))
>>> results = machine.prob_run_list(prog, qubits)
>>> for key in range(2**n):
>>>     prob = results[key]
>>>     key_hmw = bin(key).count('1')
>>>     if key_hmw == len(domain)*k:
>>>         print(bin(key)[2::].zfill(n), prob)

The corresponding quantum circuit is:

          ┌─┐                   ┌────┐                ┌────┐
q_0:  |0>─┤X├─────────── ────── ┤CNOT├ ───────■────── ┤CNOT├
          ├─┤            ┌────┐ └──┬─┘ ┌──────┴─────┐ └──┬─┘
q_1:  |0>─┤X├─────────── ┤CNOT├ ───■── ┤RY(1.570796)├ ───■──
          ├─┴──────────┐ └──┬─┘        └────────────┘
q_2:  |0>─┤RY(1.910633)├ ───■── ────── ────────────── ──────
          ├─┬──────────┘        ┌────┐                ┌────┐
q_3:  |0>─┤X├─────────── ────── ┤CNOT├ ───────■────── ┤CNOT├
          ├─┤            ┌────┐ └──┬─┘ ┌──────┴─────┐ └──┬─┘
q_4:  |0>─┤X├─────────── ┤CNOT├ ───■── ┤RY(1.570796)├ ───■──
          ├─┴──────────┐ └──┬─┘        └────────────┘
q_5:  |0>─┤RY(1.910633)├ ───■── ────── ────────────── ──────
          └────────────┘

And the probability of all possible state are (with possible floating errors):

011011 0.1111111111111111
011101 0.11111111111111113
011110 0.11111111111111113
101011 0.11111111111111113
101101 0.11111111111111113
101110 0.11111111111111113
110011 0.11111111111111113
110101 0.11111111111111113
110110 0.11111111111111113

which represents the state \(\ket{D_3^2}_{012}\otimes\ket{D_3^2}_{345}\).

pyqpanda_alg.QAOA.default_circuits.prepare_dicke_state(q_list, k, compress=True)

Prepare Dicke state.

The Dicke state is defined as \(D_{n}^{(k)} = \sum_{hmw(i)=k} |i\rangle\) , which is equally superposition state of all states with the same Hamming weight. The method prepare Dicke state with in \(O(k*log(n/k))\) depth in all-to-all connectivity architecture.

Parameters

q_list : QVec, List[Qubit], shape (n,)

Qubit addresses. List size is supposed to be the \(n\) of \(D_{n}^{(k)}\).

k : integer, k>0

The target Hamming weight of the Dicke state to be prepared, i.e., the \(k\) of \(D_{n}^{(k)}\).

compress : bool, optional

If True, compress the basic gate implementation with simulated control gates otherwise using basic gate implementation; default is True.

Return

circuit : pyqpanda QCircuit

A pyqpanda QCircuit which assumes the input state is all 0.

Raises

ValueError

If the target Hamming weight is larger than the input qubit number (\(k<n\)), or k is invalid (\(k<0\)), or qubit number is 0 (\(n=0\)).

Reference

Bärtschi A, Eidenbenz S. Short-depth circuits for dicke state preparation[C] 2022 IEEE International Conference on Quantum Computing and Engineering (QCE). IEEE, 2022: 87-96. https://doi.org/10.1109/QCE53715.2022.00027

Examples

The given example illustrates how to prepare the state \(D_4^{(2)}\).

>>> import pyqpanda as pq
>>> from pyqpanda_alg.QAOA import default_circuits
>>> n = 4
>>> k = 2
>>> machine = pq.CPUQVM()
>>> machine.initQVM()
>>> qubits = machine.qAlloc_many(n)
>>> prog = pq.QProg()
>>> prog << default_circuits.prepare_dicke_state(qubits, k)
>>> print(pq.draw_qprog(prog, output='text'))
>>> results = machine.prob_run_list(prog, qubits)
>>> for key in range(2**n):
>>>     prob = results[key]
>>>     key_hmw = bin(key).count('1')
>>>     if key_hmw == k:
>>>         print(bin(key)[2::].zfill(n), prob)

The corresponding quantum circuit is:

          ┌─┐     !                               ┌────┐         ! ┌────┐                ┌────┐
q_0:  |0>─┤X├ ────! ────────────── ────────────── ┤CNOT├──── ────! ┤CNOT├ ───────■────── ┤CNOT├
          ├─┤     !                               └──┬┬┴───┐     ! └──┬─┘ ┌──────┴─────┐ └──┬─┘
q_1:  |0>─┤X├ ────! ────────────── ────────────── ───┼┤CNOT├ ────! ───■── ┤RY(1.570796)├ ───■──
          └─┘     ! ┌────────────┐                   │└──┬─┘     ! ┌────┐ └────────────┘ ┌────┐
q_2:  |0>──── ────! ┤RY(2.300524)├ ───────■────── ───┼───■── ────! ┤CNOT├ ───────■────── ┤CNOT├
                  ! └────────────┘ ┌──────┴─────┐    │           ! └──┬─┘ ┌──────┴─────┐ └──┬─┘
q_3:  |0>──── ────! ────────────── ┤RY(0.927295)├ ───■────── ────! ───■── ┤RY(1.570796)├ ───■──
                  !                └────────────┘                !        └────────────┘

And the probability of all possible state are (with possible floating errors):

0011 0.16666666666666663
0101 0.1666666666666667
0110 0.1666666666666667
1001 0.1666666666666667
1010 0.1666666666666667
1100 0.16666666666666663

which include all states with the same Hamming weight \(k=2\).

pyqpanda_alg.QAOA.default_circuits.linear_w_state(q_list, compress=True)

Prepare W state with a divide-and-conquer algorithm on the linear architecture device.

W state is the special Dicke state where \(k=1\). The special case is compatible to Dicke state preparation while it can be formalized on a linear connectivity device with exactly \(n-1\) depth and \(3n-3\) CNOT gates.

Parameters

q_list : QVec, List[Qubit], shape (n,)

Qubit addresses. List size is supposed to be the \(n\) of \(D_{n}^{(1)}\).

compress : bool, optional

If True, compress the basic gate implementation with simulated control gates otherwise using basic gate implementation; default is True.

Return

circuit : pyqpanda QCircuit

A pyqpanda QCircuit which assumes the input state is all 0.

Raises

ValueError

If the input qubit number is zero.

Reference

Cruz D, Fournier R, Gremion F, et al. Efficient quantum algorithms for ghz and w states, and implementation on the IBM quantum computer[J]. Advanced Quantum Technologies, 2019, 2(5-6): 1900015.

Example
import pyqpanda as pq
from pyqpanda_alg.QAOA import default_circuits

n = 3
machine = pq.CPUQVM()
machine.initQVM()
qubits = machine.qAlloc_many(n)
prog = pq.QProg()
prog << default_circuits.linear_w_state(qubits, compress=True)
print(pq.draw_qprog(prog, output='text'))
results = machine.prob_run_list(prog, qubits)
for key in range(2 ** n):
    prob = results[key]
    key_hmw = bin(key).count('1')
    if key_hmw == 1:
        print(bin(key)[2::].zfill(n), prob)

The example prepare W state on a 3-qubit system which is linearly connected. The corresponding circuit reads as:

          ┌─┐                ┌────┐
q_0:  |0>─┤X├ ───────■────── ┤CNOT├ ────────────── ──────
          └─┘ ┌──────┴─────┐ └──┬─┘                ┌────┐
q_1:  |0>──── ┤RY(1.910633)├ ───■── ───────■────── ┤CNOT├
              └────────────┘        ┌──────┴─────┐ └──┬─┘
q_2:  |0>──── ────────────── ────── ┤RY(1.570796)├ ───■──
                                    └────────────┘

The resulting state should be like (with possible floating errors):

001 0.3333333333333333
010 0.3333333333333334
100 0.3333333333333334

Each of them is one-Hamming-weight.