SparseObservable
class qiskit.quantum_info.SparseObservable(data, /, num_qubits=None)
Basen: object
Ein Observable über Pauli-Basen, das seine Daten in einem Qubit-sparsen Format speichert.
Mathematik
Diese Beobachtungsgröße ist eine Summe über die Pauli-Operatoren und Pauli-Eigenzustands-Projektoren, wobei jeder Term mit einer komplexen Zahl gewichtet ist. Das heißt, die vollständige Beobachtungsgröße ist
für komplexe Zahlen und Ein-Qubit-Operatoren, die auf ein Qubit aus einem beschränkten Alphabet wirken. Die Summe über ist die Summe der einzelnen Terme, und das Tensorprodukt ergibt die Operatorenketten.
Das Alphabet der erlaubten Ein-Qubit-Operatoren, aus dem gezogen wird, besteht aus den Pauli-Operatoren und den Pauli-Eigenzustands-Projektionsoperatoren. Explizit sind dies:
Bezeichnung (Label) | Bediener | Numerischer Wert | BitTerm attribut |
|---|---|---|---|
"I" | (Identität) | Nicht gespeichert. | Nicht gespeichert. |
"X" | (Pauli X) | 0b0010 (2) | X |
"Y" | (Pauli Y) | 0b0011 (3) | Y |
"Z" | (Pauli Z) | 0b0001 (1) | Z |
"+" | (Projektor zum positiven Eigenzustand von X) | 0b1010 (10) | PLUS |
"-" | (Projektor zum negativen Eigenzustand von X) | 0b0110 (6) | MINUS |
"r" | (Projektor auf positiven Eigenzustand von Y) | 0b1011 (11) | RIGHT |
"l" | (Projektor auf den negativen Eigenzustand von Y) | 0b0111 (7) | LEFT |
"0" | (Projektor zum positiven Eigenzustand von Z) | 0b1001 (9) | ZERO |
"1" | (Projektor zum negativen Eigenzustand von Z) | 0b0101 (5) | ONE |
Das zulässige Alphabet bildet eine überkomplette Basis des Operatorraums. Das bedeutet, dass es keine eindeutige Summierung gibt, um eine bestimmte Beobachtung darzustellen. Im Vergleich dazu, SparsePauliOp verwendet eine präzise Basis des Operatorraums, so dass es (nach der Kombination von Termen derselben Pauli-Kette, dem Entfernen von Nullen und dem Sortieren der Terme in eine kanonische Reihenfolge ) nur eine Darstellung eines beliebigen Operators gibt.
SparseObservable verwendet seine besondere überkomplette Basis mit dem Ziel, die "Effizienz der Messung" mit der "Effizienz der Darstellung" gleichzusetzen. Zum Beispiel kann die beobachtbare Größe auf der Hardware mit einfachen Messungen effizient gemessen werden, aber sie kann nur dargestellt werden durch SparsePauliOp als dargestellt werden, was gespeicherte Terme erfordert. SparseObservable benötigt nur einen einzigen Begriff, um dies zu speichern.
Der Nachteil dabei ist, dass es unpraktisch ist, eine beliebige Matrix oder SparsePauliOp zu nehmen und die beste SparseObservable darstellung zu finden. Normalerweise werden Sie eine SparseObservable direkt zu konstruieren, anstatt zu versuchen, es in ein solches zu zerlegen.
Darstellung
Die interne Darstellung von a SparseObservable speichert nur die nicht-identischen Qubit-Operatoren. Dies macht es wesentlich effizienter, Observablen wie darzustellen; SparseObservable benötigt eine Speichermenge, die linear zur Gesamtzahl der Qubits ist, während SparsePauliOp quadratisch skaliert.
Die Terme werden komprimiert gespeichert, ähnlich wie beim komprimierten Sparse-Zeilen-Format von Sparse-Matrizen. In dieser Analogie sind die Terme der Summe die "Zeilen" und die Qubit-Terme die "Spalten", wobei ein fehlender Eintrag die Identität und nicht eine Null darstellt. Genauer gesagt, besteht die Darstellung aus vier zusammenhängenden Feldern:
Attribut | Länge | Beschreibung |
|---|---|---|
coeffs | Der komplexe skalare Multiplikator für jeden Term. | |
bit_terms | Jeder der nicht-identischen Ein-Qubit-Terme für alle Operatoren, in dieser Reihenfolge. Diese entsprechen der Nicht-Identität in der Summenbeschreibung, bei der die Einträge in der Reihenfolge der aufsteigenden zuerst gespeichert werden und in der Reihenfolge der aufsteigenden innerhalb jedes Terms. | |
indices | Das entsprechende Qubit ( ) für jeden der Operatoren in bit_terms. SparseObservable erfordert, dass diese Liste begrifflich sortiert ist, und Algorithmen können sich darauf verlassen, dass diese Invariante eingehalten wird. | |
boundaries | Die Indizes, die die bit_terms und indices in vollständige Terme aufteilen. Für die Termzahl ist ihr komplexer Koeffizient coeffs[i], und ihre nicht-identischen Ein-Qubit-Operatoren und ihre entsprechenden Qubits sind die Scheibe boundaries[i] : boundaries[i+1] in bit_terms und indices ein. boundaries hat immer eine explizite 0 als erstes Element. |
Der Längenparameter ist die Anzahl der Terme in der Summe, und der Parameter ist die Gesamtzahl der nicht-identischen Einzel-Qubit-Terme.
Zur Veranschaulichung einige Beispiele:
- im Falle eines Null-Operators,
boundariesdie Länge 1 (eine einzige 0) und alle anderen Vektoren sind leer. - im Falle eines vollständig vereinfachten Identitätsoperators,
boundariesist[0, 0],coeffshat einen einzigen Eintrag, undbit_termsundindicesleer sind. - für den Operator ,
boundariesist[0, 2, 4],coeffsist[1.0, -1.0],bit_termsist[BitTerm.Z, BitTerm.Z, BitTerm.Y, BitTerm.X]undindicesist[0, 2, 1, 3]. Der Operator kann auf mehr als vier Qubits wirken, je nachnum_qubitsparameter. Diebit_termssind Integer-Werte, auf deren magische Zahlen über dieBitTermattribut-Klasse zugegriffen werden kann. Beachten Sie, dass die Einzelbit-Terme und -Indizes in begrifflich sortierter Reihenfolge angeordnet sind. Dies ist eine Voraussetzung für die Teilnahme am Kurs.
Diese Fälle sind nichts Besonderes, sie entsprechen voll und ganz den Regeln und sollten nicht besonders behandelt werden müssen.
Das skalare Element des bit_terms arrays wird als numerisches Byte gespeichert. Die numerischen Werte beziehen sich auf die symplektische Pauli-Darstellung, die SparsePauliOp verwendet, und sind mit benanntem Zugriff durch eine Aufzählung zugänglich:
BitTerm
class BitTerm
Eine IntEnum das einen benannten Zugriff auf die numerischen Werte bietet, die zur Darstellung der einzelnen Begriffe des Ein-Qubit-Alphabets verwendet werden, die in Alphabet of single-qubit terms used in SparseObservable aufgezählt sind.
Diese Klasse ist angehängt an SparseObservable. Zugriff als SparseObservable.BitTerm. Wenn dies zu viel Tipparbeit ist und Sie nur mit :class:¬SparseObservable` Objekten arbeiten und der Name BitTerm nicht mehrdeutig ist, können Sie ihn wie folgt kürzen:
>>> ops = SparseObservable.BitTerm
>>> assert ops.X is SparseObservable.BitTerm.XSie können auf alle Werte der Aufzählung entweder über ihren vollständigen Namen in Großbuchstaben oder über ihre Bezeichnung mit einem Buchstaben zugreifen. Die aus einem Buchstaben bestehenden Bezeichnungen sind in der Regel keine gültigen Python Bezeichner, so dass Sie die Indizierungsnotation verwenden müssen, um auf sie zuzugreifen:
>>> assert SparseObservable.BitTerm.ZERO is SparseObservable.BitTerm["0"]Die numerische Struktur dieser Werte besteht darin, dass es sich um Vier-Bit-Werte handelt, von denen die unteren beiden Bits die (phasenlose) symplektische Darstellung des Pauli-Operators in Bezug auf das Objekt darstellen, wobei das untere Bit einen Beitrag von und das zweitniedrigste einen Beitrag von bezeichnet, während die oberen beiden Bits 00 für einen Pauli-Operator, 01 für den Projektor des negativen Eigenzustands und 10 für den Projektor des positiven Eigenzustands sind.
Werte
X
Standardwert: 2
Der Pauli Operator. Verwendet die einbuchstabige Bezeichnung "X".
PLUS
Standardwert: 10
Der Projektor für den positiven Eigenzustand des Operators: . Verwendet das Ein-Buchstaben-Label "+".
MINUS
Standardwert: 6
Der Projektor für den negativen Eigenzustand des Operators: . Verwendet das Ein-Buchstaben-Label "-".
Y
Standardwert: 3
Der Pauli Operator. Verwendet die einbuchstabige Bezeichnung "Y".
RECHTS
Standardwert: 11
Der Projektor für den positiven Eigenzustand des Operators: . Verwendet das Ein-Buchstaben-Label "r".
LINKS
Standardwert: 7
Der Projektor für den negativen Eigenzustand des Operators: . Verwendet das Ein-Buchstaben-Label "l".
Z
Standardwert: 1
Der Pauli Operator. Verwendet die einbuchstabige Bezeichnung "Z".
ZERO
Standardwert: 9
Der Projektor für den positiven Eigenzustand des Operators: . Verwendet das Ein-Buchstaben-Label "0".
ONE
Standardwert: 5
Der Projektor für den negativen Eigenzustand des Operators: . Verwendet das Ein-Buchstaben-Label "1".
Attribute
label
Die einstellige Zeichenfolge, die zur Darstellung dieses Begriffs im SparseObservable alphabet.
Jedes der array-ähnlichen Attribute verhält sich wie eine Python Sequenz. Sie können diese indizieren und mit der Standard list-wie Semantik. Das Slicen eines Attributs liefert ein Numpy ndarray zurück, das eine Kopie der relevanten Daten mit der natürlichen dtype des Feldes enthält; so können Sie leicht mathematische Operationen mit den Ergebnissen durchführen, wie etwa bitweise Operationen auf bit_terms. Sie können jedem der Attribute Indizes oder Slices zuweisen, müssen dabei aber die Regeln der Datenkohärenz einhalten. Zum Beispiel:
>>> obs = SparseObservable.from_list([("XZY", 1.5j), ("+1r", -0.5)])
>>> assert isinstance(obs.coeffs[:], np.ndarray)
>>> # Reduce all single-qubit terms to the relevant Pauli operator, if they are a projector.
>>> obs.bit_terms[:] = obs.bit_terms[:] & 0b00_11
>>> assert obs == SparseObservable.from_list([("XZY", 1.5j), ("XZY", -0.5)])Die obige Reduktion auf die Pauli-Basen kann auch erreicht werden mit pauli_bases().
Kanonische Ordnung
Für jede beliebige mathematische Beobachtungsgröße gibt es mehrere Möglichkeiten, sie darzustellen mit SparseObservable. So können beispielsweise dieselbe Menge von Einzelbit-Termen und ihre entsprechenden Indizes mehrfach in der Beobachtungsgröße erscheinen. Mathematisch gesehen ist dies gleichbedeutend mit einem einzigen Term, bei dem alle Koeffizienten addiert werden. In ähnlicher Weise können die Terme der Summe in a SparseObservable in beliebiger Reihenfolge stehen und dieselbe Beobachtungsgröße repräsentieren, da die Addition kommutativ ist (obwohl die Gleitkommadotation nicht assoziativ ist), SparseObservable keine Garantien für die Reihenfolge der Addition gibt).
Diese beiden Arten von Darstellungsdegeneriertheit können dazu führen, dass der == Operator behauptet, zwei Observablen seien nicht gleich, obwohl sie dasselbe Objekt darstellen. In solchen Fällen kann es sinnvoll sein, eine kanonische Form zu definieren, die einen strukturellen Vergleich der Observablen ermöglicht.
Sie können eine SparseObservable in kanonische Form bringen, indem Sie die simplify() methode. Die genaue Reihenfolge der Begriffe in der kanonischen Ordnung ist nicht festgelegt und kann sich zwischen verschiedenen Versionen von Qiskit ändern. Innerhalb der gleichen Version von Qiskit können Sie jedoch zwei Observablen strukturell vergleichen, indem Sie ihre vereinfachten Formen vergleichen.
Wenn Sie beim Vergleich die Gleitkommatoleranz berücksichtigen wollen, ist es am sichersten, ein Rezept wie das folgende zu verwenden:
def equivalent(left, right, tol):
return (left - right).simplify(tol) == SparseObservable.zero(left.num_qubits)Die kanonische Form, die durch simplify() erzeugte kanonische Form allein wird aufgrund des unvollständigen Basisalphabets nicht alle äquivalenten Observablen erfassen. Um einen eindeutigen Ausdruck zu erhalten, können Sie die Beobachtungsgröße zunächst nur mit Pauli-Termen darstellen, indem Sie as_paulis(), gefolgt von simplify(). Beachten Sie, dass die Projektor-Erweiterung (z. B. + in I und X) ist im großen Maßstab rechnerisch nicht machbar.
Indexierung
SparseObservable verhält sich wie eine Python Folge (die Standardform, nicht die erweiterte collections.abc.Sequence). Die Beobachtungsgröße kann durch ganze Zahlen indiziert und iterativ durchlaufen werden, um einzelne Terme zu erhalten.
Jeder Begriff erscheint als Instanz einer in sich geschlossenen Klasse. Die einzelnen Terme werden aus der Basisbeobachtungsgröße kopiert; Mutationen an ihnen haben keine Auswirkungen auf die Beobachtungsgröße.
Laufzeit
class Term(num_qubits, coeff, bit_terms, indices)
Basen: object
Ein einzelner Begriff aus einer vollständigen SparseObservable.
Diese werden in der Regel durch Indizierung oder Iteration durch eine SparseObservable.
bit_labels
bit_labels()
Gibt die Bitbezeichnungen des Begriffs als String zurück.
Die Bitbeschriftungen entsprechen der Reihenfolge von SparseTerm.indices, so dass das i-te Zeichen in der Zeichenkette auf den Qubit-Index unter term.indices[i] angewendet wird.
Rückgabe
Die Nicht-Identitäts-Bitbegriffe als verkettete Zeichenfolge.
bit_terms
Nur-Lese-Ansicht auf die einzelnen Ein-Qubit-Terme.
Die einzigen gültigen Werte im Array sind die mit einem entsprechenden BitTerm.
coeff
Der Koeffizient des Begriffs.
copy
copy()
Besorgen Sie sich eine Kopie dieses Begriffs.
indices
Nur-Lese-Ansicht auf die Indizes jedes nicht-identischen Ein-Qubit-Terms.
Die Indizes werden immer in sortierter Reihenfolge angezeigt.
num_qubits
Die Anzahl der Qubits, für die der Begriff definiert ist.
pauli_base
pauli_base()
Erhalten Sie ein Pauli objekt, das die für diesen Begriff benötigte Messbasis darstellt.
Der Projektor 0l+ liefert zum Beispiel ein Pauli ZYX. Die resultierende Pauli ist dicht in dem Sinne, dass explizite Identitäten gespeichert werden. Eine Identität in der Pauli-Ausgabe erfordert keine konkrete Messung.
Rückgabe: Pauli: der Pauli-Operator, der die notwendige
bemessungsgrundlage.
SparseObservable.pauli_bases()
Eine ähnliche Methode für ein ganzes Beobachtungsobjekt auf einmal.
to_observable
to_observable()
Konvertieren Sie diesen Begriff in eine vollständige SparseObservable.
Bauwesen
SparseObservable definiert mehrere Konstruktoren. Der Standardkonstruktor versucht, einen der spezifischeren Konstruktoren zu delegieren, der auf dem Typ der Eingabe basiert. Sie können jederzeit die spezifischen Konstruktoren verwenden, um mehr Kontrolle über die Konstruktion zu haben.
Methode | Zusammenfassung |
|---|---|
from_label() | Umwandlung einer dichten Zeichenkette in einen Einzelbegriff SparseObservable. |
from_list() | Summiert eine Liste von Tupeln dichter Zeichenfolgenbeschriftungen und der zugehörigen Koeffizienten zu einer Observable. |
from_sparse_list() | Summiert eine Liste von Tupeln mit spärlichen String-Labels, den Qubits, auf die sie sich beziehen, und ihren Koeffizienten zu einer Observable. |
from_pauli() | Erhöhen eines einzelnen Pauli in einen Einzelbegriff SparseObservable. |
from_sparse_pauli_op() | Erhöhen Sie eine SparsePauliOp in a SparseObservable. |
from_terms() | Summe expliziter Einzel Term instanzen. |
from_raw_parts() | Erstellen Sie die Beobachtungswerte aus den Rohdaten-Arrays. |
__new__
__new__(data, /, num_qubits=None)
Der Standardkonstruktor von SparseObservable.
Dies delegiert an eine der expliziten Konvertierungs-Konstruktor-Methoden, basierend auf dem Typ des data Arguments. Wenn num_qubits übergeben wird und der Konstruktor, der durch den Typ von data impliziert wird, keine Zahl akzeptiert, muss die angegebene Ganzzahl mit der Eingabe übereinstimmen.
Parameter
- data - Der Datentyp der Eingabe. Dies kann eine andere
SparseObservablesein, in diesem Fall wird die Eingabe kopiert, einPaulioderSparsePauliOpsein, wobei in diesem Fallfrom_pauli()oderfrom_sparse_pauli_op()entsprechend aufgerufen werden, oder es kann eine Liste in einem gültigen Format für entwederfrom_list()oder seinfrom_sparse_list(). - num_qubits (int|None) – Optionale Anzahl von Qubits für den Operator. Bei den meisten Dateneingaben kann dies abgeleitet werden und muss nicht angegeben werden. Sie ist nur für leere Listen oder das Sparse-List-Format erforderlich. Wenn sie unnötig angegeben wird, muss sie mit den eingegebenen Daten übereinstimmen.
Zusätzlich zu den umwandlungsbasierten Konstruktoren gibt es auch Hilfsmethoden, die spezielle Formen von Observablen konstruieren.
Methode | Zusammenfassung |
|---|---|
zero() | Der Null-Operator für eine bestimmte Anzahl von Qubits. |
identity() | Der Identitätsoperator für eine bestimmte Anzahl von Qubits. |
Konvertierungen
Ein vorhandenes SparseObservable kann in andere quantum_info Operatoren oder generische Formate konvertiert werden. Beachten Sie, dass andere Objekte dieselbe Beobachtungsgröße möglicherweise nicht so effizient darstellen können wie SparseObservable, was unter Umständen einen exponentiell höheren Speicherbedarf zur Folge haben kann.
Methode | Zusammenfassung |
|---|---|
as_paulis() | Erstellen Sie eine neue SparseObservable, die nur in Form von Pauli-Operatoren expandiert. |
to_sparse_list() | Drücken Sie die Beobachtungsgröße in einem spärlichen Listenformat mit den Elementen (bit_terms, indices, coeff) aus. |
Darüber hinaus, SparsePauliOp.from_sparse_observable() für die Konvertierung von dieser Klasse in SparsePauliOp. Beachten Sie, dass diese Methode unter denselben Problemen der exponentiellen Speichernutzung leidet wie as_paulis().
Mathematische Manipulation
SparseObservable unterstützt den Standardsatz an mathematischen Operatoren „ Python “ ebenso wie andere quantum_info Operatoren.
In den Grundrechenarten können Sie das:
- zwei Observablen hinzufügen mit
+ - zwei Observablen subtrahieren mit
- - multiplizieren oder dividieren mit einem
int,floatodercomplexmit*und/ - alle Koeffizienten in einer Beobachtungsgröße mit unärer Bedeutung zu negieren
-
Jeder der grundlegenden binären arithmetischen Operatoren hat eine entsprechende spezialisierte In-Place-Methode, die die linke Seite an Ort und Stelle verändert. Die Verwendung dieser Operatoren ist in der Regel effizienter als die der Infix-Operatoren, insbesondere bei der Erstellung einer Observable in einer Schleife.
Das Tensorprodukt wird berechnet mit tensor() (für die Standardreihenfolge der Pauli-Etiketten nebeneinander) oder expand() (für die umgekehrte Reihenfolge). Der Operator ^ ist überladen und entspricht tensor().
Bei Verwendung der binären Operatoren ^ (tensor()) und & (compose()) ist zu beachten, dass die Operator-Präferenzregeln von Python dazu führen können, dass die Auswertungsreihenfolge anders ist, als Sie es erwarten. Insbesondere bindet der Operator + fester als ^ oder &, ebenso wie * fester als + bindet.
Wenn Sie die Operatoren in gemischten Ausdrücken verwenden, ist es am sichersten, die Operanden von Tensorprodukten in Klammern zu setzen.
A SparseObservable hat eine wohldefinierte adjoint(). Die Begriffe der skalar-komplexen Konjugation (conjugate()) und der reellwertigen Transposition (transpose()) sind analog zur Matrixdarstellung anderer Pauli-Operatoren in Qiskit definiert.
Effizienzhinweise
Intern, SparseObservable ist an Ort und Stelle veränderbar, einschließlich der Verwendung von übermäßig zuweisenden wachsenden Vektoren zur Erweiterung der Anzahl von Begriffen. Das bedeutet, dass sich die Kosten für das Anhängen an eine beobachtbare Variable unter += linear mit der Gesamtzahl der hinzugefügten Terme amortisieren und nicht mit der quadratischen Komplexität, die die binäre + erfordern würde.
Additionen und Subtraktionen werden durch eine Term-Stacking-Operation realisiert; es gibt keine automatische "Vereinfachung" (Summierung gleichartiger Terme), da die meisten Additionen zum Aufbau einer Beobachtungsgröße nur eine geringe Anzahl von Duplikationen erzeugen und die Erkennung gleichartiger Terme zusätzliche Kosten verursacht. Wenn dies für Ihre Anwendungsfälle nicht ausreicht, können Sie entweder in regelmäßigen Abständen simplify()aufrufen oder mit uns über weitere APIs zur besseren Erstellung von Observables diskutieren.
Attribute
bit_terms
Eine flache Liste von Ein-Qubit-Termen. Dies ist natürlich eher eine Liste von Listen, wird aber aus Gründen der Speichernutzung und der Lokalisierung flach gespeichert, wobei die Unterlisten durch Grenzen gekennzeichnet sind.
boundaries
Indizes, die die bit_terms und indices in Unterlisten für jeden einzelnen Begriff in der Summe aufteilen. boundaries[0] : boundaries[1] ist der Bereich der Indizes in bit_terms und indices die dem ersten Term der Summe entsprechen. Alle nicht spezifizierten Qubit-Indizes sind implizit die Identität. Dies ist ein Element länger als coeffs, da boundaries[0] immer eine explizite Null ist (zur Vereinfachung des Algorithmus).
coeffs
Die Koeffizienten der einzelnen abstrakten Terme in der Summe. Diese hat so viele Elemente wie Terme in der Summe.
indices
Eine flache Liste der Qubit-Indizes, auf die die entsprechenden Einträge in bit_terms wirken. Diese Liste muss immer nach Begriffen sortiert sein, wobei ein Begriff eine Unterliste ist, die mit boundaries.
Wenn Sie von Python aus in dieses Attribut schreiben, müssen Sie sicherstellen, dass Sie nur Indizes eingeben, die nach Begriffen sortiert sind.
num_qubits
Die Anzahl der Qubits, auf die der Operator wirkt.
Dies lässt sich nicht aus anderen Formen oder Werten ableiten, da Identitäten nicht explizit gespeichert werden.
num_terms
Die Anzahl der Terme in der Summe, die dieser Operator verfolgt.
Methoden
adjoint
adjoint()
Berechnen Sie die Adjungierte dieser Beobachtungsgröße.
Dies ist im abstrakten mathematischen Sinne gut definiert. Alle Terme des Ein-Qubit-Alphabets sind selbstadjungiert, so dass das Ergebnis dieser Operation dieselbe Beobachtungsgröße ist, nur dass die Koeffizienten alle konjugiert komplex sind.
Beispiele
>>> left = SparseObservable.from_list([("XY+-", 1j)])
>>> right = SparseObservable.from_list([("XY+-", -1j)])
>>> assert left.adjoint() == rightapply_layout
apply_layout(layout, num_qubits=None)
Wenden Sie ein Transpiler-Layout auf diese SparseObservable.
In der Regel haben Sie Ihre Beobachtungsgröße in Form der virtuellen Qubits der Schaltkreise definiert, die Sie zur Vorbereitung von Zuständen verwenden werden. Nach der Transpilierung werden die virtuellen Qubits bestimmten physischen Qubits auf einem Gerät zugeordnet, das breiter als Ihr Schaltkreis sein kann. Diese Zuordnung kann sich auch im Laufe der Schaltung ändern. Mit dieser Methode wird die Eingangsbeobachtung auf virtuellen Qubits in eine Beobachtung umgewandelt, die unmittelbar nach dem vollständig umgesetzten physikalischen Schaltkreis angewendet werden kann.
Parameter
- layout (TranspileLayout |list[int] | None) – Das anzuwendende Layout. In den meisten Fällen sollte bei der Verwendung dieser Funktion das
QuantumCircuit.layoutFeld aus einem Schaltkreis übergeben werden, der für die Hardware transpiliert wurde. Außerdem können Sie eine Liste mit neuen Qubit-Indizes übergeben.NoneWird dies explizit angegeben, wird keine Neuzuordnung vorgenommen (Sie können jedoch weiterhin verwendennum_qubits, um die Beobachtbare zu erweitern). - num_qubits (int | None) – Die Anzahl der Qubits, auf die die Observable erweitert werden soll. Falls nicht angegeben, ist die Ausgabe so breit wie die angegebene
TranspileLayoutoder die gleiche Breite wie die Eingabe, wennlayoutin einer anderen Form angegeben wird.
Rückgabe
Eine neue SparseObservable mit dem angegebenen Layout.
as_paulis
as_paulis()
Drücken Sie die beobachtbare Größe nur in Pauli-Termen aus, indem Sie jeden Projektor als Summe von Pauli-Termen schreiben.
Beachten Sie, dass es keine Garantie für die Ordnung der resultierenden Pauli-Terme gibt. Verwenden Sie SparseObservable.simplify() zusätzlich, um eine kanonische Darstellung zu erhalten.
Beachten Sie, dass dies mindestens Terme benötigt, wenn Ein-Qubit-Projektoren vorhanden sind, was zu einer exponentiellen Anzahl von Termen führen kann.
Rückgabe
Die gleiche Beobachtung, aber nur in Pauli-Termen ausgedrückt.
Beispiele
Umschreiben einer beobachtbaren Größe in Form von Projektoren in Pauli-Operatoren:
>>> obs = SparseObservable("+")
>>> obs.as_paulis()
<SparseObservable with 2 terms on 1 qubit: (0.5+0j)() + (0.5+0j)(X_0)>
>>> direct = SparseObservable.from_list([("I", 0.5), ("Z", 0.5)])
>>> assert direct.simplify() == obs.as_paulis().simplify()Für kleine Operatoren kann dies mit simplify() als eine eindeutige kanonische Form verwendet werden:
>>> left = SparseObservable.from_list([("+", 0.5), ("-", 0.5)])
>>> right = SparseObservable.from_list([("r", 0.5), ("l", 0.5)])
>>> assert left.as_paulis().simplify() == right.as_paulis().simplify()SparsePauliOp.from_sparse_observable()
Ein Konstruktor von SparsePauliOp der eine Konvertierung von SparseObservable in die SparsePauliOp dichte Pauli-Darstellung umwandeln.
clear
clear()
Löscht alle Terme aus diesem Operator und macht ihn wieder gleich dem Null-Operator.
Dies hat keinen Einfluss auf die Kapazität der internen Zuweisungen, sodass bei nachfolgenden Additions- oder Subtraktionsoperationen möglicherweise keine Neuzuweisung erforderlich ist.
Beispiele
>>> obs = SparseObservable.from_list([("IX+-rl", 2.0), ("01YZII", -1j)])
>>> obs.clear()
>>> assert obs == SparseObservable.zero(obs.py_num_qubits())commutes
commutes(other, tol=1e-12)
Überprüfen Sie, ob die beobachtbare Größe mit einer anderen kommutiert.
Parameter
- other (SparseObservable) – Das andere Beobachtungselement, mit dem die Kommutierung überprüft werden kann.
- tol (float) – Wenn die Koeffizienten im Produkt von Selbst und Anderen unterhalb der Toleranz (in der Größe) liegen, werden die Terme ignoriert.
Rückgabe
True wenn die Bedingungen bis auf Toleranzen austauschbar sind, andernfalls False .
Erhöhungen
TypeError – Wenn nicht dazu gezwungen other werden SparseObservable konnte,.
compose
compose(other, /, qargs=None, *, front=False)
Fügen Sie eine weitere SparseObservable auf dieses.
In Bezug auf Operator-Algebren entspricht die Komposition der Links-Multiplikation: c = a.compose(b) entspricht $C = B A$. Mit anderen Worten: a.compose(b) liefert einen Operator, der " a ausführt und dann b auf das Ergebnis anwendet". Das Argument front=True macht dies zu einer Rechtsmultiplikation.
self und other müssen gleich groß sein, es sei denn, qargs ist angegeben. In diesem Fall kann other kleiner sein als self, sofern die Anzahl der Qubits in other und die Länge von qargs übereinstimmen. qargs kann niemals Duplikate oder Indizes von Qubits enthalten, die in self nicht existieren.
Beachten Sie, dass diese Funktion zu einer exponentiellen Explosion des Speicherverbrauchs der Observablen führen kann, da das Alphabet von SparseObservable bei der Komposition nicht geschlossen ist; die Komposition von zwei Einzelbit-Termen kann eine Summe sein, die die Gesamtzahl der Terme vervielfacht. Dieser Speicherverbrauch ist nicht zwangsläufig mit der resultierenden Beobachtungsgröße verbunden, aber die Suche nach einer effizienten Neuformulierung der Summe ist im Allgemeinen ebenso rechenintensiv. Es ist besser, das Fachwissen über die Beobachtungswerte zu nutzen, um die Anzahl der Begriffe zu minimieren, anstatt zu versuchen, sie nachträglich zu vereinfachen.
Parameter
-
andere - die für die Linksmultiplikation verwendete Beobachtungsgröße
self. -
qargs -
falls gegeben, die Qubits in
self, die mit den Qubits inotherverbunden werden sollen. Anders ausgedrückt: Wenn dies gegeben ist, ist es ähnlich wie eine effizientere Implementierung von:self.compose(other.apply_layout(qargs, self.num_qubits))da keine temporäre Observable erstellt wird, um die angewandte Layoutform von
otherzu speichern. -
front - wenn
True, dann rechtsmultiplizieren mitotherstatt linksmultiplizieren (StandardwertFalse). Dieqargssind weiterhin aufotherzu finden. Dies ist besonders nützlich, wennqargsgesetzt ist, oderotherein Objekt ist, das gezwungen werden muss, umSparseObservable.
conjugate
conjugate()
Berechnen Sie die komplexe Konjugation dieser Beobachtungsgröße.
Diese Operation wird gemäß den Standard-Matrixkonventionen von Qiskit definiert, d. h. die Matrixform wird als $Z$-Rechenbasis betrachtet. Die $X$- und $Z$-bezogenen Alphabetterme bleiben von der komplexen Konjugation unberührt, aber $Y$-bezogene Terme ändern ihre Alphabetterme. Ganz genau:
- konjugiert zu
- konjugiert zu
- konjugiert zu
Außerdem sind alle Koeffizienten konjugiert.
Beispiele
>>> obs = SparseObservable([("III", 1j), ("Yrl", 0.5)])
>>> assert obs.conjugate() == SparseObservable([("III", -1j), ("Ylr", -0.5)])copy
copy()
Holen Sie sich eine Kopie dieses Observablen.
Beispiele
>>> obs = SparseObservable.from_list([("IXZ+lr01", 2.5), ("ZXI-rl10", 0.5j)])
>>> assert obs == obs.copy()
>>> assert obs is not obs.copy()evolve
evolve(other, /, qargs=None)
Führe eine Entwicklung dieses Observables um einen Pauli-Term durch.
Eine Entwicklung des Observables durch eine Pauli- entspricht .
Im Gegensatz zu einer wörtlichen Umsetzung mittels zweier vollständiger Kompositionen führt diese Methode die Konjugation direkt auf der Ebene einzelner Qubits unter Verwendung einer festen Nachschlagetabelle durch. Dadurch wird die Materialisierung von Zwischenausdrücken vermieden SparseObservable , und die entwickelte Observable wird in einem einzigen Durchlauf über die Terme berechnet. self und other müssen dieselbe Anzahl an Qubits aufweisen, es sei denn, qargs ist vorgegeben; in diesem Fall other kann kleiner als sein self, vorausgesetzt, die Anzahl der Qubits in other und die Länge von qargs stimmen überein. qargs gibt an, welche Qubits von durch self entwickelt other werden.
Derzeit unterstützt diese Methode nur die Entwicklung durch einen Ein-Term -Operator, was bedeutet, dass ein durch dargestellter other PauliPauli-Operator sein muss.
Parameter
- anderes – der Pauli-Operator, der zur Konjugation
selfverwendet wird. - qargs – falls angegeben, die Qubits in, die durch
selfentwickelt werdenothersollen. Die Länge muss mit der Anzahl der Qubits inotherübereinstimmen.
Rückgabe
Eine neue Entwicklung SparseObservable mit angewandten Konjugationen.
Erhöhungen
- TypeError – wenn nicht vom
otherTyp istPauli. - ValueError – wenn
selfund eine unterschiedlicheotherAnzahl von Qubits haben (und nicht gegebenqargsist). - ValueError – wenn
qargsdie Länge nicht mitotherder Anzahl der Qubits übereinstimmt. - ValueError – wenn Duplikate oder Indizes außerhalb
qargsdes zulässigen Bereichs enthält. - ValueError – wenn mehr als einen
otherTerm enthält.
expand
expand(other, /)
Tensorprodukt umgekehrter Ordnung.
Dies ist äquivalent zu other.tensor(self), außer dass other zuerst in den Typ SparseObservable umgewandelt wird, wenn es nicht bereits einer ist (durch Aufruf des Standardkonstruktors).
Parameter
andere - die Beobachtungsgröße, die auf der linken Seite des Tensorprodukts steht.
Beispiele
Dies ist äquivalent zu tensor() wobei die Reihenfolge der Argumente vertauscht ist:
>>> left = SparseObservable.from_label("XYZ")
>>> right = SparseObservable.from_label("+-IIrl")
>>> assert left.tensor(right) == right.expand(left)from_label
static from_label(label, /)
Konstruieren Sie eine Beobachtungsgröße mit einem einzigen Begriff aus einem dichten String-Label.
Der resultierende Operator hat einen Koeffizienten von 1. Die Bezeichnung muss eine Folge des Alphabets 'IXYZ+-rl01' sein. Das Label wird analog zu einem Bitstring interpretiert. Mit anderen Worten: Der Buchstabe ganz rechts ist dem Qubit 0 zugeordnet usw. Dies ist dasselbe wie die Bezeichnungen für Pauli und SparsePauliOp.
Parameter
label (str) – das dichte Etikett.
Beispiele
>>> SparseObservable.from_label("IIII+ZI")
<SparseObservable with 1 term on 7 qubits: (1+0j)(+_2 Z_1)>
>>> label = "IYXZI"
>>> pauli = Pauli(label)
>>> assert SparseObservable.from_label(label) == SparseObservable.from_pauli(pauli)Eine Verallgemeinerung dieser Methode, die einen Summenoperator aus mehreren Etiketten und ihren entsprechenden Koeffizienten konstruiert.
from_list
static from_list(iter, /, *, num_qubits=None)
Konstruieren Sie eine Observable aus einer Liste von dichten Etiketten und Koeffizienten.
Dies ist analog zu SparsePauliOp.from_list()mit der Ausnahme, dass es das erweiterte Alphabet von SparseObservable. In dieser dichten Form müssen Sie alle Identitäten explizit in jedem Etikett angeben.
Die Bezeichnung muss eine Folge des Alphabets 'IXYZ+-rl01' sein. Das Label wird analog zu einem Bitstring interpretiert. Mit anderen Worten: Der Buchstabe ganz rechts ist dem Qubit 0 zugeordnet usw. Dies ist dasselbe wie die Bezeichnungen für Pauli und SparsePauliOp.
Parameter
- iter (list[tuple[str, complex]]) – Paare von Etiketten und ihre zugehörigen Koeffizienten, die zu addieren sind. Die Bezeichnungen werden auf die gleiche Weise interpretiert wie in
from_label(). - num_qubits (int | None) – Es ist nicht notwendig, dies anzugeben, wenn Sie sicher sind, dass
iterkeine leere Sequenz ist, da sie aus den Etikettenlängen abgeleitet werden kann. Wenniterleer sein kann, müssen Sie dieses Argument angeben, um zu verdeutlichen, für wie viele Qubits das Observable gilt. Wenn dies angegeben wird unditernicht leer ist, muss der Wert mit den Etikettenlängen übereinstimmen.
Beispiele
Konstruieren Sie ein Observable aus einer Liste von Etiketten gleicher Länge:
>>> SparseObservable.from_list([
... ("III++", 1.0),
... ("II--I", 1.0j),
... ("I++II", -0.5),
... ("--III", -0.25j),
... ])
<SparseObservable with 4 terms on 5 qubits:
(1+0j)(+_1 +_0) + (0+1j)(-_2 -_1) + (-0.5+0j)(+_3 +_2) + (-0-0.25j)(-_4 -_3)>Verwenden Sie num_qubits , um potenziell leere Eingaben zu disambiguieren:
>>> SparseObservable.from_list([], num_qubits=10)
<SparseObservable with 0 terms on 10 qubits: 0.0>Diese Methode ist äquivalent zu Aufrufen von from_sparse_list() mit dem expliziten Feld qubit-arguments, das auf abnehmende Ganzzahlen gesetzt ist:
>>> labels = ["XY+Z", "rl01", "-lXZ"]
>>> coeffs = [1.5j, 2.0, -0.5]
>>> from_list = SparseObservable.from_list(list(zip(labels, coeffs)))
>>> from_sparse_list = SparseObservable.from_sparse_list([
... (label, (3, 2, 1, 0), coeff)
... for label, coeff in zip(labels, coeffs)
... ])
>>> assert from_list == from_sparse_listEin ähnlicher Konstruktor, der jedoch nur ein einziges Label annimmt und dessen Koeffizient immer auf 1.0 gesetzt ist.
Konstruieren Sie die Beobachtungsgröße aus einer Liste von Bezeichnungen ohne explizite Identitäten, aber mit den explizit aufgeführten Qubits, auf die sich jeder Ein-Qubit-Term bezieht.
from_pauli
static from_pauli(pauli, /)
Konstruieren Sie eine SparseObservable aus einer einzelnen Pauli instanz.
Die Ausgangsgröße hat einen einzigen Term mit einem von der Phase abhängigen Einheitskoeffizienten.
Parameter
pauli (Pauli) – den einzelnen Pauli zu konvertieren.
Beispiele
>>> label = "IYXZI"
>>> pauli = Pauli(label)
>>> SparseObservable.from_pauli(pauli)
<SparseObservable with 1 term on 5 qubits: (1+0j)(Y_3 X_2 Z_1)>
>>> assert SparseObservable.from_label(label) == SparseObservable.from_pauli(pauli)from_raw_parts
static from_raw_parts(num_qubits, coeffs, bit_terms, indices, boundaries, check=True)
Konstruieren Sie eine SparseObservable aus rohen Numpy-Arrays, die der in der Dokumentation auf Klassenebene beschriebenen erforderlichen Datendarstellung entsprechen.
Die Daten aus jedem Array werden in neue, erweiterbare Rust-Space-Zuweisungen kopiert.
Parameter
-
num_qubits - Anzahl der Qubits in der Beobachtungsgröße.
-
coeffs - komplexe Koeffizienten der einzelnen Terme der Beobachtungsgröße. Dies sollte ein Numpy-Array mit dtype sein
complex128. -
bit_terms - abgeflachte Liste der Ein-Qubit-Terme, die alle vollständigen Terme enthält. Dies sollte ein Numpy-Array mit dtype sein
uint8(der kompatibel ist mitBitTerm). -
indizes - abgeflachte, termweise sortierte Liste der Qubits, denen jeder Ein-Qubit-Term entspricht. Dies sollte ein Numpy-Array mit dtype sein
uint32. -
grenzen - die Indizes, die
bit_termsundindicesin Begriffe unterteilen. Dies sollte ein Numpy-Array mit dtype seinuintp. -
prüfen -
falls
True(Standardeinstellung), überprüfen Sie, ob die Daten alle Kohärenzgarantien erfüllen. WennFalse, werden keine Kontrollen durchgeführt.AchtungWenn
check=False, müssen diebit_termsunbedingt alle gültige Werte vonSparseObservable.BitTerm. Ist dies nicht der Fall, kann es zu einem undefinierten Verhalten im Rust-Space kommen, das die Programmausführung vollständig ungültig macht.
Beispiele
Bilden Sie eine Summe von für jedes einzelne Qubit:
>>> num_qubits = 100
>>> terms = np.full((num_qubits,), SparseObservable.BitTerm.Z, dtype=np.uint8)
>>> indices = np.arange(num_qubits, dtype=np.uint32)
>>> coeffs = np.ones((num_qubits,), dtype=complex)
>>> boundaries = np.arange(num_qubits + 1, dtype=np.uintp)
>>> SparseObservable.from_raw_parts(num_qubits, coeffs, terms, indices, boundaries)
<SparseObservable with 100 terms on 100 qubits: (1+0j)(Z_0) + ... + (1+0j)(Z_99)>from_sparse_list
static from_sparse_list(iter, /, num_qubits)
Konstruieren Sie eine Observable aus einer Liste von Bezeichnungen, den Qubits, auf die jedes Element zutrifft, und dem Koeffizienten des gesamten Terms.
Dies ist analog zu SparsePauliOp.from_sparse_list()mit der Ausnahme, dass es das erweiterte Alphabet von SparseObservable.
Die Felder "labels" und "indices" der Tripel werden durch Zipping miteinander verbunden. Das bedeutet zum Beispiel, dass ein Aufruf von from_list() in die von dieser Methode verwendete Form umgewandelt werden kann, indem das Feld "indices" jedes Tripels auf (num_qubits-1, ..., 1, 0) gesetzt wird.
Parameter
- iter (list[tuple[str, Sequence[int], complex]]) – dreiergruppen von Bezeichnungen, die Qubits, auf die sich jeder Ein-Qubit-Term bezieht, und der Koeffizient des gesamten Terms.
- num_qubits (int) – die Anzahl der Qubits im Operator.
Beispiele
Konstruieren Sie einen einfachen Operator:
>>> SparseObservable.from_sparse_list(
... [("ZX", (1, 4), 1.0), ("YY", (0, 3), 2j)],
... num_qubits=5,
... )
<SparseObservable with 2 terms on 5 qubits: (1+0j)(X_4 Z_1) + (0+2j)(Y_3 Y_0)>Konstruieren Sie das Identitätsobservable (obwohl Sie eigentlich nur identity()):
>>> SparseObservable.from_sparse_list([("", (), 1.0)], num_qubits=100)
<SparseObservable with 1 term on 100 qubits: (1+0j)()>Diese Methode kann das Verhalten von from_list()replizieren, wenn das Feld "Qubit-Argumente" des Tripels auf abnehmende Ganzzahlen gesetzt wird:
>>> labels = ["XY+Z", "rl01", "-lXZ"]
>>> coeffs = [1.5j, 2.0, -0.5]
>>> from_list = SparseObservable.from_list(list(zip(labels, coeffs)))
>>> from_sparse_list = SparseObservable.from_sparse_list([
... (label, (3, 2, 1, 0), coeff)
... for label, coeff in zip(labels, coeffs)
... ])
>>> assert from_list == from_sparse_listDie Umkehrung dieser Methode.
from_sparse_pauli_op
static from_sparse_pauli_op(op, /)
Konstruieren Sie eine SparseObservable aus einer SparsePauliOp instanz.
Dies ist eine weitgehend direkte Übersetzung der SparsePauliOp; insbesondere gibt es keine fliegende Summierung gleicher Terme und auch keinen Versuch, Summen von Pauli-Termen in äquivalente Projektionsoperatoren umzuformulieren.
Parameter
op (SparsePauliOp) – den zu konvertierenden Operator.
Beispiele
>>> spo = SparsePauliOp.from_list([("III", 1.0), ("IIZ", 0.5), ("IZI", 0.5)])
>>> SparseObservable.from_sparse_pauli_op(spo)
<SparseObservable with 3 terms on 3 qubits: (1+0j)() + (0.5+0j)(Z_0) + (0.5+0j)(Z_1)>from_terms
static from_terms(obj, /, num_qubits=None)
Konstruieren Sie einen SparseObservable aus den einzelnen Begriffen.
Alle Begriffe müssen die gleiche Anzahl von Qubits haben. Falls angegeben, muss das Argument num_qubits mit den Begriffen übereinstimmen.
Bei der Erstellung der Beobachtungsdaten wird keine Vereinfachung vorgenommen.
Parameter
- obj (Iterable[Term]) – Iterable der einzelnen Begriffe, aus denen die Observable aufgebaut werden soll.
- num_qubits (int | None) – Die Anzahl der Qubits, auf die die Beobachtungsgröße wirken soll. Dies wird normalerweise aus der Eingabe abgeleitet, kann aber auch explizit angegeben werden, um den Fall einer leeren Iterable zu behandeln.
Rückgabe
Die entsprechende Beobachtungsgröße.
identity
static identity(num_qubits)
Ermittelt den Identitätsoperator über die angegebene Anzahl von Qubits.
Beispiele
Ermitteln Sie den Identitätsoperator für 100 Qubits:
>>> SparseObservable.identity(100)
<SparseObservable with 1 term on 100 qubits: (1+0j)()>pauli_bases
pauli_bases()
Erhalten Sie ein PauliList objekt, das die Messbasis darstellt, die für jeden Term (in dieser Reihenfolge) in dieser Observable benötigt wird.
Der Projektor 0l+ liefert zum Beispiel ein Pauli ZXY. Die resultierende Pauli ist dicht in dem Sinne, dass explizite Identitäten gespeichert werden. Eine Identität in der Pauli-Ausgabe erfordert keine konkrete Messung.
Dadurch wird für jeden Begriff in der Summe ein Eintrag in der Pauli-Liste zurückgegeben.
Rückgabe
die Liste der Pauli-Operatoren, die die notwendigen Messgrundlagen darstellen.
Rückgabetyp
simplify
simplify(tol=1e-08)
Summiert alle gleichartigen Terme in diesem Operator und entfernt sie, wenn der resultierende komplexe Koeffizient einen Absolutwert innerhalb der Toleranz von Null hat.
Als Nebeneffekt sortiert dies den Operator in kanonischer Reihenfolge.
Beachten Sie bei der Verwendung für Gleichheitsvergleiche, dass die Rundung bei Gleitkommazahlen und die Nichtassoziativität der Gleitkommaaddition dazu führen können, dass Koeffizienten von Summanden, die ungleich Null sind, als ungleich verglichen werden. Um zwei Observablen bis auf eine Toleranzgrenze zu vergleichen, ist es am sichersten, die kanonisierte Differenz der beiden Observablen mit Null zu vergleichen.
Parameter
tol (float) – nach der Summierung gleichartiger Terme werden alle Koeffizienten, deren absoluter Wert kleiner als die angegebene absolute Toleranz ist, bei der Ausgabe unterdrückt.
Beispiele
Verwendung von simplify() um zwei Operatoren zu vergleichen, die dieselbe Beobachtungsgröße darstellen, aber aufgrund der strukturellen Tests standardmäßig ungleiche Ergebnisse liefern würden:
>>> base = SparseObservable.from_sparse_list([
... ("XZ", (2, 1), 1e-10), # value too small
... ("+-", (3, 1), 2j),
... ("+-", (3, 1), 2j), # can be combined with the above
... ("01", (3, 1), 0.5), # out of order compared to `expected`
... ], num_qubits=5)
>>> expected = SparseObservable.from_list([("I0I1I", 0.5), ("I+I-I", 4j)])
>>> assert base != expected # non-canonical comparison
>>> assert base.simplify() == expected.simplify()Im obigen Beispiel sind die Koeffizienten so gewählt, dass alle Fließkommaberechnungen exakt sind und es keine Probleme mit der Rundung oder Assoziativität gibt. Wenn dies nicht garantiert werden kann, ist die sicherere Form:
>>> left = SparseObservable.from_list([("XYZ", 1.0/3.0)] * 3) # sums to 1.0
>>> right = SparseObservable.from_list([("XYZ", 1.0/7.0)] * 7) # doesn't sum to 1.0
>>> assert left.simplify() != right.simplify()
>>> assert (left - right).simplify() == SparseObservable.zero(left.num_qubits)tensor
tensor(other, /)
Tensorprodukt von zwei Observablen.
otherDie Bitreihenfolge ist so definiert, dass die Qubit-Indizes des Arguments unverändert bleiben und die Indizes von self um die Anzahl der Qubits in verschoben werden. Dies entspricht der Konvention, die auch bei den übrigen Operatoren von Qiskit quantum_info verwendet wird.
Diese Funktion wird für den Infix-Operator ^ verwendet. Wenn Sie diesen Operator verwenden, beachten Sie bitte, dass die Operator-Präzedenzregeln von Python dazu führen können, dass die Auswertungsreihenfolge von Ihren Erwartungen abweicht. Insbesondere bindet der Operator + fester als ^, ebenso wie * fester als + bindet. Verwenden Sie bei Bedarf Klammern, um die Reihenfolge der Auswertung festzulegen.
Das Argument wird in SparseObservable umgewandelt, wenn es nicht bereits in der richtigen Form vorliegt.
Parameter
andere - die Beobachtungsgröße, die auf der rechten Seite des Tensorprodukts steht.
Beispiele
Die Bitreihenfolge ist dabei so, dass das Tensorprodukt zweier Observablen, die aus einem einzigen Etikett gebildet werden, "wie" eine Observable aussieht, die durch Verkettung der beiden Zeichenketten gebildet wird:
>>> left = SparseObservable.from_label("XYZ")
>>> right = SparseObservable.from_label("+-IIrl")
>>> assert left.tensor(right) == SparseObservable.from_label("XYZ+-IIrl")Sie können auch den Infix-Operator ^ für Tensorprodukte verwenden, der in ähnlicher Weise die rechte Seite der Operation umwandelt, wenn sie nicht bereits ein SparseObservable:
>>> assert SparseObservable("rl") ^ Pauli("XYZ") == SparseObservable("rlXYZ")Die gleiche Funktion, aber mit umgekehrter Reihenfolge der Argumente. Dies kann nützlich sein, wenn Sie das Casting-Verhalten für das Argument verwenden möchten, aber Sie wollen, dass Ihre bestehende
SparseObservableauf der rechten Seite der Tensoranordnung stehen soll.
to_sparse_list
to_sparse_list()
Drücken Sie die Beobachtungsgröße in Form einer dünn besetzten Liste aus.
Dies kann als Gegenoperation von SparseObservable.from_sparse_list()gesehen werden, allerdings ist nicht garantiert, dass die Reihenfolge der Terme nach einem Roundtrip zu einer Sparse-Liste und zurück dieselbe ist.
Beispiele
>>> obs = SparseObservable.from_list([("IIXIZ", 2j), ("IIZIX", 2j)])
>>> reconstructed = SparseObservable.from_sparse_list(obs.to_sparse_list(), obs.num_qubits)Der Konstruktor, der diese Listen interpretieren kann.
transpose
transpose()
Berechnen Sie die Matrixtransposition dieser Beobachtungsgröße.
Diese Operation wird gemäß den Standard-Matrixkonventionen von Qiskit definiert, d. h. die Matrixform wird als $Z$-Rechenbasis betrachtet. Die $X$- und $Z$-bezogenen Alphabetterme bleiben von der Transposition unberührt, aber $Y$-bezogene Terme ändern ihre Alphabetterme. Ganz genau:
- wird umgesetzt in
- wird umgesetzt in
- wird umgesetzt in
Beispiele
>>> obs = SparseObservable([("III", 1j), ("Yrl", 0.5)])
>>> assert obs.transpose() == SparseObservable([("III", 1j), ("Ylr", -0.5)])zero
static zero(num_qubits)
Ermittelt den Null-Operator über die angegebene Anzahl von Qubits.
Der Nulloperator ist der Operator, dessen Erwartungswert für alle Quantenzustände gleich Null ist. Sie hat keine Bedingungen. Es ist das Identitätselement für die Addition von zwei SparseObservable instanzen; alles, was mit dem Null-Operator addiert wird, ist gleich sich selbst.
Wenn Sie den Projektor in den Zustand "Alle Nullen" versetzen wollen, verwenden Sie:
>>> num_qubits = 10
>>> all_zeros = SparseObservable.from_label("0" * num_qubits)Beispiele
Holen Sie sich den Null-Operator für 100 Qubits:
>>> SparseObservable.zero(100)
<SparseObservable with 0 terms on 100 qubits: 0.0>