Expectation Estimation Task#

Basic Concepts#

Computing Target - Expectation of Observable#

In quantum computing, we often need to estimate the expectation value of an observable (usually a Hermitian operator) in a certain quantum state. The mathematical form of expectation value is:

\[ \langle O \rangle = \langle \psi | O | \psi \rangle \]

Where:

  • \(|\psi\rangle\) is the quantum state

  • \(O\) is the Hermitian operator

Necessary Input for Computation - Quantum Circuit#

The quantum state in the expectation formula is often obtained by evolving the initial state \(|\mathbf{0}\rangle\) through a quantum circuit \(U\)

\[ |\psi\rangle = U|\mathbf{0}\rangle \]

Necessary Input for Computation - Observable#

Observable \(O\) is a Hermitian operator, and any \(n\)-qubit Hermitian operator can be decomposed into a linear combination of Pauli basis:

\[ O = \sum_{p \in \{0,1,2,3\}^n} c_{p} P_{p} \]

Where:

  • \(p = (p_1, \ldots, p_n)\), \(p_i \in \{0,1,2,3\}\) corresponds to \(\{I,X,Y,Z\}\)

  • \(P_{p} = \sigma_{p_1} \otimes \sigma_{p_2} \otimes \cdots \otimes \sigma_{p_n}\)

  • \(c_{p} \in \mathbb{R}\)

A Simple Example#

Step 1> Login#

# python code

from qpanda3_runtime import RuntimeService
from pyqpanda3.core import *

service = RuntimeService()
service.login('your_valid_api_key')

Step 2> Define the quantum circuit for expectation estimation#

  • Note: The circuit should not carry measurement nodes, and the qubits in the circuit should be consistent with the qubits in the observable

# python code
# Continue from the previous example on this page
prog = QProg()
prog << X(0)<<CNOT(0,1)

Step 3> Define the observable for expectation estimation#

# python code
# Continue from the previous example on this page
from pyqpanda3.hamiltonian import Hamiltonian
ham = Hamiltonian([('XZ', [0, 1], 3.14),('XZ', [0, 1], 1.14), ('ZY', [0, 1], 5.14)])

Step 4> Select the device to execute the task#

# python code
# Continue from the previous example on this page
dev=service.device('WK_C180') # Here we use the quantum computing chip with id WK_C180

Step 5> Submit the task to the computing backend#

# python code
# Continue from the previous example on this page
task = service.estimate(
    (prog,ham),
    dev,
)

Step 6> Query the task execution result#

# python code
# Continue from the previous example on this page
res = task.get_result_sync()
print(f'res:{res}')

Complete Example Code#

# python code

from qpanda3_runtime import RuntimeService
from pyqpanda3.core import *
from pyqpanda3.hamiltonian import Hamiltonian

service = RuntimeService()
service.login('your_valid_api_key')
prog = QProg()
prog << X(0)<<CNOT(0,1)
ham = Hamiltonian([('XZ', [0, 1], 3.14),('XZ', [0, 1], 1.14), ('ZY', [0, 1], 5.14)])
dev=service.device('WK_C180') # Here we use the quantum computing chip with id WK_C180
task = service.estimate(
    (prog,ham),
    dev,
)
res = task.get_result_sync()
print(f'res:{res}')

Single Quantum Circuit Computing Task Example#

# python code

from qpanda3_runtime import RuntimeService
from pyqpanda3.core import *
from pyqpanda3.hamiltonian import Hamiltonian

service = RuntimeService()
service.login('your_valid_api_key')
prog = QProg()
prog << X(0)<<CNOT(0,1)
ham = Hamiltonian([('XZ', [0, 1], 3.14),('XZ', [0, 1], 1.14), ('ZY', [0, 1], 5.14)])
dev=service.device('72') # Here we use the quantum computing chip with id 72
task = service.estimate(
    (prog,ham),
    dev,
)
res = task.get_result_sync()
print(f'res:{res}')

ProgramSet for Quantum Multi-Objective Decision-Making#

Quantum Multi-Objective Decision-Making

  • For more detailed information, please refer to ProgramSet

Example: n circuits + 1 observable#

# python code

from qpanda3_runtime import RuntimeService
from pyqpanda3.core import *
from pyqpanda3.hamiltonian import Hamiltonian

service = RuntimeService()
service.login('your_valid_api_key')
prog = QProg()
prog << X(0)<<CNOT(0,1)
prog2 = QProg()
prog2 << Y(1)<<CZ(1,0)
prog3 = QProg()
prog3 << Z(0)<<SWAP(0,1)
ham = Hamiltonian([('XZ', [0, 1], 3.14),('XZ', [0, 1], 1.14), ('ZY', [0, 1], 5.14)])
dev=service.device('72') # Here we use the quantum computing chip with id 72
task = service.estimate(
    ([prog,prog2,prog3],ham),
    dev,
)
res = task.get_result_sync()
print(f'res:{res}')

Example: n circuits + m observables#

# python code

from qpanda3_runtime import RuntimeService
from pyqpanda3.core import *
from pyqpanda3.hamiltonian import Hamiltonian
from qpanda3_runtime import CircuitObservableBinding

service = RuntimeService()
service.login('your_valid_api_key')
prog = QProg()
prog << X(0)<<CNOT(0,1)
prog2 = QProg()
prog2 << Y(1)<<CZ(1,0)
prog3 = QProg()
prog3 << Z(0)<<SWAP(0,1)
ham = Hamiltonian([('XZ', [0, 1], 3.14),('XZ', [0, 1], 1.14), ('ZY', [0, 1], 5.14)])
ham2 = Hamiltonian([('XZ', [0, 1], 1)])
ham3 = Hamiltonian([('ZY', [0, 1], 1)])
progs = [prog,prog2,prog3]
hams = [ham,ham2,ham3]
cir_obs = CircuitObservableBinding(progs,hams)
cir_obs.product([0,1,2],[0])
cir_obs.zip([2,1],[1,2])
dev=service.device('72') # Here we use the quantum computing chip with id 72
task = service.estimate(
    cir_obs,
    dev,
)
res = task.get_result_sync()
print(f'res:{res}')

Ways to Pass Quantum Circuits#

Supports passing quantum circuits as QProg/QCircuit/OriginIR

  • In the example code below, we define and submit an expectation estimation task with three circuits

  • The initial forms of the three quantum circuits are QProg object, QCircuit object, and OriginIR string respectively (This usage is not common, it’s only to demonstrate the related functionality)

  • Special attention needed:

    • In expectation estimation tasks, the qubits in the quantum circuit should be consistent with the qubits in the observable

    • The quantum circuit passed to the expectation estimation interface should not carry measurement nodes

# python code

from qpanda3_runtime import RuntimeService
from pyqpanda3.core import *
from pyqpanda3.hamiltonian import Hamiltonian

service = RuntimeService()
service.login('your_valid_api_key')
prog = QProg()
prog << X(0)<<CNOT(0,1)
cir = QCircuit()
cir << Y(1)<<CZ(1,0)
ir_str = '''
QINIT 2
CREG 1
Z q[0]
SWAP q[0],q[1]
'''
ham = Hamiltonian([('XZ', [0, 1], 3.14),('XZ', [0, 1], 1.14), ('ZY', [0, 1], 5.14)])
dev=service.device('72') # Here we use the quantum computing chip with id 72
task = service.estimate(
    ([prog,cir,ir_str],ham),
    dev,
)
res = task.get_result_sync()
print(f'res:{res}')

Ways to Pass Observables#

Supports passing observables as Hamiltonian/Pauli Operator/Hamiltonian string in the format supported by Origin Quantum Cloud

  • An example of the Hamiltonian string representation format supported by Origin Quantum Cloud is as follows:

    "": -1.0534210769165204,"Z0": 0.394844363355904,"Z1": -0.39484436335590417,"Z0 Z1": -0.01124615715082114,
    
  • In the example code below, three expectation estimation tasks are executed, with observables passed as Hamiltonian/Pauli Operator/Hamiltonian string in the format supported by Origin Quantum Cloud

# python code

from qpanda3_runtime import RuntimeService
from pyqpanda3.core import *
from pyqpanda3.hamiltonian import Hamiltonian,PauliOperator

service = RuntimeService()
service.login('your_valid_api_key')
prog = QProg()
prog << X(0)<<CNOT(0,1)
ham = Hamiltonian([('XZ', [0, 1], 3.14),('XZ', [0, 1], 1.14), ('ZY', [0, 1], 5.14)])
pauliop = PauliOperator([('XZ', [0, 1], 3.14),('XZ', [0, 1], 1.14), ('ZY', [0, 1], 5.14)])
ham_str = '''
"": -1.0534210769165204,
"Z0": 0.394844363355904,
"Z1": -0.39484436335590417,
"Z0 Z1": -0.01124615715082114,
'''
hams = [ham,pauliop,ham_str]
dev=service.device('WK_C180') # Here we use the quantum computing chip with id WK_C180

for o in hams:
  task = service.estimate(
      (prog,o),
      dev,
  )
  res = task.get_result_sync()
  print(f'res:{res}')

Expectation Estimation Using FakeBackend#

For detailed information, please refer to FakeBackend

Step 1> Login#

# python code

from qpanda3_runtime import RuntimeService
from pyqpanda3.core import *

service = RuntimeService()
service.login('your_valid_api_key')

Step 2> Define the quantum circuit for expectation estimation#

# python code
# Continue from the previous example on this page
prog = QProg()
prog << X(0)<<CNOT(0,1)

Step 3> Define the observable for expectation estimation#

# python code
# Continue from the previous example on this page
from pyqpanda3.hamiltonian import Hamiltonian
ham = Hamiltonian([('XZ', [0, 1], 3.14),('XZ', [0, 1], 1.14), ('ZY', [0, 1], 5.14)])

Step 4> Select the device to execute the task#

In the example code below, dev is a limited simulation of the real quantum computing chip with id WK_C180, including:

  • Has the same qubit topology structure

  • Uses limited noise simulation with noise data (T1, T2, readout errors, etc.) from real quantum chip device specifications

# python code
# Continue from the previous example on this page
dev=service.device('WK_C180').fake_backend() # Here we use the Fake Backend corresponding to the quantum computing chip with id WK_C180

Step 5> Submit the task to Fake Backend#

  • When the backend device is Fake Backend, RuntimeService.sample must run in the __name__ == '__main__' environment

  • The sampling calculation of Fake Backend is computed locally on the client

# python code
# Continue from the previous example on this page
task = service.estimate(
    (prog,ham),
    dev,
)

Step 6> Query the task execution result#

# python code
# Continue from the previous example on this page
res = task.get_result_sync()
print(f'res:{res}')

Step 7> Run On QPU#

If needed Submit the computing task data verified through Fake Backend to the corresponding real device for execution

# python code
# Continue from the previous example on this page
task2 = task.run_on_real_device(shots=1000)
res2 = task2.get_result_sync()
print(f'res2:',res2)

Complete Example Code#

# python code

from qpanda3_runtime import RuntimeService
from pyqpanda3.core import *
from pyqpanda3.hamiltonian import Hamiltonian

def est():
    service = RuntimeService()
    service.login('your_valid_api_key')
    prog = QProg()
    prog << X(0)<<CNOT(0,1)

    ham = Hamiltonian([('XZ', [0, 1], 3.14),('XZ', [0, 1], 1.14), ('ZY', [0, 1], 5.14)])
    dev=service.device('WK_C180').fake_backend() # Here we use the Fake Backend corresponding to the quantum computing chip with id WK_C180
    task = service.estimate(
        (prog,ham),
        dev,
    )
    res = task.get_result_sync()
    print(f'res:{res}')
    task2 = task.run_on_real_device(shots=1000)
    res2 = task2.get_result_sync()
    print(f'res2:',res2)

if __name__ == '__main__':
    est()