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 による分解 の絶対値 であり、この分解において係数の符号は に属し、進化演算子から直接読み取られるからである。
渡された配列には、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-formula
k)は、 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でミラーリングされています:qiskit_fermions.protocols.SupportsApplyUnitary~になるffsim.SupportsApplyUnitaryqiskit_fermions.protocols.SupportsLinearOperator~になるffsim.SupportsLinearOperator
プロトコルメソッド (
_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、現在は例外が発生するようになりました。 グループインデックスをクリアするためのNoneassigningは影響を受けません。 -
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()および に相当するものが提供されています。 -
OrbitalRotationffsim が存在しない場合、もはやジェネレータと指数関数を組み合わせたパスにフォールバックすることはなく、常に に委譲する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()同一の規則を採用しています。 その族の外側(スピンを持たないもの、あるいは反対称化された など)でアンザッツを構築するには、自身のクラスター演算子Evolutionを用いて直接構築すればよく、これにより項のトロッター順序も制御できるようになる。ラップされた演算子は として利用可能であるため
UCC.uccsd_op、その振幅は およびgate.uccsd_op.t1として取得できるgate.uccsd_op.t2。このゲートは、もはやそれらを自身の属性として反映することはない。UCC.cluster_operator()は変更されていません。 ffsim演算子によって運ばれるfinal_orbital_rotationAは、終了記号として末尾に追加されるようになった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が欠落している、fieldMS2の形式が不正である、あるいはまだサポートされていない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_canonicalizeC言語の) 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の両方に対して、公式のバインディングを通じて提供されています。