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

演算子クラスの概要

パッケージのバージョン

このページのコードは、以下の要件を使用して開発されました。 これらのバージョン以降を使用することを推奨します。

qiskit[all]~=2.3.0

Qiskit では、量子演算子は quantum_info モジュールのクラスを使って表現されます。最も重要な演算子クラスは SparsePauliOp で、これは一般的な量子演算子をパウリ文字列の線形結合として表します。SparsePauliOp は量子オブザーバブルを表現するために最もよく使用されるクラスです。このページの残りの部分では、SparsePauliOp やその他の演算子クラスの使い方を説明します。

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit
import numpy as np
from qiskit.quantum_info.operators import Operator, Pauli, SparsePauliOp

SparsePauliOp

SparsePauliOp クラスは、パウリ文字列の線形結合を表します。SparsePauliOp を初期化する方法はいくつかありますが、最も柔軟な方法は次のコードセルで示すように from_sparse_list メソッドを使用することです。from_sparse_list(pauli_string, qubit_indices, coefficient) のトリプレットのリストを受け取ります。

op1 = SparsePauliOp.from_sparse_list(
[("ZX", [1, 4], 1.0), ("YY", [0, 3], -1 + 1j)], num_qubits=5
)
op1
SparsePauliOp(['XIIZI', 'IYIIY'],
coeffs=[ 1.+0.j, -1.+1.j])

SparsePauliOp は、次のコードセルで示すように算術演算をサポートしています。

op2 = SparsePauliOp.from_sparse_list(
[("XXZ", [0, 1, 4], 1 + 2j), ("ZZ", [1, 2], -1 + 1j)], num_qubits=5
)

# Addition
print("op1 + op2:")
print(op1 + op2)
print()
# Multiplication by a scalar
print("2 * op1:")
print(2 * op1)
print()
# Operator multiplication (composition)
print("op1 @ op2:")
print(op1 @ op2)
print()
# Tensor product
print("op1.tensor(op2):")
print(op1.tensor(op2))
op1 + op2:
SparsePauliOp(['XIIZI', 'IYIIY', 'ZIIXX', 'IIZZI'],
coeffs=[ 1.+0.j, -1.+1.j, 1.+2.j, -1.+1.j])

2 * op1:
SparsePauliOp(['XIIZI', 'IYIIY'],
coeffs=[ 2.+0.j, -2.+2.j])

op1 @ op2:
SparsePauliOp(['YIIYX', 'XIZII', 'ZYIXZ', 'IYZZY'],
coeffs=[ 1.+2.j, -1.+1.j, -1.+3.j, 0.-2.j])

op1.tensor(op2):
SparsePauliOp(['XIIZIZIIXX', 'XIIZIIIZZI', 'IYIIYZIIXX', 'IYIIYIIZZI'],
coeffs=[ 1.+2.j, -1.+1.j, -3.-1.j, 0.-2.j])

Pauli

Pauli クラスは、集合 {+1,i,1,i}\set{+1, i, -1, -i} から選ばれた省略可能な位相係数を持つ単一のパウリ文字列を表します。Pauli{"I", "X", "Y", "Z"} の文字からなる文字列を渡すことで初期化できます。オプションとして、位相係数を表すために {"", "i", "-", "-i"} のいずれかを先頭に付けることができます。

op1 = Pauli("iXX")
op1
Pauli('iXX')

次のコードセルでは、いくつかの属性とメソッドの使用方法を示します。

print(f"Dimension of {op1}: {op1.dim}")
print(f"Phase of {op1}: {op1.phase}")
print(f"Matrix representation of {op1}: \n {op1.to_matrix()}")
Dimension of iXX: (4, 4)
Phase of iXX: 3
Matrix representation of iXX:
[[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.+1.j 0.+0.j 0.+0.j]
[0.+1.j 0.+0.j 0.+0.j 0.+0.j]]

Pauli オブジェクトには、随伴を求めたり、別の Pauli と(反)交換するかを判定したり、別の Pauli とのドット積を計算したりするなど、演算子を操作するための多くのメソッドが備わっています。詳細については API ドキュメントを参照してください。

Operator

Operator クラスは、一般的な線形演算子を表します。SparsePauliOp とは異なり、Operator は線形演算子を密行列として格納します。密行列の格納に必要なメモリはQubit数に対して指数関数的に増加するため、Operator クラスは少数のQubitでの使用にのみ適しています。

Operator を初期化するには、演算子の行列を格納した Numpy 配列を直接渡します。例えば、次のコードセルでは 2 Qubitのパウリ XX 演算子を作成します。

XX = Operator(
np.array(
[
[0, 0, 0, 1],
[0, 0, 1, 0],
[0, 1, 0, 0],
[1, 0, 0, 0],
]
)
)
XX
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))

演算子オブジェクトは、基底となる行列と、サブシステムの入力・出力次元を格納しています。

  • data: 基底となる Numpy 配列にアクセスするには、Operator.data プロパティを使用します。
  • dims: 演算子の入力・出力次元の合計を返すには、Operator.dim プロパティを使用します。注意: 出力はタプル (input_dim, output_dim) として返されますが、これは基底となる行列の形状とは逆順です。
XX.data
array([[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_dim, output_dim = XX.dim
input_dim, output_dim
(4, 4)

演算子クラスはサブシステムの次元も追跡しており、これを使って演算子を合成することができます。これらは input_dims および output_dims 関数を使ってアクセスできます。

2N2^N × 2M2^M の演算子については、入力・出力次元は自動的に M-QubitおよびN-Qubitと見なされます。

op = Operator(np.random.rand(2**1, 2**2))
print("Input dimensions:", op.input_dims())
print("Output dimensions:", op.output_dims())
Input dimensions: (2, 2)
Output dimensions: (2,)

入力行列がQubitサブシステムに分割できない場合は、単一のシステムの演算子として格納されます。例えば、6×66\times6 行列の場合:

op = Operator(np.random.rand(6, 6))
print("Input dimensions:", op.input_dims())
print("Output dimensions:", op.output_dims())
Input dimensions: (6,)
Output dimensions: (6,)

入力・出力次元は、新しい演算子を初期化するときに手動で指定することもできます。

# Force input dimension to be (4,) rather than (2, 2)
op = Operator(np.random.rand(2**1, 2**2), input_dims=[4])
print("Input dimensions:", op.input_dims())
print("Output dimensions:", op.output_dims())
Input dimensions: (4,)
Output dimensions: (2,)
# Specify system is a qubit and qutrit
op = Operator(np.random.rand(6, 6), input_dims=[2, 3], output_dims=[2, 3])
print("Input dimensions:", op.input_dims())
print("Output dimensions:", op.output_dims())
Input dimensions: (2, 3)
Output dimensions: (2, 3)

input_dims および output_dims 関数を使用して、サブシステムのサブセットの入力・出力次元だけを取り出すこともできます。

print("Dimension of input system 0:", op.input_dims([0]))
print("Dimension of input system 1:", op.input_dims([1]))
Dimension of input system 0: (2,)
Dimension of input system 1: (3,)

次のステップ

おすすめ