QfMajoranaOperator
QfMajoranaOperator
struct QfMajoranaOperator
Ein Majorana-Fermion-Operator.
Es handelt sich hierbei um eine für die C-API undurchsichtige Datenstruktur, deren Interna vollständig in Rust implementiert sind. Im weiteren Verlauf dieser Seite werden der Aufbau und die zugehörigen Funktionen zur Verwendung dieser Struktur beschrieben.
Begriffsbestimmung
Dieser Operator wird durch eine Linearkombination von Produkten von Majorana-Operatoren definiert [1], die sich anhand der Standard-Fermionen-Operatoren der zweiten Quantisierung für Erzeugung und Vernichtung definieren lassen (siehe auch .QfFermionOperator):
Die entscheidende Eigenschaft eines Majorana-Fermions, nämlich dass es sein eigenes Antiteilchen ist, wird sofort deutlich:
Daraus ergeben sich die folgenden Antikommutationsrelationen für Majorana-Fermionen:
Damit lautet die Definition des gesamten Operators wie folgt:
wobei der (komplexe) Koeffizient ist, der die Linearkombination der Produkte von bildet. Der Index kann jeden Wert zwischen 0 und der Anzahl der Majorana-Fermionen-Moden, auf die der Operator wirkt, minus 1 annehmen.
Bereitstellung
Diese Struktur speichert die Terme und Koeffizienten in mehreren spärlichen Vektoren, ähnlich dem „Compressed Sparse Row“-Format, das üblicherweise für spärliche Matrizen verwendet wird. Genauer gesagt enthält ein einzelner Operator vier Arrays:
Kolumne „ 1 “ | Kolumne „ 2 “ |
|---|---|
coeffs | Ein Vektor mit komplexen Koeffizienten, bestehend aus zwei 64-Bit-Gleitkommazahlen. |
modes | Ein Vektor aus 32-Bit-Ganzzahlen, in dem die Indizes der bearbeiteten Majorana-Modi gespeichert sind. |
boundaries | Ein Vektor aus ganzen Zahlen, der die Grenzen in und actions angibt indices. |
Die ganzen Zahlen in indizieren modes die Majorana-Moden: . Bei Verwendung der Hilfsfunktion gamma()werden gerade (ungerade) Indizes für ( ) verwendet.
Über die jeweiligen Funktionen können Sie auf schreibgeschützte Kopien dieser internen Arrays zugreifen:
Diese Datenstruktur ermöglicht eine sehr effiziente Erstellung und Bearbeitung von Operatoren. Dies bedeutet jedoch, dass ein Operator jederzeit doppelte Begriffe enthalten könnte. Diese müssen manuell mithilfe von qf_maj_op_simplify(). behoben werden.
Bauwesen
Ein neuer Operator kann direkt durch die Angabe der oben beschriebenen entsprechenden Arrays konstruiert werden. Alternativ QfMajoranaOperator kann ein leeres mit initialisiert werden, und qf_maj_op_zero() Terme können iterativ über hinzugefügt werden qf_maj_op_add_term().
Kolumne „ 1 “ | Kolumne „ 2 “ |
|---|---|
qf_maj_op_new() | Erstellt aus den angegebenen Arrays einen neuen Operator. |
qf_maj_op_zero() | Erzeugt den additiven Identitätsoperator. |
qf_maj_op_one() | Erzeugt den multiplikativen Identitätsoperator. |
qf_maj_op_add_term() | Fügt einen Begriff zu einem bestehenden hinzu QfMajoranaOperator. |
A kann QfMajoranaOperator mit freigegeben werden qf_maj_op_free().
Rechenaufgaben
Die folgenden Funktionen ermöglichen arithmetische Berechnungen:
Kolumne „ 1 “ | Kolumne „ 2 “ |
|---|---|
qf_maj_op_add() | Addiert zwei Operanden. |
qf_maj_op_mul() | Multipliziert einen Operator mit einem Skalar. |
qf_maj_op_compose() | Kombiniert zwei Operatoren miteinander. |
qf_maj_op_adjoint() | Gibt den hermitisch konjugierten Operator zurück. |
Bearbeitung
Die folgenden Funktionen stellen die Logik zur Bearbeitung von Operatoren bereit:
Kolumne „ 1 “ | Kolumne „ 2 “ |
|---|---|
qf_maj_op_ichop() | Entfernt Terme mit kleinen Koeffizienten. |
qf_maj_op_simplify() | Gibt einen gleichwertigen, aber vereinfachten Operator zurück. |
qf_maj_op_normal_ordered() | Gibt einen Äquivalenzoperator mit normal geordneten Termen zurück. |
qf_maj_op_relabel_modes() | Benennt die Modi eines Operators um. |
Eigenschaften
Es gibt die folgenden Funktionen, um bestimmte Eigenschaften eines Operators zu überprüfen.
Kolumne „ 1 “ | Kolumne „ 2 “ |
|---|---|
qf_maj_op_is_hermitian() | Gibt zurück, ob ein Operator hermitisch ist. |
qf_maj_op_max_rank() | Gibt den höchsten Rang der Terme in diesem Operator zurück. |
qf_maj_op_is_even() | Gibt zurück, ob ein Operator gerade ist. |
[ 1 ]
https://en.wikipedia.org/wiki/Majorana _fermion
Mitglieder
qf_maj_op_new
QfMajoranaOperator *qf_maj_op_new(uint64_t num_terms, uint64_t num_modes, const QkComplex64 *coeffs, const uint32_t *modes, const uint32_t *boundaries)
Erstellt einen neuen Operator.
Jedes der Zeigerargumente kann genau dann sein, NULL wenn seine entsprechende Länge null ist.
Beispiel
1uint64_t num_terms = 3;
2uint64_t num_modes = 4;
3uint32_t modes[4] = {0, 1, 2, 3};
4QkComplex64 coeffs[3] = {{1.0, 0.0}, {-1.0, 0.0}, {0.0, -1.0}};
5uint32_t boundaries[4] = {0, 0, 2, 4};
6QfMajoranaOperator *op = qf_maj_op_new(num_terms, num_modes, coeffs,
7 modes, boundaries);Parameter
- num_terms – Die Anzahl der Terme im Operator.
- num_modes – Die Anzahl der Moden, summiert über alle Terme.
- coeffs – Ein Zeiger auf ein Array von Termkoeffizienten. Die Länge dieses Arrays sollte betragen
num_terms. - Modi – Ein Zeiger auf ein Array von Modi für alle Terme. Die Länge dieses Arrays sollte betragen
num_modes. - Grenzen – Ein Zeiger auf ein Array, das die Grenzen zwischen den Termen enthält. Die Länge dieses Arrays sollte betragen
num_terms + 1.
qf_maj_op_free
void qf_maj_op_free(QfMajoranaOperator *op)
Gibt einen vorhandenen Operator frei.
Beispiel
1QfMajoranaOperator *op = qf_maj_op_one();
2qf_maj_op_free(op);Parameter
- op – Ein Zeiger auf den Majorana-Operator, der freigegeben werden soll.
qf_maj_op_get_coeffs
void qf_maj_op_get_coeffs(const QfMajoranaOperator *op, QkComplex64 **coeffs_out, uint64_t *coeffs_len)
Bietet Lesezugriff auf die Koeffizienten des Operators.
Die Erläuterung der internen Datenstruktur finden Sie hier.
Beispiel
1uint64_t num_terms = 2;
2uint64_t num_modes = 0;
3QkComplex64 coeffs[2] = {{1.0, 0.0}, {0.0, -1.0}};
4uint32_t boundaries[3] = {0, 0, 0};
5QfMajoranaOperator *op =
6 qf_maj_op_new(num_terms, num_modes, coeffs, NULL, boundaries);
7
8QkComplex64 *coeffs_out;
9uint64_t *coeffs_len;
10
11qf_maj_op_get_coeffs(op, &coeffs_out, &coeffs_len);
12
13assert(coeffs_len == 2);Diese Funktion gibt eine Kopie der internen Daten zurück.
Parameter
- op – Ein Zeiger auf den Majorana-Operator, dessen Koeffizienten abgerufen werden sollen.
- coeffs_out – Ein Zeiger auf das Array komplexer Werte, in das die Koeffizienten geschrieben werden sollen.
- coeffs_len – Ein Zeiger auf die Ganzzahl, in die die Länge des Ausgabe-Arrays geschrieben werden soll.
qf_maj_op_get_modes
void qf_maj_op_get_modes(const QfMajoranaOperator *op, uint32_t **modes_out, uint64_t *modes_len)
Bietet Lesezugriff auf die Indizes des Operators im „Acted-Upon“-Modus.
Die Erläuterung der internen Datenstruktur finden Sie hier.
Beispiel
1uint64_t num_terms = 2;
2bool actions[2] = {true, false};
3uint32_t modes[2] = {0, 1};
4QkComplex64 coeffs[2] = {{1.0, 0.0}, {0.0, -1.0}};
5uint32_t boundaries[3] = {0, 0, 2};
6QfMajoranaOperator *op =
7 qf_maj_op_new(num_terms, num_actions, coeffs, modes, boundaries);
8
9QkComplex64 *modes_out;
10uint64_t *modes_len;
11
12qf_maj_op_get_modes(op, &modes_out, &modes_len);
13
14assert(modes_len == 2);Diese Funktion gibt eine Kopie der internen Daten zurück.
Parameter
- op – Ein Zeiger auf den Majorana-Operator, auf dessen Moden zugegriffen werden soll.
- modes_out – Ein Zeiger auf das Array mit booleschen Werten, in das die Modi geschrieben werden sollen.
- modes_len – Ein Zeiger auf die Ganzzahl, in die die Länge des Ausgabearrays geschrieben werden soll.
qf_maj_op_get_boundaries
void qf_maj_op_get_boundaries(const QfMajoranaOperator *op, size_t **boundaries_out, uint64_t *boundaries_len)
Bietet Lesezugriff auf die Indizes, die die Grenzen zwischen den Operatorausdrücken angeben.
Die Erläuterung der internen Datenstruktur finden Sie hier.
Beispiel
1uint64_t num_terms = 2;
2uint64_t num_modes = 2;
3uint32_t modes[2] = {0, 1};
4QkComplex64 coeffs[2] = {{1.0, 0.0}, {0.0, -1.0}};
5uint32_t boundaries[3] = {0, 0, 2};
6QfMajoranaOperator *op =
7 qf_maj_op_new(num_terms, num_modes, coeffs, modes, boundaries);
8
9QkComplex64 *boundaries_out;
10uint64_t *boundaries_len;
11
12qf_maj_op_get_boundaries(op, &boundaries_out, &boundaries_len);
13
14assert(boundaries_len == 3);Diese Funktion gibt eine Kopie der internen Daten zurück.
Parameter
- op – Ein Zeiger auf den Majorana-Operator, auf dessen Grenzen zugegriffen werden soll.
- boundaries_out – Ein Zeiger auf das Array mit booleschen Werten, in das die Grenzen geschrieben werden sollen.
- boundaries_len – Ein Zeiger auf die Ganzzahl, in die die Länge des Ausgabearrays geschrieben werden soll.
qf_maj_op_num_support
uint32_t qf_maj_op_num_support(const QfMajoranaOperator *op)
Ermittelt die Größe der Stützmenge eines Operators.
Verwenden Sie dies, um die Größe des Ausgabepuffers von festzulegen qf_maj_op_get_support(), der keine eigene Länge angibt.
Beispiel
1uint32_t modes[3] = {2, 0, 2};
2QkComplex64 coeffs[2] = {{1.0, 0.0}, {1.0, 0.0}};
3uint32_t boundaries[3] = {0, 2, 3};
4QfMajoranaOperator *op = qf_maj_op_new(2, 3, coeffs, modes, boundaries);
5
6uint32_t num_support = qf_maj_op_num_support(op);
7
8assert(num_support == 2);Parameter
- op – Ein Zeiger auf den Majorana-Operator, dessen Unterstützungsgröße ermittelt werden soll.
Rückgabe
Die Anzahl der unterschiedlichen Modusindizes, auf die der Operator einwirkt.
qf_maj_op_get_support
void qf_maj_op_get_support(const QfMajoranaOperator *op, uint32_t *support_out)
Liefert die Unterstützung eines Operators, d. h. die Majorana-Modenindizes, auf die der Operator einwirkt.
Die Indizes sind in aufsteigender Reihenfolge aufgeführt, und jeder Index kommt genau einmal vor, unabhängig davon, wie viele Terme auf ihn einwirken.
Beispiel
1uint32_t modes[3] = {2, 0, 2};
2QkComplex64 coeffs[2] = {{1.0, 0.0}, {1.0, 0.0}};
3uint32_t boundaries[3] = {0, 2, 3};
4QfMajoranaOperator *op = qf_maj_op_new(2, 3, coeffs, modes, boundaries);
5
6uint32_t num_support = qf_maj_op_num_support(op);
7uint32_t *support_out = malloc(num_support * sizeof(uint32_t));
8
9qf_maj_op_get_support(op, support_out);
10
11assert(support_out[0] == 0);
12assert(support_out[1] == 2);
13
14free(support_out);Im Gegensatz zu den anderen Gettern gibt dieser keinen Zeiger auf den Operator zurück: Der Wert wird bei Bedarf berechnet und nicht gespeichert, daher muss der Aufrufer den Ausgabepuffer bereitstellen. Ermitteln Sie zunächst qf_maj_op_num_support() die erforderliche Länge der Abfrage.
Dies sind die Majorana -Modenindizes, nicht die fermionischen: Sie werden nicht durch zwei geteilt. Ein Majorana-Operator auf einem fermionischen Modus weist daher j die Indizes 2 * j und/oder auf 2 * j + 1.
Parameter
- op – Ein Zeiger auf den Majorana-Operator, dessen Unterstützungsbereich abgerufen werden soll.
- support_out – Ein Zeiger auf das Integer-Array, in das die Unterstützung geschrieben werden soll. Es muss eine Größe von mindestens :c:func:
qf_maj_op_num_supportElementen haben.
qf_maj_op_zero
QfMajoranaOperator *qf_maj_op_zero(void)
Erzeugt den additiven Identitätsoperator.
Das Hinzufügen des auf diese Weise erstellten Operators zu einem anderen hat keine Auswirkung.
Beispiel
1QfMajoranaOperator *zero = qf_maj_op_zero();
2
3QfMajoranaOperator *op_plus_zero = qf_maj_op_add(op, zero);
4
5assert(qf_maj_op_equal(op, op_plus_zero));Rückgabe
Ein Zeiger auf den erstellten Operator.
qf_maj_op_one
QfMajoranaOperator *qf_maj_op_one(void)
Erzeugt den multiplikativen Identitätsoperator.
Die Kombination des auf diese Weise gebildeten Operators mit einem anderen hat keine Auswirkungen.
Beispiel
1QfMajoranaOperator *one = qf_maj_op_one();
2
3QfMajoranaOperator *op_times_one = qf_maj_op_compose(op, one);
4
5assert(qf_maj_op_equal(op, op_times_one));Rückgabe
Ein Zeiger auf den erstellten Operator.
qf_maj_op_has_groups
bool qf_maj_op_has_groups(const QfMajoranaOperator *op)
Prüft, ob dieser Operator Gruppenindizes nachverfolgt.
Beispiel
1QfMajoranaOperator *op = ...;
2
3bool has_groups = qf_maj_op_has_groups(op);Parameter
- op – Ein Zeiger auf den zu prüfenden Majorana-Operator.
Rückgabe
Ob der angegebene Operator ein Attribut groups besitzt.
qf_maj_op_num_groups
uint32_t qf_maj_op_num_groups(const QfMajoranaOperator *op)
Ruft die Anzahl der Gruppen eines Operators ab.
Beispiel
1QfMajoranaOperator *op = ...;
2
3uint32_t num_groups = qf_maj_op_num_groups(op);Die Anzahl der Gruppen wird verzögert als der Index der größten vorkommenden Gruppe plus 1 berechnet.
Parameter
- op – Ein Zeiger auf den Majorana-Operator, dessen Gruppenanzahl ermittelt werden soll.
Rückgabe
Die Anzahl der Gruppenindizes aus dem Attribut groups des Operators.
qf_maj_op_get_groups
void qf_maj_op_get_groups(const QfMajoranaOperator *op, uint32_t **groups_out, uint64_t *groups_len)
Ruft die Gruppenindizes für alle Operatorterme ab.
Beispiel
1QfMajoranaOperator *op = ...;
2uint32_t *groups_out;
3uint32_t groups_len;
4
5qf_maj_op_get_groups(op, &groups_out, &groups_len);Parameter
- op – Ein Zeiger auf den Majorana-Operator, dessen Gruppenindizes abgerufen werden sollen.
- groups_out – Ein Zeiger auf das Integer-Array, in das die Gruppenindizes geschrieben werden sollen.
- groups_len – Ein Zeiger auf die Ganzzahl, in die die Länge des Ausgabearrays geschrieben werden soll.
qf_maj_op_set_groups
QfExitCode qf_maj_op_set_groups(QfMajoranaOperator *op, const uint32_t *groups_in, uint64_t groups_len)
Legt das Attribut groups des angegebenen Operators fest.
Die Länge wird hier überprüft, da sie weiter unten nicht noch einmal überprüft wird: Bei zu wenigen Indizes würden die nachfolgenden Terme stillschweigend weggelassen, wenn Terme zusammen mit ihren Gruppen durchlaufen werden, und bei zu vielen würden Gruppen qf_maj_op_num_groups() gemeldet, die kein Term enthält.
Beispiel
1QfMajoranaOperator *op = ...;
2
3uint32_t num_terms = 4;
4uint32_t groups_in[4] = {0, 1, 0, 1};
5qf_maj_op_set_groups(op, groups_in, num_terms);Parameter
- op – Ein Zeiger auf den Majorana-Operator, dessen Attribut
groupsgeschrieben werden soll. - groups_in – Ein Zeiger auf das
groupsInteger-Array, in das der Operator schreiben soll. - groups_len – Die Anzahl der Elemente im Array
groups_in.
Rückgabe
Ein Exit-Code.
QfExitCode_Successim ErfolgsfallQfExitCode_ValueErrorwenn von der Anzahl der Terme im Operator abweichtgroups_len
qf_maj_op_del_groups
void qf_maj_op_del_groups(QfMajoranaOperator *op)
Löscht das Attribut groups aus dem angegebenen Operator.
Beispiel
1QfMajoranaOperator *op = ...;
2
3qf_maj_op_del_groups(op);Parameter
- op – Ein Zeiger auf den Majorana-Operator, dessen Attribut
groupsgelöscht werden soll.
qf_maj_op_split_out_groups
void qf_maj_op_split_out_groups(const QfMajoranaOperator *op, const uint32_t *group_indices, uint64_t num_indices, QfMajoranaOperator **group_ops_out)
Teilt diesen Operator anhand seines Attributs groups in eine Liste neuer Operatoren auf.
Ein doppelter Index in group_indices wird einmal pro Vorkommen in geschrieben group_ops_out. Das Abfragen nur einer kleinen Anzahl von Gruppen aus einer viel größeren Gesamtmenge ist deutlich kostengünstiger als das Abfragen aller Gruppen, da Begriffe, die zu einer nicht abgefragten Gruppe gehören, übersprungen und nicht irgendwo angehängt werden.
Beispiel
1uint64_t num_terms = 4;
2uint64_t num_modes = 8;
3uint32_t modes[8] = {0, 1, 2, 3, 1, 0, 3, 2};
4QkComplex64 coeffs[4] = {{1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}, {1.0, 0.0}};
5uint32_t boundaries[5] = {0, 2, 4, 6, 8};
6QfMajoranaOperator *op = qf_maj_op_new(num_terms, num_modes, coeffs, modes, boundaries);
7
8uint32_t groups_in[4] = {0, 1, 0, 1};
9qf_maj_op_set_groups(op, groups_in, num_terms);
10
11// build every group, in index order
12QfMajoranaOperator *group_ops[2];
13qf_maj_op_split_out_groups(op, NULL, 0, group_ops);
14
15// build only group 1
16uint32_t group_indices[1] = {1};
17QfMajoranaOperator *group_op[1];
18qf_maj_op_split_out_groups(op, group_indices, 1, group_op);Parameter
- op – Ein Zeiger auf den Majorana-Operator, der herausgelöst werden
groupssoll. - group_indices – Ein Zeiger auf das Array der Gruppenindizes, für die Operatoren erstellt werden sollen, in der gewünschten Ausgabereihenfolge. Möglicherweise ist dies der Fall
NULL; in diesem Fall wird jede Gruppe in Indexreihenfolge aufgebaut (was der Übergabe jedes Index von0an :c:func:qf_maj_op_num_groupsentspricht- 1). - num_indices – Die Anzahl der Indizes im Array
group_indices. Wird ignoriert, wenn istgroup_indices``NULL. - group_ops_out – Ein Zeiger auf das Array von :c:struct:
QfMajoranaOperator, in das die Operatoren für jede angeforderte Gruppe geschrieben werden sollen. Muss auf angepasst werden, wennnum_indicesnicht istgroup_indices``NULL, oder auf :c:func:qf_maj_op_num_groups, wenn es istNULL.
qf_maj_op_add_term
void qf_maj_op_add_term(QfMajoranaOperator *op, uint64_t num_modes, const uint32_t *modes, const QkComplex64 *coeff)
Fügt einem bestehenden Operator einen Term hinzu.
Jedes der Zeigerargumente kann genau dann sein, NULL wenn seine entsprechende Länge null ist.
Diese Funktion setzt das Attribut groups des Operators auf zurück NULL.
Beispiel
1QfMajoranaOperator *one = qf_maj_op_one();
2
3QfMajoranaOperator *op = qf_maj_op_zero();
4uint32_t modes[0] = {};
5QkComplex64 coeff = {1.0, 0.0};
6
7qf_maj_op_add_term(op, 0, modes, &coeff);
8
9assert(qf_maj_op_equal(op, one));Parameter
- op – Ein Zeiger auf den zu ändernden Majorana-Operator.
- num_modes – Die Länge des „modes“-Arrays.
- Modi – Ein Zeiger auf ein Array von Modusindizes. Die Länge dieses Arrays sollte betragen
num_modes. - coeff – Ein Zeiger auf den komplexen Koeffizienten.
qf_maj_op_add
QfMajoranaOperator *qf_maj_op_add(const QfMajoranaOperator *left, const QfMajoranaOperator *right)
Addiert zwei Operanden.
Beispiel
1QfMajoranaOperator *one = qf_maj_op_one();
2QfMajoranaOperator *zero = qf_maj_op_zero();
3
4QfMajoranaOperator *result = qf_maj_op_add(one, zero);
5
6assert(qf_maj_op_equal(result, one));Parameter
- links – Ein Zeiger auf den Operator „links“.
- right – Ein Zeiger auf den Operator „right“.
Rückgabe
Ein Zeiger auf den resultierenden Operator.
qf_maj_op_scaled_add
QfMajoranaOperator *qf_maj_op_scaled_add(const QfMajoranaOperator *left, const QfMajoranaOperator *right, const QkComplex64 *factor)
Addiert zwei Operatoren und skaliert dabei die Koeffizienten des rechten Operators.
Dadurch wird die Skalierung in die Addition integriert, wodurch vermieden wird, eine vollständig skalierte Kopie zu erstellen, nur right um sie anzuhängen. Durch die Übergabe eines Faktors von wird -1 somit subtrahiert, weshalb keine separate Subtraktionsfunktion bereitgestellt wird.
Beispiel
1QfMajoranaOperator *one = qf_maj_op_one();
2QfMajoranaOperator *other = qf_maj_op_one();
3
4// Subtracting via a factor of -1 leaves the two terms cancelling each other out.
5QkComplex64 factor = {-1.0, 0.0};
6QfMajoranaOperator *result = qf_maj_op_scaled_add(one, other, &factor);
7
8QfMajoranaOperator *simplified = qf_maj_op_simplify(result, 1e-10);
9assert(qf_maj_op_len(simplified) == 0);Das bedeutet qf_maj_op_add(), dass die Terme von angehängt werden, ohne right sie mit denen von zu kombinieren left, sodass das Ergebnis keine Gruppenindizes enthält. Rufen Sie an, qf_maj_op_simplify() um die gleichen Konditionen später zu vereinbaren.
Parameter
- links – Ein Zeiger auf den Operator „links“.
- right – Ein Zeiger auf den Operator „right“.
- Faktor – Ein Zeiger auf den Faktor, mit dem die Koeffizienten des rechten Operanden skaliert werden sollen.
Rückgabe
Ein Zeiger auf den resultierenden Operator, left + factor * right.
qf_maj_op_add_inplace
void qf_maj_op_add_inplace(QfMajoranaOperator *left, const QfMajoranaOperator *right)
Fügt einen Operator in einen anderen ein, ohne die ursprünglichen Werte zu verändern.
Das In-Place-Äquivalent von qf_maj_op_add(), wodurch das Kopieren in left ein neu zugewiesenes Ergebnis vermieden wird.
Diese Funktion setzt das Attribut groups des Operators auf zurück NULL.
Beispiel
1QfMajoranaOperator *left = qf_maj_op_one();
2QfMajoranaOperator *right = qf_maj_op_one();
3
4qf_maj_op_add_inplace(left, right);
5
6assert(qf_maj_op_len(left) == 2);Parameter
- links – Ein Zeiger auf den Operator, in den die Addition eingefügt werden soll.
- right – Ein Zeiger auf den zu addierenden Operator.
qf_maj_op_scaled_add_inplace
void qf_maj_op_scaled_add_inplace(QfMajoranaOperator *left, const QfMajoranaOperator *right, const QkComplex64 *factor)
Fügt einen Operator an Ort und Stelle in einen anderen ein und skaliert dabei die Koeffizienten des rechten Operators.
Das In-Place-Äquivalent von qf_maj_op_scaled_add(), das berechnet, ohne left + factor * right ein Ergebnis zu speichern. Da wird ein Faktor von abgezogen -1 .
Diese Funktion setzt das Attribut groups des Operators auf zurück NULL.
Beispiel
1QfMajoranaOperator *left = qf_maj_op_one();
2QfMajoranaOperator *right = qf_maj_op_one();
3
4// Subtract, leaving two terms that cancel each other out.
5QkComplex64 factor = {-1.0, 0.0};
6qf_maj_op_scaled_add_inplace(left, right, &factor);
7
8QfMajoranaOperator *simplified = qf_maj_op_simplify(left, 1e-10);
9assert(qf_maj_op_len(simplified) == 0);Parameter
- links – Ein Zeiger auf den Operator, in den die Addition eingefügt werden soll.
- right – Ein Zeiger auf den zu addierenden Operator.
- Faktor – Ein Zeiger auf den Faktor, mit dem die Koeffizienten des rechten Operanden skaliert werden sollen.
qf_maj_op_mul_inplace
void qf_maj_op_mul_inplace(QfMajoranaOperator *op, const QkComplex64 *scalar)
Multipliziert einen Operator mit einem Skalar, ohne die Ergebnisse zu speichern.
Das In-Place-Äquivalent von qf_maj_op_mul(), wodurch das Kopieren des Operators in ein neu zugewiesenes Ergebnis entfällt.
Beispiel
1QfMajoranaOperator *op = qf_maj_op_one();
2QkComplex64 scalar = {2.0, 0.0};
3
4qf_maj_op_mul_inplace(op, &scalar);Im Gegensatz zu den beiden oben genannten In-Place-Ergänzungen bleibt dabei das Attribut groups erhalten: Durch die Skalierung der Koeffizienten bleiben die Anzahl der Terme und somit die Invariante „ein Index pro Term“ unverändert.
Parameter
- op – Ein Zeiger auf den Operator, der skaliert werden soll.
- Skalar – Ein Zeiger auf den Skalar.
qf_maj_op_mul
QfMajoranaOperator *qf_maj_op_mul(const QfMajoranaOperator *op, const QkComplex64 *scalar)
Multipliziert einen Operator mit einem Skalar.
Beispiel
1QfMajoranaOperator *one = qf_maj_op_one();
2QkComplex64 coeff = {2.0, 0.0};
3QfMajoranaOperator *result = qf_maj_op_mul(one, &coeff);
4
5QfMajoranaOperator *expected = qf_maj_op_zero();
6uint32_t modes[0] = {};
7qf_maj_op_add_term(expected, 0, modes, &coeff);
8
9assert(qf_maj_op_equal(result, expected));Parameter
- op – Ein Zeiger auf den Operator.
- Skalar – Ein Zeiger auf den Skalar.
Rückgabe
Ein Zeiger auf den resultierenden Operator.
qf_maj_op_compose
QfMajoranaOperator *qf_maj_op_compose(const QfMajoranaOperator *left, const QfMajoranaOperator *right)
Kombiniert zwei Operatoren miteinander.
Beispiel
1QfMajoranaOperator *one = qf_maj_op_one();
2QfMajoranaOperator *zero = qf_maj_op_zero();
3
4QfMajoranaOperator *result = qf_maj_op_compose(one, zero);
5
6assert(qf_maj_op_equal(result, zero));Die Verknüpfung zweier Operatoren verfolgt keine Gruppen, selbst wenn beide Operanden dies tun.
Parameter
- links – Ein Zeiger auf den Operator „links“.
- right – Ein Zeiger auf den Operator „right“.
Rückgabe
Ein Zeiger auf left.compose(right), der dem Operator result = right @ left im Sinne der Matrixmultiplikation entspricht @. Mit anderen Worten: right wird zuerst angewendet. Um das Ergebnis zu erhalten left @ right, tausche die Argumente aus.
qf_maj_op_adjoint
QfMajoranaOperator *qf_maj_op_adjoint(const QfMajoranaOperator *op)
Gibt das hermitische Konjugat (oder Adjungierte) eines Operators zurück.
Dies wirkt sich wie folgt auf die Terme und Koeffizienten aus:
- Die Reihenfolge der Aktionen in jedem Term kehrt sich um
- Die Koeffizienten sind komplex konjugiert
Beispiel
1QfMajoranaOperator *op = qf_maj_op_zero();
2uint32_t modes[0] = {};
3QkComplex64 coeff = {0.0, 1.0};
4qf_maj_op_add_term(op, 0, modes, &coeff);
5
6QfMajoranaOperator *adjoint = qf_maj_op_adjoint(op);
7
8QfMajoranaOperator *expected = qf_maj_op_zero();
9QkComplex64 coeff_adj = {0.0, -1.0};
10qf_maj_op_add_term(expected, 0, modes, &coeff_adj);
11
12assert(qf_maj_op_equal(adjoint, expected));Parameter
- op – Ein Zeiger auf den Operator.
Rückgabe
Ein Zeiger auf den erstellten Operator.
qf_maj_op_ichop
void qf_maj_op_ichop(QfMajoranaOperator *op, double atol)
Entfernt Terme, deren Koeffizientenwert unterhalb des angegebenen Schwellenwerts liegt.
Diese Funktion kürzt Koeffizienten gnadenlos! Falls der Operand, auf den die Funktion angewendet wird, möglicherweise separate Koeffizienten für doppelte Terme enthält, sollten Sie stattdessen qf_maj_op_simplify() den Aufruf in Betracht ziehen!
Beispiel
1QfMajoranaOperator *op = qf_maj_op_zero();
2uint32_t modes[0] = {};
3QkComplex64 coeff = {1e-8};
4qf_maj_op_add_term(op, 0, modes, &coeff);
5
6qf_maj_op_ichop(op, 1e-6);
7
8QfMajoranaOperator *expected = qf_maj_op_zero();
9
10assert(qf_maj_op_equal(op, expected));Parameter
- op – Ein Zeiger auf den Operator.
- atol – Die absolute Toleranz für die Koeffizientenabschneidung.
qf_maj_op_simplify
QfMajoranaOperator *qf_maj_op_simplify(const QfMajoranaOperator *op, double atol)
Gibt einen gleichwertigen, aber vereinfachten Operator zurück.
Bei der Vereinfachung werden zunächst alle Koeffizienten addiert, die zu gleichen Termen gehören, und anschließend nur diejenigen beibehalten, deren Gesamtkoeffizient die festgelegte Toleranz überschreitet (genau wie qf_maj_op_ichop()).
Wenn ein Operator arithmetisch so verändert oder konstruiert wurde, dass keine Eindeutigkeit der Terme mehr gewährleistet ist, sollte diese Methode aufgerufen werden, bevor eine Methode angewendet wird, die numerisch kleine Koeffizienten herausfiltert, um Informationsverlust zu vermeiden. Das folgende Beispiel veranschaulicht, wie Terme abgeschnitten werden qf_maj_op_ichop() können, deren Koeffizienten insgesamt eine Größe erreichen, die eigentlich nicht abgeschnitten werden sollte:
1uint64_t num_terms = 100000;
2uint64_t num_modes = 0;
3uint32_t modes[0] = {};
4QkComplex64 coeffs[100000];
5uint32_t boundaries[100001];
6for (int i = 0; i < 100000; i++) {
7 coeffs[i].re = 1e-5;
8 coeffs[i].im = 0.0;
9 boundaries[i] = 0;
10}
11boundaries[100000] = 0;
12QfMajoranaOperator *op =
13 qf_maj_op_new(num_terms, num_modes, coeffs, modes, boundaries);
14
15QfMajoranaOperator *canon = qf_maj_op_simplify(op, 1e-4);
16
17QfMajoranaOperator *one = qf_maj_op_one();
18bool canon_is_equal = qf_maj_op_equiv(canon, one, 1e-6);
19
20qf_maj_op_ichop(op, 1e-4);
21
22QfMajoranaOperator *zero = qf_maj_op_zero();
23bool ichop_is_equal = qf_maj_op_equiv(op, zero, 1e-6);Parameter
- op – Ein Zeiger auf den zu vereinfachenden Majorana-Operator.
- atol – Die absolute Toleranz für die Koeffizientenabschneidung.
Rückgabe
Ein gleichwertiger, aber vereinfachter Operator.
qf_maj_op_normal_ordered
QfMajoranaOperator *qf_maj_op_normal_ordered(const QfMajoranaOperator *op, bool ascending, bool reduce)
Gibt einen Äquivalenzoperator mit normal geordneten Termen zurück.
Die normale Reihenfolge eines Operatorausdrucks ist so definiert, dass alle Aktionen lexikografisch geordnet sind. Ob sie ansteigen oder abfallen, hängt vom Wert des Parameters ascending ab.
Beispiel
1QfMajoranaOperator *op = qf_maj_op_zero();
2uint32_t modes[4] = {0, 2, 1, 3};
3QkComplex64 coeff = {1.0, 0.0};
4qf_maj_op_add_term(op, 4, modes, &coeff);
5
6QfMajoranaOperator *normal_ordered = qf_maj_op_normal_ordered(op, false, true);
7
8QkComplex64 coeff_minus = {-1.0, 0.0};
9QfMajoranaOperator *expected = qf_maj_op_zero();
10uint32_t modes_exp[4] = {3, 2, 1, 0};
11qf_maj_op_add_term(expected, 4, modes_exp, &coeff_minus);
12
13assert(qf_maj_op_equal(normal_ordered, expected));Parameter
- op – Ein Zeiger auf den Operator.
- aufsteigend – Ob Indizes steigen oder fallen sollen.
- reduzieren – Gibt an, ob jeder Term auf seine Minimalform reduziert werden soll, indem Terme entfernt werden, die mit der Identität quadriert werden.
Rückgabe
Ein Zeiger auf den erstellten Operator.
qf_maj_op_is_hermitian
bool qf_maj_op_is_hermitian(const QfMajoranaOperator *op, double atol)
Prüft, ob ein Operator hermitesch ist.
Beispiel
1QfMajoranaOperator *op = qf_maj_op_zero();
2uint32_t modes1[2] = {0, 1};
3QkComplex64 coeff1 = {0.0, 1.00001};
4qf_maj_op_add_term(op, 2, modes1, &coeff1);
5uint32_t modes2[2] = {0, 1};
6QkComplex64 coeff2 = {0.0, -1};
7qf_maj_op_add_term(op, 2, modes2, &coeff2);
8
9assert(qf_maj_op_is_hermitian(op, 1e-4));
10assert(!qf_maj_op_is_hermitian(op, 1e-8));Diese Überprüfung erfolgt qf_maj_op_equiv() anhand der Differenz qf_maj_op_normal_ordered() zwischen op und dessen sowie qf_maj_op_adjoint() qf_maj_op_zero().
Parameter
- op – Ein Zeiger auf den zu prüfenden Majorana-Operator.
- Atol – Die absolute Toleranz, bis zu der Koeffizienten als gleich angesehen werden.
Rückgabe
Ob der angegebene Operator hermitisch ist.
qf_maj_op_max_rank
uint32_t qf_maj_op_max_rank(const QfMajoranaOperator *op)
Prüft den maximalen Rang eines Operators.
Beispiel
1QfMajoranaOperator *op = qf_maj_op_zero();
2uint32_t modes[4] = {0, 1, 2, 3};
3QkComplex64 coeff = {1.0, 0.0};
4qf_maj_op_add_term(op, 4, modes, &coeff);
5
6assert(qf_maj_op_max_rank(op), 4);Die Länge des längsten Terms kann von der Form des Operators abhängen, was bedeutet, dass (beispielsweise) eine Operatorvereinfachung oder eine Normalordnung zu einem anderen maximalen Rang führen kann.
Parameter
- op – Ein Zeiger auf den zu prüfenden Majorana-Operator.
Rückgabe
Der maximale Rang des Operators.
qf_maj_op_is_even
bool qf_maj_op_is_even(const QfMajoranaOperator *op)
Prüft, ob ein Operator gerade ist.
Beispiel
1QfMajoranaOperator *op = qf_maj_op_zero();
2QkComplex64 coeff = {1.0, 0.0};
3uint32_t modes1[2] = {0, 1};
4qf_maj_op_add_term(op, 2, modes1, &coeff);
5
6assert(qf_maj_op_is_even(op));
7
8uint32_t modes2[1] = {2};
9qf_maj_op_add_term(op, 2, modes2, &coeff);
10
11assert(!qf_maj_op_is_even(op));Ein Operator gilt als gerade, auch wenn alle seine Terme eine gerade Anzahl von Aktionen enthalten.
Parameter
- op – Ein Zeiger auf den zu prüfenden Majorana-Operator.
Rückgabe
Ob der angegebene Operator gerade ist.
qf_maj_op_equal
bool qf_maj_op_equal(const QfMajoranaOperator *left, const QfMajoranaOperator *right)
Vergleiche zwei Operanden auf Gleichheit.
Beispiel
1QfMajoranaOperator *one = qf_maj_op_one();
2QfMajoranaOperator *zero = qf_maj_op_zero();
3
4assert(qf_maj_op_equal(one, one));
5assert(!qf_maj_op_equal(one, zero));Parameter
- links – Ein Zeiger auf den Operator „links“.
- right – Ein Zeiger auf den Operator „right“.
Rückgabe
Ob die beiden Operatoren gleich sind.
qf_maj_op_equiv
bool qf_maj_op_equiv(const QfMajoranaOperator *left, const QfMajoranaOperator *right, double atol)
Vergleiche zwei Operatoren auf Gleichwertigkeit.
Äquivalenz bedeutet in diesem Zusammenhang eine annähernde Gleichheit bis auf die angegebene absolute Toleranz. Genauer gesagt gibt diese Methode den Wert zurück True, wenn alle Absolutwerte der Koeffizienten in der Differenz unter dem festgelegten Schwellenwert liegen other - self``atol .
Beispiel
1QfMajoranaOperator *zero = qf_maj_op_zero();
2
3QfMajoranaOperator *op = qf_maj_op_zero();
4uint32_t modes[0] = {};
5QkComplex64 coeff = {1e-7, 0.0};
6qf_maj_op_add_term(op, 0, modes, &coeff);
7
8assert(qf_maj_op_equiv(op, zero, 1e-6));
9assert(!qf_maj_op_equiv(op, zero, 1e-8));Parameter
- links – Ein Zeiger auf den Operator „links“.
- right – Ein Zeiger auf den Operator „right“.
- atol – Die absolute Toleranz für die Koeffizientenäquivalenz.
Rückgabe
Ob die beiden Operatoren gleichwertig sind.
qf_maj_op_len
size_t qf_maj_op_len(const QfMajoranaOperator *op)
Gibt die Länge (bzw. die Anzahl der Terme) des angegebenen Operators zurück.
Beispiel
1QfMajoranaOperator *op = qf_maj_op_zero();
2uint32_t modes[4] = {0, 1, 2, 3};
3QkComplex64 coeff = {1.0, 0.0};
4qf_maj_op_add_term(op, 4, modes, &coeff);
5
6assert(qf_maj_op_len(op) == 1);Parameter
- op – Ein Zeiger auf den Majorana-Operator.
Rückgabe
Die Länge (bzw. die Anzahl der Terme) des Operators.
qf_maj_op_relabel_modes
QfExitCode qf_maj_op_relabel_modes(QfMajoranaOperator *op, uint64_t num_modes, const uint32_t *permutation)
Benennt die Modi des angegebenen Operators um.
Beispiel
1QfMajoranaOperator *op = qf_maj_op_zero();
2uint32_t modes[4] = {0, 1, 2, 3};
3QkComplex64 coeff = {1.0, 0.0};
4qf_maj_op_add_term(op, 4, modes, &coeff);
5
6uint32_t permutation[4] = {3, 2, 1, 0};
7
8QfExitCode exit = qf_maj_op_relabel_modes(op, 4, permutation);
9
10assert(exit == QfExitCode_Success);Parameter
- op – Ein Zeiger auf den Majorana-Operator.
- num_modes – Die Anzahl der Modusindizes in der angegebenen Permutationsliste.
- Permutation – Die Liste der Indexpermutationen.
Rückgabe
Ein Exit-Code.
QfExitCode_Successim ErfolgsfallQfExitCode_DuplicateIndexErrorfalls in der Permutation doppelte Indizes gefunden wurdenQfExitCode_IndexErrorbei allen anderen Indexfehlern, wie z. B. ungültigen Indizes.