Skip to main content
IBM Quantum Platform

QfMajoranaOperator

QfMajoranaOperator

struct QfMajoranaOperator

Ein Majorana-Fermion-Operator.

Anmerkung

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):

γ=a†+a  and  γ′=i(a†−a)\gamma = a^\dagger + a ~~\text{and}~~ \gamma' = i(a^\dagger - a)

Die entscheidende Eigenschaft eines Majorana-Fermions, nämlich dass es sein eigenes Antiteilchen ist, wird sofort deutlich:

γi=γi†  and  γi2=(γi†)2=1\gamma_i = \gamma_i^\dagger ~~\text{and}~~ \gamma_i^2 = (\gamma_i^\dagger)^2 = 1

Daraus ergeben sich die folgenden Antikommutationsrelationen für 2n2n Majorana-Fermionen:

{γi,γj}=2δij\left\{\gamma_i,\gamma_j\right\} = 2\delta_{ij}

Damit lautet die Definition des gesamten Operators wie folgt:

MajoranaOperator=∑ici⨂jγj^ ,\text{\texttt{MajoranaOperator}} = \sum_i c_i \bigotimes_j \hat{\gamma_j} \, ,

wobei cic_i der (komplexe) Koeffizient ist, der die Linearkombination der Produkte von γj\gamma_j bildet. Der Index jj 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 “
coeffsEin Vektor mit komplexen Koeffizienten, bestehend aus zwei 64-Bit-Gleitkommazahlen.
modesEin Vektor aus 32-Bit-Ganzzahlen, in dem die Indizes der bearbeiteten Majorana-Modi gespeichert sind.
boundariesEin Vektor aus ganzen Zahlen, der die Grenzen in und actions angibt indices.

Die ganzen Zahlen in indizieren modes die Majorana-Moden: jj. Bei Verwendung der Hilfsfunktion gamma()werden gerade (ungerade) Indizes für γ\gamma ( γ′\gamma' ) verwendet.

Anmerkung

Ü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.
Anmerkung

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.

Siehe auch

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);
Anmerkung

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.

Siehe auch

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);
Anmerkung

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.

Siehe auch

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);
Anmerkung

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);
Anmerkung

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.

Anmerkung

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_support Elementen 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);
Anmerkung

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 groups geschrieben werden soll.
  • groups_in – Ein Zeiger auf das groups Integer-Array, in das der Operator schreiben soll.
  • groups_len – Die Anzahl der Elemente im Array groups_in .

Rückgabe

Ein Exit-Code.

  • QfExitCode_Success im Erfolgsfall
  • QfExitCode_ValueError wenn von der Anzahl der Terme im Operator abweicht groups_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 groups gelö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 groups soll.
  • 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 von 0 an :c:func:qf_maj_op_num_groups entspricht - 1).
  • num_indices – Die Anzahl der Indizes im Array group_indices . Wird ignoriert, wenn ist group_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, wenn num_indices nicht ist group_indices``NULL , oder auf :c:func:qf_maj_op_num_groups , wenn es ist NULL.

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.

Vorsicht

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);
Anmerkung

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.

Vorsicht

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 .

Vorsicht

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);
Anmerkung

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));
Anmerkung

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.

Vorsicht

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));
Anmerkung

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);
Anmerkung

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));
Anmerkung

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_Success im Erfolgsfall
  • QfExitCode_DuplicateIndexError falls in der Permutation doppelte Indizes gefunden wurden
  • QfExitCode_IndexError bei allen anderen Indexfehlern, wie z. B. ungültigen Indizes.
War diese Seite hilfreich?
Melden Sie auf GitHub einen Fehler, einen Tippfehler oder fordern Sie Inhalte an.