Agora vamos analisar o algoritmo de Grover para entender como ele funciona.
Começaremos com o que poderia ser descrito como uma análise simbólica, onde calculamos como a operação de Grover G age sobre certos estados, e depois conectaremos essa análise simbólica a uma imagem geométrica que é útil para visualizar como o algoritmo funciona.
Vamos começar definindo dois conjuntos de strings.
A0A1={x∈Σn:f(x)=0}={x∈Σn:f(x)=1}
O conjunto A1 contém todas as soluções do nosso problema de busca, enquanto A0 contém as strings que não são soluções (que podemos chamar de não-soluções quando conveniente).
Esses dois conjuntos satisfazem A0∩A1=∅ e A0∪A1=Σn, ou seja, trata-se de uma bipartição de Σn.
Em seguida, definiremos dois vetores unitários representando superposições uniformes sobre os conjuntos de soluções e não-soluções.
Formalmente, cada um desses vetores só está definido quando o conjunto correspondente é não-vazio, mas daqui em diante vamos nos concentrar no caso em que nem A0 nem A1 é vazio.
Os casos em que A0=∅ e A1=∅ podem ser tratados separadamente com facilidade, e faremos isso mais tarde.
Como observação, a notação usada aqui é comum: sempre que temos um conjunto finito e não-vazio S, podemos escrever ∣S⟩ para denotar o vetor de estado quântico uniforme sobre os elementos de S.
Vamos também definir ∣u⟩ como o estado quântico uniforme sobre todas as strings de n bits:
∣u⟩=N1x∈Σn∑∣x⟩.
Observe que
∣u⟩=N∣A0∣∣A0⟩+N∣A1∣∣A1⟩.
Temos também que ∣u⟩=H⊗n∣0n⟩, portanto ∣u⟩ representa o estado do registrador Q após a inicialização no passo 1 do algoritmo de Grover.
Isso implica que, imediatamente antes das iterações de G acontecerem no passo 2, o estado de Q está contido no espaço vetorial bidimensional gerado por ∣A0⟩ e ∣A1⟩, e além disso os coeficientes desses vetores são números reais.
Como veremos, o estado de Q sempre terá essas propriedades — ou seja, o estado é uma combinação linear real de ∣A0⟩ e ∣A1⟩ — após qualquer número de iterações da operação G no passo 2.
Voltaremos agora nossa atenção para a operação de Grover
G=H⊗nZORH⊗nZf,
começando com uma observação interessante sobre ela.
Imagine por um momento que substituímos a função f pela composição de f com a função NOT — ou seja, a função que obtemos invertendo o bit de saída de f.
Chamaremos essa nova função de g, e podemos expressá-la usando símbolos de algumas formas alternativas.
g(x)=¬f(x)=1⊕f(x)=1−f(x)={10f(x)=0f(x)=1
Observe que
(−1)g(x)=(−1)1⊕f(x)=−(−1)f(x)
para toda string x∈Σn, e portanto
Zg=−Zf.
Isso significa que, se substituíssemos a função f pela função g, o algoritmo de Grover não funcionaria de forma diferente — porque os estados obtidos pelo algoritmo nos dois casos são necessariamente equivalentes a menos de uma fase global.
Isso não é um problema!
Intuitivamente, o algoritmo não se importa com quais strings são soluções e quais são não-soluções — ele apenas precisa ser capaz de distinguir soluções e não-soluções para operar corretamente.
Como já observamos, o estado de Q imediatamente antes do passo 2 está contido no espaço bidimensional gerado por ∣A0⟩ e ∣A1⟩, e acabamos de estabelecer que G mapeia qualquer vetor nesse espaço para outro vetor no mesmo espaço.
Isso significa que, para fins de análise, podemos concentrar nossa atenção exclusivamente nesse subespaço.
Para entender melhor o que está acontecendo nesse espaço bidimensional, vamos expressar a ação de G nesse espaço como uma matriz,
cujas primeira e segunda linhas/colunas correspondem a ∣A0⟩ e ∣A1⟩, respectivamente.
Até agora nesta série, sempre conectamos as linhas e colunas de matrizes com os estados clássicos de um sistema, mas as matrizes também podem ser usadas para descrever as ações de mapeamentos lineares em diferentes bases, como temos aqui.
Embora não seja nada óbvio à primeira vista, a matriz M é o que obtemos ao elevar ao quadrado uma matriz de aparência mais simples.
Esse ângulo θ vai desempenhar um papel muito importante na análise que se segue, portanto vale a pena enfatizar sua importância aqui quando o vemos pela primeira vez.
Isso ocorre porque rotacionar pelo ângulo θ duas vezes é equivalente a rotacionar pelo ângulo 2θ.
Outra forma de ver isso é usar a expressão alternativa
θ=cos−1(N∣A0∣),
juntamente com as fórmulas do ângulo duplo da trigonometria:
cos(2θ)sin(2θ)=cos2(θ)−sin2(θ)=2sin(θ)cos(θ).
Em resumo, o estado do registrador Q no início do passo 2 é
Agora vamos conectar a análise que acabamos de fazer a uma imagem geométrica.
A ideia é que a operação G é o produto de duas reflexões,
Zf e H⊗nZORH⊗n.
E o efeito líquido de realizar duas reflexões é realizar uma rotação.
Vamos começar com Zf.
Como já observamos anteriormente, temos
Zf∣A0⟩Zf∣A1⟩=∣A0⟩=−∣A1⟩.
Dentro do espaço vetorial bidimensional gerado por ∣A0⟩ e ∣A1⟩,
essa é uma reflexão em torno da reta paralela a ∣A0⟩, que chamaremos de L1.
Aqui está uma figura ilustrando a ação dessa reflexão sobre um vetor unitário hipotético ∣ψ⟩,
que assumimos ser uma combinação linear real de ∣A0⟩ e ∣A1⟩.
Em segundo lugar, temos a operação H⊗nZORH⊗n, que já vimos poder ser escrita como
H⊗nZORH⊗n=2∣u⟩⟨u∣−I.
Essa também é uma reflexão, desta vez em torno da reta L2 paralela ao vetor ∣u⟩.
Aqui está uma figura que ilustra a ação dessa reflexão sobre um vetor unitário ∣ψ⟩.
Quando combinamos essas duas reflexões, obtemos uma rotação — pelo dobro do ângulo entre as retas de reflexão — como esta figura ilustra.
Isso explica, em termos geométricos, por que o efeito da operação de Grover é rotacionar combinações lineares de ∣A0⟩ e ∣A1⟩ por um ângulo de 2θ.