Skip to main content
IBM Quantum Platform

Qiskit Fermions リリースノート


0.2.0

序曲

今回のリリースにより、このパッケージによる回路合成の制御機能がさらに強化されました。 Anゲート Evolution は現在、明示的な synthesis メソッドを受け取るようになり、新しいモジュール synthesis が1次および高次のフェルミオン積の式を提供し、 FermionicTrotterization passは回路内のすべての進化に対して一度に1つを選択して適用するようになった。 これに伴い、Jordan-Wigner マッパーでは 4 つの演算子表現すべてに対する直接実装が追加され、新しいアダプタにより、マッパーの出力をグループごとに簡略化したり、グループ単位で出力したりできるようになりました。 C APIは大幅に追いついた。 エッジ頂点および転送頂点の表現、それらのマッパー、およびそれらの代数は、演算子のサポート、セクターの保存、インプレース演算、スケーリング演算、グループの順序付けと同様に、Cから利用可能になりました。 また、両方のAPIは、FCIDumpによって解析された電子積分へのアクセスも可能になりました。これまでは、データ構造全体をオペレータに変換することでしかアクセスできませんでした。 さらに、今回のリリースでは、このパッケージの用途についてより明確な境界線を引いています。具体的には、フェルミオン演算子、それらを変換するマッパー、そしてマッパーに依存しない回路とそのトランスパイレーションです。 シミュレーションは ffsimの担当であるため、ネイティブのFCIカーネルおよびそれを複製していた線形代数ユーティリティは削除され、代わりにffsimに処理を委譲するようになりました。また、 および UCC ゲート UCJ は、パラメータ化を再実装するのではなく、ffsimの演算子をラップするようになりました。 したがって、シミュレーションには追加 ffsim の機能が必要となり、ffsimが PySCF, に依存しているため、Windowsでは利用できません。一方、演算子の構築、マッピング、および結果として得られる回路のトランスパイルは、すべてのプラットフォームで引き続きサポートされています。 これは依然として pre-1.0 のリリースであるため、これらの変更はすべて非推奨化ではなく削除によって行われました。以下のアップグレードノートでは、削除されたAPIとそれに代わるAPIをそれぞれ対にして記載していますので、アップグレードを行う前に全文をよくお読みになることをお勧めします。

Python APIの機能

  • フェルミオン空間における ゲ Evolution ートの分解方法は、Qiskitの の 引数 synthesis と同様に、新たに追加されたキーワードのみの synthesis 引数を通じて設定可能になりました PauliEvolutionGate。 利用可能なメソッドは新しい qiskit_fermions.circuit.library.synthesis モジュール内にあり、このモジュールは FermionicEvolutionSynthesis インターフェースとその一階の実装 FermionicLieTrotter を提供しています。

    このフェルミオンからフェルミオンへの変換ステップは任意です。つまり、その演算子がいくつの項を含んでいようとも、aゲ Evolution ートをフェルミオンから量子ビットへの変換ステージに直接渡すことができます。 事前に因数分解を行うのは、より安価な因数を得るため、あるいは後の段階で活用できる構造(互いに可換であることなど groups)を明らかにするための選択肢である。 書き換えの双方がフェルミオン空間にとどまるため、その構造は書き換え後も維持されます。この点こそが、これらの手法では活用できる一方で、Qiskitでは活用 EvolutionSynthesis できない点なのです。

    デフォルト設定は変更されていません。をのままにすると synthesis が使用 None され FermionicLieTrotter、これによりが以前に行 Evolution っていた分解が完全に再現されるため、既存の回路はまったく同じように合成されます。

  • のサンプリング重みは、呼び出しのたびに進化演算子から導出されるのではなく、新しいキーワード専用 weights 引数を通じて指定できるよう QDriftTrotterization になりました。 None (デフォルトの)設定のままにしておくと、以前とまったく同じ動作をするため、既存の回路は同じようにサンプリングされます。

    これはパフォーマンス上の選択肢です。デフォルトのパスでは、``の呼び出しごとに、 演算子項ごとの値をグループごとに1つに集約しますが run()、単一のハミルトニアンからアンサンブルを生成する場合、結果は毎回同一であるにもかかわらず、この処理が繰り返し行われることになります。 代わりに group_coeff_means() 、と組み合わせて一度だけ導出すると group_order()、グループの検索が同じループの外側に移されます:

    hamiltonian = group_order(hamiltonian)
    weights = group_coeff_means(hamiltonian)
    pm.optimization = FermionicPassManager(
        [QDriftTrotterization(num_groups, weights=weights)]
    )

    各要素は非負でなければならない。なぜなら、重みは、 qDRIFT による分解 H=∑jhjHjH = \sum_j h_j H_j の絶対値 hjh_j であり、この分解において係数の符号は HjH_j に属し、進化演算子から直接読み取られるからである。

    渡された配列には、2つの制約が伴います。 そのスケールは自由ではありません。重みの合計は共有の進化時間も決定するため、各エントリに を乗じると、サンプリング gamma は同一になりますが、進化時間は となります gamma * t。 また、この配列は特定の演算子の項(またはグループ)を表しているため、その長さは適用されるすべてのゲート Evolution に対して検証され、そのようなゲートを2つ以上含む回路は却下されます。この設定を「未設定 weights 」のままにしておくと、各ゲートが独自の長さを導出するため、そのような回路もサポートされ続けます。

  • FCIDump これによって、これまでデータ構造全体を.に変換しなければアクセスできなかった、解析済みの電子積分が公開されるようになった FermionOperator。 新しいメソッドは、 NumPy 配列として読み取り専用のコピーを返します。そのレイアウトは、電子積分コンストラクタが使用するのと同じ平坦化されたレイアウトです: get_one_body_tril_a(), get_one_body_tril_b(), get_two_body_tril_aa(), および get_two_body_tril_ab() get_two_body_tril_bb()。 ベータ・スピン・アレイは、スピン制限のあるファイルに対して None 結果を返します。新しい属性 is_unrestricted は、これら3つすべてについて一度に結果を報告します。 新しい属性 constant は、定数(核反発)エネルギーを指定します。ファイルに何も指定されていない None 場合は、

    fcidump = FCIDump.from_file("molecule.fcidump")
    one_body = fcidump.get_one_body_tril_a()
    two_body = fcidump.get_two_body_tril_aa()

    なお、 は他の2体配列とはパッキング get_two_body_tril_ab() 方法が異なります。これは4回対称であるため、行列 (npair, npair) 全体を保持しており、その行のペアがアルファスピン種を、列のペアがベータスピン種をそれぞれ指し示しています。 各配列のインデックス計算式については、クラスのドキュメントを参照してください。 例えば、サンプルベースの対角化ツールで必要とされるように、これらを高密度 または (norb, norb) テンソル (norb,) * 4 に展開することは、呼び出し側の責任となります。

  • フェルミオン空間における ゲ Evolution ートを分解するための高次積の公式を追加した FermionicSuzukiTrotter。 各因子を一度適用 FermionicLieTrotter する場合、これらは対称的に組み合わされ、低次の誤差項が相殺される。また、その引数 reps によって、進化はいくつかのより短いステップに分割される:

    Evolution(num_modes, operator, time=1.0, synthesis=FermionicSuzukiTrotter(order=2, reps=4))

    これはフェルミオン演算子に対して作用するため、その演算子が割り当てられている箇所 groups に沿ってそれを分割する――この分割は、フェルミオンから量子ビットへの写像の後に適用される積の公式では利用できなくなってしまう。 3つのフローセットにグループ化された6モードのフェルミ・ハバード鎖において、 は order=2 、2量子ビットゲートの数をわずかに減らしながら、2次量子ビット側の式に比べてトロッター誤差を約2分の1に低減することに成功 reps=4 した。

    FermionicLieTrotter このファミリーの第一階の要素であり、現在はそのように実装されている。これにより、以前は欠けていた reps 引数も得られるようになった。 両者は等しい値において互換性がある reps。

    なお、高次の式ほど精度が高くなる一方で、計算の深さが増すことに注意してください。高次の式(order-formulak )は、 order-2 の式に比べて、およそ 倍 5**((k-2)/2) の因子を生成します。 また、分解された回路の精度は、フェルミオン式とフェルミオン-クビット式のいずれか弱い方の式によって決まるため、後者が1次式のままである状態で、ここで次数を上げてもほとんど意味がないことに留意すべきである。

  • 回路内のすべてのゲ Evolution ートを FermionicTrotterization、あるフェルミオン間合成法を用いて「トロッター化」するトランスパイラー・パスを追加した:

    pm.optimization = FermionicPassManager(
        [FermionicTrotterization(FermionicSuzukiTrotter(order=2, reps=4))]
    )

    ゲートごとに合成手法を選択するということは、そのゲートを構成するすべての要素――内部で独自に構築される や UCC も含めて―― Evolution をすべて通していくことを意味します UCJ。 このパスでは、パイプライン全体に対して一度だけ選択を行います。 オプションの述語 filter は、ゲートの部分集合にそれを制限するものであり、回路において、高次から恩恵を受ける進化とそうでない進化が混在している場合(例えば、の全可換対角クーロン演算子など)に、これを活用する価値がある UCJ。

    このパスは、選択された各ゲートを、そのメソッドが生成する因数に展開するため、別途展開処理を行う必要はありません。 Pass を指定 apply=False してメソッドのみを選択し、展開は Qiskit などの他の処理に委ねます Decompose。なお、一度も展開されないゲートは、フェルミオンから量子ビットへの変換段階にそのまま到達し、そこで読み取られる Evolution.synthesis ことなくマッピングされます。

  • この qiskit_fermions.operators.terms.grouping モジュールでは、グループインデックスの割り当てに加え、既存のグループ分けの分析についても扱うようになりました。 グループインデックスには本質的な意味がないため、新しい関数のいずれも、グループ分けが「正しい」かどうかを報告するものではありません。各関数はグループ分けに関する1つの限定的な質問に答えるものであり、これにより、下流の利用者が行う仮定を、呼び出しのたびにコストを払って確認するのではなく、事前に検証できるようになります:

    • groups_are_hermitian() 各グループについて、その項からなる演算子がエルミート演算子であるかどうかを報告する。 これは、ランダム化された生成式が群全体からサンプリングを行う際に依拠する性質である。なぜなら、ユニタリな時間発展を持つのはエルミート群のみだからである。
    • groups_have_uniform_coeffs() 各グループについて、その係数が数値的に等しいかどうか(デフォルトでは絶対値で)を報告します。

    「グループ演算子の用語」 を参照してください。演算子の構造を用いた具体例が掲載されています。

  • を追加しました group_order()。これは、オペレータの項をグループインデックスの順に並べ替えたコピーを返すものです。 各グループは連続した項の列となり、グループのインデックスは非減少となる。このソートは安定ソートであるため、グループ内の項は相対的な順序を保つ。 グループインデックスを追跡しない演算子は、並べ替えの基準となるものがなく、変更されていないコピーとして返されます。

    グループインデックスは、どの項が互いに属するかを示すだけであるため、これにより演算子の項の配置は変わりますが、その値は変わりません。 このレイアウトこそが、グループ検索のコストを低く抑える要因となっています。通常、要求されたグループを見つけるにはすべての項をスキャンする必要があります split_out_groups() が、グループ順に並べられた演算子では、代わりにグループの境界を二分探索するため、検索にかかるコストは、保持されている項の数ではなく、要求されたグループの数に比例することになります。 したがって、最初に一度だけ並べ替えを行っておけば、その後の繰り返し検索においてその効果が発揮されます:

    from qiskit_fermions.operators.terms.ordering import group_order
    
    hamil = group_order(hamil)
    # every subsequent hamil.split_out_groups(group_indices=...) is now a binary search

    これは QDriftTrotterization、呼び出しのたびにサンプリングされたグループを検索する を使用して繰り返しトランスパイルを行う前に、行っておく価値があります。 具体的な例については、「 SqDRIFT 回路の生成」 を参照してください。

  • 残りの3つの演算子データ構造、 majorana_jordan_wigner()、 edge_vertex_jordan_wigner() 、 に対して、直接的なジョーダン・ウィグナーマッパーを追加しました transfer_vertex_jordan_wigner()。

  • jordan_wigner() 現在は、特定の演算子だけでなく、4種類の演算子すべてに対して処理を実行し FermionOperator、渡された演算子に一致する直接実装に処理を委譲するようになりました。 以前、他の3つの演算子タイプのうちの1つを通過すると、. が発生していました TypeError。

  • このメソッド is_hermitian() は、現在、このプロトコル OperatorTrait の一部となっています。 すべての演算子クラスがすでにこれを提供しているため、具体的な演算子クラスだけでなく、 OperatorTrait ``型として型付けされた任意の値に対しても呼び出すことができるようになりました。

    なお、このチェックの強度は演算子の種類によって異なり、プロトコルではこれが最も弱い保証として規定されています。すなわち、a の True 結果は常に信頼性がありますが、正規形が真の標準形ではない演算子の種類については、a の False 結果は保守的となります。 そのような事例の一つ is_hermitian() については、こちらを参照してください。

  • マッパー関数をラップして、その関数が生成するパウリ項の順序を制御する2つのアダプタを追加しました。これにより、合成後も順序が保持される MapperFnEvolutionSynthesis ようになりました。

    simplify() マッピングされた演算子を簡略化し、重複するパウリ項を統合し、標準的な項の順序を固定する。

    group_wise() 演算子を1つのエントリ groups ずつ適用し、その結果を合計します。 演算子は変わらないが、各グループの項が交互に配置されるのではなく隣接して配置されるため、互いに交わらない量子ビットに作用する項が同じ回路層を共有できるようになる:

    MapperFnEvolutionSynthesis(group_wise(jordan_wigner))
  • QDriftTrotterization 現在、そのモード filter_trivial で破棄された引き分けの数を記録します。 実際にフィルタリングされたゲート Evolution が少なくとも1つあった場合、返される回路の「 metadata キャリー」と filter_trivial.discarded 「」には filter_trivial.emitted、回路の順序に従って、フィルタリングされた各ゲートにつき1カウントずつが保持されます。 この比率は受入確率を推定するものであり、これはフィルタリングによって保持された項の係数が、どの程度増幅されたかを示す係数である。 ゲートがフィルタリングされていない場合、どちらのフィールドも存在しないため、これらを読み取るには を使用してください .get()。

  • Evolution このパッケージの任意の演算子タイプについて、シミュレーションが可能になりました FermionOperator。 別のタイプのオペレーターは、シミュレーションが行われる前にそのフェルミオン像(プロトコル SupportsFermionOperator )を通じて変換されるため、 MajoranaOperator、または EdgeVertexOperator を進化させても、もはやを TransferVertexOperator 発生させない NotImplementedError。

  • FermionOperator 現在、新しい _trace_() メソッド ffsim.SupportsTrace を通じて実装されているため、固定された (norb, nelec) セクター上の演算子のトレースを計算できるよう ffsim.trace() になった。 これが、進化の道筋 scipy.sparse.linalg.expm_multiply() における前提条件です。

C API の機能

  • を追加した qf_ferm_op_conserves_sector()。これは、の各項が、 各モードブロック内で粒子数を保存 QfFermionOperator していることを確認するものである。 これは qf_ferm_op_conserves_particle_number()、合計のみを確認する既存の機能と相まって機能します。 空間 norb 軌道のスピン軌道配置において、2つのブロックを通過するには、アルファセクターとベータセクターをそれぞれ個別に保存 {norb, norb} する必要がある。すなわち、粒子数とスピンのz成分の両方を厳密に保存しなければならない:

    uint32_t spin_blocks[2] = {norb, norb};
    bool conserves = qf_ferm_op_conserves_sector(op, spin_blocks, 2);

    ブロック数を指定 NULL して渡すと、すべてのモードが単一のブロックとして 0 扱われます。これは、を呼び出すのと同じです qf_ferm_op_conserves_particle_number()。

  • C API に演算子のサポートを追加しました。これまでは、 Python からのみ利用可能でした get_support。 4つの演算子表現のそれぞれに、関数 qf_ferm_op_num_support() と のペアに加え qf_ferm_op_get_support()、、 qf_maj_op、および qf_edge_op に相当 qf_transfer_op する関数が追加された。

    他のゲッターとは異なり、これらは演算子へのポインタを返しません。これは、サポート情報が格納されるのではなく、必要に応じて計算されるためです。 まず、関 num_support 数を呼び出して出力バッファのサイズを設定し、そのバッファを に渡します get_support:

    uint32_t num_support = qf_ferm_op_num_support(op);
    uint32_t *support = malloc(num_support * sizeof(uint32_t));
    qf_ferm_op_get_support(op, support);

    C関数はモードのインデックスを昇順で書き出しますが、 Python メソッドは順不同のインデックスを返します set。

  • C API にインプレース演算子を追加しました。これにより、左側のオペランドを上書きできる場合、結果の演算子の割り当てを回避できるようになりました。 4つの演算子表現はそれぞれ add_inplace、、 mul_inplace、 scaled_add_inplace および を得た。例えば qf_ferm_op_add_inplace()、、 qf_ferm_op_scaled_add_inplace() である qf_ferm_op_mul_inplace():

    // Accumulate `factor * right` into `left` without building an intermediate.
    QkComplex64 factor = {-1.0, 0.0};
    qf_ferm_op_scaled_add_inplace(left, right, &factor);

    これら3つは、群指標の扱い方が異なる点に注意してください。 これら2つの追加操作は、右オペランドの項を末尾に追加するため、 と同様に NULL、属 groups 性を にリセット qf_ferm_op_add() します。 mul_inplace 係数の値のみを調整するため、項の数は変わらない。したがって、グループ分けは維持される。

  • 以前は Python からのみ利用可能だった、エッジ頂点および転送頂点の演算子表現に対する C API を追加しました。 これには、2つの新しい不透明構造体 と QfEdgeVertexOperator が含まれており QfTransferVertexOperator、それぞれが既存の演算子構造体と同等の関数セットを備えています。

    どちらの演算子も、マジョラナ演算子が使用する単一の配列 modes の代わりに、2つの並列なインデックス配列、および left_indices``right_indices 、を保持しています。 ジェネレータは常にちょうど1組の (left, right) ペアによって一意に識別されるため、2つの配列は必然的に同じ長さとなり、したがってコンストラクタは両方を網羅する単一の引数 num_indices を受け取ります。

  • および qf_edge_op_canonical_order() を追加し qf_transfer_op_canonical_order()、さらに、これら2つの新しい演算子タイプ(qf_edge_op_commutator() および関連する演算子)に対する可換子、反可換子、および二重可換子の関数を追加しました。

  • エッジ・頂点マッパーおよび転送・頂点マッパー用の C API 関数 qf_edge_vertex_to_fermion()、, qf_edge_vertex_to_majorana(), qf_transfer_vertex_to_fermion(), qf_transfer_vertex_to_majorana(), および を追加しました qf_transfer_vertex_to_edge_vertex()。

  • 4つの演算子表現すべて( qf_ferm_op_scaled_add(), qf_maj_op_scaled_add(), および qf_edge_op_scaled_add() )について、C API に scaled_add 追加されました qf_transfer_op_scaled_add()。 それぞれが を返し left + factor * right、スケーリングを加算に組み込むことで、処理の途中で右側のオペランドのスケーリング済みコピーが生成されることはありません。

    C API でも引き算はこのように記述されます。これは、乗数によって後続の係数が負の -1 値に置き換えられるためです:

    QkComplex64 minus_one = {-1.0, 0.0};
    QfFermionOperator *difference = qf_ferm_op_scaled_add(left, right, &minus_one);

    については qf_ferm_op_add()、右オペランドの項は左オペランドの項と結合されるのではなく、それに付加されるため、結果にはグループインデックスは含まれません。 同次項をまとめたい場合は、対応する関 simplify 数を呼び出してください。

  • QfFCIDump これによって、これまでデータ構造全体を.に変換しなければアクセスできなかった、解析済みの電子積分が公開されるようになった QfFermionOperator。 新しいアクセサ qf_fcidump_get_one_body_tril_a(), qf_fcidump_get_one_body_tril_b(), qf_fcidump_get_two_body_tril_aa(), および qf_fcidump_get_two_body_tril_ab() は、内部バッファを借用 qf_fcidump_get_two_body_tril_bb() し、ポインタと長さをアウトパラメータを通じて書き込みます:

    double *integrals;
    uint64_t len;
    qf_fcidump_get_one_body_tril_a(fcidump, &integrals, &len);

    返されたポインタは解放してはならず、そのポインタが解放 QfFCIDump されるまで有効です。 3つのベータスピンゲッターを新しい で保護し qf_fcidump_is_unrestricted()、 を新しい qf_fcidump_constant() で保護してください qf_fcidump_has_constant()。いずれかをガードなしで呼び出すと、パニックが発生します。 各配列のインデックス式については、ヘッダーのドキュメントを参照してください。特に、この配列は他の2体配列とはパッキング qf_fcidump_get_two_body_tril_ab() 方法が異なり、4倍対称であるため、完全な行列 (npair, npair) が格納されている点に注意してください。

  • および qf_ferm_op_groups_are_hermitian() を追加しました qf_ferm_op_groups_have_uniform_coeffs()。これらは、各グループについて、その項から構成される演算子がエルミート演算子であるかどうか、およびその係数が数値的に等しいかどうかを報告するほか、マジョラーナ演算子、エッジ・頂点演算子、転移・頂点演算子の各タイプに対する同等の関数も提供します。

  • 演算子の項をグループインデックスの順に並べ替えたコピーを返す関数 Added を追加しました qf_ferm_op_group_order()。また、マジョラナ演算子 (qf_maj_op_group_order())、エッジ-頂点演算子 (qf_edge_op_group_order())、転送-頂点演算子 (qf_transfer_op_group_order()) に対応する関数も追加しました。 各グループは連続した項の列となり、これにより、すべての項をスキャンする代わりに、グループの境界を二分 qf_ferm_op_split_out_groups() 探索できるようになります。

  • 既存の qf_ferm_op_jordan_wigner(): qf_maj_op_jordan_wigner()、 qf_edge_op_jordan_wigner() 、 に加え、残りの3つの演算子データ構造に対して、直接的なジョーダン・ウィグナーマッパーを追加しました qf_transfer_op_jordan_wigner()。

Python APIのアップグレードに関する注意事項

  • および qiskit_fermions.linalg.apply_unitary 関 qiskit_fermions.linalg.linear_operator 数は削除されました。 これらは、および _apply_unitary_ プロトコル _linear_operator_ メソッドを包む薄いラッパーであり、および ffsim.apply_unitary() を複製したものでした ffsim.linear_operator()。 代わりに ffsim の関数を呼び出すか、ffsim がインストールされていない場合は、オブジェクトの protocol メソッドを直接呼び出してください:

    # before
    from qiskit_fermions.linalg import apply_unitary, linear_operator
    vec = apply_unitary(vec, gate, norb, nelec)
    linop = linear_operator(operator, norb, nelec)
    
    # after (with ffsim)
    vec = ffsim.apply_unitary(vec, gate, norb=norb, nelec=nelec)
    linop = ffsim.linear_operator(operator, norb=norb, nelec=nelec)
    
    # after (without ffsim)
    vec = gate._apply_unitary_(vec, norb, nelec, copy=True)
    linop = operator._linear_operator_(norb, nelec)

    方法そのものは変更されていません。

  • および qiskit_fermions.protocols.SupportsApplyUnitary プロトコ qiskit_fermions.protocols.SupportsLinearOperator ルは、同じ理由で削除されました。これらは、ffsim が定義する契約を再記述していたためです。 ffsim独自のプロトコルを使用します。これらは1対1でミラーリングされています:

    プロトコルメソッド (_apply_unitary_ および _linear_operator_)に変更はないため、これらを実装していたこのパッケージのオブジェクトは引き続きそれらを実装しています。削除されたのは、インターフェースのローカルな再定義のみです。 SupportsApplyUnitaryPlaced これは、モード配置 ffsim.SupportsApplyUnitary によって拡張されており、ffsim に対応するものが存在しないため、そのまま残されます。

  • from_file() ファイルの解析ができない場合、Rustのパニックを伝播させる代わりに、キャッチ可能な Python 例外をスローするようになりました。 開くことも読み取ることもできないパスでは が発生し OSError、FCIDump 形式に準拠していないファイル(ヘッダーの namelist が欠落している、 または NORB フィールド NELEC が欠落している、あるいは フィールド MS2 の形式が不正である場合)では が発生します ValueError。 まだサポートされていない MO エネルギー値を含む FCIDump についても、同様の問題が発生します ValueError。

  • このメソッド group_weights は、すべてのオペレータクラスおよびプロトコル OperatorTrait から削除されました。 これは group_coeff_means()、 qiskit_fermions.operators.terms.grouping モジュール内のフリー関数である に置き換えられ、その挙動は変わらない:

    # before
    weights = op.group_weights()
    
    # after
    from qiskit_fermions.operators.terms.grouping import group_coeff_means
    
    weights = group_coeff_means(op)
  • 演算子の項数と長さが異なる配列 groups を代入すると、以前は黙って受け入れられていましたが ValueError 、現在は例外が発生するようになりました。 グループインデックスをクリアするための None assigning は影響を受けません。

  • MapperFnEvolutionSynthesis もはや、その.によって返される演算子を単純化することはありません mapper_fn。 単純化処理では、パウリ項が標準的な順序に並べ替えられ、積の式はそれらを受け取った順序で合成するため、以前の動作ではマッパーが選択した順序がすべて無視されていました。

    これにより、既存のパイプラインの合成回路が変更されます。ゲート数は影響を受けませんが、回転が出力される順序(ひいては2量子ビットの深さ)が異なる場合があります。 近似対象となる進化には変化がない。

    また、Rustコアの演算子は、項が追加された順序を保持しないため、マッパーが生成する項の順序が実行ごとに安定しているとは限らない点にも注意してください。 以前の動作を復元し、正規の順序を固定 simplify() するには、マッパーを新しい で囲みます:

    MapperFnEvolutionSynthesis(simplify(jordan_wigner))
  • qiskit_fermions.linalg: double_factorized_t2、 double_factorized_t2_alpha_beta、 reconstruct_t2、 reconstruct_t2_alpha_beta および から、二重因数分解ユーティリティが削除されました double_factorized_2body。 これらのバリアント t2 は UCJ.from_t_amplitudes、現在はffsimに存在する にサービスを提供するために存在していましたが、呼び出し元はありませんでした double_factorized_2body 。 代わりに ffsim.linalg.double_factorized() ffsim.linalg.double_factorized_t2()、、 ffsim.linalg.double_factorized_t2_alpha_beta() を使用してください。最後の は、削除された2体ルーチンの上位集合であり、さらに最適化された (optimize=True) 分解機能も提供しています。

  • シミュレーションを行うには、 ffsim が必要になりました。 以前はこれを支えていたネイティブのRust FCI(フル構成相互作用)カーネルは削除 _linear_operator_ されました。現在、このメソッドは を FermionOperator に変換し ffsim.FermionOperator 、 に委譲することで実装されています ffsim.linear_operator()。

    シミュレーションはffsimの担当分野です。このパッケージは、フェルミオン・マッパーと、マッパーに依存しない回路およびそのトランスパイルに焦点を当てています。 ffsimは PySCF, に依存していますが、同ライブラリはWindowsをサポートしていないため、Windows上ではシミュレーションが利用できません。ただし、パッケージのその他の機能(演算子の構築、それらのマッピング、および結果として得られる回路のトランスパイル)については、どのプラットフォームでも影響を受けません。 シミュレーションが必要なWindowsユーザーは、 「 Linux 用Windowsサブシステム」 を通じてシミュレーションを行うことができます。

    ffsim がインストールされていない状態でシミュレーションのエントリポイントを呼び出すと、現在、. が発生します MissingOptionalLibraryError。

  • このモジュール qiskit_fermions.linalg.fci は、カーネルとともに削除されました。これには、その FciLinearOperator クラスおよび slater_determinant_statevector と の occupation_axis_mask 関数も含まれます。 ffsim では、 ffsim.addresses_to_strings() それぞれ ffsim.slater_determinant() および に相当するものが提供されています。

  • OrbitalRotation ffsim が存在しない場合、もはやジェネレータと指数関数を組み合わせたパスにフォールバックすることはなく、常に に委譲する ffsim.apply_orbital_rotation()。 ffsimをインストールしても、結果は変わりません。

  • このゲート UCC は現在、ffsimのUCCSD演算子の1つから構成されており、これがその唯一のコンストラクタ引数となっています。 スピンのバリエーションとモードの数はその演算子から読み取られるため、 variant 引数と列挙 UCC.Variant 型は不要になります:

    # before
    ansatz = UCC("restricted", t1, t2)
    
    # after
    ansatz = UCC(ffsim.UCCSDOpRestrictedReal(t1=t1, t2=t2))

    したがって、 UCC.from_t_amplitudes、 UCC.num_parameters、および UCC.from_parameters は削除 UCC.to_parameters されました。また、ffsimに相当するものが存在しないの バリアント spinless およびオプトインの パラメータ antisymmetric 化も同様に削除されました。 ffsimの演算子は n_params()、 from_parameters() 、、 に対して to_parameters() 同一の規則を採用しています。 その族の外側(スピンを持たないもの、あるいは反対称化された t2t_2 など)でアンザッツを構築するには、自身のクラスター演算子 Evolution を用いて直接構築すればよく、これにより項のトロッター順序も制御できるようになる。

    ラップされた演算子は として利用可能であるため UCC.uccsd_op、その振幅は および gate.uccsd_op.t1 として取得できる gate.uccsd_op.t2。このゲートは、もはやそれらを自身の属性として反映することはない。 UCC.cluster_operator() は変更されていません。 ffsim演算子によって運ばれる final_orbital_rotation Aは、終了記号として末尾に追加されるようになった OrbitalRotation。

    ffsimは現在、オプションのアクセラレータではなくゲートの入力型となっているため、を構築するには追加 ffsim の (pip install "qiskit-fermions[ffsim]") が必要 UCC であり、それが MissingOptionalLibraryError なければ が発生します。 ffsimはWindowsに対応していないため、Windowsではこのゲートを利用できません。WSLをご利用ください。

  • このゲート UCJ は現在、ffsimのUCJ演算子の1つから構成されており、これがその唯一のコンストラクタ引数となっています。 スピン変種、空間軌道の数、およびモードの数はその演算子から読み取られるため、 variant 引数と列挙 UCJ.Variant 型は削除されました:

    # before
    ansatz = UCJ.from_t_amplitudes(nelec, t2, t1=t1, n_reps=2)
    ansatz = UCJ("balanced", diag_coulomb_mats, orbital_rotations)
    
    # after
    ansatz = UCJ(ffsim.UCJOpSpinBalanced.from_t_amplitudes(t2, t1=t1, n_reps=2))
    ansatz = UCJ(ffsim.UCJOpSpinBalanced(diag_coulomb_mats, orbital_rotations))

    したがって、 UCJ.from_t_amplitudes、 UCJ.num_parameters、および UCJ.from_parameters は削除 UCJ.to_parameters されました。ffsimの演算子は from_t_amplitudes()、 n_params()、および from_parameters()to_parameters() に対して同一の規約を提供しており、さらに、このパッケージでは実装されたことのない圧縮型(optimize=True)の二重因数分解およびも提供しています from_cisd_vec()。 ラップされたオペレータは として利用可能であるため UCJ.ucj_op、そのテンソルは など gate.ucj_op.diag_coulomb_mats として参照可能であり、ゲートはもはやそれらを自身の属性として反映しなくなった。

    ffsimは現在、オプションのアクセラレータではなくゲートの入力型となっているため、を構築するには追加 ffsim の (pip install "qiskit-fermions[ffsim]") が必要 UCJ であり、それが MissingOptionalLibraryError なければ が発生します。 ffsimはWindowsに対応していないため、Windowsではこのゲートを利用できません。WSLをご利用ください。

  • 項ごとにグループ添字が1ずつ増えないオペレータをピックル解除すると、グループ添字が項と一致しなくなったオペレータが生成されるのではなく ValueError 、 が発生するようになりました。 これは、手作業で作成されたペイロード、または互換性のないバージョンで作成されたペイロードでのみ発生します。このバージョンで作成されたpickleは、往復しても変更されません。

C API アップグレードに関する注意事項

  • qf_fcidump_from_file() これで を返し、解析済みの を新しい出力パラメータ QfFCIDump を通じて受け取るようになり QfExitCode 、これはマッパー関数ですでに使用されている規約と一致しています:

    QfFCIDump *fcidump = NULL;
    QfExitCode exit = qf_fcidump_from_file("molecule.fcidump", &fcidump);

    ファイルがFCIDump形式に準拠していない場合 QfExitCode_ValueError (ヘッダーのnamelistが欠落している、または NORB フィールド NELEC が欠落している、field MS2 の形式が不正である、あるいはまだサポートされていないMOエネルギー値が含まれている場合など)、この関数はを返し、outパラメータは変更されません。 これは、ポインタを直接返すだけで、失敗を報告する手段がなかった以前のシグネチャに代わるものです(解析不可能なファイルの場合、FFIの境界を越えてRustのパニックが伝播してしまい、これは未定義の挙動となります)。

  • qf_ferm_op_group_weights およびその型ごとの対応する関数は、 qf_ferm_op_group_coeff_means() および関連関数へと名称が変更されました。 彼らの振る舞いは相変わらずだ。

  • qf_ferm_op_set_groups() また、各型に対応する関数は、これまでとは QfExitCode 異なり、 を返すようになりました void。 演算子の項数と異なる長さのグループ配列を渡すと、黙って受け入れられる QfExitCode_ValueError のではなく が返されます。グループインデックスをクリア NULL するために を渡した場合、この動作には影響しません。

ビルドシステムの変更点

  • オプション simulation の依存関係は に名称変更されたため ffsim、 は となります pip install "qiskit-fermions[simulation]"``pip install "qiskit-fermions[ffsim]" 。 この「extra」という名前は、機能ではなく、インストールされる依存関係を指しています。 のインストールには影響 qiskit-fermions[all] ありません。

  • オプション optimization の依存関係は に名称変更されたため pyomo、 は となります pip install "qiskit-fermions[optimization]"``pip install "qiskit-fermions[pyomo]" 。 この新しい名称は、機能ではなく、インストールされる依存関係を指しています。以前の名称は期待以上のことを示唆していました。Pyomoはモデリング言語であるため、および RelabelModes の背後にある混合整数プログラムを構築することはできます build_excitation_span_minimization_model() が、それを解くことはできません。 ソルバーの選択は、それとは別の、意図的な手順です(RelabelModes 引 solver 数を順に検討していくプロセスであり、このパッケージではどのソルバーを使用すべきかを指定しません)。また、その追加機能を「Pyomo」にちなんで命名することで、インストール時にその境界が明確になります。 のインストールには影響 qiskit-fermions[all] ありません。

バグ修正

  • および fermion_jordan_wigner() の過剰なメモリ消費( qf_ferm_op_jordan_wigner() ひいては、これを に適用した場合 jordan_wigner() の のメモリ消費 FermionOperator)を修正しました。 マッパーは、重複するパウリ項をマージするのではなく連結する加算演算を用いてマッピングされた項を蓄積したため、中間観測量は、 異なるパウリ項の数ではなく、 放出されたパウリ項の数に応じて増加した。 したがって、簡略化された結果は桁違いに小さかったとしても、大規模なハミルトニアンをマッピングすると、利用可能なメモリを使い果たしてしまう可能性がある。 アキュムレータは、前回のマージ後のサイズをある倍数だけ超えて大きくなると正規化される。これにより、アキュムレータが実際に表す演算子に基づいて、そのアキュムレータが保持するメモリ量に上限が設けられる。

    ピークメモリ使用量は、ワーカースレッドの数に比例して依然として増加します。これは、項が、それらが生成するパウリ文字列によって分割されるのではなく、空き状態のスレッドに割り当てられるためであり、その結果、各アキュムレータには、マップされた演算子のほぼ完全なコピーが保持されることになります。 変化したのは、各々が持つ因子です。以前は放出されるパウリ項の数に比例していましたが、現在は異なるパウリ項の数に比例するようになりました。 したがって、rayonの RAYON_NUM_THREADS 環境変数を通じてスレッド数を減らすと、ピーク値がほぼ比例して低下するため、メモリが不足している際にはこの設定を調整するのが有効です。

    マッピングされた演算子は変更されません。正規化では重複する項が統合されるだけなので、結果は以前とまったく同じ観測量を表します。 ただし、完全に簡約化されているとはもはや保証されず、含まれる項の数はスレッド数によって異なる場合があります。 重複する項目をすべて結合したい場合は、 simplify() (qk_obs_canonicalize C言語の) call を使用してください。

  • Trotter化を行うゲートのメソッド Evolution.synthesis が破棄 QDriftTrotterization されてしまう問題、および非ユニタリな因数に分解可能なサンプリングされたゲートが出力されてしまう問題を修正しました。 サンプリングされたゲートは、置き換えるゲートの合成手法を引き継ぎ、とマークされます Evolution.atomic。

  • 回路のゲート Evolution がすでに分解されていた場合に、誤ったハミルトニアンに対する順列が見つかって RelabelModes しまう問題を修正しました。 Aは、それが出力する各因子をその因子のサポート上に限定 FermionicEvolutionSynthesis するため、その因子の演算子はゲートに局所的なモードインデックスを持ち、レジスタ内での位置はノードの量子ビット引数によって決まる。 自動最適化では演算子のみが解析され、その結果、次のような局所的な指標が導き出された。すなわち、絞り込まれたすべての2モード因子は、実際にどのモードと結合しているかに関係 (0, 1) なく励起因子となり、長距離結合はモデルから完全に除外された。

    この関数が返した順列は有効でしたが、回路のものではないハミルトニアンに対して最適化されたものであり、局所インデックス自体が有効なモードインデックスであるため、エラーは発生しませんでした。 進化が「パス・ホール」段階に達したサーキットは、影響を受けませんでした。 分解された回路の順列に依存していた場合は、そのパスを再実行してください。再実行すると、異なる(そしてより良い)結果が返される可能性があります。

  • 終了しない Evolution ゲートの分解を修正しました。 ある単一の演算子項の展開は、常に同一の単一項に分解されてしまっていたため Evolution、繰り返し展開を行っても進展が見られなかった。 最も顕著な影響として、ゲートの定義を再帰的に処理するため RecursionError、これにより が inverse() を引き起こしました。

    によって生成された因子は、現在 とマーク FermionicEvolutionSynthesis され Evolution.atomic 、再度展開されることなく decompose() 、 によってその場に留められます。 したがって、を繰り返し Evolution 分解していくと、固定点に到達する。

  • 群を持つ演算子に対して2回以上適用した際に、非ユニタリな因子が生成 decompose() される問題を修正しました。 各群は項ごとにさらに細分化されたが、たとえそれを含む群がエルミート群であっても、個々の項は一般にエルミートではない。その好例として、クラ UCC スター生成子の共役対が挙げられる。 このような因子の指数関数はユニタリではない。

    フェルミオンから量子ビットへの変換段階では、複素係数に関する ValueError これらの要因が排除されたが、状態ベクトルシミュレーションではそれらが何の異議もなく適用され、正規化されていない状態が返された。 グループは現在アトミックであるため、そのグループを生み出した分割はもはや発生しません。

  • Evolution.inverse() これは現在、直接実装されており、負の時間に対して同じ演算子を進化させ Evolution 、ゲートの メソッド synthesis を維持する を返す。 以前は、継承された実装はゲートの定義を再帰的に処理し、演算子と合成メソッドの両方を破棄して Gate、単なる を返していました。

パフォーマンスの改善

  • SciPy’s の行列指数関数ルーチンに、正確な固定セクター演算子のトレースを供給することで、および EvolutionOrbitalRotation ゲートに対する状態ベクトルシミュレーションの数値的条件付けを改善した。

  • fermion_jordan_wigner() 指定された演算子をコピーしなくなりました。 Python バインディングは引数を値渡しで受け取っていたため、入力の内容を読み取るためだけに FermionOperator 、すべての項バッファが複製されてしまっていた。


0.1.0

序曲

これは、フェルミオン系向けのツールを備えたQiskitの拡張版である「Qiskit Fermions」の最初のリリースです。 このライブラリは、演算子のデータ構造、それらの演算子を量子ビット形式に変換するためのフレームワークとライブラリ(マッパー)、および対応する量子回路を合成するためのフレームワークとライブラリを提供します。 Qiskitの設計思想に沿い、このパッケージの中核部分はRustで記述されており、 Python およびCの両方に対して、公式のバインディングを通じて提供されています。

このページは役に立ちましたか?
バグや誤字の報告、またはコンテンツの要求はGitHubで行ってください。