注釈
このページは tutorials/algorithms/01_algorithms_introduction.ipynb から生成されました。
IBM Quantum lab でインタラクティブに実行します。
Qiskit におけるアルゴリズム入門¶
これは Qiskit によるアルゴリズムの入門編となっており、入門にあたって様々な機能の理解に役立つ高水準の概観を提供しています。その他のチュートリアルでは、アルゴリズムやその使用方法などについて、より詳細な資料を提供します。
アルゴリズム・ライブラリの構成¶
Qiskit は、多くの アルゴリズム を提供しており、それらは適用可能なタスクに応じてカテゴリーごとにグループ分けされています。例えば、化学的なハミルトニアンの基底エネルギーや、イジングハミルトニアンとして表現された最適化問題の解といった、演算子の最小固有値を求めるための Minimum Eigensolvers
があります。また、機械学習における分類問題のための Classifiers
や、金融アプリケーションなどに用いられる推定のための Amplitude Estimators
があります。カテゴリーの全セットは、上記リンク先のアルゴリズム・ドキュメントで見ることができます。
アルゴリズムは構成することが可能で、多くの場合、そうした構成の一部は小さな構成要素となっており、構成要素の型ごとに異なったインスタンスを指定することができます。例えば VQE
(Variational Quantum Eigensolver) は、試行波動関数を QuantumCircuit
の形で受け取り、また古典的なオプティマイザーなども受け取ります。このような構成要素は Components から、回路は Circuit Library から、それぞれ入手することができます。
VQE インスタンスを構築する例を見てみましょう。ここで TwoLocal
は変分形式 (試行波動関数) 、つまりパラメーター表示されている変分可能な回路であり、 SLSQP
は古典的なオプティマイザーです。これらは別々のインスタンスとして作成され、 VQE の構築時に渡されます。例えば、別の古典的なオプティマイザーや変分形式を試す場合には、単純に所望のインスタンスを作成して、 VQE に渡すだけでよいです。
[1]:
from qiskit.aqua.algorithms import VQE
from qiskit.aqua.components.optimizers import SLSQP
from qiskit.circuit.library import TwoLocal
num_qubits = 2
ansatz = TwoLocal(num_qubits, 'ry', 'cz')
opt = SLSQP(maxiter=1000)
vqe = VQE(var_form=ansatz, optimizer=opt)
VQE オプティマイザーが最小固有値を求める際の変分パラメーターが θ[0] から θ[7] であるような QuantumCircuit となっていることを確認するため、 ansatz を描画してみましょう。パラメータについては、後ほど作業例で説明します。
[2]:
ansatz.draw()
[2]:

しかしアルゴリズムの実行には、これだけではまだ不十分です。次に進みましょう。
アルゴリズムの実行¶
アルゴリズムを実行するためには、そのアルゴリズムを構成する回路の実行が可能なバックエンド、シミュレーター、実デバイスが必要です。例えば、 BasicAer プロバイダーの statevector_simulator
を用いることができます。
[3]:
from qiskit import BasicAer
backend = BasicAer.get_backend('statevector_simulator')
この時点で、バックエンド単体はどのように回路を動作させるかといった情報をもっていません。例えば、ショット数、ノイズモデルを使うかどうか、回路のトランスパイル周りのオプションなどです。そのため、Qiskit Aquaには QuantumInstance があり、バックエンドだけでなく、回路の処理や実行に関する様々な設定を提供しています。
[4]:
from qiskit.aqua import QuantumInstance
backend = BasicAer.get_backend('qasm_simulator')
quantum_instance = QuantumInstance(backend=backend, shots=800, seed_simulator=99)
注: バックエンドを直接提供した場合は、デフォルト設定で内部的に QuantumInstance が作成されるので、アルゴリズムは常に QuantumInstance を通して動作します。
この時点で、run() メソッドを呼び出すことができるようになりました。これは全てのアルゴリズムに共通のもので、アルゴリズムごとに特有の結果を戻り値とします。今回の場合は、 VQE が MinimumEigensolver であるので、 compute_mininum_eigenvalue() メソッドを使うことができます。後者は、 Chemistry や Optimization といったアプリケーション・モジュールのための選択肢となっているインターフェースであり、特定のカテゴリー内のどのアルゴリズムとも互換性をもって動作するようにすることができます。
完全な実例¶
Let’s put what we have learned from above together and create a complete working example. VQE will find the minimum eigenvalue, i.e. minimum energy value of a Hamiltonian operator and hence we need such an operator for VQE to work with. Such an operator is given below. This was originally created by the Chemistry application module as the Hamiltonian for an H2 molecule at 0.735A interatomic distance. It’s a sum of Pauli terms as below, but for now I am not going to say anything further about it since the goal is to run the algorithm, but further information on operators can be found in other tutorials.
[5]:
from qiskit.aqua.operators import X, Z, I
H2_op = (-1.052373245772859 * I ^ I) + \
(0.39793742484318045 * I ^ Z) + \
(-0.39793742484318045 * Z ^ I) + \
(-0.01128010425623538 * Z ^ Z) + \
(0.18093119978423156 * X ^ X)
では、コンストラクターに演算子と QuantumInstance によるバックエンドを渡して、 VQE インスタンスを作成してみましょう。ここで VQE にはセッターがあるので、演算子とバックエンドは後から渡すこともできます。これらを後から設定することは、問題特有の情報をもたないアルゴリズムを作成して、後からそれを利用するという場合に便利です。例えば、 Chemistry アプリケーション・モジュールを用いて、解くべき特定の化学の問題のための演算子を作成する場合です。
注: このノートブックを実行して全く同じ出力が得られるようにするため、 Aqua 全体で用いられている乱数生成器は aqua_globalsで、トランスパイラーとシミュレーターは QuantimInstance を通して、それぞれシード値が固定されています。このようにする必要は必ずしもありませんが、毎回全く同じ結果を再現したい場合にはこのようにします。
それでは VQE を実行して、その返り値を表示してみましょう。
[6]:
from qiskit.aqua import aqua_globals
seed = 50
aqua_globals.random_seed = seed
qi = QuantumInstance(BasicAer.get_backend('statevector_simulator'), seed_transpiler=seed, seed_simulator=seed)
ansatz = TwoLocal(rotation_blocks='ry', entanglement_blocks='cz')
slsqp = SLSQP(maxiter=1000)
vqe = VQE(operator=H2_op, var_form=ansatz, optimizer=slsqp, quantum_instance=qi)
result = vqe.run()
import pprint
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(result)
{ 'cost_function_evals': 72,
'eigenstate': array([-9.55448660e-05+2.12037105e-17j, 9.93766273e-01+2.25293943e-16j,
-1.11483565e-01+1.52657541e-16j, -1.77521351e-05+3.71607315e-17j]),
'eigenvalue': (-1.857275017559769+0j),
'optimal_parameters': { Parameter(θ[0]): 4.296520551468743,
Parameter(θ[1]): 4.426962086704216,
Parameter(θ[2]): 0.5470753710293924,
Parameter(θ[7]): 0.3602072316165878,
Parameter(θ[6]): -4.717618235040379,
Parameter(θ[5]): 1.5683261371389359,
Parameter(θ[3]): 6.09294789784282,
Parameter(θ[4]): -2.598325857134344},
'optimal_point': array([ 4.29652055, 4.42696209, 0.54707537, 6.0929479 , -2.59832586,
1.56832614, -4.71761824, 0.36020723]),
'optimal_value': -1.857275017559769,
'optimizer_evals': 72,
'optimizer_time': 1.310880184173584}
上記の結果から、与えられた H2 分子の電子の基底エネルギーである -1.85727
という最小固有値を得るまで、オプティマイザーが 72
回のパラメーター評価を要したことがわかります。また、 ansatz の最適パラメーターは、 ansatz が最小値であったときの値を見ればわかります。
MinimumEigensolver としての VQE¶
最後に、 MinimumEigensolver インターフェースを用いて、演算子も QuantumInstance も与えずに VQE インスタンスを作成してみましょう。後から QusntumInstance を設定し、最後に演算子を compute_minimum_eigenvalue
メソッドに渡します。 (ただし、 VQE が実行されるまでに演算子がありさえすれば、より早い段階でセッターによって渡しておいても構いません。)
[7]:
aqua_globals.random_seed = seed
qi = QuantumInstance(BasicAer.get_backend('statevector_simulator'), seed_transpiler=seed, seed_simulator=seed)
ansatz = TwoLocal(rotation_blocks='ry', entanglement_blocks='cz')
slsqp = SLSQP(maxiter=1000)
vqe = VQE(var_form=ansatz, optimizer=slsqp)
vqe.quantum_instance = qi
result = vqe.compute_minimum_eigenvalue(operator=H2_op)
pp.pprint(result)
{ 'cost_function_evals': 72,
'eigenstate': array([-9.55448660e-05+2.12037105e-17j, 9.93766273e-01+2.25293943e-16j,
-1.11483565e-01+1.52657541e-16j, -1.77521351e-05+3.71607315e-17j]),
'eigenvalue': (-1.857275017559769+0j),
'optimal_parameters': { Parameter(θ[4]): -2.598325857134344,
Parameter(θ[5]): 1.5683261371389359,
Parameter(θ[6]): -4.717618235040379,
Parameter(θ[7]): 0.3602072316165878,
Parameter(θ[1]): 4.426962086704216,
Parameter(θ[0]): 4.296520551468743,
Parameter(θ[2]): 0.5470753710293924,
Parameter(θ[3]): 6.09294789784282},
'optimal_point': array([ 4.29652055, 4.42696209, 0.54707537, 6.0929479 , -2.59832586,
1.56832614, -4.71761824, 0.36020723]),
'optimal_value': -1.857275017559769,
'optimizer_evals': 72,
'optimizer_time': 2.8010470867156982}
先ほどの例と同じシード値が使われているので、結果は同じであることがわかります。
これで Qiskit におけるアルゴリズムの入門編は終了です。このシリーズの他のアルゴリズム・チュートリアルでは、より広い範囲のアルゴリズムをより詳細に学ぶことができます。
[8]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright
Version Information
Qiskit Software | Version |
---|---|
Qiskit | 0.23.1 |
Terra | 0.16.1 |
Aer | 0.7.1 |
Ignis | 0.5.1 |
Aqua | 0.8.1 |
IBM Q Provider | 0.11.1 |
System information | |
Python | 3.7.8 | packaged by conda-forge | (default, Jul 31 2020, 02:25:08) [GCC 7.5.0] |
OS | Linux |
CPUs | 8 |
Memory (Gb) | 31.40900421142578 |
Fri Jan 15 12:11:24 2021 UTC |
This code is a part of Qiskit
© Copyright IBM 2017, 2021.
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.
[ ]: