注釈

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

励起状態ソルバー#

はじめに#

6ea4a5eac56541b68cea6190b1b7fe29

このチュートリアルでは、Qiskit Natureの励起状態計算インターフェースについて説明します。 目的は分子ハミルトニアンの励起状態を計算することです。 このハミルトニアンは、電子的あるいは振動的なものである可能性があります。 ハミルトニアンの準備についての詳細は、 電子構造振動構造のチュートリアル を参照してください。

まず分子系の定義から始めます。以下では、水素分子の電子部分を求めています。

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

driver = PySCFDriver(
    atom="H 0 0 0; H 0 0 0.735",
    basis="sto3g",
    charge=0,
    spin=0,
    unit=DistanceUnit.ANGSTROM,
)

es_problem = driver.run()

また、Jordan-Wignerマッピングを使う予定です。Qiskit Natureで利用できる様々なマッパーについてもっと知りたい方は、量子ビット空間への変換 をチェックしてください。

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

mapper = JordanWignerMapper()

ソルバー#

次に、ソルバーを定義する必要があります。ソルバーとは、励起状態を求めるアルゴリズムのことです。

まず、純粋に古典的な NumPyEigensolver の例から始めましょう。このアルゴリズムは、ハミルトニアンを正確に対角化します。これは規模の大きな問題には適用できませんが、小さな系で量子アルゴリズムの結果を確認するために用いることができます。ここでは、与えられた粒子数の固有状態にのみ関心があります。これらの状態のみを計算するために、フィルター関数を ``NumPyEigensolver``に渡します。この目的で使用できるデフォルトのフィルター関数は Qiskit Natureで既に実装されています。

また、NumPyEigensolver で計算する固有値の数を指定する必要があります。 この特定のシステムにおいて、私たちは基底状態と最初の3つの励起状態に興味を持っていますので、 k=4 を設定します (デフォルトは 1 ですので、必ず設定してください。さもないと、基底状態だけを取得します)。

[3]:
from qiskit_algorithms import NumPyEigensolver

numpy_solver = NumPyEigensolver(k=4, filter_criterion=es_problem.get_default_filter_criterion())

励起エネルギーは、 qEOM アルゴリズム <https://journals.aps.org/prresearch/abstract/10.1103/PhysRevResearch.2.043140>`__によっても求めることができます。 EOM 法は、以下の擬似固有値問題を解くことにより、励起エネルギー (基底状態と全ての第 :math:`n 励起状態との間のエネルギー差) を求めます。

\[\begin{split}\begin{pmatrix} \text{M} & \text{Q}\\ \text{Q*} & \text{M*} \end{pmatrix} \begin{pmatrix} \text{X}_n\\ \text{Y}_n \end{pmatrix} = E_{0n} \begin{pmatrix} \text{V} & \text{W}\\ -\text{W*} & -\text{V*} \end{pmatrix} \begin{pmatrix} \text{X}_n\\ \text{Y}_n \end{pmatrix}\end{split}\]

ただし

\[M_{\mu_{\alpha}\nu_{\beta}} = \langle0| [(\hat{\text{E}}_{\mu_{\alpha}}^{(\alpha)})^{\dagger},\hat{\text{H}}, \hat{\text{E}}_{\nu_{\beta}}^{(\beta)}]|0\rangle\]
\[Q_{\mu_{\alpha}\nu_{\beta}} = -\langle0| [(\hat{\text{E}}_{\mu_{\alpha}}^{(\alpha)})^{\dagger}, \hat{\text{H}}, (\hat{\text{E}}_{\nu_{\beta}}^{(\beta)})^{\dagger}]|0\rangle\]
\[V_{\mu_{\alpha}\nu_{\beta}} = \langle0| [(\hat{\text{E}}_{\mu_{\alpha}}^{(\alpha)})^{\dagger}, \hat{\text{E}}_{\nu_{\beta}}^{(\beta)}]|0\rangle\]
\[W_{\mu_{\alpha}\nu_{\beta}} = -\langle0| [(\hat{\text{E}}_{\mu_\alpha}^{(\alpha)})^{\dagger}, (\hat{\text{E}}_{\nu_{\beta}}^{(\beta)})^{\dagger}]|0\rangle\]

上の式は古典的に解くことができますが、各行列要素は対応する基底状態を量子コンピュータ上で測定しなければなりません。QiskitでqEOMをソルバーとして使用するには、まず基底状態の計算を定義する必要があり、これにより必要な基底状態の情報をアルゴリズムに提供することができます。これにより、qEOMソルバーは次のように初期化することができます:

[4]:
from qiskit_algorithms import VQE
from qiskit_algorithms.optimizers import SLSQP
from qiskit.primitives import Estimator
from qiskit_nature.second_q.algorithms import GroundStateEigensolver, QEOM, EvaluationRule
from qiskit_nature.second_q.circuit.library import HartreeFock, UCCSD

ansatz = UCCSD(
    es_problem.num_spatial_orbitals,
    es_problem.num_particles,
    mapper,
    initial_state=HartreeFock(
        es_problem.num_spatial_orbitals,
        es_problem.num_particles,
        mapper,
    ),
)

estimator = Estimator()
# This first part sets the ground state solver
# see more about this part in the ground state calculation tutorial
solver = VQE(estimator, ansatz, SLSQP())
solver.initial_point = [0.0] * ansatz.num_parameters
gse = GroundStateEigensolver(mapper, solver)

# The qEOM algorithm is simply instantiated with the chosen ground state solver and Estimator primitive
qeom_excited_states_solver = QEOM(gse, estimator, "sd", EvaluationRule.ALL)

計算と結果#

これで結果を計算する準備ができました。以下では、デフォルトのフィルター基準を有効にして、厳密な NumPyEigensolver で得られた結果と、qEOMアルゴリズムで得られた結果を比較しています。

[5]:
from qiskit_nature.second_q.algorithms import ExcitedStatesEigensolver

numpy_excited_states_solver = ExcitedStatesEigensolver(mapper, numpy_solver)
numpy_results = numpy_excited_states_solver.solve(es_problem)

qeom_results = qeom_excited_states_solver.solve(es_problem)

print(numpy_results)
print("\n\n")
print(qeom_results)
=== GROUND STATE ENERGY ===

* Electronic ground state energy (Hartree): -1.857275030202
  - computed part:      -1.857275030202
~ Nuclear repulsion energy (Hartree): 0.719968994449
> Total ground state energy (Hartree): -1.137306035753

=== EXCITED STATE ENERGIES ===

  1:
* Electronic excited state energy (Hartree): -0.882722150245
> Total excited state energy (Hartree): -0.162753155796
  2:
* Electronic excited state energy (Hartree): -0.224911252831
> Total excited state energy (Hartree): 0.495057741618

=== MEASURED OBSERVABLES ===

  0:  # Particles: 2.000 S: 0.000 S^2: 0.000 M: 0.000
  1:  # Particles: 2.000 S: 0.000 S^2: 0.000 M: 0.000
  2:  # Particles: 2.000 S: 0.000 S^2: 0.000 M: 0.000

=== DIPOLE MOMENTS ===

~ Nuclear dipole moment (a.u.): [0.0  0.0  1.3889487]

  0:
  * Electronic dipole moment (a.u.): [0.0  0.0  1.388948701555]
    - computed part:      [0.0  0.0  1.388948701555]
  > Dipole moment (a.u.): [0.0  0.0  -0.000000001555]  Total: 0.000000001555
                 (debye): [0.0  0.0  -0.000000003953]  Total: 0.000000003953

  1:
  * Electronic dipole moment (a.u.): [0.0  0.0  1.388948701555]
    - computed part:      [0.0  0.0  1.388948701555]
  > Dipole moment (a.u.): [0.0  0.0  -0.000000001555]  Total: 0.000000001555
                 (debye): [0.0  0.0  -0.000000003953]  Total: 0.000000003953

  2:
  * Electronic dipole moment (a.u.): [0.0  0.0  1.388948701555]
    - computed part:      [0.0  0.0  1.388948701555]
  > Dipole moment (a.u.): [0.0  0.0  -0.000000001555]  Total: 0.000000001555
                 (debye): [0.0  0.0  -0.000000003953]  Total: 0.000000003953




=== GROUND STATE ENERGY ===

* Electronic ground state energy (Hartree): -1.857275030145
  - computed part:      -1.857275030145
~ Nuclear repulsion energy (Hartree): 0.719968994449
> Total ground state energy (Hartree): -1.137306035696

=== EXCITED STATE ENERGIES ===

  1:
* Electronic excited state energy (Hartree): -1.244586756145
> Total excited state energy (Hartree): -0.524617761696
  2:
* Electronic excited state energy (Hartree): -0.882724356546
> Total excited state energy (Hartree): -0.162755362097
  3:
* Electronic excited state energy (Hartree): -0.224913459141
> Total excited state energy (Hartree): 0.495055535308

=== MEASURED OBSERVABLES ===

  0:  # Particles: 2.000 S: 0.000 S^2: 0.000 M: 0.000
  1:  # Particles: 2.000 S: 1.000 S^2: 2.000 M: 0.000
  2:  # Particles: 2.000 S: 0.000 S^2: -0.000 M: 0.000
  3:  # Particles: 2.000 S: 0.000 S^2: 0.000 M: -0.000

=== DIPOLE MOMENTS ===

~ Nuclear dipole moment (a.u.): [0.0  0.0  1.3889487]

  0:
  * Electronic dipole moment (a.u.): [0.0  0.0  1.388948961657]
    - computed part:      [0.0  0.0  1.388948961657]
  > Dipole moment (a.u.): [0.0  0.0  -0.000000261657]  Total: 0.000000261657
                 (debye): [0.0  0.0  -0.000000665065]  Total: 0.000000665065

  1:
  * Electronic dipole moment (a.u.): [0.0  0.0  1.388948701647]
    - computed part:      [0.0  0.0  1.388948701647]
  > Dipole moment (a.u.): [0.0  0.0  -0.000000001647]  Total: 0.000000001647
                 (debye): [0.0  0.0  -0.000000004186]  Total: 0.000000004186

  2:
  * Electronic dipole moment (a.u.): [0.0  0.0  1.388949035771]
    - computed part:      [0.0  0.0  1.388949035771]
  > Dipole moment (a.u.): [0.0  0.0  -0.000000335771]  Total: 0.000000335771
                 (debye): [0.0  0.0  -0.000000853445]  Total: 0.000000853445

  3:
  * Electronic dipole moment (a.u.): [0.0  0.0  1.388948738594]
    - computed part:      [0.0  0.0  1.388948738594]
  > Dipole moment (a.u.): [0.0  0.0  -0.000000038594]  Total: 0.000000038594
                 (debye): [0.0  0.0  -0.000000098097]  Total: 0.000000098097

これらの結果から、NumPyの結果から1つの状態が欠落していることがわかります。これは、スピンがフィルターとしても使用され、一重項状態のみが表示されるためです。以下では、カスタムフィルター関数を使用して、結果を一貫してチェックし、間違った粒子数 (この場合の粒子数は2) の状態だけでなく、誤った磁化 (この場合0に強制) をフィルタリングします。

[6]:
import numpy as np


def filter_criterion(eigenstate, eigenvalue, aux_values):
    return np.isclose(aux_values["ParticleNumber"][0], 2.0) and np.isclose(
        aux_values["Magnetization"][0], 0.0
    )


new_numpy_solver = NumPyEigensolver(k=4, filter_criterion=filter_criterion)
new_numpy_excited_states_solver = ExcitedStatesEigensolver(mapper, new_numpy_solver)
new_numpy_results = new_numpy_excited_states_solver.solve(es_problem)

print(new_numpy_results)
=== GROUND STATE ENERGY ===

* Electronic ground state energy (Hartree): -1.857275030202
  - computed part:      -1.857275030202
~ Nuclear repulsion energy (Hartree): 0.719968994449
> Total ground state energy (Hartree): -1.137306035753

=== EXCITED STATE ENERGIES ===

  1:
* Electronic excited state energy (Hartree): -1.244584549813
> Total excited state energy (Hartree): -0.524615555364
  2:
* Electronic excited state energy (Hartree): -0.882722150245
> Total excited state energy (Hartree): -0.162753155796
  3:
* Electronic excited state energy (Hartree): -0.224911252831
> Total excited state energy (Hartree): 0.495057741618

=== MEASURED OBSERVABLES ===

  0:  # Particles: 2.000 S: 0.000 S^2: 0.000 M: 0.000
  1:  # Particles: 2.000 S: 1.000 S^2: 2.000 M: 0.000
  2:  # Particles: 2.000 S: 0.000 S^2: 0.000 M: 0.000
  3:  # Particles: 2.000 S: 0.000 S^2: 0.000 M: 0.000

=== DIPOLE MOMENTS ===

~ Nuclear dipole moment (a.u.): [0.0  0.0  1.3889487]

  0:
  * Electronic dipole moment (a.u.): [0.0  0.0  1.388948701555]
    - computed part:      [0.0  0.0  1.388948701555]
  > Dipole moment (a.u.): [0.0  0.0  -0.000000001555]  Total: 0.000000001555
                 (debye): [0.0  0.0  -0.000000003953]  Total: 0.000000003953

  1:
  * Electronic dipole moment (a.u.): [0.0  0.0  1.388948701555]
    - computed part:      [0.0  0.0  1.388948701555]
  > Dipole moment (a.u.): [0.0  0.0  -0.000000001555]  Total: 0.000000001555
                 (debye): [0.0  0.0  -0.000000003953]  Total: 0.000000003953

  2:
  * Electronic dipole moment (a.u.): [0.0  0.0  1.388948701555]
    - computed part:      [0.0  0.0  1.388948701555]
  > Dipole moment (a.u.): [0.0  0.0  -0.000000001555]  Total: 0.000000001555
                 (debye): [0.0  0.0  -0.000000003953]  Total: 0.000000003953

  3:
  * Electronic dipole moment (a.u.): [0.0  0.0  1.388948701555]
    - computed part:      [0.0  0.0  1.388948701555]
  > Dipole moment (a.u.): [0.0  0.0  -0.000000001555]  Total: 0.000000001555
                 (debye): [0.0  0.0  -0.000000003953]  Total: 0.000000003953

[7]:
import qiskit.tools.jupyter

%qiskit_version_table
%qiskit_copyright

Version Information

Qiskit SoftwareVersion
qiskit-terra0.24.1
qiskit-nature0.7.0
System information
Python version3.10.11
Python compilerGCC 12.2.1 20221121 (Red Hat 12.2.1-4)
Python buildmain, Apr 5 2023 00:00:00
OSLinux
CPUs8
Memory (Gb)62.48404312133789
Wed Jun 07 10:45:42 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.