QuTiPの短いパルス計算、出力間隔と積分刻みを分けて確かめる

淡い青の細い峰を小さな粒の列がたどり、その上を間隔の広い白い小石が並ぶ抽象的な風景。

量子ビットに短い制御パルスを加えたのに、計算結果では何も起きていない。保存する時刻を細かくしても、同じ結果が返ってくることがあります。時間発展を計算するQuTiPでは、結果を取り出す時刻と、微分方程式を解く内部の刻みを分けて考える必要があります。

ここではQuTiP 5.1.1のsesolveを使い、答えを式で求められる一つの短いパルスを計算します。出力点、内部刻み、許容誤差のどれを変えたかを分けると、精度を確かめる手順が見えてきます。実機の性能比較ではなく、同じ数理モデルを解く設定の比較です。

簡単にまとめると?

  • tlistは結果を取り出す時刻列、max_stepは内部の1ステップの長さの上限です。出力点を増やしても、内部刻みを同じ間隔に固定したことにはなりません。
  • 今回の矩形パルスでは、出力点の増加や許容誤差の厳格化だけでは変化を捉えられませんでした。まずパルス幅に対して内部刻みを十分短くし、その後に誤差の変化を比べます。
  • 配列で波形を渡す場合、時刻列は補間する波形の定義にも関わります。同じ物理モデルを比較しているかも確認します。

二つの「時間の細かさ」

sesolveは、初期状態とハミルトニアンからシュレーディンガー方程式を解きます。ハミルトニアンは、どの向きへどれだけ状態を変化させるかを記述する演算子です。tlistに0、1、2を渡せば、その3時刻の状態や期待値を結果として受け取れます。

一方、数値積分器は結果を求める途中で内部ステップを進めます。今回選ぶAdams法では、その長さを状況に応じて変えます。出力点は内部計算の到達要求にはなりますが、隣り合う出力点の間隔を内部ステップの上限として指定するものではありません。波形がほぼゼロの区間で大きな刻みが選ばれると、その途中にある短い変化が計算に十分反映されないことがあります。

設定 役割 変えたときの確認点
tlist 結果を受け取る時刻列 見たい時刻を含むか。波形配列にも使っていないか
max_step 内部1ステップの長さの上限 最短のパルスに対して十分短いか
nsteps 隣接する出力時刻間で許す内部ステップ数の上限 短い刻みで必要になる回数を許せるか
atol / rtol 積分器の絶対・相対許容誤差 厳しくしたとき観測量がどれだけ変わるか

nstepsを増やすのは、使える回数の上限を広げる操作です。その回数で必ず計算させる指定ではありません。また、atolとrtolは積分器の誤差制御の設定であり、最終的な測定確率の誤差をその数値以下に保証するものでもありません。

答えが分かる短いパルスで試す

初期状態を|0>、ハミルトニアンをH(t)=Ω(t)σx/2とします。σxは二つの基底状態を入れ替えるパウリ演算子です。ℏ=1とし、時間は無次元で0から2まで。Ω(t)は0.45以上0.55未満でπ/0.1、それ以外では0となる矩形パルスに固定します。幅0.1の間だけ回転を加える設定です。

この例では回転軸が変わらないため、角度θ(t)=∫Ω(s)dsから、|1>にある確率をP1(t)=sin²[θ(t)/2]と計算できます。パルス全体の面積はπなので、パルス後の正解はP1=1です。数値計算が0のままなら、小さな丸め誤差ではなく、状態の変化を取り落としていると分かります。

波形は同じ関数を全比較に渡しました。実行環境はQuTiP 5.1.1、NumPy 1.26.4、SciPy 1.17.1、Python 3.12.14です。積分法はadams、nsteps=100000とし、数値誤差を見える形で残すため出力の正規化を無効にしました。3点の出力時刻は[0, 1, 2]、201点は0から2までの等間隔です。

幅0.1の矩形パルスと、出力点を増やすだけでは状態変化を捉えず、内部刻みを制限すると解析解に近づく比較図
上段は計算に与えた同じパルス、下段は|1>の確率。点線は解析解、赤は出力201点・内部刻み上限の指定なし、青は出力201点・max_step=0.005かつ許容誤差を厳しくした計算。時間は無次元。下記条件の計算から作図。

出力点を増やすだけでは直らなかった

比較 出力点数 max_step atol / rtol 最後のP₁と1との差
A 基準 3 0(指定なし) 10⁻⁸ / 10⁻⁶ 1
B 出力点だけ増加 201 0 10⁻⁸ / 10⁻⁶ 1
C 内部刻みを制限 3 0.01 10⁻⁸ / 10⁻⁶ 約3.05×10⁻⁵
D 上限を半分へ 3 0.005 10⁻⁸ / 10⁻⁶ 約3.05×10⁻⁵
G Dの許容誤差を厳格化 3 0.005 10⁻¹⁰ / 10⁻⁸ 約9.65×10⁻⁸
E 許容誤差だけ厳格化 3 0 10⁻¹² / 10⁻¹⁰ 1

表の差は絶対値です。A、B、Eでは最後のP1が0のままでした。Bはパルス区間にも出力点を置いていますが、それだけでは改善していません。内部刻みの上限を0.01にしたCでは、正解との差が約3万分の1になりました。ただし、上限をさらに半分にしたDでは差がほとんど変わらず、許容誤差も厳しくしたGで小さくなりました。

CとDのP1は約1.0000305です。確率が物理的に1を超えるという意味ではありません。正規化を無効にした数値状態に残る誤差です。正規化後の見かけだけで精度を判断せず、状態のノルムや解析解との差も確認する理由がここにあります。

図の青線はGと同じ内部刻み・許容誤差で出力を201点にしたFで、最後の差は約1.68×10⁻⁷でした。出力点の変更も計算経路に影響し得るので、結果が完全に同じになるとは限りません。この一例を、あらゆる波形や積分法で同じ誤差になるという予測に使うことはできません。

波形を配列で渡すときは、もう一つ確認する

今回の比較は、任意の時刻でΩ(t)を返す関数を使っています。ところがQuTiPのQobjEvoへ係数を数値配列で渡す場合、対応するtlistは波形を定義する点にもなります。5.1.1では既定の補間は3次スプラインで、order=0なら直前の値を使う段階的な補間になります。

したがって、波形配列を作り直しながら時刻列を細かくすると、「結果を取り出す点」だけでなく「解いている波形」も変えている可能性があります。矩形パルスを想定したのに、補間によって端の形が変わっていないか。比較前に係数そのものを描き、同じ入力を保っているかを確かめます。

Open Quantum Designの公開エミュレーターでも、今回参照した固定版ではdtを用いて時刻列を作り、sesolveへ渡しています。上位ツールにある「時間刻み」という名前だけで内部積分の設定まで決めつけず、どの引数へ届くかを確認することが大切です。公開実装の構成はOQDの既存解説で扱っています。

自分の計算で確かめる順序

まず波形の最短の時間幅を調べ、出力時刻と内部刻みを区別します。QuTiP 5.1.1のsesolve資料は、パルスを使う場合のmax_stepを最短パルス幅の半分より短くするよう案内しています。これは精度確認の出発点であり、最終結果の保証ではありません。

次に、同じ波形でmax_stepを半分にし、必要に応じてatolとrtolを厳しくして、目的の観測量を比較します。解析解がある小さな系や、既知の保存量も確認先になります。上限を短くして計算回数が足りなくなった場合はnstepsも確認します。結果が安定したことと、ハミルトニアンや雑音モデルが実機を正しく表していることは、別の検証です。

保存点を増やせばグラフは細かく描けます。しかし、そのグラフが信頼できるかは、見えていない内部計算と入力波形も含めて確かめる必要があります。

参考資料