ข้ามไปยังเนื้อหาหลัก
โครงการนี้อยู่ในช่วงเบต้า พบข้อผิดพลาด? สร้าง GitHub Issue มีคำถามหรือไอเดีย? ถามใน Discussions — ยินดีรับฟังความคิดเห็น!
คุณภาพการแปลในหน้านี้เป็นอย่างไร?

คลาส Operator

Package versions

โค้ดในหน้านี้พัฒนาโดยใช้ข้อกำหนดต่อไปนี้ เราแนะนำให้ใช้เวอร์ชันเหล่านี้หรือใหม่กว่า

qiskit[all]~=2.5.2

หน้านี้แสดงวิธีใช้คลาส Operator สำหรับภาพรวมระดับสูงของการแทนค่า operator ใน Qiskit รวมถึงคลาส Operator และคลาสอื่นๆ ดูที่ ภาพรวมของคลาส operator

# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util

_needed = {"numpy": "numpy", "qiskit": "qiskit"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")
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

แปลงคลาสต่างๆ เป็น Operator​

คลาสอื่นๆ หลายคลาสใน Qiskit สามารถแปลงเป็น object Operator ได้โดยตรงโดยใช้วิธี operator initialization ตัวอย่างเช่น:

  • object Pauli

  • object Gate และ Instruction

  • object QuantumCircuit

โปรดทราบว่าข้อสุดท้ายหมายความว่าคุณสามารถใช้คลาส Operator เป็น unitary simulator เพื่อคำนวณ unitary matrix สุดท้ายสำหรับ quantum circuit โดยไม่ต้องเรียก simulator Backend ถ้า Circuit มีการดำเนินการที่ไม่รองรับ จะเกิด exception การดำเนินการที่ไม่รองรับได้แก่: measure, reset, conditional operations หรือ Gate ที่ไม่มีนิยาม matrix หรือการแตกตัวในรูปของ Gate ที่มีนิยาม matrix

# 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))

ใช้ Operator ใน Circuit​

Operators แบบ unitary สามารถแทรกเข้าไปใน QuantumCircuit ได้โดยตรงโดยใช้เมธอด QuantumCircuit.append วิธีนี้จะแปลง Operator เป็นอ็อบเจ็กต์ UnitaryGate ซึ่งจะถูกเพิ่มเข้าไปในวงจร

ถ้า operator ไม่ใช่ unitary จะเกิด exception สามารถตรวจสอบได้โดยใช้ฟังก์ชัน Operator.is_unitary() ซึ่งคืนค่า True ถ้า operator เป็น unitary และ False หากไม่ใช่

# 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")

Output of the previous code cell

โปรดทราบว่าในตัวอย่างข้างต้น operator ถูก initialize จาก object Pauli แต่ object Pauli ก็สามารถแทรกเข้าไปใน Circuit โดยตรงได้เช่นกันและจะถูกแปลงเป็นลำดับของ single-qubit Pauli Gate:

# 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

รวม Operator​

Operator สามารถรวมกันได้หลายวิธี

ผลคูณเทนเซอร์ (Tensor product)​

Operator สองตัว AA และ BB สามารถรวมกันเป็น tensor product operator A⊗BA\otimes B ได้โดยใช้ฟังก์ชัน Operator.tensor โปรดทราบว่าถ้าทั้ง AA และ BB เป็น single-qubit operator แล้ว A.tensor(B) = A⊗BA\otimes B จะมี subsystem ที่ index ว่าเมทริกซ์ BB อยู่ที่ subsystem 0 และเมทริกซ์ AA อยู่ที่ 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)​

การดำเนินการที่เกี่ยวข้องใกล้ชิดคือ Operator.expand ซึ่งทำงานเหมือน tensor product แต่ในลำดับย้อนกลับ ดังนั้น สำหรับ operator สองตัว AA และ BB คุณจะได้ A.expand(B) = B⊗AB\otimes A โดย subsystem จะ index ว่าเมทริกซ์ AA อยู่ที่ subsystem 0 และเมทริกซ์ BB อยู่ที่ 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​

คุณยังสามารถ compose operator สองตัว AA และ BB เพื่อทำการคูณเมทริกซ์โดยใช้เมธอด Operator.compose โดย A.compose(B) คืนค่า operator ที่มีเมทริกซ์ B.AB.A:

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,))

คุณยังสามารถ compose ในลำดับย้อนกลับได้โดยใช้ BB ด้านหน้า AA ผ่าน kwarg front ของ compose: A.compose(B, front=True) = A.BA.B:

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​

โปรดทราบว่า compose ก่อนหน้าต้องการให้ output dimension รวมของ operator แรก AA เท่ากับ input dimension รวมของ operator ที่ compose BB (และในทำนองเดียวกัน output dimension ของ BB ต้องเท่ากับ input dimension ของ AA เมื่อ compose ด้วย front=True)

คุณยังสามารถ compose operator ขนาดเล็กกว่ากับ subsystem ที่เลือกของ operator ขนาดใหญ่กว่าได้โดยใช้ kwarg qargs ของ compose ไม่ว่าจะใช้หรือไม่ใช้ front=True ในกรณีนี้ input และ output dimension ที่เกี่ยวข้องของ subsystem ที่ถูก compose ต้องตรงกัน โปรดทราบว่า operator ขนาดเล็กต้องเป็น argument ของเมธอด compose เสมอ

ตัวอย่างเช่น การ compose two-qubit Gate กับ 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))

การรวมเชิงเส้น​

Operator ยังสามารถรวมกันได้โดยใช้ตัวดำเนินการเชิงเส้นมาตรฐานสำหรับการบวก การลบ และการคูณสเกลาร์ด้วยจำนวนเชิงซ้อน

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))

สิ่งสำคัญคือ ในขณะที่ tensor, expand และ compose รักษาความเป็น unitary ของ unitary operator ไว้ แต่การรวมเชิงเส้นไม่รักษา ดังนั้น การบวก unitary operator สองตัวโดยทั่วไปจะได้ผลลัพธ์เป็น non-unitary operator:

op.is_unitary()
False

การแปลงโดยนัยเป็น Operator​

โปรดทราบว่าสำหรับเมธอดต่อไปนี้ทั้งหมด หากอ็อบเจ็กต์ที่สองยังไม่ใช่อ็อบเจ็กต์ Operator มันจะถูกแปลงเป็นหนึ่งโดยปริยายโดยเมธอดนั้น ซึ่งหมายความว่าเมทริกซ์สามารถส่งเข้าไปได้โดยตรงโดยไม่ต้องแปลงเป็น Operator อย่างชัดเจนก่อน หากไม่สามารถแปลงได้ จะเกิดข้อยกเว้นขึ้น

# 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,))

เปรียบเทียบ Operator​

Operator มีเมธอดความเท่าเทียมที่ใช้ตรวจสอบว่า operator สองตัวเท่ากันโดยประมาณหรือไม่

Operator(Pauli("X")) == Operator(XGate())
True

โปรดทราบว่านี่จะตรวจสอบว่าแต่ละ element ของเมทริกซ์ของ operator เท่ากันโดยประมาณ unitary สองตัวที่ต่างกันเพียง global phase จะไม่ถือว่าเท่ากัน:

Operator(XGate()) == np.exp(1j * 0.5) * Operator(XGate())
False

ความเที่ยงตรงของกระบวนการ (Process fidelity)​

คุณยังสามารถเปรียบเทียบ operator โดยใช้ฟังก์ชัน process_fidelity จากโมดูล Quantum Information นี่คือปริมาณเชิงทฤษฎีสารสนเทศที่บอกว่า quantum channel สองช่องมีความใกล้เคียงกันแค่ไหน และในกรณีของ unitary operator จะไม่ขึ้นอยู่กับ 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

โปรดทราบว่า process fidelity โดยทั่วไปเป็นตัวชี้วัดความใกล้เคียงที่ถูกต้องก็ต่อเมื่อ operator input เป็น unitary (หรือ CP ในกรณีของ quantum channel) และจะเกิด exception ถ้า input ไม่ใช่ CP

ขั้นตอนถัดไป​

คำแนะนำ