Application d'une porte quantique multi-qubit à des qubits spécifiques

9

Une matrice non gérée contrôlée ressemble à ceci:

[1000010000010010]

Cela fonctionne très bien lorsque vous n'avez que deux qubits et que vous souhaitez utiliser le premier qubit comme contrôle et le deuxième qubit comme entrée à inverser (ou non).

Existe-t-il une méthode pour convertir cette matrice à utiliser, par exemple, si vous aviez 3 qubits et que vous vouliez utiliser qubit 1 comme contrôle et qubit 3 comme entrée éventuellement inversée?

En y réfléchissant logiquement, je peux trouver ceci:

[1000000001000000001000000001000000000100000010000000000100000010]

Existe-t-il un meilleur moyen, plus formel / généralisé, de convertir des portes multi-qubit pour utiliser les qubits spécifiés, plutôt que le premier dans un circuit de qubit ?NN

Alan Wolfe
la source

Réponses:

7

Expand-n-Swap

Si vous souhaitez appliquer une porte à un sous-ensemble des qubits:

Il peut être fastidieux de faire toutes ces grandes multiplications matricielles, mais les matrices de swap sont rares et l'idée est très simple.

Les commandes sont plus faciles

Dans le cas de l'ajout de contrôles à une opération (qui s'applique à l'exemple spécifique que vous avez donné), il existe une astuce plus simple. Développez simplement l'opération comme d'habitude, puis remplacez toutes les parties de la matrice qui correspondent aux entrées ayant échoué au contrôle par ce que serait la matrice d'identité.

C'est un peu plus facile à suivre si vous introduisez une fausse "valeur de contrôle" qui remplace le comportement habituel du produit tensorielc , de sorte qu'au lieu de , vous avez (en d' autres termes: lorsqu'une entrée est que vous ne faites pas la tuile sur l'entrée et l' échelle par l'entrée, vous utiliser au lieu de ).[c]U=cU[c]U=cIcUUIU

Définissez «l'opération» d'un contrôle qubit-must-be-ON comme . Un no-op est , et un PAS est . Ensuite, l'opération à partir de votre question pourrait être calculée comme ceci (en supposant un ordre big-endian):C=[c001]IX

CNOT31=CIX

=[c001][1001][0110]

=[c[1001]0[1001]0[1001]1[1001]][0110]

=[[c00c][0000][0000][1001]][0110]

=[c0000c0000100001][0110]

(Remarque: va utiliser un seul zéro pour signifier de manière ambiguë une matrice de zéro 2x2 lorsque cela est pratique)

=[c[0110]0000c[0110]0000[0110]0000[0110]]

=[[c00c]0000[c00c]0000[0110]0000[0110]]

=[c00000000c00000000c00000000c000000000100000010000000000100000010]

(maintenant nous avons fini avec les produits tenseurs et nous n'avons plus besoin des )c

[1000000001000000001000000001000000000100000010000000000100000010]

Ça a du sens?

Craig Gidney
la source
8

N'utilisez pas la méthode swap, c'est très inefficace. Et la réponse de l'autre personne est spécifique à la porte CNOT, et pour être franc, complique trop les choses.

Voici un algorithme très simple qui résout votre problème pour chaque cas, pas seulement la porte CNOT, pour tous les bits arbitraires.

L'algorithme:

let sys = matrix representing the current state of the system
let n = number of qubits being simulated
let lgm = logic gate matrix of size 2^n by 2^n
let f = our logic gate transformation function
for i = 0 to (2^n) - 1:
    lgm[column = i] = f(i)
sys = sys × lgg

Dans les ordinateurs classiques, il y a quelque chose connu comme le "décodeur". Disons que je n'ai que 3 fils, en fait, 3 bits. Mais je veux contrôler 8 fils. Cela peut-il être fait? Oui, car 3 bits ont 8 possibilités différentes: 000, 001, 010, 011, 100, 101, 110, 111. Nous pouvons donc attribuer chaque possibilité à l'un de nos 8 fils de sortie. C'est ce qu'on appelle le «décodage».

Si je passe le nombre 101 et que nous avons 3 bits, nous savons que 101 = 5, alors je mettrai le fil de sortie 5 à une tension élevée et les 7 autres fils de sortie seront 0, que nous pouvons représenter comme ceci: décoder (101) = [0, 0, 0, 0, 0, 1, 0, 0].

Dans cet algorithme, je mentionne la "fonction de transformation" appelée "f". Pour les ordinateurs classiques, la fonction de transformation prend simplement une valeur d'entrée et renvoie la version "décodée" de la valeur de sortie. Donc, si nous avons 3 bits et que la sortie est 4, alors nous retournerons [0, 0, 0, 0, 1, 0, 0, 0]. Nous attribuons ensuite cela comme colonne de notre matrice pour cette valeur.

Pensons au "décodage" en termes de qubits. Comment décoder les qubits | 101>?

Nous savons que pour nos vecteurs de probabilité qubit, | 0> est [1, 0] et | 1> est [0, 1]. Le décodage des qubits peut alors être fait ce qu'on appelle le produit Kronecker.

Donc, si nous convertissons chaque bit en équivalent de vecteur de probabilité et prenons le produit Kronecker de chacun d'eux, nous obtenons ...

|101> = |1> ⊗ |0> ⊗ |1> = [0, 1] ⊗ [1, 0] ⊗ [0, 1] = [0, 0, 0, 0, 0, 1, 0, 0]

C'est ainsi que nous voudrions décoder les qubits. Cet algorithme peut être appliqué aux qubits de la même manière en utilisant ceci.

Essayons cet algorithme sur un problème plus simple.

Supposons que nous ayons un système avec seulement 2 qubits. Si nous voulons appliquer la porte Hadamard à seulement 1 qubit, nous pouvons générer une porte logique pour les deux qubits qui n'applique la porte Hadamard qu'à un seul qubit. Supposons que le qubit unique auquel nous voulons l'appliquer soit notre qubit le plus significatif et que le moins significatif ne soit pas affecté.

Nous voulons une fonction de transformation qui, pour chacune de nos entrées possibles, produise la sortie correcte. Nous avons deux qubits, cela signifie qu'il y a quatre sorties possibles.

f(|00>) = ?
f(|01>) = ?
f(|10>) = ?
f(|11>) = ?

Nous savons que le qubit le moins significatif ne sera pas affecté, nous pouvons donc le remplir.

f(|00>) = ? ⊗ |0>
f(|01>) = ? ⊗ |1>
f(|10>) = ? ⊗ |0>
f(|11>) = ? ⊗ |1>

Nous savons également ce que le Hadamard fait à un qubit, de sorte que:

H(|0>) = 1/sqrt(2)|0> + 1/sqrt(2)|1>
H(|1>) = 1/sqrt(2)|0> - 1/sqrt(2)|1>

Notre fonction de transformation est donc simplement:

f(|00>) = (1/sqrt(2)|0> + 1/sqrt(2)|1>) ⊗ |0>
f(|01>) = (1/sqrt(2)|0> + 1/sqrt(2)|1>) ⊗ |1>
f(|10>) = (1/sqrt(2)|0> - 1/sqrt(2)|1>) ⊗ |0>
f(|11>) = (1/sqrt(2)|0> - 1/sqrt(2)|1>) ⊗ |1>

Développez cela à notre forme vectorielle de probabilité normalisée ...

f(|00>) = [ 1/sqrt(2), 1/sqrt(2) ] ⊗ [ 1, 0 ]
f(|01>) = [ 1/sqrt(2), 1/sqrt(2) ] ⊗ [ 0, 1 ]
f(|10>) = [ 1/sqrt(2), -1/sqrt(2) ] ⊗ [ 1, 0 ]
f(|11>) = [ 1/sqrt(2), -1/sqrt(2) ] ⊗ [ 0, 1 ]

Maintenant, résolvons réellement cela ...

f(|00>) = [ 1/sqrt(2), 0, 1/sqrt(2), 0 ]
f(|01>) = [ 0, 1/sqrt(2), 0, 1/sqrt(2) ]
f(|10>) = [ 1/sqrt(2), 0, -1/sqrt(2), 0 ]
f(|11>) = [ 0, 1/sqrt(2), 0, -1/sqrt(2) ]

C'est notre fonction de transformation.

Notre matrice de portes logiques, "lgm", est de taille 2 ^ n par 2 ^ n où n = nombre de qubits simulés, donc dans ce cas, c'est 2 ^ 2 par 2 ^ 2 ou 4x4. Notre algorithme nous dit que pour chaque colonne i, définissez la colonne égale à f (i). Nous avons défini notre fonction de transformation de probabilité, afin que nous puissions facilement remplir ces colonnes.

lgm = 
    |00>       |01>        |10>        |11>
[ 1/sqrt(2),         0,  1/sqrt(2),          0 ] 
[         0, 1/sqrt(2),          0,  1/sqrt(2) ]
[ 1/sqrt(2),         0, -1/sqrt(2),          0 ]
[         0, 1/sqrt(2),          0, -1/sqrt(2) ]

Maintenant, la dernière étape de notre algorithme consiste simplement à multiplier par matrice notre matrice représentant l'ensemble du système quantique, sys, par cette porte logique, lgm.

Et c'est ce que nous voulons. Il appliquera la porte hadamard uniquement au qubit le plus élevé et laissera le qubit le moins significatif seul. Si vous ne me croyez pas, vous pouvez l'essayer vous-même et voir que cela fonctionne.

La raison pour laquelle cela est si puissant est qu'il s'applique à tous les cas.

Essayons cet algorithme sur votre problème.

Imaginez que nous avons un système à 3 qubits et que nous voulons appliquer une porte CNOT à qubit [0] et qubit [2]. Si vous recherchez la matrice CNOT sur Wikipedia, cette matrice ne s'applique qu'à un système à 2 qubits. Une solution naïve serait d'y ajouter des matrices d'identité en utilisant le produit Kronecker pour le faire fonctionner sur des systèmes à trois qubits. Mais cela échoue ici: qubit [0] et qubit [2] ne sont pas adjacents, donc simplement ajouter des matrices d'identité ne fonctionnera pas.

Nous pourrions échanger qubit [0] avec qubit [1], appliquer la porte CNOT, puis les échanger à nouveau. Mais c'est lent. Au lieu de cela, nous pourrions simplement générer une porte CNOT non adjacente pour notre problème en utilisant l'algorithme ci-dessus.

Nous devons d'abord trouver une fonction de transformation pour chaque cas.

f(|000>) = |0> ⊗ |0> ⊗ |0>
f(|001>) = |0> ⊗ |0> ⊗ |1>
f(|010>) = |0> ⊗ |1> ⊗ |0>
f(|011>) = |0> ⊗ |1> ⊗ |1>
f(|100>) = |1> ⊗ |0> ⊗ |1>
f(|101>) = |1> ⊗ |0> ⊗ |0>
f(|110>) = |1> ⊗ |1> ⊗ |1>
f(|111>) = |1> ⊗ |1> ⊗ |0>

Si vous comprenez la porte CNOT, vous pouvez comprendre pourquoi c'est notre fonction. Pensez à cela comme une table de vérité. Puisque notre qubit de contrôle est le qubit le plus significatif, qubit [2], ce n'est que lorsque ce qubit est | 1> que le qubit le moins significatif, qubit [0], sera annulé.

Développez cela à notre forme vectorielle de probabilité normalisée ...

f(|000>) = [ 1, 0 ] ⊗ [ 1, 0 ] ⊗ [ 1, 0 ]
f(|001>) = [ 1, 0 ] ⊗ [ 1, 0 ] ⊗ [ 0, 1 ]
f(|010>) = [ 1, 0 ] ⊗ [ 0, 1 ] ⊗ [ 1, 0 ]
f(|011>) = [ 1, 0 ] ⊗ [ 0, 1 ] ⊗ [ 0, 1 ]
f(|100>) = [ 0, 1 ] ⊗ [ 1, 0 ] ⊗ [ 0, 1 ]
f(|101>) = [ 0, 1 ] ⊗ [ 1, 0 ] ⊗ [ 1, 0 ]
f(|110>) = [ 0, 1 ] ⊗ [ 0, 1 ] ⊗ [ 0, 1 ]
f(|111>) = [ 0, 1 ] ⊗ [ 0, 1 ] ⊗ [ 1, 0 ]

Maintenant, résolvons réellement cela ...

f(|000>) = [ 1, 0, 0, 0, 0, 0, 0, 0 ]
f(|001>) = [ 0, 1, 0, 0, 0, 0, 0, 0 ]
f(|010>) = [ 0, 0, 1, 0, 0, 0, 0, 0 ]
f(|011>) = [ 0, 0, 0, 1, 0, 0, 0, 0 ]
f(|100>) = [ 0, 0, 0, 0, 0, 1, 0, 0 ]
f(|101>) = [ 0, 0, 0, 0, 1, 0, 0, 0 ]
f(|110>) = [ 0, 0, 0, 0, 0, 0, 0, 1 ]
f(|111>) = [ 0, 0, 0, 0, 0, 0, 1, 0 ]

Faisons-en les colonnes de notre matrice lgm.

lgm =
[ 1, 0, 0, 0, 0, 0, 0, 0 ]
[ 0, 1, 0, 0, 0, 0, 0, 0 ]
[ 0, 0, 1, 0, 0, 0, 0, 0 ]
[ 0, 0, 0, 1, 0, 0, 0, 0 ]
[ 0, 0, 0, 0, 0, 1, 0, 0 ]
[ 0, 0, 0, 0, 1, 0, 0, 0 ]
[ 0, 0, 0, 0, 0, 0, 0, 1 ]
[ 0, 0, 0, 0, 0, 0, 1, 0 ]

Maintenant, si la matrice multiplie notre matrice système entière, sys, par notre matrice de porte logique, lgm, notre résultat sera l'effet de l'application de la porte CNOT à qubit [2] et qubit [0] où qubit [2] est le contrôle qubit.

Amelia Hartman
la source
Merci d'avoir inclus un exemple à la fin; ce fut très utile. Pourriez-vous également fournir une définition du produit Kronecker? (Je pense aussi que vous l'avez peut-être mal orthographié "Kornecker" une fois.)
Pro Q
1
Je recommande ceci pour le produit Kronecker: youtube.com/watch?v=e1UJXvu8VZk
Amelia Hartman