注釈

このページは docs/tutorials/06_qubit_mappers.ipynb から生成されました。

量子ビット空間へのマッピング#

Qiskit Natureで扱う問題や演算子は、量子アルゴリズムで解く前に (通常は) 量子ビット空間にマッピングされる必要があります。このタスクは様々な QubitMapper クラスによって処理されます。

このチュートリアルでは、利用可能なさまざまなオプションについて学びます。

フェルミオン・マッパー#

このセクションでは、フェルミオン演算子を量子ビット空間に変換する、フェルミオン・マッパーを扱います。これは主に電子構造スタック <01_electronic_structure.ipynb>`__ で使用されますが、FermiHubbardModel <TODO>`__ にも応用されています。

異なる特性を持つマッピングタイプが存在します。Qiskit Natureはすでに以下のフェルミオン・マッピングをサポートしています:

  • Jordan-Wigner (Zeitschrift für Physik, 47, 631-651 (1928))

  • Parity (The Journal of chemical physics, 137(22), 224109 (2012))

  • Bravyi-Kitaev (Annals of Physics, 298(1), 210-226 (2002))

以下のセクションで、これらのいくつかを説明します。どのマッパーでも快適に使えるように、必要な情報はすべて学んでください。

様々なマッピングを議論するために、H2分子の電子構造ハミルトニアンを使用します。入手方法の詳細は、`電子構造チュートリアル<01_electronic_structure.ipynb>`__を参照してください。

[1]:
from qiskit_nature.second_q.drivers import PySCFDriver

driver = PySCFDriver()
problem = driver.run()
fermionic_op = problem.hamiltonian.second_q_op()

Jordan-Wigner マッピング#

Jordan-Wignerマッピングは、1つのスピン軌道の占有を1つの量子ビットの占有にマッピングするため、最も単純なマッピングであり、物理的解釈も最もシンプルです。

7e7e1d0f66b8407a8fb4ac8253008448

以下のように構築できます。

[2]:
from qiskit_nature.second_q.mappers import JordanWignerMapper

mapper = JordanWignerMapper()
[3]:
qubit_jw_op = mapper.map(fermionic_op)
print(qubit_jw_op)
-0.8105479805373283 * IIII
+ 0.17218393261915543 * IIIZ
- 0.2257534922240237 * IIZI
+ 0.12091263261776633 * IIZZ
+ 0.17218393261915543 * IZII
+ 0.16892753870087907 * IZIZ
+ 0.045232799946057826 * YYYY
+ 0.045232799946057826 * XXYY
+ 0.045232799946057826 * YYXX
+ 0.045232799946057826 * XXXX
- 0.22575349222402363 * ZIII
+ 0.1661454325638241 * ZIIZ
+ 0.16614543256382408 * IZZI
+ 0.1746434306830045 * ZIZI
+ 0.12091263261776633 * ZZII
True

パリティ・マッピング#

パリティ・マッピングはJordan-Wignerマッピングの二重写像で、パリティ情報を1つの量子ビットに局所的に符号化するのに対し、占有情報はすべての量子ビットに非局在化されるという意味です。

[4]:
from qiskit_nature.second_q.mappers import ParityMapper

mapper = ParityMapper()
[5]:
qubit_p_op = mapper.map(fermionic_op)
print(qubit_p_op)
-0.8105479805373283 * IIII
+ 0.17218393261915543 * IIIZ
- 0.2257534922240237 * IIZZ
+ 0.12091263261776633 * IIZI
+ 0.17218393261915543 * IZZI
+ 0.16892753870087907 * IZZZ
+ 0.045232799946057826 * ZXIX
- 0.045232799946057826 * IXZX
- 0.045232799946057826 * ZXZX
+ 0.045232799946057826 * IXIX
- 0.22575349222402363 * ZZII
+ 0.1661454325638241 * ZZIZ
+ 0.16614543256382408 * IZIZ
+ 0.1746434306830045 * ZZZZ
+ 0.12091263261776633 * ZIZI

これは、各スピン種の粒子の数を保持したい問題の場合、1つの大きな利点があり、2つの量子ビットの情報が冗長になるため、それらを削除することができます。Qiskit Natureは、前半がアルファスピン、後半がベータスピンの情報をエンコードするように、ブロックオーダーで量子ビットを配置するので、N/2番目とN番目の量子ビットを削除することができることを意味します。

これを行うには、次のようにシステム内の粒子の数を指定する必要があります:

[6]:
mapper = ParityMapper(num_particles=problem.num_particles)
[7]:
qubit_op = mapper.map(fermionic_op)
print(qubit_op)
-1.0523732457728605 * II
+ 0.39793742484317896 * IZ
- 0.39793742484317896 * ZI
- 0.01128010425623538 * ZZ
+ 0.18093119978423122 * XX

より高度な量子ビット数の削減#

量子ビットのHilbert空間におけるZ2対称性を見つけることに基づいて、より高度な量子ビット削減を実行することもできます。この機能を利用するためには、どのような対称性-部分空間から実際の解を探す必要があるかが分かっている必要があります。これは少し厄介なことですが、幸運なことにQiskit Natureの問題クラスは、自動的に正しい部分空間を決定するユーティリティーを提供してくれます。

これをどう活用するか、ご紹介します:

[8]:
tapered_mapper = problem.get_tapered_mapper(mapper)
print(type(tapered_mapper))
<class 'qiskit_nature.second_q.mappers.tapered_qubit_mapper.TaperedQubitMapper'>
[9]:
qubit_op = tapered_mapper.map(fermionic_op)
print(qubit_op)
-1.041093141516625 * I
- 0.7958748496863577 * Z
- 0.1809311997842312 * X

このように、H2分子は非常にシンプルなシステムなので、1つの量子ビットで完全にシミュレーションできるのです!

インターリーブ順序#

前述の通りQisKit Natureは、量子ビット・レジスターのフェルミオン的スピンアップとスピンダウン部分をブロック順に整列します。 ただし、時にはレジスターをインターリーブしたい場合があります。 これは InterleavedQubitMapper によって実現できます。HarteFock 初期状態回路の検査時に最適に表示されます。

[10]:
from qiskit_nature.second_q.circuit.library import HartreeFock
[11]:
hf_state = HartreeFock(2, (1, 1), JordanWignerMapper())
hf_state.draw()
[11]:
     ┌───┐
q_0: ┤ X ├
     └───┘
q_1: ─────
     ┌───┐
q_2: ┤ X ├
     └───┘
q_3: ─────
          
[12]:
from qiskit_nature.second_q.mappers import InterleavedQubitMapper
[13]:
interleaved_mapper = InterleavedQubitMapper(JordanWignerMapper())
[14]:
hf_state = HartreeFock(2, (1, 1), interleaved_mapper)
hf_state.draw()
[14]:
     ┌───┐
q_0: ┤ X ├
     ├───┤
q_1: ┤ X ├
     └───┘
q_2: ─────

q_3: ─────
          
[15]:
import qiskit.tools.jupyter

%qiskit_version_table
%qiskit_copyright

Version Information

Qiskit SoftwareVersion
qiskit-terra0.24.0.dev0+2b3686f
qiskit-aer0.11.2
qiskit-ibmq-provider0.19.2
qiskit-nature0.6.0
System information
Python version3.9.16
Python compilerGCC 12.2.1 20221121 (Red Hat 12.2.1-4)
Python buildmain, Dec 7 2022 00:00:00
OSLinux
CPUs8
Memory (Gb)62.50002670288086
Thu Apr 06 09:11:44 2023 CEST

This code is a part of Qiskit

© Copyright IBM 2017, 2023.

This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.

Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.