Multiplicar matrices de Pauli

12

Las matrices de Pauli son un conjunto de matrices de 2x2 que aparecen con mucha frecuencia en física cuántica (no, no es necesario conocer ninguna física cuántica para este desafío). Si incluimos la identidad en el conjunto, las cuatro matrices son:

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

Multiplicando dos de estos dará siempre otra matriz Pauli, aunque puede ser multiplicado por una de las fases complejas 1, i, -1, -i. Por ejemplo, .σ1σ3 = -iσ2

Su tarea es multiplicar varias matrices de Pauli y devolver la matriz y la fase resultantes. De entrada será dado como una cadena no vacía de dígitos 0a 3representa las matrices a . La salida debe ser una cadena que contenga un solo dígito para la matriz resultante, opcionalmente precedida por , o para indicar la fase ( es para ).σ0σ3i--i--1

Puede escribir un programa o función, tomando la entrada a través de STDIN (o la alternativa más cercana), argumento de línea de comando o argumento de función y generando el resultado a través de STDOUT (o la alternativa más cercana), el valor de retorno de la función o el parámetro de función (out).

No debe utilizar ninguna función integrada (o de terceros) relacionada con las matrices Pauli.

Este es el código de golf, gana la respuesta más corta (en bytes).

Casos de prueba

1 => 1
13 => -i2
000 => 0
123 => i0
03022 => 3
02132230 => -i3
1320130100032 => i2
311220321030322113103 => -2
0223202330203313021301011023230323 => -i0
1323130203022111323321112122313213130330103202032222223 => -1
Martin Ender
fuente
3
He agregado la etiqueta abstract-algebra porque esencialmente se trata de simplificar las palabras en el grupo de cuaternión generalizado .
Peter Taylor

Respuestas:

3

Pyth, 47 bytes

Supongo que esto todavía es golfable. Pero supera a CJam por mucho.

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

Pruébelo en línea: Demostración o conjunto de pruebas

Explicación

Determinar el tipo de matriz resultante es simplemente exportar todos los números.

Al multiplicar 2 matrices A*B, la fase cambia, si ninguna de las matrices es σ0y 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
fuente
Por supuesto, tengo 44 si uso el mismo algoritmo, que es esencialmente Sp300.
Optimizador
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`

(Gracias a @grc y @xnor por la ayuda)

Explicación

Dividamos el coeficiente y la matriz base. Si nos centramos solo en la matriz base, obtenemos esta tabla de multiplicación (por ejemplo , 13es -i2, así que ponemos 2):

  0123

0 0123
1 1032
2 2301
3 3210

que resulta ser lo mismo que hacer bitor xor.

Ahora centrémonos en los coeficientes. Si dejamos 0123denotar 1,i,-1,-irespectivamente, obtenemos:

  0123

0 0000
1 0031
2 0103
3 0310

Para esto, primero verificamos si cualquiera de los números es 0 haciendo m*y, cuidando la columna izquierda y la fila superior. Agregar (m-y)%3luego da:

  0123

0 0000
1 0021
2 0102
3 0210

que está cerca, excepto que tenemos en 2lugar de 3. Tenemos en cuenta esto mediante la realización *3/2.

Para la indexación, notamos que si tomamos la cadena "--i"y seleccionamos cada segundo carácter a partir de los índices 0123que obtenemos "-i","-","i","".

Sp3000
fuente
Buen corte de hilo, me había olvidado de esto . Creo que se puede hacer 3-n%4tan ~n%4. Sospecho que puedes expresar m*y and(m-y)%3*3/2más corto en una cuerda mágica, pero mi primer intento 877449216>>2*m+8*ysolo empató. También hay una fórmula bastante algebraica, que si Y=m^y, la expresión es (m-y)*(y-Y)*(Y-m)/2, pero eso es largo.
xnor
@xnor Oh ~, bien, el fuera de lugar me estaba molestando: / Estoy bastante seguro de que también m*y and(m-y)%3*3/2se puede acortar, pero pasé toda la noche y no llegué a ningún lado ... Volveré a eso si tener tiempo. Tal vez el hecho de que tengo libertad mod 4 podría ayudar.
Sp3000
6

Retina , 77 bytes

Pensé en aprovechar esta oportunidad para mostrar una nueva función de Retina: bucles de varias etapas. Esto debería acortar considerablemente muchas tareas (especialmente el reemplazo condicional).

ii
-
+`(.)\1|0

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

Retina es mi propio lenguaje de programación basado en expresiones regulares. El código fuente se puede agrupar en etapas: cada etapa consta de dos líneas donde la primera contiene la expresión regular (y potencialmente alguna configuración) y la segunda línea es la cadena de reemplazo. Las etapas se aplican a STDIN en orden y el resultado final se imprime a STDOUT.

Puede usar lo anterior directamente como un archivo fuente con el -sinterruptor de línea de comandos. Sin embargo, no estoy contando el cambio, porque también puede colocar cada línea en un archivo separado (luego pierde 15 bytes para las nuevas líneas, pero agrega +15 para los archivos adicionales).

Explicación

Lo nuevo de esta solución es )la penúltima etapa. Esto cierra un ciclo de múltiples etapas. No hay coincidencia (, lo que significa que el ciclo comienza implícitamente en la primera etapa. Por lo tanto, las primeras 7 etapas se repiten hasta que un pase completo a través de las 7 deja de cambiar el resultado. Estas 7 etapas simplemente realizan varias transformaciones que reducen gradualmente el número de matrices en la cadena y combinan fases. Una vez que alcanzamos el resultado final, ninguno de los siete patrones coincide más y el ciclo termina. Luego, agregamos un 0 si todavía no hay un dígito en el resultado (ya que las etapas anteriores simplemente eliminan todas las identidades, incluido el resultado).

Esto es lo que hacen las etapas individuales:

ii
-

Combina todos los pares de ien -para reducir los caracteres de fase.

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

Ahora, si quedan dos caracteres idénticos consecutivos, es una --o dos matrices idénticas. En cualquier caso, multiplicarlos da la identidad. Pero no necesitamos identidades, por lo que las eliminamos todas y también las identidades explícitas ( 0s). Esta etapa se repite en sí misma +hasta que el resultado deja de cambiar. Esto asegura que cosas como 123321se resuelvan por completo, de modo que el siguiente paso pueda suponer que todos los pares de dígitos son distintos.

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

Esto es en realidad dos transformaciones separadas en una (para golfitude). Tenga en cuenta que si la primera alternativa coincide, $2y $3están vacías, y si la segunda coincide, $1está vacía. Entonces esto se puede descomponer en estos dos pasos:

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

Esto simplemente intercambia todos los pares de dígitos y agrega un signo menos. Desde que eliminó todas 0s y todos los pares idénticos, esto sólo coincidirá 12, 23, 31, 21, 32, 13. Este paso puede parecer extraño, pero me permite verificar solo la mitad de estos casos más adelante, porque los que no puedo procesar se intercambiarán aquí en la próxima iteración.

La otra parte de la etapa anterior fue:

(.)-
-$1

Esto mueve gradualmente los -signos hacia la izquierda (una posición por iteración). Hago esto de manera tal que, en última instancia, estén todos juntos y se resuelvan en el paso anterior.

12
i3
23
i1
31
i2

Estas tres etapas ahora simplemente resuelven los tres pares de productos. Como dije anteriormente, esto solo detectará la mitad de los casos relevantes, pero la otra mitad se resolverá en la próxima iteración, después de que el paso anterior intercambiara todos los pares.

)`(\d)i
i$1

Esta es la última etapa del ciclo. Es similar al que se desplaza -hacia la izquierda, excepto i. La principal diferencia es que este se intercambia isolo con dígitos. Si lo usara (.)i, en los casos en que obtenga uno -io i-los dos se intercambiarían indefinidamente y el programa no terminaría. Entonces esto solo los cambia a la derecha de los -signos. Esto es suficiente: siempre que todos -y iaparezcan juntos en algún momento, se pueden resolver correctamente.

^\D*$
$&0

El paso final (fuera del bucle). Recuerde que siempre eliminamos todas las identidades, por lo que si el resultado es en realidad la identidad (multiplicada por una fase), ya no tendremos el dígito requerido en la salida, así que lo volveremos a agregar.

Como ejemplo, aquí están todas las formas intermedias de 0223202330203313021301011023230323(omitiendo etapas que no realizan ningún cambio):

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
fuente