Moltiplica le matrici di Pauli


12

Le matrici di Pauli sono un insieme di matrici 2x2 che appaiono molto comunemente nella fisica quantistica (no, non è necessario conoscere alcuna fisica quantistica per questa sfida). Se includiamo l'identità nel set, le quattro matrici sono:

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

Moltiplicando due di questi saranno sempre dare un'altra matrice Pauli, anche se può essere moltiplicato per una delle fasi complesse 1, i, -1, -i. Per esempio, .σ1σ3 = -iσ2

Il tuo compito è moltiplicare un numero di matrici di Pauli e restituire la matrice e la fase risultanti. Ingresso sarà dato come una stringa non vuota di cifre 0per 3rappresentare le matrici a . L'output dovrebbe essere una stringa contenente una singola cifra per la matrice risultante, eventualmente preceduto da , o per indicare la fase ( è per ).σ0σ3i--i--1

È possibile scrivere un programma o una funzione, prendendo l'input tramite STDIN (o l'alternativa più vicina), l'argomento della riga di comando o l'argomento della funzione e producendo il risultato tramite STDOUT (o l'alternativa più vicina), il valore di ritorno della funzione o il parametro della funzione (out).

Non è necessario utilizzare alcuna funzionalità integrata (o di terze parti) relativa alle matrici Pauli.

Questo è il codice golf, vince la risposta più breve (in byte).

Casi test

1 => 1
13 => -i2
000 => 0
123 => i0
03022 => 3
02132230 => -i3
1320130100032 => i2
311220321030322113103 => -2
0223202330203313021301011023230323 => -i0
1323130203022111323321112122313213130330103202032222223 => -1

3
Ho aggiunto il tag di algebra astratta perché questo essenzialmente richiede una semplificazione delle parole nel gruppo quaternione generalizzato .
Peter Taylor,

Risposte:


3

Pyth, 47 byte

Immagino che sia ancora giocabile a golf. Ma batte CJam di molto.

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

Provalo online: dimostrazione o Test Suite

Spiegazione

Determinare il tipo di matrice risultante è semplicemente xoring tutti i numeri.

Durante la moltiplicazione di 2 matrici A*B, la fase cambia, se non delle matrici è σ0e 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

ovviamente ne ho 44 se uso lo stesso algoritmo, che è essenzialmente Sp300.
Ottimizzatore

9

Python 2, 108 89 87 86 byte

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`

(Grazie a @grc e @xnor per l'aiuto)

Spiegazione

Dividiamo il coefficiente e la matrice di base. Se ci concentriamo sulla matrice solo base, otteniamo questa tabella moltiplicazione (ad esempio 13è -i2, quindi abbiamo messo 2):

  0123

0 0123
1 1032
2 2301
3 3210

che sembra essere la stessa cosa di fare xor bit per bit.

Ora concentriamoci sui coefficienti. Se lasciamo 0123denotare 1,i,-1,-irispettivamente, otteniamo:

  0123

0 0000
1 0031
2 0103
3 0310

Per questo, per prima cosa controlliamo se uno dei due numeri è 0 m*y, occupandoci della colonna sinistra e della riga superiore. L'aggiunta (m-y)%3quindi dà:

  0123

0 0000
1 0021
2 0102
3 0210

che è vicino, tranne che abbiamo 2invece di 3. Teniamo conto di ciò eseguendo *3/2.

Per l'indicizzazione, notiamo che se prendiamo la stringa "--i"e selezioniamo ogni secondo carattere a partire dagli indici 0123che otteniamo "-i","-","i","".


Nizza affettare stringa, che si era dimenticato di questo . Credo che tu possa fare 3-n%4come ~n%4. Ho il sospetto che tu possa esprimere m*y and(m-y)%3*3/2più breve in una stringa magica, ma il mio primo tentativo è 877449216>>2*m+8*ysolo legato. C'è anche una formula piuttosto algebrica, che se Y=m^yl'espressione è (m-y)*(y-Y)*(Y-m)/2, ma è lunga.
xnor

@xnor Oh ~, bello - l'off-by-one mi dava fastidio: / Sono abbastanza sicuro che m*y and(m-y)%3*3/2può anche essere abbreviato, ma ho passato tutta la notte e non sono arrivato da nessuna parte ... Ci tornerò se avere tempo. Forse il fatto che io abbia la libertà mod 4 potrebbe aiutare.
Sp3000,

6

Retina , 77 byte

Ho pensato di sfruttare questa opportunità per sfoggiare una nuova funzione Retina: loop multi-stage. Ciò dovrebbe abbreviare considerevolmente molte attività (in particolare la sostituzione condizionale).

ii
-
+`(.)\1|0

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

Retina è il mio linguaggio di programmazione basato su regex. Il codice sorgente può essere raggruppato in fasi: ogni fase è composta da due righe in cui la prima contiene la regex (e potenzialmente una certa configurazione) e la seconda riga è la stringa di sostituzione. Le fasi vengono quindi applicate a STDIN in ordine e il risultato finale viene stampato su STDOUT.

È possibile utilizzare quanto sopra direttamente come file di origine con l' -sopzione della riga di comando. Tuttavia, non sto contando lo switch, perché puoi anche solo mettere ogni riga in un file separato (quindi perdi 15 byte per le nuove righe, ma aggiungi +15 per i file aggiuntivi).

Spiegazione

La novità di questa soluzione è )la penultima tappa. Questo chiude un loop a più stadi. Non c'è corrispondenza (, il che significa che il ciclo inizia implicitamente al primo stadio. Quindi, i primi 7 stadi vengono ripetuti fino a quando un passaggio completo attraverso tutti e 7 smette di cambiare il risultato. Queste 7 fasi eseguono semplicemente varie trasformazioni che riducono gradualmente il numero di matrici nella stringa e combinano le fasi. Una volta raggiunto il risultato finale, nessuno dei sette modelli corrisponde più e il ciclo termina. Successivamente, aggiungiamo uno 0 se non ci sono ancora cifre nel risultato (poiché le fasi precedenti semplicemente eliminano tutte le identità, incluso il risultato).

Ecco cosa fanno le singole fasi:

ii
-

Combina tutte le coppie di iin -per ridurre i caratteri di fase.

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

Ora, se rimangono due caratteri identici consecutivi, sono una --o due matrici identiche. In entrambi i casi, moltiplicandoli si ottiene l'identità. Ma non abbiamo bisogno di identità, quindi le rimuoviamo tutte e anche le identità esplicite 0. Questa fase si ripete da sola +fino a quando il risultato non smette di cambiare. Ciò garantisce che cose come la 123321risoluzione completa, in modo che il passaggio successivo possa presumere che tutte le coppie di cifre siano distinte.

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

In realtà si tratta di due trasformazioni separate in una (per golfitude). Nota che se la prima alternativa corrisponde $2e $3sono vuoti e se la seconda corrisponde $1è vuota. Quindi questo può essere scomposto in questi due passaggi:

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

Questo scambia solo tutte le coppie di cifre e aggiunge un segno meno. Poiché abbiamo rimosso tutti 0s e tutte le coppie identiche, questo corrisponde solo 12, 23, 31, 21, 32, 13. Questo passaggio può sembrare strano, ma mi permette di verificare solo la metà di questi casi in seguito, perché quelli che non riesco a elaborare verranno scambiati qui nella prossima iterazione.

L'altra parte della fase precedente era:

(.)-
-$1

Questo sposta gradualmente i -segni completamente a sinistra (una posizione per iterazione). Lo faccio in modo tale che alla fine siano tutti vicini e risolti nel passaggio precedente.

12
i3
23
i1
31
i2

Queste tre fasi ora risolvono semplicemente le tre coppie di prodotti. Come ho detto sopra, questo prenderà solo la metà dei casi rilevanti, ma l'altra metà verrà curata nella successiva iterazione, dopo che il passaggio precedente ha scambiato tutte le coppie.

)`(\d)i
i$1

Questo è l'ultimo stadio del ciclo. È simile a quello che si sposta -a sinistra, tranne che per i. La differenza principale è che questo scambia isolo con cifre. Se lo usassi (.)iallora nei casi in cui ottengo uno -io i-due verrebbero scambiati a tempo indeterminato e il programma non terminerebbe. Quindi questo li scambia solo a destra dei -segni. Questo è sufficiente - finché tutto -e iappaiono insieme ad un certo punto, possono essere risolti correttamente.

^\D*$
$&0

Il passaggio finale (al di fuori del ciclo). Ricorda che abbiamo sempre eliminato tutte le identità, quindi se il risultato è in realtà l'identità (volte una fase), allora non avremo più la cifra richiesta nell'output, quindi la aggiungiamo di nuovo.

Ad esempio, qui ci sono tutte le forme intermedie di 0223202330203313021301011023230323(saltare le fasi che non eseguono alcuna modifica):

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.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.