Multiplier les matrices de Pauli


12

Les matrices Pauli sont un ensemble de matrices 2x2 qui apparaissent très couramment en physique quantique (non, vous n'avez pas besoin de connaître de physique quantique pour ce défi). Si nous incluons l'identité dans l'ensemble, les quatre matrices sont:

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

En multipliant deux d' entre eux sera toujours donner une autre matrice Pauli, bien qu'il peut être multiplié par l' une des phases complexes 1, i, -1, -i. Par exemple, .σ1σ3 = -iσ2

Votre tâche consiste à multiplier un certain nombre de matrices de Pauli et à renvoyer la matrice et la phase résultantes. Entrée sera donnée sous forme de chaîne non vide de chiffres 0pour 3représenter les matrices à . La sortie doit être une chaîne contenant un seul chiffre pour la matrice résultante, éventuellement précédée de , ou pour indiquer la phase ( est pour ).σ0σ3i--i--1

Vous pouvez écrire un programme ou une fonction, en prenant une entrée via STDIN (ou l'alternative la plus proche), un argument de ligne de commande ou un argument de fonction et en sortant le résultat via STDOUT (ou l'alternative la plus proche), la valeur de retour de la fonction ou le paramètre de la fonction (out).

Vous ne devez pas utiliser de fonctionnalités intégrées (ou tierces) liées aux matrices Pauli.

Il s'agit du code golf, la réponse la plus courte (en octets) l'emporte.

Cas de test

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

3
J'ai ajouté la balise abstract-algebra car cela demande essentiellement une simplification des mots dans le groupe quaternion généralisé .
Peter Taylor

Réponses:


3

Pyth, 47 octets

Je suppose que c'est toujours jouable au golf. Mais il bat beaucoup CJam.

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

Essayez-le en ligne: démonstration ou suite de tests

Explication

Déterminer le type de matrice résultant revient simplement à xorer tous les nombres.

En multipliant 2 matrices A*B, la phase change, si aucune des matrices n'est σ0et 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

bien sûr, j'en ai 44 si j'utilise le même algorithme, qui est essentiellement le Sp300.
Optimizer

9

Python 2, 108 89 87 86 octets

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`

(Merci à @grc et @xnor pour l'aide)

Explication

Divisons le coefficient et la matrice de base. Si nous nous concentrons sur la matrice de base seulement, nous obtenons cette table de multiplication (par exemple 13est -i2, nous avons donc mis 2):

  0123

0 0123
1 1032
2 2301
3 3210

qui se trouve être la même chose que de faire xor au niveau du bit.

Concentrons-nous maintenant sur les coefficients. Si nous 0123désignons 1,i,-1,-irespectivement, nous obtenons:

  0123

0 0000
1 0031
2 0103
3 0310

Pour cela, nous vérifions d'abord si l'un ou l'autre nombre est 0 en faisant m*y, en prenant soin de la colonne de gauche et de la ligne supérieure. L'ajout (m-y)%3donne alors:

  0123

0 0000
1 0021
2 0102
3 0210

qui est proche, sauf que nous avons 2au lieu de 3. Nous en tenons compte en effectuant *3/2.

Pour l'indexation, nous remarquons que si nous prenons la chaîne "--i"et sélectionnons chaque deuxième caractère à partir des indices que 0123nous obtenons "-i","-","i","".


Joli tranchage de cordes, j'avais oublié ça . Je pense que vous pouvez faire 3-n%4comme ~n%4. Je soupçonne que vous pouvez exprimer m*y and(m-y)%3*3/2plus court dans une chaîne magique, mais ma première tentative 877449216>>2*m+8*yn'a fait que lier. Il y a aussi une formule assez algébrique, que si Y=m^y, l'expression est (m-y)*(y-Y)*(Y-m)/2, mais c'est long.
xnor

@xnor Oh ~, chouette - le coup par coup m'ennuyait : / Je suis sûr que ça m*y and(m-y)%3*3/2peut aussi être raccourci, mais j'ai passé toute la nuit et je n'ai rien obtenu ... J'y reviendrai si je avoir le temps. Peut-être que le fait d'avoir le mod 4 de liberté pourrait aider.
Sp3000

6

Rétine , 77 octets

J'ai pensé profiter de cette opportunité pour montrer une nouvelle fonctionnalité Retina: les boucles multi-étapes. Cela devrait considérablement raccourcir de nombreuses tâches (notamment le remplacement conditionnel).

ii
-
+`(.)\1|0

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

Retina est mon propre langage de programmation basé sur l'expression rationnelle. Le code source peut être regroupé en étapes: chaque étape se compose de deux lignes où la première contient l'expression régulière (et éventuellement une configuration) et la deuxième ligne est la chaîne de remplacement. Les étapes sont ensuite appliquées à STDIN dans l'ordre et le résultat final est imprimé à STDOUT.

Vous pouvez utiliser ce qui précède directement comme fichier source avec le -scommutateur de ligne de commande. Cependant, je ne compte pas le commutateur, car vous pouvez également simplement mettre chaque ligne dans un fichier séparé (vous perdez alors 15 octets pour les sauts de ligne, mais ajoutez +15 pour les fichiers supplémentaires).

Explication

La nouveauté de cette solution est )l'avant-dernière étape. Cela ferme une boucle en plusieurs étapes. Il n'y a pas de correspondance (, ce qui signifie que la boucle démarre implicitement au premier stade. Par conséquent, les 7 premières étapes sont répétées jusqu'à ce qu'un passage complet à travers les 7 étapes cesse de changer le résultat. Ces 7 étapes effectuent simplement diverses transformations qui réduisent progressivement le nombre de matrices dans la chaîne et combinent les phases. Une fois que nous atteignons le résultat final, aucun des sept modèles ne correspond plus et la boucle se termine. Ensuite, nous ajoutons un 0 s'il n'y a pas encore de chiffre dans le résultat (car les étapes ci-dessus suppriment simplement toutes les identités, y compris le résultat).

Voici ce que font les différentes étapes:

ii
-

Combine toutes les paires de ien -pour réduire les caractères de phase.

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

Maintenant, s'il reste deux caractères identiques consécutifs, c'est soit --deux matrices identiques. Dans les deux cas, leur multiplication donne l'identité. Mais nous n'avons pas besoin d'identités, nous les supprimons donc toutes, ainsi que les identités explicites 0. Cette étape se répète en elle-même +jusqu'à ce que le résultat cesse de changer. Cela garantit que des choses comme la 123321résolution complète, de sorte que l'étape suivante peut supposer que toutes les paires de chiffres sont distinctes.

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

Il s'agit en fait de deux transformations distinctes en une (pour la golfitude). Notez que si la première alternative correspond, $2et $3sont vides, et si la seconde correspond $1est vide. Cela peut donc être décomposé en ces deux étapes:

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

Cela permute simplement toutes les paires de chiffres et ajoute un signe moins. Depuis que nous avons supprimé toutes les 0s et toutes les paires identiques, cela ne correspond 12, 23, 31, 21, 32, 13. Cette étape peut sembler étrange, mais elle me permet de ne vérifier que la moitié de ces cas plus tard, car ceux que je ne peux pas traiter seront échangés ici lors de la prochaine itération.

L'autre partie de l'étape ci-dessus était:

(.)-
-$1

Cela déplace progressivement les -panneaux vers la gauche (une position par itération). Je fais cela de telle sorte qu'en fin de compte, ils sont tous côte à côte et résolus à l'étape précédente.

12
i3
23
i1
31
i2

Ces trois étapes résolvent désormais simplement les trois paires de produits. Comme je l'ai dit ci-dessus, cela n'attrapera que la moitié des cas pertinents, mais l'autre moitié sera prise en charge lors de la prochaine itération, après que l'étape précédente ait échangé toutes les paires.

)`(\d)i
i$1

C'est la dernière étape de la boucle. Il est similaire à celui qui se déplace -vers la gauche, à l'exception de i. La principale différence est que celui-ci échange iuniquement avec des chiffres. Si j'utilisais (.)ialors dans les cas où j'obtiens un -iou i-les deux seraient échangés indéfiniment et le programme ne se terminerait pas. Cela ne fait donc que les échanger à droite des -panneaux. C'est suffisant - tant que tous -et iapparaissent ensemble à un moment donné, ils peuvent être résolus correctement.

^\D*$
$&0

La dernière étape (en dehors de la boucle). N'oubliez pas que nous avons toujours supprimé toutes les identités, donc si le résultat est réellement l'identité (fois une phase), nous n'aurons plus le chiffre requis dans la sortie, nous l'ajoutons donc.

À titre d'exemple, voici toutes les formes intermédiaires de 0223202330203313021301011023230323(saut d'étapes qui n'effectuent aucun changement):

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.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.