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
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)
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
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())
Output is as follows.
- 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.
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
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
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
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
def test_expectation2():
qvm = CPUQVM()
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"""
Ham = Hamiltonian({"X0 Z1": 2, "X1 Y2": 3})
print("without I:\n", Ham)
try:
res = qvm.expval_hamiltonian(prog, Ham)
print("res:", res)
res2 = expval_hamiltonian(prog,Ham,backend='CPU')
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_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
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
def test_expectation2():
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"""
Ham = Hamiltonian({"X0 Z1": 2, "X1 Y2": 3})
print("without I:\n", Ham)
try:
res2 = expval_hamiltonian(prog,Ham,backend='GPU')
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
expval_hamiltonian(self:
pyqpanda3.vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, exp_type: pyqpanda3.vqcircuit.ExpectationType = <ExpectationType.THEORETICAL: 0>)
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
expval_hamiltonian(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, shots: int = 1000, model: QPanda3::NoiseModel, used_threads: int = 4, backend: str = 'CPU')
expval_hamiltonian(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, used_threads: int = 4, backend: str = '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')
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
expval_hamiltonian(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, shots: int = 1000, model: QPanda3::NoiseModel, used_threads: int = 4, backend: str = 'CPU')
expval_hamiltonian(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, used_threads: int = 4, backend: str = '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')
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
new interface
API doc of pyqpanda3.core.expval_pauli_operator
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
def test_expectation2():
qvm = CPUQVM()
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"""
op = PauliOperator({"X0 Z1": 2, "X1 Y2": 3})
print("without I:\n", op)
try:
res = qvm.expval_pauli_operator(prog, op)
print("res:", res)
res2 = expval_pauli_operator(prog,op,backend='CPU')
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
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
def test_expectation2():
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"""
op = PauliOperator({"X0 Z1": 2, "X1 Y2": 3})
print("without I:\n", op)
try:
res2 = expval_pauli_operator(prog,op,backend='GPU')
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
expval_pauli_operator(self:
pyqpanda3.vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, exp_type: pyqpanda3.vqcircuit.ExpectationType = <ExpectationType.THEORETICAL: 0>)
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
expval_pauli_operator(self: vqcircuit.VQCResult, pauli_operator: QPanda3::PauliOperator, shots: int = 1000, model: QPanda3::NoiseModel, used_threads: int = 4, backend: str = 'CPU')
expval_pauli_operator(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, used_threads: int = 4, backend: str = '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')
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
expval_pauli_operator(self: vqcircuit.VQCResult, pauli_operator: QPanda3::PauliOperator, shots: int = 1000, model: QPanda3::NoiseModel, used_threads: int = 4, backend: str = 'CPU')
expval_pauli_operator(self: vqcircuit.VQCResult, hamiltonian: QPanda3::Hamiltonian, used_threads: int = 4, backend: str = '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')
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:
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)
- 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:
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
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"]
pauli_string_list = []
coefficient_list = []
for _ in range(num):
pauli_string = "".join(random.choice(pauli_symbols) for i in range(num_qubits))
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)
operator = PauliOperator(pauli_string_list, coefficient_list, True)
return operator
operator = generate_random_pauli_operator(3, 30)
operators: list[PauliOperator] = operator.group_commuting(True)
- Generate a PauliOperator object from a real matrix
The example program is as follows.
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]]
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.
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]]
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.
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, }
)
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.
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, }
)
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.
prog = QProg()
prog << RX(0,3.1415926)<<CNOT(0,2)
qasm = convert_qprog_to_qasm(prog,10)
print('qasm:\n',qasm)
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.
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
- Resolved occasional crashes and exceptions when running pyqpanda3 on macOS.
- Address the issue of errors in merging some Pauli terms in some special cases when constructing a PauliOperator object.
- Resolve the issue of parsing gate errors when generating a QProg object from QASM.
Optimize
- We optimized the simulation performance of CPUQVM by integrating the mimalloc library, achieving an approximately 30% speedup in full-amplitude simulation compared to before.
- Optimizing the internal implementation of quantum circuits for desired calculations on quantum systems with specified Pauli operators or Hamiltonians.