Multiplizieren Sie Pauli-Matrizen

12

Die Pauli-Matrizen sind eine Menge von 2x2-Matrizen, die in der Quantenphysik sehr häufig vorkommen (nein, Sie müssen für diese Herausforderung keine Quantenphysik kennen). Wenn wir die Identität in die Menge aufnehmen, sind die vier Matrizen:

 σ0 =      σ1 =      σ2 =      σ3 = 
[1  0]    [0  1]    [0 -i]    [1  0]
[0  1]    [1  0]    [i  0]    [0 -1]

Multipliziert man zwei von ihnen werden immer eine andere Pauli - Matrix geben, obwohl es von einem der komplexen Phasen multipliziert werden kann 1, i, -1, -i. Zum Beispiel .σ1σ3 = -iσ2

Ihre Aufgabe ist es, eine Anzahl von Pauli-Matrizen zu multiplizieren und die resultierende Matrix und Phase zurückzugeben. Die Eingabe erfolgt als nicht leere Ziffernfolge 0zur 3Darstellung der Matrizen bis . Die Ausgabe sollte eine Zeichenkette sein , eine einzelne Stelle für die resultierende Matrix enthält, die gegebenenfalls mit vorangestellter , oder der Phase , um anzuzeigen ( für ).σ0σ3i--i--1

Sie können ein Programm oder eine Funktion schreiben, indem Sie eine Eingabe über STDIN (oder die nächstgelegene Alternative), ein Befehlszeilenargument oder ein Funktionsargument vornehmen und das Ergebnis über STDOUT (oder die nächstgelegene Alternative), einen Funktionsrückgabewert oder einen Funktionsparameter (out) ausgeben.

Sie dürfen keine integrierten Funktionen (oder Funktionen von Drittanbietern) in Bezug auf Pauli-Matrizen verwenden.

Dies ist Codegolf, die kürzeste Antwort (in Bytes) gewinnt.

Testfälle

1 => 1
13 => -i2
000 => 0
123 => i0
03022 => 3
02132230 => -i3
1320130100032 => i2
311220321030322113103 => -2
0223202330203313021301011023230323 => -i0
1323130203022111323321112122313213130330103202032222223 => -1
Martin Ender
quelle
3
Ich habe das Abstract-Algebra- Tag hinzugefügt, da dies im Wesentlichen eine Vereinfachung der Wörter in der verallgemeinerten Quaternion-Gruppe erfordert .
Peter Taylor

Antworten:

3

Pyth, 47 Bytes

Ich denke, das ist immer noch Golf. Aber es schlägt CJam um einiges.

p.U&-=T*q3l{[0bZ)^_1%-Zb3xbZmvdz@+c"i - -i")khT

Probieren Sie es online aus: Demo oder Test Suite

Erläuterung

Das Bestimmen des resultierenden Matrixtyps ist einfach das Xoring aller Zahlen.

Beim Multiplizieren von 2 Matrizen A*Bändert sich die Phase, wenn nicht eine der Matrizen ist σ0und A != B.

                                                 implicit: T=10, z=input string
                            mvdz                 evaluate each char of the input 
 .U                                              reduce: b=first value, for Y in mvdz[1:]
    -=T                                            T -= ...
        q3l{[0bZ)                                     (3 == len(set([0,b,Z])))
       *         ^_1%-Zb3                             * (-1)^((Z-b)%3)
   &                                               and
                         xbY                       update b by (b xor Y)
                                 +c"i - -i")k    the list ["i", "-", "-i", ""]
                                @            hT  take the element at index T+1 (modulo wrapping)
p                                                print phase and matrix
Jakube
quelle
Natürlich habe ich 44, wenn ich den gleichen Algorithmus verwende, der im Wesentlichen Sp300 ist.
Optimierer
9

Python 2, 108 89 87 86 Bytes

x=y=0
for m in map(int,raw_input()):x+=m*y and(m-y)%3*3/2;y^=m
print"--i"[~x%4::2]+`y`

(Danke an @grc und @xnor für die Hilfe)

Erläuterung

Teilen wir den Koeffizienten und die Basismatrix auf. Wenn wir nur auf die Grundmatrix konzentrieren, bekommen wir diese Multiplikationstabelle (zB 13ist -i2, so dass wir setzen 2):

  0123

0 0123
1 1032
2 2301
3 3210

das ist einfach das gleiche wie bitweises xor.

Konzentrieren wir uns nun auf die Koeffizienten. Wenn wir jeweils 0123bezeichnen lassen 1,i,-1,-i, erhalten wir:

  0123

0 0000
1 0031
2 0103
3 0310

Dazu prüfen wir zunächst, ob eine der beiden Zahlen 0 ist m*y, und achten dabei auf die linke Spalte und die obere Reihe. Hinzufügen (m-y)%3ergibt dann:

  0123

0 0000
1 0021
2 0102
3 0210

die Nähe, mit der Ausnahme , dass wir 2statt 3. Wir tragen dem durch Leistung Rechnung *3/2.

Bei der Indizierung stellen wir fest, dass, wenn wir die Zeichenfolge nehmen "--i"und jedes zweite Zeichen auswählen, beginnend mit den Indizes, die 0123wir erhalten "-i","-","i","".

Sp3000
quelle
Nizza String Slicing, hatte ich vergessen dies . Ich glaube du kannst machen 3-n%4wie ~n%4. Ich vermute man kann m*y and(m-y)%3*3/2kürzer in einer magischen Saite ausdrücken , aber mein erster Versuch ist 877449216>>2*m+8*ynur gebunden. Es gibt auch eine ziemlich algebraische Formel, dass wenn Y=m^y, der Ausdruck ist (m-y)*(y-Y)*(Y-m)/2, aber das ist lang.
xnor
@xnor Oh ~, schön - der Off-by-One hat mich genervt : / Ich bin mir ziemlich sicher, m*y and(m-y)%3*3/2dass ich mich auch verkürzen kann, aber ich habe die ganze Nacht verbracht und bin nirgendwo hingekommen ... Ich werde darauf zurückkommen, wenn ich Zeit haben. Vielleicht könnte die Tatsache, dass ich Freedom Mod 4 habe, helfen.
Sp3000,
6

Retina , 77 Bytes

Ich dachte, ich würde diese Gelegenheit nutzen, um ein neues Retina-Feature vorzuführen: mehrstufige Loops. Dies sollte viele Aufgaben erheblich verkürzen (insbesondere den bedingten Austausch).

ii
-
+`(.)\1|0

(.)-|(\d)(\d)
-$1$3$2
12
i3
23
i1
31
i2
)`(\d)i
i$1
^\D*$
$&0

Retina ist meine eigene, auf Regex basierende Programmiersprache. Der Quellcode kann in Phasen gruppiert werden: Jede Phase besteht aus zwei Zeilen, wobei die erste die Regex (und möglicherweise eine Konfiguration) enthält und die zweite Zeile die Ersatzzeichenfolge ist. Die Stufen werden dann der Reihe nach auf STDIN angewendet, und das Endergebnis wird auf STDOUT gedruckt.

Sie können die oben genannten direkt als Quelldatei mit der -sBefehlszeilenoption verwenden. Ich zähle den Schalter jedoch nicht, da Sie auch einfach jede Zeile in eine separate Datei einfügen können (dann verlieren Sie 15 Byte für die Zeilenumbrüche, fügen jedoch +15 für die zusätzlichen Dateien hinzu).

Erläuterung

Das Neue an dieser Lösung ist )das vorletzte Stadium. Dies schließt eine mehrstufige Schleife. Es gibt keine Übereinstimmung (, was bedeutet, dass die Schleife implizit in der ersten Stufe beginnt. Daher werden die ersten 7 Stufen wiederholt, bis ein vollständiger Durchlauf durch alle 7 das Ergebnis nicht mehr ändert. Diese 7 Stufen führen einfach verschiedene Transformationen durch, die die Anzahl der Matrizen in der Kette allmählich verringern und die Phasen kombinieren. Sobald wir das Endergebnis erreicht haben, stimmt keines der sieben Muster mehr überein und die Schleife endet. Danach fügen wir eine 0 hinzu, wenn das Ergebnis noch keine Ziffer enthält (da in den obigen Schritten einfach alle Identitäten einschließlich des Ergebnisses gelöscht werden).

Das machen die einzelnen Stufen:

ii
-

Kombiniert alle Paare von iin -, um die Phasenzeichen zu reduzieren.

+`(.)\1|0
<empty>

Wenn nun zwei aufeinanderfolgende identische Zeichen übrig sind, sind es entweder --zwei identische Matrizen. In beiden Fällen ergibt die Multiplikation die Identität. Wir brauchen aber keine Identitäten, also entfernen wir einfach alle und auch die expliziten Identitäten 0. Diese Phase wird in sich wiederholt, +bis sich das Ergebnis nicht mehr ändert. Dies stellt sicher, dass Dinge wie 123321vollständig aufgelöst werden, sodass der nächste Schritt davon ausgehen kann, dass alle Ziffernpaare unterschiedlich sind.

(.)-|(\d)(\d)
-$1$3$2

Dies sind eigentlich zwei getrennte Transformationen in einer (für Golf). Beachten Sie, dass, wenn die erste Alternative zutrifft $2und $3leer ist, und wenn die zweite zutrifft, $1leer ist. Das kann also in diese zwei Schritte zerlegt werden:

(\d)(\d)
-$2$1

Dadurch werden nur alle Ziffernpaare vertauscht und ein Minuszeichen hinzugefügt. Da wir alle entfernt 0s und alle identische Paare, wird dies nur passen 12, 23, 31, 21, 32, 13. Dieser Schritt mag seltsam erscheinen, aber ich kann später nur die Hälfte dieser Fälle überprüfen, da diejenigen, die ich dann nicht verarbeiten kann, in der nächsten Iteration hier ausgetauscht werden.

Der andere Teil der obigen Etappe war:

(.)-
-$1

Dadurch werden die -Zeichen schrittweise ganz nach links verschoben (eine Position pro Iteration). Ich mache das so, dass sie letztendlich alle nebeneinander stehen und im vorherigen Schritt gelöst werden.

12
i3
23
i1
31
i2

Diese drei Stufen lösen nun einfach die drei Produktpaare auf. Wie ich oben sagte, wird dies nur die Hälfte der relevanten Fälle erfassen, aber die andere Hälfte wird in der nächsten Iteration behoben, nachdem der vorherige Schritt alle Paare vertauscht hat.

)`(\d)i
i$1

Dies ist die letzte Stufe der Schleife. Es ist ähnlich wie das, das sich -nach links verschiebt, mit Ausnahme von i. Der Hauptunterschied ist, dass dieser inur mit Ziffern vertauscht wird. Wenn ich (.)idann in Fällen verwendet, in denen ich ein -ioder i-die zwei bekomme, würde auf unbestimmte Zeit getauscht und das Programm würde nicht beendet. Das vertauscht sie also nur rechts von den -Zeichen. Dies ist ausreichend - solange alle -und izu einem bestimmten Zeitpunkt zusammen angezeigt werden, können sie korrekt aufgelöst werden.

^\D*$
$&0

Der letzte Schritt (außerhalb der Schleife). Denken Sie daran, dass wir immer alle Identitäten gelöscht haben. Wenn das Ergebnis also tatsächlich die Identität ist (mal eine Phase), haben wir die erforderliche Ziffer nicht mehr in der Ausgabe, also fügen wir sie zurück.

Als Beispiel sind hier alle Zwischenformen von 0223202330203313021301011023230323(Überspringen von Phasen, die keine Änderungen durchführen):

0223202330203313021301011023230323

321321312        # Remove identities
-23-31-12-132    # Swap all pairs
-23-31-i3-132    # Resolve 12
-i1-31-i3-132    # Resolve 23
-i1-i2-i3-132    # Resolve 31
-i-1i-2i-3-312   # Move - to the left and swap pairs
-i-1i-2i-3-3i3   # Resolve 12
-i-i1-i2-3-i33   # Move i to the left
-i-i1-i2-3-i     # Remove identities
--ii-1i-2-3i     # Move - to the left
--ii-i1-2-i3     # Move i to the left
----i1-2-i3      # Resolve ii
i1-2-i3          # Remove identities
i-1-2i3          # Move - to the left
i-1-i23          # Move i to the left
-i-1i-32         # Move - to the left and swap pairs
-i-i1-32         # Move i to the left
--ii-1-23        # Move - to the left and swap pairs
--ii-1-i1        # Resolve 23
----1-i1         # Resolve ii
1-i1             # Remove identities
-1i1             # Move - to the left
-i11             # Move i to the left
-i               # Remove identities. Now the loop can't change this any longer.
-i0              # Fix the result by adding in the 0.
Martin Ender
quelle