Implementação com Qiskit
Na lição anterior, tivemos um primeiro contato com as classes Statevector e Operator do Qiskit, e as usamos para simular operações e medições em qubits individuais.
Nesta seção, usaremos essas classes para explorar o comportamento de múltiplos qubits.
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit
from qiskit import __version__
print(__version__)
2.1.1
Começaremos importando as classes Statevector e Operator, bem como a função de raiz quadrada do NumPy.
A partir daqui, em geral, cuidaremos de todos os imports necessários logo no início de cada lição.
from qiskit.quantum_info import Statevector, Operator
from numpy import sqrt
Produtos tensoriais
A classe Statevector possui um método tensor, que retorna o produto tensorial daquele Statevector com outro, fornecido como argumento.
O argumento é interpretado como o fator tensorial à direita.
Por exemplo, abaixo criamos dois vetores de estado representando e e usamos o método tensor para criar um novo vetor,
Observe que estamos usando o método from_label para definir os estados e em vez de defini-los manualmente.
zero = Statevector.from_label("0")
one = Statevector.from_label("1")
psi = zero.tensor(one)
display(psi.draw("latex"))
Outros rótulos permitidos incluem "+" e "-" para os estados mais e menos, bem como "r" e "l" (abreviações de "right" e "left") para os estados
Aqui, "+" , "-" ou "right" e "left" vêm do contexto do spin na mecânica quântica, no qual uma componente do spin pode apontar para a esquerda ou para a direita em um experimento; não se refere ao qubit mais à direita ou mais à esquerda em sistemas de múltiplos qubits. Veja um exemplo do produto tensorial de e
plus = Statevector.from_label("+")
minus_i = Statevector.from_label("l")
phi = plus.tensor(minus_i)
display(phi.draw("latex"))
Uma alternativa é usar a operação ^ para produtos tensoriais, que naturalmente fornece os mesmos resultados.
display((plus ^ minus_i).draw("latex"))
A classe Operator também possui um método tensor (assim como um método from_label), como vemos nos exemplos a seguir.
H = Operator.from_label("H")
Id = Operator.from_label("I")
X = Operator.from_label("X")
display(H.tensor(Id).draw("latex"))
display(H.tensor(Id).tensor(X).draw("latex"))
Novamente, como no caso dos vetores, a operação ^ é equivalente.
display((H ^ Id ^ X).draw("latex"))
Estados compostos podem ser evoluídos usando operações compostas como esperaríamos — assim como vimos para sistemas únicos na lição anterior. Por exemplo, o código a seguir calcula o estado para (que já foi definido acima).
display(phi.evolve(H ^ Id).draw("latex"))
Aqui está um código que define uma operação e calcula para Para deixar claro, esta é uma operação em que o qubit à esquerda é o controle e o qubit à direita é o alvo. O resultado é o estado de Bell
CX = Operator([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])
psi = plus.tensor(zero)
display(psi.evolve(CX).draw("latex"))
Medições parciais
Na lição anterior, usamos o método measure para simular uma medição de um vetor de estado quântico.
Este método retorna dois itens: o resultado simulado da medição e o novo Statevector dado essa medição.
Por padrão, measure mede todos os qubits no vetor de estado.
Como alternativa, podemos fornecer uma lista de inteiros como argumento, o que faz com que apenas os índices de qubit indicados sejam medidos.
Para demonstrar isso, o código abaixo cria o estado
e mede o qubit de número 0, que é o qubit mais à direita. (O Qiskit numera os qubits a partir de 0, da direita para a esquerda. Voltaremos a essa convenção de numeração na próxima lição.)
w = Statevector([0, 1, 1, 0, 1, 0, 0, 0] / sqrt(3))
display(w.draw("latex"))
result, state = w.measure([0])
print(f"Measured: {result}\nState after measurement:")
display(state.draw("latex"))
result, state = w.measure([0, 1])
print(f"Measured: {result}\nState after measurement:")
display(state.draw("latex"))
Measured: 0
State after measurement:
Measured: 00
State after measurement: