メインコンテンツへスキップ

Pauli基底でオブザーバブルを指定する

Package versions

The code on this page was developed using the following requirements. We recommend using these versions or newer.

qiskit[all]~=2.3.0

量子力学では、オブザーバブルは測定可能な物理的性質に対応します。 例えばスピン系を考えるとき、系のエネルギーを測定したり、磁化やスピン間の相関などのスピンの整列に関する情報を得ることに興味があるかもしれません。

nn量子ビットのオブザーバブル OO を量子コンピューターで測定するには、それをPauli演算子のテンソル積の和として表現する必要があります。すなわち、

O=k=1KαkPk,  Pk{I,X,Y,Z}n,  αkR,O = \sum_{k=1}^K \alpha_k P_k,~~ P_k \in \{I, X, Y, Z\}^{\otimes n},~~ \alpha_k \in \mathbb{R},

ここで

I=(1001)  X=(0110)  Y=(0ii0)  Z=(1001)I = \begin{pmatrix} 1 & 0 \\ 0 & 1 \end{pmatrix} ~~ X = \begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix} ~~ Y = \begin{pmatrix} 0 & -i \\ i & 0 \end{pmatrix} ~~ Z = \begin{pmatrix} 1 & 0 \\ 0 & -1 \end{pmatrix}

であり、オブザーバブルがエルミートである(すなわち O=OO^\dagger = O)という事実を利用します。OO がエルミートでない場合でもPauliの和に分解することは可能ですが、係数 αk\alpha_k が複素数になります。

多くの場合、対象の系を量子ビットにマッピングした後、オブザーバブルはこの表現で自然に指定されます。 例えば、スピン-1/2 系はイジングハミルトニアンにマッピングできます。

H=i,jZiZji=1nXi,H = \sum_{\langle i, j\rangle} Z_i Z_j - \sum_{i=1}^n X_i,

ここで、添字 i,j\langle i, j\rangle は相互作用するスピンの対を走り、スピンは XX 方向の横磁場を受けています。 添字はPauli演算子がどの量子ビットに作用するかを示します。すなわち、XiX_i は量子ビット iiXX 演算子を適用し、残りは変化させません。

Qiskit SDKでは、このハミルトニアンは次のコードで構築できます。

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit
from qiskit.quantum_info import SparsePauliOp

# define the number of qubits
n = 12

# define the single Pauli terms as ("Paulis", [indices], coefficient)
interactions = [
("ZZ", [i, i + 1], 1) for i in range(n - 1)
] # we assume spins on a 1D line
field = [("X", [i], -1) for i in range(n)]

# build the operator
hamiltonian = SparsePauliOp.from_sparse_list(
interactions + field, num_qubits=n
)
print(hamiltonian)
SparsePauliOp(['IIIIIIIIIIZZ', 'IIIIIIIIIZZI', 'IIIIIIIIZZII', 'IIIIIIIZZIII', 'IIIIIIZZIIII', 'IIIIIZZIIIII', 'IIIIZZIIIIII', 'IIIZZIIIIIII', 'IIZZIIIIIIII', 'IZZIIIIIIIII', 'ZZIIIIIIIIII', 'IIIIIIIIIIIX', 'IIIIIIIIIIXI', 'IIIIIIIIIXII', 'IIIIIIIIXIII', 'IIIIIIIXIIII', 'IIIIIIXIIIII', 'IIIIIXIIIIII', 'IIIIXIIIIIII', 'IIIXIIIIIIII', 'IIXIIIIIIIII', 'IXIIIIIIIIII', 'XIIIIIIIIIII'],
coeffs=[ 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j,
1.+0.j, 1.+0.j, 1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j,
-1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j, -1.+0.j])

エネルギーを測定したい場合、オブザーバブルはハミルトニアン自体になります。あるいは、オブザーバブル

O=1ni=1ZiO = \frac{1}{n} \sum_{i=1} Z_i

を用いて ZZ 方向に整列したスピンの数を数えることで、平均磁化のような系の性質を測定することにも興味があるかもしれません。

Pauli演算子ではなく行列形式で与えられたオブザーバブルについては、量子コンピューターで評価するために、まずPauli基底で再定式化する必要があります。 Pauli行列はエルミート 2n×2n2^n \times 2^n 行列の基底を形成するため、このような表現は常に見つけることができます。 オブザーバブル OO を次のように展開します。

O=P{I,X,Y,Z}nTr(OP)P,O = \sum_{P \in \{I, X, Y, Z\}^{\otimes n}} \mathrm{Tr}(O P) P,

ここで、和はすべての可能な nn 量子ビットPauli項を走り、Tr()\mathrm{Tr}(\cdot) は内積として機能する行列のトレースです。 この行列からPauli項への分解は、SparsePauliOp.from_operator メソッドを使って次のように実装できます。

import numpy as np
from qiskit.quantum_info import SparsePauliOp

matrix = np.array(
[[-1, 0, 0.5, -1], [0, 1, 1, 0.5], [0.5, 1, -1, 0], [-1, 0.5, 0, 1]]
)

observable = SparsePauliOp.from_operator(matrix)
print(observable)
SparsePauliOp(['IZ', 'XI', 'YY'],
coeffs=[-1. +0.j, 0.5+0.j, 1. -0.j])

これは、この行列がPauli項を用いて O=Z1+0.5X2+Y2Y1O = -Z_1 + 0.5 X_2 + Y_2 Y_1 と書けることを意味します。

備考

テンソル積の順序は qnqn1q1q_n \otimes q_{n-1} \otimes \cdots \otimes q_1 のように量子ビットにマッピングされることを覚えておいてください。

備考

オブザーバブルがエルミートである(O=OO^\dagger = O を満たす)場合、Pauli係数は実数です。 ただし、複素数値の係数を許容すれば、任意の複素行列をPauliの和に分解することも可能です。

Pauli基底での測定

測定は量子ビットの状態を計算基底 {0,1}\{|0\rangle, |1\rangle\} に射影します。これは、IIZZ 項のみからなるPauliのように、この基底で対角なオブザーバブルしか測定できないことを意味します。 任意のPauli項を測定するには、それらを対角化するための基底変換が必要です。これを行うには、次の変換を実行します。

XZ=HXHYZ=HSYSH,\begin{aligned} X &\rightarrow Z = H X H \\ Y &\rightarrow Z = H S^\dagger Y S H, \end{aligned}

ここで、HH はアダマールゲート、S=ZS = \sqrt{Z} は位相ゲートと呼ばれることがあります。 期待値の計算に Estimator を使用している場合、基底変換は自動的に実行されます。

以下は、量子回路を準備し、量子ビット0をX基底、量子ビット1をY基底、量子ビット2をZ基底で手動に測定する方法を示す例です。 前の式で示した変換を適用すると、次の回路が得られます。

from qiskit.circuit import QuantumCircuit

# create a circuit, where we would like to measure
# q0 in the X basis, q1 in the Y basis and q2 in the Z basis
circuit = QuantumCircuit(3)
circuit.ry(0.8, 0)
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.barrier()

# diagonalize X with the Hadamard gate
circuit.h(0)

# diagonalize Y with Hadamard as S^\dagger
circuit.sdg(1)
circuit.h(1)

# the Z basis is the default, no action required here

# measure all qubits
circuit.measure_all()
circuit.draw("mpl")

Output of the previous code cell

次のステップ

推奨事項