QPanda3
Supported by OriginQ
Loading...
Searching...
No Matches
v0.2.0

New features and important updates

  • Optimized the CPU measurement algorithm, involving CPUQVM and GPUQVM.

Performance improvements were made for large-qubit measurement processes (when the measurement node is at the end), resulting in a significant reduction in execution time.

A very obvious example,It can be concluded that there has been a significant improvement in operating speed

from pyqpanda3.core import QProg,H,CNOT,measure,CPUQVM
prog = QProg()
prog << H(0)
for i in range(21):
prog << CNOT(i, i + 1)
for i in range(22):
prog << measure(i, i)
machine = CPUQVM()
machine.run(prog, 10000)
measure_result = machine.result().get_counts()
print(measure_result)
Definition __init__.py:1

Output is as follows.

{'0000000000000000000000': 4957, '1111111111111111111111': 5043}
  • Quantum cloud computing service:

For tasks targeting real quantum chips, users can choose to transmit quantum programs in binary stream format when submitting tasks, offering faster communication efficiency compared to the original approach. The existing run interface has been updated with additional parameters, while all other usage remains unchanged from the previous version.

import time
from pyqpanda3.core import QProg,H,CNOT,measure
from pyqpanda3.qcloud import QCloudService,QCloudOptions,JobStatus
prog = QProg()
prog << H(0)
prog << CNOT(0, 1)
prog.append(measure(0,0))
api_key = "302e020030100602a8648ce3020160528100050204615ad5e";
service = QCloudService(api_key)
backend = service.backend("72")
options = QCloudOptions()
job = backend.run(prog, 1000, options, True)
while True:
status = job.status()
if status == JobStatus.FINISHED:
break
print(job.job_id()," wait for finished.")
time.sleep(2)
result = job.result()
print(result.get_probs())
Definition __init__.py:1

Output is as follows.

{'0': 0.55, '1': 0.45}
  • The quantum cloud cluster tasks have been standardized and adjusted for both partial amplitude and single amplitude interfaces.

The task submission interfaces for cluster partial amplitude and single amplitude have slight differences in parameters: besides QProg, they correspond to an amplitude array and a single amplitude value, respectively. The query interface is completely identical, both using QCloudResult.get_amplitudes, which returns an array.

from pyqpanda3.core import QProg,H,CNOT,RX,RY
from pyqpanda3.qcloud import QCloudService
prog = QProg(6)
prog << H(0)
prog << CNOT(1, 2)
prog << RY(0, 0.34)
prog << RX(1, 0.98)
api_key = "302e020100301006094453a3c8a/6327";
service = QCloudService(api_key)
service.setup_logging()
single_amplitude_backend = service.backend("single_amplitude")
single_amplitude_job = single_amplitude_backend.run(prog, "0")
print(single_amplitude_job.result().get_amplitudes())
partial_amplitude_backend = service.backend("partial_amplitude")
partial_amplitude_job = partial_amplitude_backend.run(prog, ["0","1","2"])
print(partial_amplitude_job.result().get_amplitudes())

The output is as follows.

{'0': (0.5093563616148238+0j)}
{'0': (0.5093563616148238+0j), '1': (0.7204633002944995+0j), '2': (0.5093563616148238+0j)}

Note that cluster tasks support asynchronous operations but do not support submitting multiple circuits in batch mode.

  • Noise simulation has been added to the GPU virtual machine.

Like the CPUQVM virtual machine, it supports the following noise models, and the interface usage remains completely identical.The supported noise errors are as follows.

def pauli_x_error(prob: float) -> QuantumError
def pauli_y_error(prob: float) -> QuantumError
def pauli_z_error(prob: float) -> QuantumError
def phase_damping_error(prob: float) -> QuantumError
def amplitude_damping_error(prob: float) -> QuantumError
def decoherence_error(arg0: float, arg1: float, arg2: float) -> QuantumError
def depolarizing_error(prob: float) -> QuantumError

The example program is as follows.

from pyqpanda3.core import QCircuit,QProg,H,RX,RY,CNOT,measure,GateType
from pyqpanda3.core import GPUQVM,NoiseModel,pauli_x_error
circuit = QCircuit(3)
circuit << H(0)
circuit << RY(1, 0.3)
circuit << RY(2, 2.7)
circuit << RX(0, 1.5)
circuit << CNOT(0, 1)
circuit << CNOT(1, 2)
prog = QProg()
prog.append(circuit)
prog.append(measure(0, 0))
prog.append(measure(1, 1))
prog.append(measure(2, 2))
model = NoiseModel()
model.add_all_qubit_quantum_error(pauli_x_error(0.5),GateType.RX)
model.add_all_qubit_quantum_error(pauli_x_error(0.9),GateType.H)
machine = GPUQVM()
machine.run(prog, 1000, model)
measure_result = machine.result().get_counts()
print(measure_result)

Output is :

{'011': 466, '001': 3, '100': 468, '111': 22, '000': 17, '101': 13, '010': 11}
  • The related interface for expectation value calculation has been changed.

(1) Use CPUQVM to calculate the expectation value of a quantum circuit on a quantum system with a specified Hamiltonian. (pyqpanda3.core)

old interface

API doc of pyqpanda3.core.CPUQVM.expval_hamiltonian

# old interface
# note: This old interface is still retained in this version but will be deprecated in the future.
expval_hamiltonian(self: core.CPUQVM, prog: core.QProg, hamiltonian: QPanda3::Hamiltonian, shots: int = 1000, noise_model: core.NoiseModel = <core.NoiseModel object at 0x000002548518BB30>)

new interface

API doc of pyqpanda3.core.expval_hamiltonian

# new interface
# If you want to use CPUQVM to calculate the expectation value, the parameter backend needs to be passed with the argument 'CPU'.
expval_hamiltonian(node: core.QProg, hamiltonian: QPanda3::Hamiltonian, shots: int = 1, model: core.NoiseModel = <core.NoiseModel object at 0x0000026A734CB370>, used_threads: int = 4, backend: str = \'CPU\')

The example program is as follows.

from pyqpanda3.core import CPUQVM, QProg, S, BARRIER,expval_hamiltonian
from pyqpanda3.hamiltonian import Hamiltonian
def test_expectation2():
# Prepare the quantum simulator
qvm = CPUQVM()
# Prepare quantum program
prog = QProg()
prog << S(0)
prog << BARRIER([0, 1, 2])
"""The qubits used in qprog should be consistent with the qubits in the Pauli operator. The simulator determines the qubits that should be included in the quantum system based on the qbits in QProg, which are three quantum #bits in this case"""
# Prepare the Pauli operator
Ham = Hamiltonian({"X0 Z1": 2, "X1 Y2": 3})
print("without I:\n", Ham)
# Calculate Expectation
try:
# Calculate Expectation
res = qvm.expval_hamiltonian(prog, Ham) #old interface,will be deprecated in the future.
print("res:", res)
res2 = expval_hamiltonian(prog,Ham,backend='CPU') # new interface
print('res2:',res2)
except Exception as e:
print(e)
if __name__ == "__main__":
test_expectation2()
Definition __init__.py:1

Output is :

without I:
{ qbit_total = 3, pauli_with_coef_s = { 'X0 Z1 ':2 + 0j, 'X1 Y2 ':3 + 0j, } }
res: 0.0
res2: 0.0
Warrning! This interface will be deprecated in the future. Please use the new interface expval_hamiltonian (a global interface exported by pyqpanda3.core).

(2) Use GPUQVM to calculate the expectation value of a quantum circuit on a quantum system with a specified Hamiltonian. (pyqpanda3.core)

new interface

API doc of pyqpanda3.core.expval_hamiltonian

# new interface
# If you want to use GPUQVM to calculate the expectation value, the parameter backend needs to be passed with the argument 'GPU'.
expval_hamiltonian(node: core.QProg, hamiltonian: QPanda3::Hamiltonian, shots: int = 1, model: core.NoiseModel = <core.NoiseModel object at 0x0000026A734CB370>, used_threads: int = 4, backend: str = \'CPU\')

The example program is as follows.

from pyqpanda3.core import QProg, S, BARRIER,expval_hamiltonian
from pyqpanda3.hamiltonian import Hamiltonian
def test_expectation2():
# Prepare quantum program
prog = QProg()
prog << S(0)
prog << BARRIER([0, 1, 2])
"""The qubits used in qprog should be consistent with the qubits in the Pauli operator. The simulator determines the qubits that should be included in the quantum system based on the qbits in QProg, which are three quantum #bits in this case"""
# Prepare the Pauli operator
Ham = Hamiltonian({"X0 Z1": 2, "X1 Y2": 3})
print("without I:\n", Ham)
# Calculate Expectation
try:
# Calculate Expectation
res2 = expval_hamiltonian(prog,Ham,backend='GPU') # new interface
print('res2:',res2)
except Exception as e:
print(e)
if __name__ == "__main__":
test_expectation2()

Output is :

without I:
{ qbit_total = 3, pauli_with_coef_s = { 'X0 Z1 ':2 + 0j, 'X1 Y2 ':3 + 0j, } }
res2: 0.0

(3) Use CPUQVM to calculate the expectation value of a quantum circuit on a quantum system with a specified Hamiltonian. (pyqpanda3.vqcircuit)

old interface

# old interface (CPUQVM, batch processing mode, deprecated)
expval_hamiltonian(self: pyqpanda3.vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, exp_type: pyqpanda3.vqcircuit.ExpectationType = <ExpectationType.THEORETICAL: 0>)
# old interface(CPUQVM, non-batch processing mode, deprecated)
expval_hamiltonian(self: pyqpanda3.vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, idx_s: list[int], exp_type: pyqpanda3.vqcircuit.ExpectationType = <ExpectationType.THEORETICAL: 0>)
Definition vqcircuit.pyi:7

new interface

API doc of pyqpanda3.vqcircuit.VQCResult.expval_hamiltonian

# new interface (batch processing mode, with NoiseModel)
# If you want to use GPUQVM to calculate the expectation value, the parameter backend needs to be passed with the argument 'CPU'.
expval_hamiltonian(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, shots: int = 1000, model: QPanda3::NoiseModel, used_threads: int = 4, backend: str = 'CPU')
# new interface (batch processing mode, without NoiseModel)
# If you want to use GPUQVM to calculate the expectation value, the parameter backend needs to be passed with the argument 'CPU'.
expval_hamiltonian(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, used_threads: int = 4, backend: str = 'CPU')
# new interface (no-batch processing mode, with NoiseModel)
# If you want to use GPUQVM to calculate the expectation value, the parameter backend needs to be passed with the argument 'CPU'.
expval_hamiltonian(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, idx_s: list[int], shots: int = 1000, model: QPanda3::NoiseModel, used_threads: int = 4, backend: str = 'CPU')
# new interface (no-batch processing mode, without NoiseModel)
# If you want to use GPUQVM to calculate the expectation value, the parameter backend needs to be passed with the argument 'CPU'.
expval_hamiltonian(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, idx_s: list[int], used_threads: int = 4, backend: str = 'CPU')

(4) Use GPUQVM to calculate the expectation value of a quantum circuit on a quantum system with a specified Hamiltonian. (pyqpanda3.vqcircuit)

new interface

API doc of pyqpanda3.vqcircuit.VQCResult.expval_hamiltonian

# new interface (batch processing mode, with NoiseModel)
# If you want to use GPUQVM to calculate the expectation value, the parameter backend needs to be passed with the argument 'GPU'.
expval_hamiltonian(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, shots: int = 1000, model: QPanda3::NoiseModel, used_threads: int = 4, backend: str = 'CPU')
# new interface (batch processing mode, without NoiseModel)
# If you want to use GPUQVM to calculate the expectation value, the parameter backend needs to be passed with the argument 'GPU'.
expval_hamiltonian(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, used_threads: int = 4, backend: str = 'CPU')
# new interface (no-batch processing mode, with NoiseModel)
# If you want to use GPUQVM to calculate the expectation value, the parameter backend needs to be passed with the argument 'GPU'.
expval_hamiltonian(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, idx_s: list[int], shots: int = 1000, model: QPanda3::NoiseModel, used_threads: int = 4, backend: str = 'CPU')
# new interface (no-batch processing mode, without NoiseModel)
# If you want to use GPUQVM to calculate the expectation value, the parameter backend needs to be passed with the argument 'GPU'.
expval_hamiltonian(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, idx_s: list[int], used_threads: int = 4, backend: str = 'CPU')

(5) Use CPUQVM to calculate the expectation value of a quantum circuit on a quantum system with a specified PauliOperator object. (pyqpanda3.core)

old interface

API doc of pyqpanda3.CPUQVM.expval_pauli_operator

# old interface
# note: This old interface is still retained in this version but will be deprecated in the future.
expval_pauli_operator(self: pyqpanda3.core.CPUQVM, prog: pyqpanda3.core.QProg, pauli_operator: QPanda3::PauliOperator, shots: int = 1000, noise_model: pyqpanda3.core.NoiseModel = <pyqpanda3.core.NoiseModel object at 0x000001DCCEEE5E30>)
Definition core.pyi:24
Definition core.pyi:2015
Definition core.pyi:2678

new interface

API doc of pyqpanda3.core.expval_pauli_operator

# new interface
# If you want to use CPUQVM to calculate the expectation value, the parameter backend needs to be passed with the argument 'CPU'.
expval_pauli_operator(node: core.QProg, pauli_operator: QPanda3::PauliOperator, shots: int = 1, model: core.NoiseModel = <core.NoiseModel object at 0x0000026A734CB5B0>, used_threads: int = 4, backend: str = \'CPU\')

The example program is as follows.

from pyqpanda3.core import CPUQVM, QProg, S, BARRIER,expval_pauli_operator
from pyqpanda3.hamiltonian import PauliOperator
def test_expectation2():
# Prepare the quantum simulator
qvm = CPUQVM()
# Prepare quantum program
prog = QProg()
prog << S(0)
prog << BARRIER([0, 1, 2])
"""The qubits used in qprog should be consistent with the qubits in the Pauli operator. The simulator determines the qubits that should be included in the quantum system based on the qbits in QProg, which are three quantum #bits in this case"""
# Prepare the Pauli operator
op = PauliOperator({"X0 Z1": 2, "X1 Y2": 3})
print("without I:\n", op)
# Calculate Expectation
try:
# Calculate Expectation
res = qvm.expval_pauli_operator(prog, op) #old interface,will be deprecated in the future.
print("res:", res)
res2 = expval_pauli_operator(prog,op,backend='CPU') # new interface
print('res2:',res2)
except Exception as e:
print(e)
if __name__ == "__main__":
test_expectation2()

Output is :

without I:
{ qbit_total = 3, pauli_with_coef_s = { 'X0 Z1 ':2 + 0j, 'X1 Y2 ':3 + 0j, } }
res: 0.0
res2: 0.0
Warrning! This interface will be deprecated in the future. Please use the new interface expval_pauli_operator (a global interface exported by pyqpanda3.core).

(6) Use GPUQVM to calculate the expectation value of a quantum circuit on a quantum system with a specified PauliOperator object. (pyqpanda3.core)

new interface

API doc of pyqpanda3.core.expval_pauli_operator

# new interface
# If you want to use GPUQVM to calculate the expectation value, the parameter backend needs to be passed with the argument 'GPU'.
expval_pauli_operator(node: core.QProg, pauli_operator: QPanda3::PauliOperator, shots: int = 1, model: core.NoiseModel = <core.NoiseModel object at 0x0000026A734CB5B0>, used_threads: int = 4, backend: str = \'CPU\')

The example program is as follows.

from pyqpanda3.core import QProg, S, BARRIER,expval_pauli_operator
from pyqpanda3.hamiltonian import PauliOperator
def test_expectation2():
# Prepare quantum program
prog = QProg()
prog << S(0)
prog << BARRIER([0, 1, 2])
"""The qubits used in qprog should be consistent with the qubits in the Pauli operator. The simulator determines the qubits that should be included in the quantum system based on the qbits in QProg, which are three quantum #bits in this case"""
# Prepare the Pauli operator
op = PauliOperator({"X0 Z1": 2, "X1 Y2": 3})
print("without I:\n", op)
# Calculate Expectation
try:
# Calculate Expectation
res2 = expval_pauli_operator(prog,op,backend='GPU') # new interface
print('res2:',res2)
except Exception as e:
print(e)
if __name__ == "__main__":
test_expectation2()

Output is :

without I:
{ qbit_total = 3, pauli_with_coef_s = { 'X0 Z1 ':2 + 0j, 'X1 Y2 ':3 + 0j, } }
res2: 0.0

(7) Use CPUQVM to calculate the expectation value of a quantum circuit on a quantum system with a specified PauliOperator object. (pyqpanda3.vqcircuit)

old interface

# old interface (CPUQVM, batch processing mode, deprecated)
expval_pauli_operator(self: pyqpanda3.vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, exp_type: pyqpanda3.vqcircuit.ExpectationType = <ExpectationType.THEORETICAL: 0>)
# old interface(CPUQVM, non-batch processing mode, deprecated)
expval_pauli_operator(self: pyqpanda3.vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, idx_s: list[int], exp_type: pyqpanda3.vqcircuit.ExpectationType = <ExpectationType.THEORETICAL: 0>)

new interface

API doc of pyqpanda3.vqcircuit.VQCResult.expval_pauli_operator

# new interface (batch processing mode, with NoiseModel)
# If you want to use GPUQVM to calculate the expectation value, the parameter backend needs to be passed with the argument 'CPU'.
expval_pauli_operator(self: vqcircuit.VQCResult, pauli_operator: QPanda3::PauliOperator, shots: int = 1000, model: QPanda3::NoiseModel, used_threads: int = 4, backend: str = 'CPU')
# new interface (batch processing mode, without NoiseModel)
# If you want to use GPUQVM to calculate the expectation value, the parameter backend needs to be passed with the argument 'CPU'.
expval_pauli_operator(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, used_threads: int = 4, backend: str = 'CPU')
# new interface (no-batch processing mode, with NoiseModel)
# If you want to use GPUQVM to calculate the expectation value, the parameter backend needs to be passed with the argument 'CPU'.
expval_pauli_operator(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, idx_s: list[int], shots: int = 1000, model: QPanda3::NoiseModel, used_threads: int = 4, backend: str = 'CPU')
# new interface (no-batch processing mode, without NoiseModel)
# If you want to use GPUQVM to calculate the expectation value, the parameter backend needs to be passed with the argument 'CPU'.
expval_pauli_operator(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, idx_s: list[int], used_threads: int = 4, backend: str = 'CPU')

(8) Use GPUQVM to calculate the expectation value of a quantum circuit on a quantum system with a specified PauliOperator object. (pyqpanda3.vqcircuit)

API doc of pyqpanda3.vqcircuit.VQCResult.expval_pauli_operator

new interface

# new interface (batch processing mode, with NoiseModel)
# If you want to use GPUQVM to calculate the expectation value, the parameter backend needs to be passed with the argument 'GPU'.
expval_pauli_operator(self: vqcircuit.VQCResult, pauli_operator: QPanda3::PauliOperator, shots: int = 1000, model: QPanda3::NoiseModel, used_threads: int = 4, backend: str = 'CPU')
# new interface (batch processing mode, without NoiseModel)
# If you want to use GPUQVM to calculate the expectation value, the parameter backend needs to be passed with the argument 'GPU'.
expval_pauli_operator(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, used_threads: int = 4, backend: str = 'CPU')
# new interface (no-batch processing mode, with NoiseModel)
# If you want to use GPUQVM to calculate the expectation value, the parameter backend needs to be passed with the argument 'GPU'.
expval_pauli_operator(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, idx_s: list[int], shots: int = 1000, model: QPanda3::NoiseModel, used_threads: int = 4, backend: str = 'CPU')
# new interface (no-batch processing mode, without NoiseModel)
# If you want to use GPUQVM to calculate the expectation value, the parameter backend needs to be passed with the argument 'GPU'.
expval_pauli_operator(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, idx_s: list[int], used_threads: int = 4, backend: str = 'CPU')
  • The Compilation Module Adds Support for Oracle Gates

The Transpiler and decompose under the compilation module both support the handling of Oracle gates.

Example code is as follows:

from pyqpanda3.core import QProg, CNOT, Oracle
from pyqpanda3.transpilation import Transpiler, decompose
prog = QProg()
matrix = CNOT(0, 1).matrix()
prog << Oracle([0, 1], matrix)
t = Transpiler()
prog2 = t.transpile(prog, [], {}, 2, ['RX', 'RY', 'RZ', 'CNOT'])
prog3 = decompose(prog, ['RX', 'RY', 'RZ', 'CNOT'])
print(prog2)
print(prog3)
Definition __init__.py:1
  • Quantum Circuit Compilation and Decomposition Can Be Decomposed into Specified Gate Sets

The Transpiler and decompose under the compilation module both support decomposition into specified basic gate sets.

Example code is as follows:

from pyqpanda3.core import QProg, random_qcircuit
from pyqpanda3.transpilation import Transpiler, decompose
prog = QProg()
prog << random_qcircuit(list(range(3)), 10, ['RX', 'RY', 'RZ', 'U3', 'H', 'SWAP', 'CNOT'])
t = Transpiler()
basic_gates = ['RX', 'RY', 'RZ', 'CP']
prog2 = t.transpile(prog, [], {}, 2, basic_gates=basic_gates)
prog3 = decompose(prog, basic_gates=basic_gates)
print(prog2)
print(prog3)
  • Added Pauli Operator Grouping Functionality

The PauliOperator class has added the group_commuting interface, which groups commuting Pauli operators together.

Example code is as follows:

import random
from pyqpanda3.hamiltonian import PauliOperator
def generate_random_pauli_operator(num_qubits, num: int = 10, max_coeff=1.0):
"""
Generate a set of random Pauli operators.
Parameters:
num_operators (int): The number of Pauli operators to generate.
num_qubits (int): The number of qubits the operators act on.
max_coeff (float): The maximum value of the coefficients (default is 1.0).
Returns:
list[PauliOperator]: A list of generated random Pauli operators.
"""
pauli_symbols = ["I", "X", "Y", "Z"] # Symbols for Pauli operators
pauli_string_list = []
coefficient_list = []
for _ in range(num):
# Randomly generate Pauli operators for each qubit
pauli_string = "".join(random.choice(pauli_symbols) for i in range(num_qubits))
# Randomly generate coefficients (complex numbers)
real_part = random.uniform(-max_coeff, max_coeff)
imag_part = random.uniform(-max_coeff, max_coeff)
coefficient = complex(real_part, imag_part)
pauli_string_list.append(pauli_string)
coefficient_list.append(coefficient)
# Initialize the PauliOperator object using the constructor
operator = PauliOperator(pauli_string_list, coefficient_list, True)
return operator
# Generate a random Pauli operator
operator = generate_random_pauli_operator(3, 30)
# Grouping
operators: list[PauliOperator] = operator.group_commuting(True)
  • Generate a PauliOperator object from a real matrix

The example program is as follows.

from pyqpanda3.hamiltonian import PauliOperator
# prepare real matrix
mat =[[0.77386158,0.29688609,0.74116861,0.67669958]
,[0.09515128,0.69212901,0.09219669,0.94389747]
,[0.72101242,0.41921056,0.55843845,0.92963435]
,[0.46651845,0.30803558,0.1703278,0.33562784]]
# Generate a PauliOperator object from a real matrix
op = PauliOperator(mat)
print("op:\n", op)

Output is :

op:
{ qbit_total = 2, pauli_with_coef_s = { 'X0 ':0.373 + 0j, 'Y0 ':-0 -0.24026j, 'X0 Z1 ':-0.176981 + 0j, 'Y0 Z1 ':0 + 0.139393j, 'X1 ':0.678529 + 0j, 'Z0 X1 ':0.052562 + 0j, 'Y1 ':-0 -0.164005j, 'Z0 Y1 ':0 + 0.153926j, 'X0 X1 ':0.413656 + 0j, 'Y0 X1 ':-0 -0.134299j, 'X0 Y1 ':0 + 0.0292082j, 'Y0 Y1 ':-0.157953 + 0j, '':0.590014 + 0j, 'Z0 ':0.0761358 + 0j, 'Z1 ':0.142981 + 0j, 'Z0 Z1 ':-0.0352695 + 0j, } }
  • Generate a Hamiltonian object from a real matrix.

The example program is as follows.

from pyqpanda3.hamiltonian import Hamiltonian
# prepare real matrix
mat =[[0.77386158,0.29688609,0.74116861,0.67669958]
,[0.09515128,0.69212901,0.09219669,0.94389747]
,[0.72101242,0.41921056,0.55843845,0.92963435]
,[0.46651845,0.30803558,0.1703278,0.33562784]]
# Generate a Hamiltonian object from a real matrix
op = Hamiltonian(mat)
print("op:\n", op)

Output is :

op:
{ qbit_total = 2, pauli_with_coef_s = { 'X0 ':0.373 + 0j, 'Y0 ':-0 -0.24026j, 'X0 Z1 ':-0.176981 + 0j, 'Y0 Z1 ':0 + 0.139393j, 'X1 ':0.678529 + 0j, 'Z0 X1 ':0.052562 + 0j, 'Y1 ':-0 -0.164005j, 'Z0 Y1 ':0 + 0.153926j, 'X0 X1 ':0.413656 + 0j, 'Y0 X1 ':-0 -0.134299j, 'X0 Y1 ':0 + 0.0292082j, 'Y0 Y1 ':-0.157953 + 0j, '':0.590014 + 0j, 'Z0 ':0.0761358 + 0j, 'Z1 ':0.142981 + 0j, 'Z0 Z1 ':-0.0352695 + 0j, } }
  • Generate a matrix from a PauliOperator object.

API doc

The example program is as follows.

from pyqpanda3.hamiltonian import PauliOperator
# prepare PauliOperator object
op = PauliOperator(pauli_with_coef_s = {
'X0 ':0.373 + 0j, 'Y0 ':-0 -0.24026j, 'X0 Z1 ':-0.176981 + 0j, 'Y0 Z1 ':0 + 0.139393j,
'X1 ':0.678529 + 0j, 'Z0 X1 ':0.052562 + 0j, 'Y1 ':-0 -0.164005j, 'Z0 Y1 ':0 + 0.153926j,
'X0 X1 ':0.413656 + 0j, 'Y0 X1 ':-0 -0.134299j, 'X0 Y1 ':0 + 0.0292082j, 'Y0 Y1 ':-0.157953 + 0j,
'':0.590014 + 0j, 'Z0 ':0.0761358 + 0j, 'Z1 ':0.142981 + 0j, 'Z0 Z1 ':-0.0352695 + 0j, }
)
# Generate a matrix from a PauliOperator object.
mat = op.matrix()
print('mat:\n',mat)

Output is :

mat:
[[0.7738613+0.j 0.296886 +0.j 0.74117 +0.j 0.6766998+0.j]
[0.095152 +0.j 0.6921287+0.j 0.0921958+0.j 0.943898 +0.j]
[0.721012 +0.j 0.4192102+0.j 0.5584383+0.j 0.929634 +0.j]
[0.4665182+0.j 0.308036 +0.j 0.170328 +0.j 0.3356277+0.j]]
  • Generate a matrix from a Hamiltonian object.

API doc

The example program is as follows.

from pyqpanda3.hamiltonian import Hamiltonian
# prepare Hamiltonian object
op = Hamiltonian(pauli_with_coef_s = {
'X0 ':0.373 + 0j, 'Y0 ':-0 -0.24026j, 'X0 Z1 ':-0.176981 + 0j, 'Y0 Z1 ':0 + 0.139393j,
'X1 ':0.678529 + 0j, 'Z0 X1 ':0.052562 + 0j, 'Y1 ':-0 -0.164005j, 'Z0 Y1 ':0 + 0.153926j,
'X0 X1 ':0.413656 + 0j, 'Y0 X1 ':-0 -0.134299j, 'X0 Y1 ':0 + 0.0292082j, 'Y0 Y1 ':-0.157953 + 0j,
'':0.590014 + 0j, 'Z0 ':0.0761358 + 0j, 'Z1 ':0.142981 + 0j, 'Z0 Z1 ':-0.0352695 + 0j, }
)
# Generate a matrix from a Hamiltonian object.
mat = op.matrix()
print('mat:\n',mat)

Output is :

mat:
[[0.7738613+0.j 0.296886 +0.j 0.74117 +0.j 0.6766998+0.j]
[0.095152 +0.j 0.6921287+0.j 0.0921958+0.j 0.943898 +0.j]
[0.721012 +0.j 0.4192102+0.j 0.5584383+0.j 0.929634 +0.j]
[0.4665182+0.j 0.308036 +0.j 0.170328 +0.j 0.3356277+0.j]]
  • Generate a QASM 2.0 instruction string from a QProg object.

API doc of convert_qprog_to_qasm

The example program is as follows.

from pyqpanda3.intermediate_compiler import convert_qprog_to_qasm
from pyqpanda3.core import QProg,RX,CNOT
# prepare QProg object
prog = QProg()
prog << RX(0,3.1415926)<<CNOT(0,2)
# Generate a QASM 2.0 instruction string from a QProg object. The precision of the door parameters is set by the second input parameter of the interface.
qasm = convert_qprog_to_qasm(prog,10)
print('qasm:\n',qasm)
Definition __init__.py:1

Output is :

qasm:
OPENQASM 2.0;
include "qelib1.inc";
qreg q[3];
creg c[0];
rx(3.1415926000) q[0];
cx q[0],q[2];
  • Changes to the implementation related to generating a QProg object from QASM.

Before the change, different qubit register array names all pointed to the register array named "q"

After the change, different qubit register array names identify different starting register indexes and element counts

API doc of convert_qasm_string_to_qprog

The example program is as follows.

from pyqpanda3.intermediate_compiler import convert_qasm_string_to_qprog
from pyqpanda3.core import QProg
qasm='''
OPENQASM 2.0;
include "qelib1.inc";
qreg q1[2];
qreg q2[2];
creg c[0];
x q1[0];
y q1[1];
z q2[0];
s q2[1];
'''
prog:QProg = convert_qasm_string_to_qprog(qasm)
print('prog:\n',prog)
print('used qbits in prog:',prog.qubits())

Before changing, the output is:

prog:
┌─┐ ┌─┐
q_0: |0>─┤X├ ┤Z├
├─┤ ├─┤
q_1: |0>─┤Y├ ┤S├
└─┘ └─┘
c : / ═
used qbits in prog: [0, 1]

After changing, the output is :

prog:
┌─┐
q_0: |0>─┤X├
├─┤
q_1: |0>─┤Y├
├─┤
q_2: |0>─┤Z├
├─┤
q_3: |0>─┤S├
└─┘
c : / ═
used qbits in prog: [0, 1, 2, 3]
  • Add quantum state preparation functionality.

Which can be invoked via the Encode class. The supported encoding methods are consistent with those in QPanda2. For specific usage, refer to the Quantum State Encoding section.

Fixed bug

  1. Resolved occasional crashes and exceptions when running pyqpanda3 on macOS.
  2. Address the issue of errors in merging some Pauli terms in some special cases when constructing a PauliOperator object.
  3. Resolve the issue of parsing gate errors when generating a QProg object from QASM.

Optimize

  1. We optimized the simulation performance of CPUQVM by integrating the mimalloc library, achieving an approximately 30% speedup in full-amplitude simulation compared to before.
  2. Optimizing the internal implementation of quantum circuits for desired calculations on quantum systems with specified Pauli operators or Hamiltonians.