Ang Operator class
Mga bersyon ng package
Ang code sa pahinang ito ay ginawa gamit ang mga sumusunod na requirements. Inirerekomenda naming gamitin ang mga bersyong ito o mas bago pa.
qiskit[all]~=2.3.0
Ipinapakita ng pahinang ito kung paano gamitin ang Operator class. Para sa pangkalahatang-ideya ng mga representasyon ng operator sa Qiskit, kabilang ang Operator class at iba pa, tingnan ang Overview of operator classes.
# Added by doQumentation β required packages for this notebook
!pip install -q numpy qiskit
import numpy as np
from qiskit.circuit import QuantumCircuit
from qiskit.circuit.library import CXGate, RXGate, XGate
from qiskit.quantum_info import Operator, Pauli, process_fidelity
I-convert ang mga class sa Operatorsβ
Maraming iba pang mga class sa Qiskit ang maaaring direktang i-convert sa isang Operator object gamit ang paraan ng pagsisimula ng operator. Halimbawa:
- Mga
Pauliobject - Mga
GateatInstructionobject - Mga
QuantumCircuitobject
Tandaan na ang huling punto ay nangangahulugang maaari mong gamitin ang Operator class bilang isang unitary simulator para makuha ang panghuling unitary matrix ng isang quantum circuit, nang hindi kailangang tumawag ng simulator backend. Kung ang circuit ay naglalaman ng anumang hindi sinusuportahang operasyon, magtataas ng exception. Ang hindi sinusuportahang mga operasyon ay: measure, reset, conditional operations, o isang gate na walang matrix definition o decomposition sa pamamagitan ng mga gate na may matrix definitions.
# Create an Operator from a Pauli object
pauliXX = Pauli("XX")
Operator(pauliXX)
Operator([[0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],
[0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],
[0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],
[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j]],
input_dims=(2, 2), output_dims=(2, 2))
# Create an Operator for a Gate object
Operator(CXGate())
Operator([[1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j],
[0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],
[0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j]],
input_dims=(2, 2), output_dims=(2, 2))
# Create an operator from a parameterized Gate object
Operator(RXGate(np.pi / 2))
Operator([[0.70710678+0.j , 0. -0.70710678j],
[0. -0.70710678j, 0.70710678+0.j ]],
input_dims=(2,), output_dims=(2,))
# Create an operator from a QuantumCircuit object
circ = QuantumCircuit(10)
circ.h(0)
for j in range(1, 10):
circ.cx(j - 1, j)
# Convert circuit to an operator by implicit unitary simulation
Operator(circ)
Operator([[ 0.70710678+0.j, 0.70710678+0.j, 0. +0.j, ...,
0. +0.j, 0. +0.j, 0. +0.j],
[ 0. +0.j, 0. +0.j, 0.70710678+0.j, ...,
0. +0.j, 0. +0.j, 0. +0.j],
[ 0. +0.j, 0. +0.j, 0. +0.j, ...,
0. +0.j, 0. +0.j, 0. +0.j],
...,
[ 0. +0.j, 0. +0.j, 0. +0.j, ...,
0. +0.j, 0. +0.j, 0. +0.j],
[ 0. +0.j, 0. +0.j, 0.70710678+0.j, ...,
0. +0.j, 0. +0.j, 0. +0.j],
[ 0.70710678+0.j, -0.70710678+0.j, 0. +0.j, ...,
0. +0.j, 0. +0.j, 0. +0.j]],
input_dims=(2, 2, 2, 2, 2, 2, 2, 2, 2, 2), output_dims=(2, 2, 2, 2, 2, 2, 2, 2, 2, 2))
Gamitin ang Operators sa mga circuitβ
Ang mga unitary Operator ay maaaring direktang ipasok sa isang QuantumCircuit gamit ang QuantumCircuit.append na paraan. Kino-convert nito ang Operator sa isang UnitaryGate object, na idinaragdag sa circuit.
Kung ang operator ay hindi unitary, magtataas ng exception. Maaari itong suriin gamit ang Operator.is_unitary() na function, na nagbabalik ng True kung ang operator ay unitary at False kung hindi.
# Create an operator
XX = Operator(Pauli("XX"))
# Add to a circuit
circ = QuantumCircuit(2, 2)
circ.append(XX, [0, 1])
circ.measure([0, 1], [0, 1])
circ.draw("mpl")
Tandaan na sa halimbawa sa itaas, ang operator ay sinimulan mula sa isang Pauli object. Gayunpaman, ang Pauli object ay maaari ring direktang ipasok sa circuit mismo at ico-convert sa isang sequence ng single-qubit Pauli gates:
# Add to a circuit
circ2 = QuantumCircuit(2, 2)
circ2.append(Pauli("XX"), [0, 1])
circ2.measure([0, 1], [0, 1])
circ2.draw()
βββββββββββββββββ
q_0: β€0 ββ€Mββββ
β Pauli(XX) βββ₯ββββ
q_1: β€1 βββ«ββ€Mβ
ββββββββββββββ β ββ₯β
c: 2/ββββββββββββββββ©βββ©β
0 1
Pagsamahin ang mga Operatorβ
Ang mga Operator ay maaaring pagsamahin gamit ang ilang pamamaraan.
Tensor productβ
Dalawang operator na at ay maaaring pagsamahin sa isang tensor product operator na gamit ang Operator.tensor na function. Tandaan na kung parehong single-qubit operators ang at , ang A.tensor(B) = ay magkakaroon ng mga subsystem na naka-index bilang matrix sa subsystem 0, at matrix sa subsystem 1.
A = Operator(Pauli("X"))
B = Operator(Pauli("Z"))
A.tensor(B)
Operator([[ 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j],
[ 0.+0.j, -0.+0.j, 0.+0.j, -1.+0.j],
[ 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[ 0.+0.j, -1.+0.j, 0.+0.j, -0.+0.j]],
input_dims=(2, 2), output_dims=(2, 2))
Tensor expansionβ
Ang isang malapit na kaugnay na operasyon ay ang Operator.expand, na kumikilos tulad ng isang tensor product ngunit sa kabaligtaran na pagkakasunud-sunod. Kaya, para sa dalawang operator na at , mayroon kang A.expand(B) = kung saan ang mga subsystem ay naka-index bilang matrix sa subsystem 0, at matrix sa subsystem 1.
A = Operator(Pauli("X"))
B = Operator(Pauli("Z"))
A.expand(B)
Operator([[ 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j],
[ 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[ 0.+0.j, 0.+0.j, -0.+0.j, -1.+0.j],
[ 0.+0.j, 0.+0.j, -1.+0.j, -0.+0.j]],
input_dims=(2, 2), output_dims=(2, 2))
Compositionβ
Maaari ka ring mag-compose ng dalawang operator na at para ipatupad ang matrix multiplication gamit ang Operator.compose na paraan. Ang A.compose(B) ay nagbabalik ng operator na may matrix :
A = Operator(Pauli("X"))
B = Operator(Pauli("Z"))
A.compose(B)
Operator([[ 0.+0.j, 1.+0.j],
[-1.+0.j, 0.+0.j]],
input_dims=(2,), output_dims=(2,))
Maaari ka ring mag-compose sa kabaligtaran na pagkakasunud-sunod sa pamamagitan ng pag-apply ng sa harap ng gamit ang front kwarg ng compose: A.compose(B, front=True) = :
A = Operator(Pauli("X"))
B = Operator(Pauli("Z"))
A.compose(B, front=True)
Operator([[ 0.+0.j, -1.+0.j],
[ 1.+0.j, 0.+0.j]],
input_dims=(2,), output_dims=(2,))
Subsystem compositionβ
Tandaan na ang nakaraang compose ay nangangailangan na ang kabuuang output dimension ng unang operator na ay katumbas ng kabuuang input dimension ng composed operator na (at gayundin, ang output dimension ng ay dapat katumbas ng input dimension ng kapag nag-compose gamit ang front=True).
Maaari ka ring mag-compose ng isang mas maliit na operator sa isang seleksyon ng mga subsystem sa isang mas malaking operator gamit ang qargs kwarg ng compose, may o walang front=True. Sa kasong ito, ang kaugnay na mga input at output dimension ng mga subsystem na ino-compose ay dapat magkatugma. Tandaan na ang mas maliit na operator ay palaging dapat na argument ng compose na paraan.
Halimbawa, para mag-compose ng isang two-qubit gate sa isang three-qubit operator:
# Compose XZ with a 3-qubit identity operator
op = Operator(np.eye(2**3))
XZ = Operator(Pauli("XZ"))
op.compose(XZ, qargs=[0, 2])
Operator([[ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j,
0.+0.j],
[ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, -1.+0.j, 0.+0.j,
0.+0.j],
[ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 1.+0.j,
0.+0.j],
[ 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,
-1.+0.j],
[ 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,
0.+0.j],
[ 0.+0.j, -1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,
0.+0.j],
[ 0.+0.j, 0.+0.j, 1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,
0.+0.j],
[ 0.+0.j, 0.+0.j, 0.+0.j, -1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j,
0.+0.j]],
input_dims=(2, 2, 2), output_dims=(2, 2, 2))
# Compose YX in front of the previous operator
op = Operator(np.eye(2**3))
YX = Operator(Pauli("YX"))
op.compose(YX, qargs=[0, 2], front=True)
Operator([[0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.-1.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.-1.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.-1.j],
[0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.-1.j, 0.+0.j],
[0.+0.j, 0.+1.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+1.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+0.j, 0.+1.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j],
[0.+0.j, 0.+0.j, 0.+1.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+0.j]],
input_dims=(2, 2, 2), output_dims=(2, 2, 2))
Mga linear na kombinasyonβ
Ang mga Operator ay maaari ring pagsamahin gamit ang mga karaniwang linear operator para sa karagdagan, pagbabawas, at scalar multiplication sa pamamagitan ng mga kumplikadong numero.
XX = Operator(Pauli("XX"))
YY = Operator(Pauli("YY"))
ZZ = Operator(Pauli("ZZ"))
op = 0.5 * (XX + YY - 3 * ZZ)
op
Operator([[-1.5+0.j, 0. +0.j, 0. +0.j, 0. +0.j],
[ 0. +0.j, 1.5+0.j, 1. +0.j, 0. +0.j],
[ 0. +0.j, 1. +0.j, 1.5+0.j, 0. +0.j],
[ 0. +0.j, 0. +0.j, 0. +0.j, -1.5+0.j]],
input_dims=(2, 2), output_dims=(2, 2))
Ang isang mahalagang punto ay habang pinananatili ng tensor, expand, at compose ang unitary ng mga unitary operator, ang mga linear na kombinasyon ay hindi; kaya, ang pagdaragdag ng dalawang unitary operator ay, sa pangkalahatan, magreresulta sa isang non-unitary operator:
op.is_unitary()
False
Implicit na conversion sa mga Operatorβ
Tandaan na para sa lahat ng sumusunod na pamamaraan, kung ang pangalawang object ay hindi pa isang Operator object, ito ay awtomatikong kino-convert sa isa ng pamamaraan. Ibig sabihin, maaaring direktang ipasa ang mga matrix nang hindi muna ito tahasan na kino-convert sa isang Operator. Kung hindi posible ang conversion, magtataas ng exception.
# Compose with a matrix passed as a list
Operator(np.eye(2)).compose([[0, 1], [1, 0]])
Operator([[0.+0.j, 1.+0.j],
[1.+0.j, 0.+0.j]],
input_dims=(2,), output_dims=(2,))
Ikumpara ang mga Operatorβ
Ang mga Operator ay may equality method na maaaring gamitin para suriin kung ang dalawang operator ay halos magkapantay.
Operator(Pauli("X")) == Operator(XGate())
True
Tandaan na sinusuri nito ang bawat matrix element ng mga operator na halos magkapantay; dalawang unitary na may pagkakaiba ng global phase ay hindi itinuturing na magkapantay:
Operator(XGate()) == np.exp(1j * 0.5) * Operator(XGate())
False
Process fidelityβ
Maaari ka ring ikumpara ang mga operator gamit ang process_fidelity na function mula sa Quantum Information module. Ito ay isang information-theoretic na dami para sa kung gaano kalapit ang dalawang quantum channel sa isa't isa, at sa kaso ng mga unitary operator, hindi ito nakasalalay sa global phase.
# Two operators which differ only by phase
op_a = Operator(XGate())
op_b = np.exp(1j * 0.5) * Operator(XGate())
# Compute process fidelity
F = process_fidelity(op_a, op_b)
print("Process fidelity =", F)
Process fidelity = 1.0
Tandaan na ang process fidelity ay karaniwang valid lamang bilang sukatan ng pagkakatulad kung ang mga input operator ay unitary (o CP sa kaso ng mga quantum channel), at magtataas ng exception kung ang mga input ay hindi CP.
Mga susunod na hakbangβ
- Tuklasin ang Operator API reference.