QfTransferVertexOperator
QfTransferVertexOperator
struct QfTransferVertexOperator
転送頂点演算子。
これは、C API からは内部構造が不透明なデータ構造であり、その内部実装はすべて Rust で記述されています。 このページの残りの部分では、この構造体を使用するための設計および関連する関数について説明します。
定義
この演算子は、転送頂点( 、 )演算子を用いて定義されます:
ここで、 はの辺演算子であり、これらの個々の項は QfEdgeVertexOperator 、 に対して以下のフェルミオン・ボソン混合の可換関係を満たす: [1]
エッジ演算子とは異なり、 では2つの向きが単一の演算子の2つの表現となるのに対し、 および は異なる演算子である。 したがって、2つのインデックス配列の順序は重要であり、正規化するための向きに関する規約は存在しません。これが、が ascending パラメータを受け取らないのに対し、が qf_transfer_op_normal_ordered()qf_edge_op_normal_ordered() 受け取る理由です。
表記法を少し大雑把に扱って、 を定義することができます。これは、この演算子の内部データ構造がどのように機能するかを反映したものです。 これにより、演算子全体の定義は次のようになります:
ここで、 は関連する演算子項の添字を表し、 は積の線形結合を構成する(複素)係数である。 インデックス および は、0 から、その演算子が作用するフェルミオンモードの数から 1 を引いた値までの任意の値をとることができます。
を一般化された転送演算子と呼ぶことにする。
実装
この構造体は、疎行列で一般的に使用される「 圧縮疎行形式 」と同様に、項と係数を複数の疎ベクトルとして格納します。 より具体的に言えば、1つの演算子には4つの配列が含まれています:
コラム「 1 」 | コラム「 2 」 |
|---|---|
coeffs | 2つの64ビット浮動小数点数からなる、複素係数のベクトル。 |
left_indices | 左側のフェルミオンモードのインデックス( )を格納する32ビット整数のベクトル。 |
right_indices | 正しいフェルミオンモードのインデックス( )を格納する、32ビット整数のベクトル。 |
boundaries | 項間の境界を示す整数のベクトル。 |
および left_indices でインデックス付けられたフェルミオンモードは、スピンを持たないとみなされる right_indices 。 すべてのジェネレータは正確に1組の (left, right) ペアによって一意に識別されるため、2つのインデックス配列の長さは常に同じになります。これが、コンストラクタが両方の配列に対して単一の長 num_indices さを受け取る理由です。
これらの内部配列の読み取り専用コピーには、 それぞれの関数を通じてアクセスできます:
qf_transfer_op_get_coeffs()qf_transfer_op_get_left_indices()qf_transfer_op_get_right_indices()qf_transfer_op_get_boundaries()
返されたポインタは、その演算子が変更されるか解放されるまで有効であり、呼び出し元によって解放してはならない。
このデータ構造により、演算子の構築や操作を非常に効率的に行うことができます。 しかし、これは、演算子の中にいつでも重複する項が含まれている可能性があることを意味します。 これらは、. を使用して手動で解決する必要があります qf_transfer_op_simplify()。
建設
上記で説明した対応する配列を指定することで、新しい演算子を直接構築することができます。 あるいは、空の を で初期化し qf_transfer_op_zero() 、 を通じて反復的に項を追加することもできます QfTransferVertexOperatorqf_transfer_op_add_term() 。
コラム「 1 」 | コラム「 2 」 |
|---|---|
qf_transfer_op_new() | 指定された配列から新しい演算子を構築します。 |
qf_transfer_op_zero() | 加法単位演算子を構築する。 |
qf_transfer_op_one() | 乗法単位演算子を構築します。 |
qf_transfer_op_add_term() | 既存の.に項を追加します QfTransferVertexOperator。 |
A は を使って解放 QfTransferVertexOperator できます qf_transfer_op_free()。
算数
以下の関数は、算術演算を行うものです:
コラム「 1 」 | コラム「 2 」 |
|---|---|
qf_transfer_op_add() | 2つの演算子を足し合わせます。 |
qf_transfer_op_mul() | 演算子にスカラーを乗算します。 |
qf_transfer_op_compose() | 2つの演算子を互いに合成します。 |
qf_transfer_op_adjoint() | エルミート共役演算子を返します。 |
操作
以下の関数は、演算子の操作ロジックを提供します:
コラム「 1 」 | コラム「 2 」 |
|---|---|
qf_transfer_op_ichop() | 係数の絶対値が小さい項を除去します。 |
qf_transfer_op_simplify() | 同等だが簡略化された演算子を返します。 |
qf_transfer_op_normal_ordered() | 通常の順序を持つ項を持つ等価演算子を返します。 |
qf_transfer_op_relabel_modes() | 演算子のモードに新しいラベルを割り当てます。 |
プロパティ-
演算子の特定の性質を確認するために、以下の関数が用意されています。
コラム「 1 」 | コラム「 2 」 |
|---|---|
qf_transfer_op_is_hermitian() | 演算子がエルミートであるかどうかを返します。 |
qf_transfer_op_len() | この演算子の項の数を返します。 |
マッピング
以下の関数は、この演算子を別の表現に変換します:
コラム「 1 」 | コラム「 2 」 |
|---|---|
qf_transfer_vertex_to_fermion() | QfFermionOperator. へのマップ |
qf_transfer_vertex_to_majorana() | QfMajoranaOperator. へのマップ |
qf_transfer_vertex_to_edge_vertex() | QfEdgeVertexOperator. へのマップ |
[ 1 ]
https://arxiv.org/abs/2512.11418
メンバー
qf_transfer_op_new
QfTransferVertexOperator *qf_transfer_op_new(uint64_t num_terms, uint64_t num_indices, const QkComplex64 *coeffs, const uint32_t *left_indices, const uint32_t *right_indices, const uint32_t *boundaries)
新しい演算子を構築します。
ポインタ引数のいずれかが となるのは、それに対応する長さがゼロである場合 NULL に限られる。
添字が等しいジェネレータは頂点演算子であり、 ;添字が異なるものは転送演算子であり、 。
エッジ演算子とは異なり、 と は異なる演算子であり、1つの演算子の2つの表現というわけではない。 したがって、2つのインデックス配列の順序は重要となります。
例
1// this builds `1.0 + (-1.0) * V(0) T(0,1)`
2uint64_t num_terms = 2;
3uint64_t num_indices = 2;
4uint32_t left_indices[2] = {0, 0};
5uint32_t right_indices[2] = {0, 1};
6QkComplex64 coeffs[2] = {{1.0, 0.0}, {-1.0, 0.0}};
7uint32_t boundaries[3] = {0, 0, 2};
8QfTransferVertexOperator *op = qf_transfer_op_new(num_terms, num_indices, coeffs,
9 left_indices, right_indices, boundaries);パラメーター
- num_terms – 演算子に含まれる項の数。
- num_indices – すべての項について合計した生成子の数。 すべてのジェネレータは、正確に1組の
(left, right)ペアによって一意に識別されるため、両方のインデックス配列は同じ長さになります。 - coeffs – 項の係数の配列へのポインタ。 この配列の長さは であるべきです
num_terms。 - left_indices – すべての項にわたる左側モードのインデックスの配列へのポインタ。 この配列の長さは であるべきです
num_indices。 - right_indices – すべての項にわたる右側モードのインデックスの配列へのポインタ。 この配列の長さは であるべきです
num_indices。 - 境界 – 項間の境界の配列へのポインタ。 この配列の長さは であるべきです
num_terms + 1。
戻り値
作成された演算子へのポインタ。
qf_transfer_op_free
void qf_transfer_op_free(QfTransferVertexOperator *op)
既存の演算子を解放します。
例
1QfTransferVertexOperator *op = qf_transfer_op_one();
2qf_transfer_op_free(op);パラメーター
- op – 解放対象の転送頂点演算子へのポインタ。
qf_transfer_op_get_coeffs
void qf_transfer_op_get_coeffs(const QfTransferVertexOperator *op, QkComplex64 **coeffs_out, uint64_t *coeffs_len)
演算子の係数に対して読み取り専用のアクセス権限を提供します。
内部データ構造の説明はこちらです。
例
1uint64_t num_terms = 2;
2QkComplex64 coeffs[2] = {{1.0, 0.0}, {0.0, -1.0}};
3uint32_t boundaries[3] = {0, 0, 0};
4QfTransferVertexOperator *op =
5 qf_transfer_op_new(num_terms, 0, coeffs, NULL, NULL, boundaries);
6
7QkComplex64 *coeffs_out;
8uint64_t coeffs_len;
9
10qf_transfer_op_get_coeffs(op, &coeffs_out, &coeffs_len);
11
12assert(coeffs_len == 2);この関数は、バッファをコピーするのではなく、演算子の内部バッファを借用します。 返されたポインタは、その演算子が変更されるか解放されるまで有効です。自分で解放しないでください。
パラメーター
- op – アクセスする係数を持つ転送頂点演算子へのポインタ。
- coeffs_out – 係数を書き込む複素数値の配列へのポインタ。
- coeffs_len – 出力配列の長さを書き込む整数変数へのポインタ。
qf_transfer_op_get_left_indices
void qf_transfer_op_get_left_indices(const QfTransferVertexOperator *op, uint32_t **left_indices_out, uint64_t *left_indices_len)
オペレータの左側モードインデックスへの読み取り専用アクセスを提供します。
内部データ構造の説明はこちらです。
例
1uint64_t num_terms = 1;
2uint64_t num_indices = 2;
3uint32_t left_indices[2] = {0, 0};
4uint32_t right_indices[2] = {0, 1};
5QkComplex64 coeffs[1] = {{1.0, 0.0}};
6uint32_t boundaries[2] = {0, 2};
7QfTransferVertexOperator *op = qf_transfer_op_new(num_terms, num_indices, coeffs,
8 left_indices, right_indices, boundaries);
9
10uint32_t *left_out;
11uint64_t left_len;
12
13qf_transfer_op_get_left_indices(op, &left_out, &left_len);
14
15assert(left_len == 2);この関数は、バッファをコピーするのではなく、演算子の内部バッファを借用します。 返されたポインタは、その演算子が変更されるか解放されるまで有効です。自分で解放しないでください。
パラメーター
- op – アクセスする左インデックスを持つ転送頂点演算子へのポインタ。
- left_indices_out – インデックスを書き込む整数の配列へのポインタ。
- left_indices_len – 出力配列の長さを書き込む整数へのポインタ。
qf_transfer_op_get_right_indices
void qf_transfer_op_get_right_indices(const QfTransferVertexOperator *op, uint32_t **right_indices_out, uint64_t *right_indices_len)
オペレータの右側モードインデックスへの読み取り専用アクセスを提供します。
内部データ構造の説明はこちらです。
例
1uint64_t num_terms = 1;
2uint64_t num_indices = 2;
3uint32_t left_indices[2] = {0, 0};
4uint32_t right_indices[2] = {0, 1};
5QkComplex64 coeffs[1] = {{1.0, 0.0}};
6uint32_t boundaries[2] = {0, 2};
7QfTransferVertexOperator *op = qf_transfer_op_new(num_terms, num_indices, coeffs,
8 left_indices, right_indices, boundaries);
9
10uint32_t *right_out;
11uint64_t right_len;
12
13qf_transfer_op_get_right_indices(op, &right_out, &right_len);
14
15assert(right_len == 2);この関数は、バッファをコピーするのではなく、演算子の内部バッファを借用します。 返されたポインタは、その演算子が変更されるか解放されるまで有効です。自分で解放しないでください。
パラメーター
- op – アクセスする右インデックスを持つ転送頂点演算子へのポインタ。
- right_indices_out – インデックスを書き込む整数の配列へのポインタ。
- right_indices_len – 出力配列の長さを書き込む整数へのポインタ。
qf_transfer_op_get_boundaries
void qf_transfer_op_get_boundaries(const QfTransferVertexOperator *op, size_t **boundaries_out, uint64_t *boundaries_len)
演算子の項間の境界を示すインデックスへの読み取り専用アクセスを提供します。
内部データ構造の説明はこちらです。
例
1uint64_t num_terms = 1;
2uint64_t num_indices = 2;
3uint32_t left_indices[2] = {0, 0};
4uint32_t right_indices[2] = {0, 1};
5QkComplex64 coeffs[1] = {{1.0, 0.0}};
6uint32_t boundaries[2] = {0, 2};
7QfTransferVertexOperator *op = qf_transfer_op_new(num_terms, num_indices, coeffs,
8 left_indices, right_indices, boundaries);
9
10size_t *boundaries_out;
11uint64_t boundaries_len;
12
13qf_transfer_op_get_boundaries(op, &boundaries_out, &boundaries_len);
14
15assert(boundaries_len == 2);この関数は、バッファをコピーするのではなく、演算子の内部バッファを借用します。 返されたポインタは、その演算子が変更されるか解放されるまで有効です。自分で解放しないでください。
パラメーター
- op – アクセスする境界を持つ転送頂点演算子へのポインタ。
- boundaries_out – 境界値を書き込む整数の配列へのポインタ。
- boundaries_len – 出力配列の長さを書き込む整数へのポインタ。
qf_transfer_op_num_support
uint32_t qf_transfer_op_num_support(const QfTransferVertexOperator *op)
演算子の支持集合のサイズを取得します。
これを使用して qf_transfer_op_get_support()、独自の長さを報告しない の出力バッファのサイズを指定します。
例
1uint32_t left_indices[3] = {2, 0, 2};
2uint32_t right_indices[3] = {2, 1, 2};
3QkComplex64 coeffs[2] = {{1.0, 0.0}, {1.0, 0.0}};
4uint32_t boundaries[3] = {0, 2, 3};
5QfTransferVertexOperator *op =
6 qf_transfer_op_new(2, 3, coeffs, left_indices, right_indices, boundaries);
7
8uint32_t num_support = qf_transfer_op_num_support(op);
9
10assert(num_support == 3);パラメーター
- op – 取得するサポートサイズを持つ転送頂点演算子へのポインタ。
戻り値
演算子が作用する異なるモード指標の数。
qf_transfer_op_get_support
void qf_transfer_op_get_support(const QfTransferVertexOperator *op, uint32_t *support_out)
演算子のサポート、すなわち、その演算子が作用するモードのインデックスを取得します。
添字は昇順で記述され、どの項がそれに対して作用しようとも、各添字は正確に1回だけ現れます。
例
1uint32_t left_indices[3] = {2, 0, 2};
2uint32_t right_indices[3] = {2, 1, 2};
3QkComplex64 coeffs[2] = {{1.0, 0.0}, {1.0, 0.0}};
4uint32_t boundaries[3] = {0, 2, 3};
5QfTransferVertexOperator *op =
6 qf_transfer_op_new(2, 3, coeffs, left_indices, right_indices, boundaries);
7
8uint32_t num_support = qf_transfer_op_num_support(op);
9uint32_t *support_out = malloc(num_support * sizeof(uint32_t));
10
11qf_transfer_op_get_support(op, support_out);
12
13assert(support_out[0] == 0);
14assert(support_out[1] == 1);
15assert(support_out[2] == 2);
16
17free(support_out);他のゲッターとは異なり、このゲッターは演算子へのポインタを返しません。サポートはあらかじめ格納されるのではなく、必要に応じて計算されるため、呼び出し側が出力バッファを用意する必要があります。 まずは qf_transfer_op_num_support() 、その必要な長さを照会します。
すべての一般化転送演算子の左添字と右添字の両方が、その支持集合を構成する。
パラメーター
- op – 取得対象の転送頂点演算子へのポインタ。
- support_out – サポートを書き込む整数配列へのポインタ。 サイズは少なくとも :c:func:
qf_transfer_op_num_support個の要素に設定する必要があります。
qf_transfer_op_zero
QfTransferVertexOperator *qf_transfer_op_zero(void)
加法単位演算子を構築する。
この方法で構築された演算子を別の演算子に追加しても、何の効果もありません。
例
1QfTransferVertexOperator *zero = qf_transfer_op_zero();
2
3QfTransferVertexOperator *op_plus_zero = qf_transfer_op_add(op, zero);
4
5assert(qf_transfer_op_equal(op, op_plus_zero));戻り値
作成された演算子へのポインタ。
qf_transfer_op_one
QfTransferVertexOperator *qf_transfer_op_one(void)
乗法単位演算子を構築します。
この方法で構築された演算子を別の演算子と組み合わせても、何の効果もありません。
例
1QfTransferVertexOperator *one = qf_transfer_op_one();
2
3QfTransferVertexOperator *op_times_one = qf_transfer_op_compose(op, one);
4
5assert(qf_transfer_op_equal(op, op_times_one));戻り値
作成された演算子へのポインタ。
qf_transfer_op_has_groups
bool qf_transfer_op_has_groups(const QfTransferVertexOperator *op)
演算子にその属性 groups が設定されているかどうかを確認します。
グループ演算子の用語に関する説明:演算子の構造を使用してください。
例
1QfTransferVertexOperator *op = ...;
2
3bool has_groups = qf_transfer_op_has_groups(op);パラメーター
- op – チェック対象の転送頂点演算子へのポインタ。
戻り値
オペレータがグループインデックスを追跡するかどうか。
qf_transfer_op_num_groups
uint32_t qf_transfer_op_num_groups(const QfTransferVertexOperator *op)
演算子からグループ数を取得します。
グループ演算子の用語に関する説明:演算子の構造を使用してください。
例
1QfTransferVertexOperator *op = ...;
2
3uint32_t num_groups = qf_transfer_op_num_groups(op);グループの数は、出現する最大のグループインデックスに1を加えた値として、遅延評価されます。
パラメーター
- op – 取得するグループ数を指定する、転送頂点演算子へのポインタ。
戻り値
演算子の属性 groups に基づくグループインデックスの数。
qf_transfer_op_get_groups
void qf_transfer_op_get_groups(const QfTransferVertexOperator *op, uint32_t **groups_out, uint64_t *groups_len)
すべての演算子項のグループインデックスを取得します。
グループ演算子の用語に関する説明:演算子の構造を使用してください。
例
1QfTransferVertexOperator *op = ...;
2uint32_t *groups_out;
3uint64_t groups_len;
4
5qf_transfer_op_get_groups(op, &groups_out, &groups_len);この関数は、バッファをコピーするのではなく、演算子の内部バッファを借用します。 返されたポインタは、その演算子が変更されるか解放されるまで有効です。自分で解放しないでください。
パラメーター
- op – グループインデックスを取得する転送頂点演算子へのポインタ。
- groups_out – グループインデックスを書き込む整数配列へのポインタ。
- groups_len – 出力配列の長さを書き込む整数変数へのポインタ。
qf_transfer_op_set_groups
QfExitCode qf_transfer_op_set_groups(QfTransferVertexOperator *op, const uint32_t *groups_in, uint64_t groups_len)
指定された演算子の属 groups 性を設定します。
この長さの検証は、下流で再チェックが行われないため、ここで実施されます。インデックスの数が少なすぎると、項がグループと共に反復処理される際に末尾の項が黙って除外されてしまいますし、多すぎると、どの項にも含まれていないグループが報告 qf_transfer_op_num_groups() されてしまうからです。
グループ演算子の用語に関する説明:演算子の構造を使用してください。
例
1QfTransferVertexOperator *op = ...;
2
3uint32_t num_terms = 4;
4uint32_t groups_in[4] = {0, 1, 0, 1};
5qf_transfer_op_set_groups(op, groups_in, num_terms);パラメーター
- op – 書き込み対象の
groups属性を持つ転送頂点演算子へのポインタ。 - groups_in – 演算子に書き込む整数
groups配列へのポインタ。 - groups_len – 配列
groups_inに含まれる項の数。
戻り値
終了コード。
QfExitCode_Success成功した際にQfExitCode_ValueErrorもし が演算子の項の数と異なるgroups_len場合
qf_transfer_op_del_groups
void qf_transfer_op_del_groups(QfTransferVertexOperator *op)
指定された演算子から 属 groups 性を削除します。
グループ演算子の用語に関する説明:演算子の構造を使用してください。
例
1QfTransferVertexOperator *op = ...;
2
3qf_transfer_op_del_groups(op);パラメーター
- op – 削除対象の
groups属性を持つ転送頂点演算子へのポインタ。
qf_transfer_op_split_out_groups
void qf_transfer_op_split_out_groups(const QfTransferVertexOperator *op, const uint32_t *group_indices, uint64_t num_indices, QfTransferVertexOperator **group_ops_out)
この演算子を、その属性 groups に基づいて新しい演算子のリストに分割します。
における重複インデックスは、における出現回数に応じて1回ずつ書き込まれます group_indices``group_ops_out 。 総数に比べてごく少数のグループのみをリクエストする場合、それらすべてをリクエストする場合よりも大幅にコストが抑えられます。これは、リクエスト対象外のグループに属する用語は、どこにも追加されることなくスキップされるためです。
グループ演算子の用語に関する説明:演算子の構造を使用してください。
例
1QfTransferVertexOperator *op = ...;
2
3uint32_t groups_in[4] = {0, 1, 0, 1};
4qf_transfer_op_set_groups(op, groups_in, 4);
5
6// build every group, in index order
7QfTransferVertexOperator *group_ops[2];
8qf_transfer_op_split_out_groups(op, NULL, 0, group_ops);
9
10// build only group 1
11uint32_t group_indices[1] = {1};
12QfTransferVertexOperator *group_op[1];
13qf_transfer_op_split_out_groups(op, group_indices, 1, group_op);パラメーター
- op – 分割対象
groupsの転送頂点演算子へのポインタ。 - group_indices – 演算子を構築するグループインデックスの配列へのポインタ。配列は、希望する出力順に並んでいる必要があります。 そうかもしれません
NULL。その場合、すべてのグループはインデックスの順に構築されます(これは、すべてのインデックスを:c:func:qf_transfer_op_num_groups0に渡すことと同等です- 1)。 - num_indices – 配列
group_indicesに含まれるインデックスの数。group_indicesが の場合、無視されるNULL。 - group_ops_out – 要求された各グループの演算子を書き込む :c:struct:
QfTransferVertexOperatorの配列へのポインタ。 がgroup_indices非のnum_indicesときは にNULL、が のときは :c:func:qf_transfer_op_num_groupsにサイズ設定する必要がありますNULL。
qf_transfer_op_add_term
void qf_transfer_op_add_term(QfTransferVertexOperator *op, uint64_t num_indices, const uint32_t *left_indices, const uint32_t *right_indices, const QkComplex64 *coeff)
既存の演算子に項を追加します。
ポインタ引数のいずれかが となるのは、それに対応する長さがゼロである場合 NULL に限られる。
この関数は、演算子の属 groups 性を にリセットします NULL。
例
1QfTransferVertexOperator *one = qf_transfer_op_one();
2
3QfTransferVertexOperator *op = qf_transfer_op_zero();
4QkComplex64 coeff = {1.0, 0.0};
5
6qf_transfer_op_add_term(op, 0, NULL, NULL, &coeff);
7
8assert(qf_transfer_op_equal(op, one));パラメーター
- op – 変更対象の転送頂点演算子へのポインタ。
- num_indices – 両方のインデックス配列の長さ。
- left_indices – 左モードのインデックスの配列へのポインタ。 この配列の長さは であるべきです
num_indices。 - right_indices – 右側モードのインデックスの配列へのポインタ。 この配列の長さは であるべきです
num_indices。 - coeff – 複素係数を指すポインタ。
qf_transfer_op_add
QfTransferVertexOperator *qf_transfer_op_add(const QfTransferVertexOperator *left, const QfTransferVertexOperator *right)
2つの演算子を足し合わせます。
例
1QfTransferVertexOperator *one = qf_transfer_op_one();
2QfTransferVertexOperator *zero = qf_transfer_op_zero();
3
4QfTransferVertexOperator *result = qf_transfer_op_add(one, zero);
5
6assert(qf_transfer_op_equal(result, one));パラメーター
- left – 左演算子へのポインタ。
- right – right 演算子へのポインタ。
戻り値
結果となる演算子へのポインタ。
qf_transfer_op_scaled_add
QfTransferVertexOperator *qf_transfer_op_scaled_add(const QfTransferVertexOperator *left, const QfTransferVertexOperator *right, const QkComplex64 *factor)
2つの演算子を足し合わせ、右側の演算子の係数をスケーリングします。
これにより、スケーリングが加算処理に統合されるため、単に right 追加するためだけに完全にスケーリングされたコピーを作成する必要がなくなります。 係数を乗じると、結果 -1 として引き算が行われることになるため、別途引き算関数が用意されていないのです。
例
1QfTransferVertexOperator *one = qf_transfer_op_one();
2QfTransferVertexOperator *other = qf_transfer_op_one();
3
4// Subtracting via a factor of -1 leaves the two terms cancelling each other out.
5QkComplex64 factor = {-1.0, 0.0};
6QfTransferVertexOperator *result = qf_transfer_op_scaled_add(one, other, &factor);
7
8QfTransferVertexOperator *simplified = qf_transfer_op_simplify(result, 1e-10);
9assert(qf_transfer_op_len(simplified) == 0);つまり qf_transfer_op_add()、これは の項を のもので結合すること right なく追加するため left、結果にはグループインデックスが追跡されません。 後で同等の条件で着信課金 qf_transfer_op_simplify() で電話してください。
パラメーター
- left – 左演算子へのポインタ。
- right – right 演算子へのポインタ。
- 因子 – 右辺演算子の係数をスケールするための因子へのポインタ。
戻り値
結果の演算子へのポインタ、 left + factor * right.
qf_transfer_op_add_inplace
void qf_transfer_op_add_inplace(QfTransferVertexOperator *left, const QfTransferVertexOperator *right)
ある演算子を別の演算子に、その場(インプレース)で追加します。
のインプレース版であり qf_transfer_op_add()、新しく割り当てられた結果変数 left へのコピーを省略します。
この関数は、演算子の属 groups 性を にリセットします NULL。
例
1QfTransferVertexOperator *left = qf_transfer_op_one();
2QfTransferVertexOperator *right = qf_transfer_op_one();
3
4qf_transfer_op_add_inplace(left, right);
5
6assert(qf_transfer_op_len(left) == 2);パラメーター
- left – 追加先の演算子へのポインタ。
- right – 加算する演算子へのポインタ。
qf_transfer_op_scaled_add_inplace
void qf_transfer_op_scaled_add_inplace(QfTransferVertexOperator *left, const QfTransferVertexOperator *right, const QkComplex64 *factor)
ある演算子を別の演算子にその場で追加し、右側の演算子の係数をスケーリングします。
のインプレース版であり qf_transfer_op_scaled_add()、結果を割り当て left + factor * right ずに を計算する。 そこで、ある係数が差し引かれる -1 。
この関数は、演算子の属 groups 性を にリセットします NULL。
例
1QfTransferVertexOperator *left = qf_transfer_op_one();
2QfTransferVertexOperator *right = qf_transfer_op_one();
3
4// Subtract, leaving two terms that cancel each other out.
5QkComplex64 factor = {-1.0, 0.0};
6qf_transfer_op_scaled_add_inplace(left, right, &factor);
7
8QfTransferVertexOperator *simplified = qf_transfer_op_simplify(left, 1e-10);
9assert(qf_transfer_op_len(simplified) == 0);パラメーター
- left – 追加先の演算子へのポインタ。
- right – 加算する演算子へのポインタ。
- 因子 – 右辺演算子の係数をスケールするための因子へのポインタ。
qf_transfer_op_mul_inplace
void qf_transfer_op_mul_inplace(QfTransferVertexOperator *op, const QkComplex64 *scalar)
演算子にスカラーを掛け合わせ、その場で結果を更新します。
のインプレース版であり qf_transfer_op_mul()、演算子を新たに割り当てられた結果変数にコピーする手間を省くことができます。
例
1QfTransferVertexOperator *op = qf_transfer_op_one();
2QkComplex64 scalar = {2.0, 0.0};
3
4qf_transfer_op_mul_inplace(op, &scalar);上記の2つのインプレース追加とは異なり、この方法では属性 groups が保持されます。係数をスケーリングしても、項の数は変わらず、したがって「1項につき1つのインデックス」という不変性も損なわれません。
パラメーター
- op – 拡大・縮小を行う演算子へのポインタ。
- スカラー – スカラーへのポインタ。
qf_transfer_op_mul
QfTransferVertexOperator *qf_transfer_op_mul(const QfTransferVertexOperator *op, const QkComplex64 *scalar)
演算子にスカラーを乗算します。
例
1QfTransferVertexOperator *one = qf_transfer_op_one();
2QkComplex64 coeff = {2.0, 0.0};
3QfTransferVertexOperator *result = qf_transfer_op_mul(one, &coeff);
4
5QfTransferVertexOperator *expected = qf_transfer_op_zero();
6qf_transfer_op_add_term(expected, 0, NULL, NULL, &coeff);
7
8assert(qf_transfer_op_equal(result, expected));パラメーター
- op – 演算子へのポインタ。
- スカラー – スカラーへのポインタ。
戻り値
結果となる演算子へのポインタ。
qf_transfer_op_compose
QfTransferVertexOperator *qf_transfer_op_compose(const QfTransferVertexOperator *left, const QfTransferVertexOperator *right)
2つの演算子を互いに合成します。
例
1QfTransferVertexOperator *one = qf_transfer_op_one();
2QfTransferVertexOperator *zero = qf_transfer_op_zero();
3
4QfTransferVertexOperator *result = qf_transfer_op_compose(one, zero);
5
6assert(qf_transfer_op_equal(result, zero));2つの演算子からなる式は、たとえ両方のオペランドがグループを指定していても、グループを追跡しません。
パラメーター
- left – 左演算子へのポインタ。
- right – right 演算子へのポインタ。
戻り値
へのポインタ left.compose(right)。これは、行列乗算 を用いて result = right @ left 、演算子 と等しい @。 つまり、 が先に適用される right 。 を得るには left @ right、引数の順序を入れ替えます。
qf_transfer_op_adjoint
QfTransferVertexOperator *qf_transfer_op_adjoint(const QfTransferVertexOperator *op)
演算子のエルミート共役(または随伴)を返します。
これにより、項と係数には次のような影響が生じます:
- 各項の発電機の順序が逆になる
- 係数は複素共役である
例
1QfTransferVertexOperator *op = qf_transfer_op_zero();
2QkComplex64 coeff = {0.0, 1.0};
3qf_transfer_op_add_term(op, 0, NULL, NULL, &coeff);
4
5QfTransferVertexOperator *adjoint = qf_transfer_op_adjoint(op);
6
7QfTransferVertexOperator *expected = qf_transfer_op_zero();
8QkComplex64 coeff_adj = {0.0, -1.0};
9qf_transfer_op_add_term(expected, 0, NULL, NULL, &coeff_adj);
10
11assert(qf_transfer_op_equal(adjoint, expected));演算子文字列を逆順にすることは不可欠である。転移生成子と頂点生成子は、インデックスを共有する場合に反交換するため、一般に BA != AB 。
パラメーター
- op – 演算子へのポインタ。
戻り値
作成された演算子へのポインタ。
qf_transfer_op_ichop
void qf_transfer_op_ichop(QfTransferVertexOperator *op, double atol)
指定された閾値未満の係数の絶対値を持つ項を除去します。
この関数は、係数を貪欲に切り捨ててしまいます! 対象となる演算子に、重複する項ごとに個別の係数が含まれている可能性がある場合は、代わりに qf_transfer_op_simplify() を呼び出すことを検討してください!
例
1QfTransferVertexOperator *op = qf_transfer_op_zero();
2QkComplex64 coeff = {1e-8, 0.0};
3qf_transfer_op_add_term(op, 0, NULL, NULL, &coeff);
4
5qf_transfer_op_ichop(op, 1e-6);
6
7QfTransferVertexOperator *expected = qf_transfer_op_zero();
8
9assert(qf_transfer_op_equal(op, expected));パラメーター
- op – 演算子へのポインタ。
- atol – 係数の切り捨てに対する絶対許容誤差。
qf_transfer_op_simplify
QfTransferVertexOperator *qf_transfer_op_simplify(const QfTransferVertexOperator *op, double atol)
同等だが簡略化された演算子を返します。
簡略化のプロセスでは、まず同じ項に属するすべての係数を合計し、その合計係数が指定された許容誤差を超えるもののみを残します(ちょうど…のように qf_transfer_op_ichop())。
演算子が算術的に操作されたり、一意な項が保証されない方法で構築されたりした場合、情報の損失を防ぐために、数値的に小さい係数をフィルタリングするメソッドを適用する前に、このメソッドを呼び出す必要があります。
例
1QfTransferVertexOperator *op = qf_transfer_op_zero();
2QkComplex64 coeff = {1e-5, 0.0};
3for (int i = 0; i < 100; i++) {
4 qf_transfer_op_add_term(op, 0, NULL, NULL, &coeff);
5}
6
7QfTransferVertexOperator *canon = qf_transfer_op_simplify(op, 1e-4);
8
9assert(qf_transfer_op_len(canon) == 1);これにより、用語は保存されているインデックス配列の値が完全に一致する順にグループ化されます。 まず qf_transfer_op_normal_ordered() 、数学的に等しい項を共通の形にまとめるために、分母を計算してください。
パラメーター
- op – 簡略化する転送頂点演算子へのポインタ。
- atol – 係数の切り捨てに対する絶対許容誤差。
戻り値
同等だが簡略化された演算子。
qf_transfer_op_normal_ordered
QfTransferVertexOperator *qf_transfer_op_normal_ordered(const QfTransferVertexOperator *op, bool reduce)
通常の順序を持つ項を持つ等価演算子を返します。
このフラグ reduce は、隣接するジェネレータを収縮させます。 ルールは正確に2つある。 および (2つの同一の隣接因子はスカラーに収縮する)、そして (2つの逆平行な転送演算子は頂点演算子のペアとなる)。
例
1// `T(0,1) T(1,0)` reduces to `-1/4 V(0) V(1)`
2QfTransferVertexOperator *op = qf_transfer_op_zero();
3uint32_t left[2] = {0, 1};
4uint32_t right[2] = {1, 0};
5QkComplex64 coeff = {4.0, 0.0};
6qf_transfer_op_add_term(op, 2, left, right, &coeff);
7
8QfTransferVertexOperator *ordered = qf_transfer_op_normal_ordered(op, true);
9
10QfTransferVertexOperator *expected = qf_transfer_op_zero();
11uint32_t left_exp[2] = {0, 1};
12uint32_t right_exp[2] = {0, 1};
13QkComplex64 coeff_exp = {-1.0, 0.0};
14qf_transfer_op_add_term(expected, 2, left_exp, right_exp, &coeff_exp);
15
16assert(qf_transfer_op_equal(ordered, expected));とは異なり qf_edge_op_normal_ordered()、この関数はパラメータ ascending を一切受け取りません。 方向に関する規則を修正する必要はありません。 と は、1つの演算子の2つの表記というのではなく、 別々の演算子です。
融合のルールは存在しません。 単一のモードを共有する2つの転送演算子は決して1つに収束しないため、 のような積は短縮できません。
パラメーター
- op – 演算子へのポインタ。
- reduce – 代数の恒等式を用いて、隣接する生成子を縮約するかどうか。
戻り値
作成された演算子へのポインタ。
qf_transfer_op_is_hermitian
bool qf_transfer_op_is_hermitian(const QfTransferVertexOperator *op, double atol)
演算子がエルミートであるかどうかを調べます。
例
1// `V(0) T(0,1)` is *not* Hermitian: the two generators share the index 0 and therefore
2// anticommute.
3QfTransferVertexOperator *op = qf_transfer_op_zero();
4uint32_t left[2] = {0, 0};
5uint32_t right[2] = {0, 1};
6QkComplex64 coeff = {1.0, 0.0};
7qf_transfer_op_add_term(op, 2, left, right, &coeff);
8
9assert(!qf_transfer_op_is_hermitian(op, 1e-10));このチェックは、と op 、その、 qf_transfer_op_adjoint() およびの qf_transfer_op_normal_ordered() 差 qf_transfer_op_equiv() を用いて実装されています qf_transfer_op_zero()。
パラメーター
- op – チェック対象の転送頂点演算子へのポインタ。
- atol – 係数が等しいとみなされる絶対許容誤差。
戻り値
指定された演算子がエルミート演算子であるかどうか。
qf_transfer_op_equal
bool qf_transfer_op_equal(const QfTransferVertexOperator *left, const QfTransferVertexOperator *right)
2つの演算子の等価性を比較する。
この文脈における「等価」とは、内部のデータ配列が完全に一致することを意味します。
例
1QfTransferVertexOperator *one = qf_transfer_op_one();
2QfTransferVertexOperator *zero = qf_transfer_op_zero();
3
4assert(qf_transfer_op_equal(one, one));
5assert(!qf_transfer_op_equal(one, zero));パラメーター
- left – 左演算子へのポインタ。
- right – right 演算子へのポインタ。
戻り値
2つの演算子が等しいかどうか。
qf_transfer_op_equiv
bool qf_transfer_op_equiv(const QfTransferVertexOperator *left, const QfTransferVertexOperator *right, double atol)
2つの演算子の等価性を比較する。
この文脈における「等価性」とは、指定された絶対許容差の範囲内での近似的な等しさを意味します。 より正確に言えば、このメソッドは True、差分 に含まれる係数の絶対値がすべて、指定された閾値 を下回 other - self っている場合に、 を返します atol。
例
1QfTransferVertexOperator *zero = qf_transfer_op_zero();
2
3QfTransferVertexOperator *op = qf_transfer_op_zero();
4QkComplex64 coeff = {1e-7, 0.0};
5qf_transfer_op_add_term(op, 0, NULL, NULL, &coeff);
6
7assert(qf_transfer_op_equiv(op, zero, 1e-6));
8assert(!qf_transfer_op_equiv(op, zero, 1e-8));パラメーター
- left – 左演算子へのポインタ。
- right – right 演算子へのポインタ。
- atol – 係数の等価性に対する絶対許容誤差。
戻り値
この2つの演算子が等価であるかどうか。
qf_transfer_op_len
size_t qf_transfer_op_len(const QfTransferVertexOperator *op)
指定された演算子の長さ(または項の数)を返します。
例
1QfTransferVertexOperator *op = qf_transfer_op_zero();
2uint32_t left[2] = {0, 1};
3uint32_t right[2] = {1, 2};
4QkComplex64 coeff = {1.0, 0.0};
5qf_transfer_op_add_term(op, 2, left, right, &coeff);
6
7assert(qf_transfer_op_len(op) == 1);パラメーター
- op – 転送頂点演算子へのポインタ。
戻り値
演算子の長さ(または項の数)。
qf_transfer_op_relabel_modes
QfExitCode qf_transfer_op_relabel_modes(QfTransferVertexOperator *op, uint64_t num_modes, const uint32_t *permutation)
指定された演算子のモードを再ラベル付けします。
例
1QfTransferVertexOperator *op = qf_transfer_op_zero();
2uint32_t left[2] = {0, 2};
3uint32_t right[2] = {1, 3};
4QkComplex64 coeff = {1.0, 0.0};
5qf_transfer_op_add_term(op, 2, left, right, &coeff);
6
7uint32_t permutation[4] = {3, 2, 1, 0};
8
9QfExitCode exit = qf_transfer_op_relabel_modes(op, 4, permutation);
10
11assert(exit == QfExitCode_Success);両方のインデックス配列のラベルが変更されました。 ほとんどの演算とは異なり、この演算では演算子の属性 groups が保持されます。これは、再ラベル付けによってモードインデックスが並べ替えられるものの、項の順序変更、分割、または結合は行われないためです。
パラメーター
- op – 転送頂点演算子へのポインタ。
- num_modes – 指定された順列リストに含まれるモードインデックスの数。
- 順列 – インデックスの順列リスト。
戻り値
終了コード。
QfExitCode_Success成功した際にQfExitCode_DuplicateIndexError順列の中に重複するインデックスが見つかった場合QfExitCode_IndexError無効なインデックスなど、その他のインデックスに関するエラーについては。