Pular para o conteúdo principal

Explorando a incerteza

Para este módulo do Qiskit in Classrooms, os alunos precisam ter um ambiente Python funcional com os seguintes pacotes instalados:

  • qiskit v2.1.0 ou mais recente
  • qiskit-ibm-runtime v0.40.1 ou mais recente
  • qiskit-aer v0.17.0 ou mais recente
  • qiskit.visualization
  • numpy
  • pylatexenc

Para configurar e instalar os pacotes acima, consulte o guia Instalar o Qiskit. Para executar jobs em computadores quânticos reais, os alunos precisarão criar uma conta no IBM Quantum® seguindo os passos do guia Configurar sua conta IBM Cloud.

Este módulo foi testado e utilizou 8 minutos de tempo de QPU. Isso é apenas uma estimativa. O uso real pode variar. Dois cálculos demorados estão marcados como tal nos comentários de cabeçalho e podem ser realizados em simuladores caso os alunos estejam com pouco tempo de QPU. Sem eles, o módulo requer apenas ~30 segundos de tempo de QPU.

# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-aer qiskit-ibm-runtime
# Uncomment and modify this line as needed to install dependencies
#!pip install 'qiskit>=2.1.0' 'qiskit-ibm-runtime>=0.40.1' 'qiskit-aer>=0.17.0' 'numpy' 'pylatexenc'

Assista ao guia do módulo apresentado pela Dra. Katie McCormick abaixo, ou clique aqui para assistir no YouTube.


Introdução

Você provavelmente já ouviu falar do princípio da incerteza, mesmo fora dos seus cursos de física. Uma reformulação coloquial comum da incerteza é "Ao observar algo, você o influencia." Isso é certamente verdade. Mas uma maneira mais física de descrever a incerteza é que existem certas grandezas físicas observáveis que possuem uma incompatibilidade que impede que ambas sejam conhecidas simultaneamente com precisão arbitrária. Muitos alunos encontram pela primeira vez o par de variáveis incompatíveis xx e pxp_x, que representam a posição ao longo de um eixo chamado eixo xx e o momento linear ao longo dessa direção, respectivamente. Para essas variáveis, a restrição sobre a incerteza é escrita como ΔxΔpx2.\Delta x \Delta p_x \geq \frac{\hbar}{2}. Aqui, Δx\Delta x é chamado de "incerteza em xx", que tem a mesma definição que o desvio padrão em estatística, e pode ser definido como Δx=x2x2.\Delta x = \sqrt{\langle x^2 \rangle - \langle x \rangle^2}. Δpx\Delta p_x é definido da mesma forma. Aqui, não vamos derivar essa relação de incerteza; vamos apontar que ela é consistente com nossa compreensão das ondas clássicas. Ou seja, uma onda com uma frequência ff e comprimento de onda λ\lambda verdadeiramente perfeitos se estenderia para sempre como um seno perfeito. Quanticamente, isso corresponderia a conhecer o momento perfeitamente de acordo com a hipótese de de Broglie: λ=h/p\lambda = h/p. Mas para saber ondeonde uma partícula ondular está localizada, a onda que a descreve deve tornar-se mais concentrada no espaço, como uma Gaussiana muito estreita, por exemplo. Sabemos que podemos expressar qualquer função contínua, incluindo tais funções de onda concentradas, como uma série de Fourier de funções senoidais com diferentes comprimentos de onda. Mas à medida que a função de onda se torna mais concentrada (e a posição é melhor conhecida), precisaremos de mais termos na série de Fourier, significando uma mistura de mais comprimentos de onda (e, portanto, quanticamente, mais valores de momento).

Dito de forma mais simples: um estado com momento bem definido (um seno perfeito no espaço) tem posição muito incerta. Um estado com posição bem definida (como uma distribuição delta de Dirac) tem momento muito incerto.

Existem outras variáveis que exibem tal incompatibilidade. Por exemplo, a projeção do spin de uma partícula pode ser bem definida ao longo de um eixo, mas então não sabemos nada sobre a projeção em um eixo ortogonal. Por exemplo, o estado 0|0\rangle \sim |\uparrow\rangle (para um qubit ou partícula de spin-1/2) tem uma projeção definida ao longo do eixo zz (de 1 no contexto de um qubit, e de /2\hbar/2 no contexto de uma partícula de spin-1/2). Mas esse estado pode ser escrito como uma superposição de dois estados, cada um dos quais tem uma projeção bem definida no eixo xx: 0=12(+x+x)|0\rangle = \frac{1}{\sqrt{2}}(|+\rangle_x+|-\rangle_x) ou equivalentemente (10)=12[12(11)+12(11)].\begin{pmatrix} 1 \\ 0\end{pmatrix} = \frac{1}{\sqrt{2}}\left[\frac{1}{\sqrt{2}}\begin{pmatrix} 1 \\ 1\end{pmatrix}+\frac{1}{\sqrt{2}}\begin{pmatrix} 1 \\ -1\end{pmatrix}\right]. +x|+\rangle_x tem uma projeção bem definida em xx, assim como x|-\rangle_x. Portanto, se especificarmos a projeção de um estado ao longo do eixo xx, não sabemos a projeção ao longo do eixo zz. E se especificarmos a projeção no eixo zz, não sabemos a projeção ao longo de xx. Existem pequenas diferenças ao discutir isso no contexto do spin e dos qubits. Mas, de modo geral, os autoestados das matrizes de Pauli têm uma relação interessante que podemos explorar. Ao longo desta aula, verificaremos experimentalmente nossa intuição sobre a incerteza nessas variáveis incompatíveis, e verificaremos que as relações de incerteza se mantêm nos computadores quânticos da IBM®.

Verificação simples da intuição

Neste primeiro experimento e ao longo do módulo, usaremos uma estrutura para computação quântica conhecida como "padrões Qiskit" (Qiskit patterns), que divide os fluxos de trabalho nas seguintes etapas:

  • Etapa 1: Mapear entradas clássicas para um problema quântico
  • Etapa 2: Otimizar o problema para execução quântica
  • Etapa 3: Executar usando os Primitivos do Qiskit Runtime
  • Etapa 4: Pós-processamento e análise clássica

Em geral, seguiremos essas etapas, embora nem sempre as rotulemos explicitamente.

Vamos começar carregando alguns pacotes necessários, incluindo os primitivos do Runtime. Também selecionaremos o computador quântico menos ocupado disponível para nós.

Há um código abaixo para salvar suas credenciais no primeiro uso. Certifique-se de excluir essas informações do notebook após salvá-las em seu ambiente, para que suas credenciais não sejam compartilhadas acidentalmente ao compartilhar o notebook. Consulte Configurar sua conta IBM Cloud e Inicializar o serviço em um ambiente não confiável para mais orientações.

from numpy import pi

# Load the Qiskit Runtime service
from qiskit_ibm_runtime import QiskitRuntimeService

# Syntax for first saving your token. Delete these lines after saving your credentials.
# QiskitRuntimeService.save_account(channel='ibm_quantum_platform', instance = '<YOUR_IBM_INSTANCE_CRN>', token='<YOUR-API_KEY>', overwrite=True, set_as_default=True)
# service = QiskitRuntimeService(channel='ibm_quantum_platform')

# Load saved credentials
service = QiskitRuntimeService()
# Load the Runtime primitive and session
from qiskit_ibm_runtime import (
Batch,
SamplerV2 as Sampler,
EstimatorV2 as Estimator,
)

# Use the least busy backend
backend = service.least_busy(min_num_qubits=127)
print(backend.name)
ibm_sherbrooke

Se um aluno esgotar seu tempo disponível de computação quântica durante a aula, as linhas abaixo podem ser descomentadas e usadas para configurar um simulador que imita parcialmente o comportamento de ruído do computador quântico selecionado acima.

# Import an estimator, this time from qiskit (we will import from Runtime for real hardware)
from qiskit_aer.primitives import SamplerV2, EstimatorV2
from qiskit_aer.noise import NoiseModel

# Generate the noise model from the backend properties
noise_model = NoiseModel.from_backend(backend)

noisy_sampler = SamplerV2(options={"backend_options": {"noise_model": noise_model}})
noisy_estimator = EstimatorV2(options={"backend_options": {"noise_model": noise_model}})

Você deve se lembrar de que um autoestado de um operador, Z, não é um autoestado de outro operador X. Vamos observar isso agora, experimentalmente, fazendo medições ao longo dos eixos xx e zz. Para a medição ao longo de zz, simplesmente usamos qc.measure(), pois os computadores quânticos da IBM são estruturados para medir ao longo de zz. Mas para medir ao longo de xx, precisamos rotacionar o sistema para efetivamente mover o eixo xx até a orientação ao longo da qual medimos. Isso é feito com uma porta Hadamard. Um passo semelhante é necessário para medições ao longo de yy. Os passos necessários são reunidos aqui para conveniência:

  • Para medir ao longo de zz: qc.measure()
  • Para medir ao longo de xx: qc.h() e depois qc.measure()
  • Para medir ao longo de yy: qc.sdg(), qc.h(), qc.s e depois qc.measure()

Etapa 1: Mapear entradas clássicas para um problema quântico

Neste caso, a etapa de mapeamento consiste simplesmente em expressar as medições e rotações descritas acima em um circuito quântico:

# Step 1: Map

# Import some general packages
from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister

# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(2, "c")
qc = QuantumCircuit(qr, cr)

# Add a first measurement
qc.measure(qr, cr[0])
qc.barrier()

# Change basis so that measurements made on quantum computer which normally tell us about z, now tell us about x.
qc.h(qr)

# Add a second measurement
qc.measure(qr, cr[1])

qc.draw("mpl")

Saída da célula de código anterior

Etapa 2: Otimizar o problema para execução quântica

Esta etapa pega as operações que queremos realizar e as expressa em termos da funcionalidade de um computador quântico específico. Ela também mapeia nosso problema para o layout do computador quântico.

# Step 2: Transpile
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager

target = backend.target
pm = generate_preset_pass_manager(target=target, optimization_level=3)

qc_isa = pm.run(qc)

Etapa 3: Executar usando os Primitivos do Qiskit Runtime

Podemos usar o Sampler para coletar estatísticas sobre as medições. Vamos construir o primitivo Sampler para executar em um computador quântico real usando mode = backend. Existem outros modos para outros fluxos de trabalho, e usaremos um deles abaixo. O Sampler será usado chamando seu método run() com uma lista de "pubs" (Primitive Unified Blocs). Cada pub contém até três valores que, juntos, definem uma unidade de trabalho computacional para o estimador completar: circuitos, observáveis, parâmetros. Você também pode fornecer uma lista de circuitos, uma lista de observáveis e uma lista de parâmetros. Para mais informações, leia a Visão geral dos PUBs.

Queremos executar em um computador quântico real, para que estejamos realizando um experimento real de física quântica. Se você esgotar o tempo alocado em computadores quânticos reais, pode comentar o código abaixo para o computador quântico e descomentar o código para execução em um simulador.

# Step 3: Run the job on a real quantum computer

sampler = Sampler(mode=backend)
pubs = [qc_isa]
job = sampler.run(pubs)
res = job.result()

counts = res[0].data.c.get_counts()

# Run the job on the Aer simulator with noise model from real backend

# job = noisy_sampler.run([qc_isa])
# res=job.result()
# counts=res[0].data.c.get_counts()

Etapa 4: Pós-processamento

Este é um caso especialmente simples de pós-processamento, no qual simplesmente visualizamos as contagens.

Observe que o Qiskit ordena qubits, medições e outras coisas listando o item de menor número por último / à direita, uma convenção chamada de "little-endian". Isso significa que a coluna abaixo rotulada como "10" refere-se às contagens em que a primeira medição resultou em "0" e a segunda medição resultou em "1".

# Step 4: Post-process

from qiskit.visualization import plot_histogram

plot_histogram(counts)

Saída da célula de código anterior

Se essa convenção não for conveniente para você, pode usar marginal_counts para visualizar os resultados de cada medição separadamente:

from qiskit.result import marginal_counts

plot_histogram(
marginal_counts(counts, indices=[0]), title="Counts after first measurement"
)

Saída da célula de código anterior

plot_histogram(
marginal_counts(counts, indices=[1]), title="Counts after second measurement"
)

Saída da célula de código anterior

Por padrão, os estados no Qiskit são inicializados no estado 0|0\rangle. Portanto, não é surpresa que quase todas as primeiras medições tenham resultado em 0|0\rangle. Observe, no entanto, que houve uma divisão quase igual na segunda medição (aquela que fornece informações sobre as projeções do estado em xx). Parece que esse estado, que nos dá um resultado muito previsível de medições ao longo de zz, nos dá um conjunto muito imprevisível de resultados para medições ao longo de xx. Vamos explorar isso.

O que acontece se fizermos as medições na ordem inversa? Poderíamos começar usando a porta Hadamard para obter estatísticas sobre a probabilidade de 0|0\rangle ser medido em ±x|\pm\rangle_x. Depois, para a segunda medição, voltaremos à base zz usando uma segunda porta Hadamard.

# Step 1:

# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(2, "c")
qc = QuantumCircuit(qr, cr)

# Change basis to measure along x.
qc.h(qr)
qc.measure(qr, cr[0])
qc.barrier()

# Change our basis back to z and make a second measurement
qc.h(qr)
qc.measure(qr, cr[1])

qc.draw("mpl")

Saída da célula de código anterior

# Step 2: Transpile the circuit for running on a quantum computer

pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
# Step 3: Run the job on a real quantum computer

sampler = Sampler(mode=backend)
pubs = [qc_isa]
job = sampler.run(pubs)
res = job.result()
counts = res[0].data.c.get_counts()

# Run the job on the Aer simulator with noise model from real backend
# job = noisy_sampler.run([qc_isa])
# res=job.result()
# counts=res[0].data.c.get_counts()
# Step 4: Post-process
from qiskit.visualization import plot_histogram

plot_histogram(counts)

Saída da célula de código anterior

Aqui, parece que temos ainda menos previsibilidade! Anteriormente, pelo menos sabíamos qual seria o resultado da primeira medição; agora temos uma distribuição bastante uniforme por todos os estados possíveis. Não é difícil ver por que isso aconteceu. Começamos no estado 0|0\rangle, que é uma mistura 50-50 de +x|+\rangle_x e x|-\rangle_x, de acordo com 0=12(+x+x)|0\rangle=\frac{1}{\sqrt{2}}(|+\rangle_x+|-\rangle_x) Portanto, claramente deve haver igual probabilidade de obter o estado + ou - (mapeados para 0 e 1 no gráfico) para a primeira medição. A medição ao longo de xx colapsa o estado para um autoestado +x|+\rangle_x ou para o autoestado x|-\rangle_x. Cada um desses estados é uma mistura 50-50 de 0|0\rangle e 1|1\rangle, de acordo com +x=12(0+1)|+\rangle_x = \frac{1}{\sqrt{2}}(|0\rangle+|1\rangle) x=12(01)|-\rangle_x = \frac{1}{\sqrt{2}}(|0\rangle-|1\rangle) Portanto, uma vez que o sistema esteja em um autoestado de xx, claramente as medições ao longo de zz produzirão tanto 0|0\rangle quanto 1|1\rangle, e o farão com probabilidade aproximadamente igual. Assim, nosso primeiro exemplo nos mostrou que alguns estados terão resultados muito previsíveis para algumas medições, mas resultados imprevisíveis para outras. O exemplo atual nos mostra que podemos ter um desempenho pior do que isso. Há estados que podem nos dar resultados imprevisíveis para ambas as medições, mesmo que tudo o que façamos seja trocar a ordem das medições. Vamos investigar o quão certa ou incerta é uma grandeza para um dado estado.

Calculando a incerteza

Podemos quantificar isso usando incerteza, ou variância. A "incerteza" é frequentemente definida como a raiz quadrada da "variância" de uma distribuição. Ou seja, a incerteza de um observável SS é denotada por ΔS\Delta S e é dada por

(ΔS)2(SS)2(ΔS)2=S22SS+S2(ΔS)2=S2S2\begin{aligned} (\Delta S)^2 & \equiv \langle (S - \langle S \rangle)^2 \rangle\\ (\Delta S)^2 & = \langle S^2 - 2 S \langle S \rangle +\langle S \rangle^2 \rangle\\ (\Delta S)^2 & = \langle S^2 \rangle - \langle S \rangle^2 \end{aligned}

Para o caso das matrizes de Pauli, para as quais S2=IS^2 = I, isso se torna

(ΔS)2=1S2(\Delta S)^2 = 1 - \langle S \rangle^2

Vamos aplicar isso a um exemplo concreto. Vamos começar com o estado ψ=+y=12(1i),|\psi\rangle = |+\rangle_y = \frac{1}{\sqrt{2}}\begin{pmatrix} 1 \\ i \end{pmatrix}, e determinar a incerteza do observável XX nesse estado.

Verifique seu entendimento

Leia a pergunta abaixo, pense na sua resposta e depois clique no triângulo para revelar a solução.

Calcule a incerteza de XX no estado +y=+i|+\rangle_y = |+i\rangle, à mão.

Resposta:

ΔX=+iX2+i+iX+i2\Delta X =\sqrt{\langle+i| X^2 |+i\rangle - \langle+i| X |+i\rangle^2}

No estado dado, isso resulta em:

ΔX=12(1i)(0110)(0110)12(1i)(12(1i)(0110)12(1i))2ΔX=12(1i)(1001)(1i)(12(1i)(i1))2ΔX=12(1i)(1i)(12(0)))2ΔX=12(2)=1\begin{aligned} \Delta X & =\sqrt{\frac{1}{\sqrt{2}}\begin{pmatrix}1 & -i\end{pmatrix} \begin{pmatrix}0 & 1 \\ 1 & 0\end{pmatrix} \begin{pmatrix}0 & 1 \\ 1 & 0\end{pmatrix} \frac{1}{\sqrt{2}}\begin{pmatrix}1 \\ i\end{pmatrix} - \left(\frac{1}{\sqrt{2}}\begin{pmatrix}1 & -i\end{pmatrix} \begin{pmatrix}0 & 1 \\ 1 & 0\end{pmatrix} \frac{1}{\sqrt{2}}\begin{pmatrix}1 \\ i\end{pmatrix}\right)^2}\\ \Delta X & =\sqrt{\frac{1}{2}\begin{pmatrix}1 & -i\end{pmatrix} \begin{pmatrix}1 & 0 \\ 0 & 1\end{pmatrix} \begin{pmatrix}1 \\ i\end{pmatrix} - \left(\frac{1}{2}\begin{pmatrix}1 & -i\end{pmatrix} \begin{pmatrix}i \\ 1\end{pmatrix}\right)^2}\\ \Delta X & =\sqrt{\frac{1}{2}\begin{pmatrix}1 & -i\end{pmatrix} \begin{pmatrix}1 \\ i\end{pmatrix} - \left(\frac{1}{2}(0))\right)^2}\\ \Delta X & =\sqrt{\frac{1}{2}(2)} = 1 \end{aligned}

Podemos criar um estado inicial arbitrário usando qc.initialize(). Note que a sintaxe para a unidade imaginária aqui é 1j1j.

# Step 1: Map the problem into a quantum circuit

from qiskit.quantum_info import SparsePauliOp
import numpy as np

obs = SparsePauliOp("X")

# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(1, "c")
qc = QuantumCircuit(qr, cr)

# Initialize the state
qc.initialize([1, 1j] / np.sqrt(2))

# Step 2: Transpile the circuit

pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
obs_isa = obs.apply_layout(layout=qc_isa.layout)

# Step 3: Run the circuit on a real quantum computer

estimator = Estimator(mode=backend)
pubs = [(qc_isa, obs_isa)]
job = estimator.run([[qc_isa, obs_isa]])
res = job.result()

# Run the job on the Aer simulator with noise model from real backend
# job = noisy_estimator.run([[qc_isa,obs_isa]])
# res=job.result()

# Step 4: Return the result in classical form, and analyze.

print(res[0].data.evs)
-0.02408454165642664

De acordo com nossa equação acima, (ΔX)2=1X2=1(0.0015...)2ΔX=0.999...(\Delta X)^2 = 1 - \langle X \rangle^2 = 1-(0.0015...)^2 \rightarrow \Delta X = 0.999... Vamos manter o mesmo estado, mas agora encontrar o valor esperado de ZZ:

# Step 1: Map the problem into a quantum circuit

obs = SparsePauliOp("Z")

# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(1, "c")
qc = QuantumCircuit(qr, cr)

# Initialize the state to |+>_y
qc.initialize([1, 1j] / np.sqrt(2))

# Step 2: Transpile the circuit

pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
obs_isa = obs.apply_layout(layout=qc_isa.layout)

# Step 3: Run the circuit on a real quantum computer

estimator = Estimator(mode=backend)
pubs = [(qc_isa, obs_isa)]
job = estimator.run(pubs)
res = job.result()

# Run the job on the Aer simulator with noise model from real backend
# job = noisy_estimator.run([[qc_isa,obs_isa]])
# res=job.result()

# Step 4: Return the result in classical form, and analyze.

print(res[0].data.evs)
0.04958271968581247

Poderíamos fazer a mesma matemática de antes, mas veríamos que a variância novamente ficaria muito próxima de 1,0. Poderíamos concluir que ΔXΔZ1.0\Delta X \Delta Z \approx 1.0. De fato, isso é aproximadamente correto para o estado que escolhemos. Mas será que podemos fazer melhor? Ou pior?

Lembre-se de que existe uma relação de incerteza entre a posição ao longo de uma direção, x,x, e o momento ao longo da mesma direção, px.p_x. Para essas variáveis, a forma mais familiar é provavelmente ΔxΔpx/2\Delta x \Delta p_x \geq \hbar/2 Se é tudo o que lembramos, poderíamos ser tentados a pensar que ΔX\Delta X e ΔZ\Delta Z também poderiam ter tal limite fundamental sobre a incerteza. Talvez seja impossível que o produto ΔXΔZ\Delta X \Delta Z chegue a zero? Vamos tentar outro estado e ver se isso se mantém. Desta vez, usaremos ψ=12(11).|\psi\rangle = \frac{1}{\sqrt{2}}\begin{pmatrix} 1 \\ 1 \end{pmatrix}. Vamos ver o que acontece. Note que no código abaixo, o estimator pode aceitar dois conjuntos de circuitos e observáveis na mesma submissão de job.

# Step 1: Map the problem into a quantum circuit

obs1 = SparsePauliOp("X")
obs2 = SparsePauliOp("Z")

# Define registers

qr = QuantumRegister(1, "q")
cr = ClassicalRegister(1, "c")
qc = QuantumCircuit(qr, cr)

# Initialize the state
qc.initialize([1, 1] / np.sqrt(2))

# Step 2: Transpile the circuit

pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
obs1_isa = obs1.apply_layout(layout=qc_isa.layout)
obs2_isa = obs2.apply_layout(layout=qc_isa.layout)

# Step 3: Run the circuit on a real quantum computer

with Batch(backend=backend) as batch:
estimator = Estimator(mode=batch)
pubs = [(qc_isa, obs1_isa), (qc_isa, obs2_isa)]
job = estimator.run(pubs)
res = job.result()
batch.close()

# Run the job on the Aer simulator with noise model from real backend

# job = noisy_estimator.run([[qc,obs1],[qc,obs2]])
# res=job.result()

# Step 4: Return the result in classical form, and analyze.

print("The expectation value of the first observable is: ", res[0].data.evs)
print("The expectation value of the second observable is: ", res[1].data.evs)
The expectation value of the first observable is:  1.0011036174126302
The expectation value of the second observable is: 0.0029429797670141016

O valor esperado de XX deve ser próximo de 1,0, mas não deve exceder 1,0. Não se preocupe se ultrapassar 1,0 por uma quantidade muito pequena. Isso pode ser atribuído a fatores como ruído e/ou erro de leitura. Embora esse seja um tema muito importante, podemos ignorá-lo por ora.

Obtivemos um valor esperado de XX muito próximo de 1,0 (correspondendo a uma variância muito baixa para XX). Isso faz com que o produto das duas variâncias seja bastante pequeno:

ΔXΔZ=1(0.9853)2×1(0.00195)2=0.171.\Delta X \Delta Z = \sqrt{1-(0.9853)^2} \times \sqrt{1-(-0.00195)^2} = 0.171.

Embora esse valor não seja exatamente zero, ele está ficando pequeno em comparação com os autovalores dos operadores de Pauli (±1\pm 1). Bem, você pode se lembrar de que a relação de incerteza entre posição linear e momento poderia ser escrita de forma diferente, usando explicitamente a relação de comutação entre os operadores xx e pxp_x:

ΔxΔpx12[x,px]\Delta x \Delta p_x \geq \frac{1}{2}|\langle [x,p_x] \rangle|

onde

[x,px]=xpxpxx[x,p_x] = xp_x-p_xx

é o comutador de xx e pxp_x.

Esta é a forma que pode ser mais facilmente estendida aos operadores de Pauli. De forma geral, para dois operadores AA e BB,

ΔAΔB12[A,B].\Delta A \Delta B \geq \frac{1}{2}|\langle [A,B] \rangle|.

E no caso das matrizes de Pauli XX e ZZ, precisamos de [X,Z][X,Z] para calcular

ΔXΔZ12[X,Z].\Delta X \Delta Z \geq \frac{1}{2}|\langle [X,Z] \rangle|.

Mostramos isso aqui e deixamos cálculos semelhantes para o leitor como exercício:

[X,Z]=XZZX=(0110)(1001)(1001)(0110)[X,Z] = XZ-ZX = \begin{pmatrix}0 & 1 \\ 1 & 0\end{pmatrix}\begin{pmatrix}1 & 0 \\ 0 & -1\end{pmatrix}-\begin{pmatrix}1 & 0 \\ 0 & -1\end{pmatrix}\begin{pmatrix}0 & 1 \\ 1 & 0\end{pmatrix} [X,Z]=(0110)(0110)=2(0110)[X,Z] = \begin{pmatrix}0 & -1 \\ 1 & 0\end{pmatrix}-\begin{pmatrix}0 & 1 \\ -1 & 0\end{pmatrix} = 2\begin{pmatrix}0 & -1 \\ 1 & 0\end{pmatrix}

Esta é uma resposta perfeitamente aceitável, mas com mais um passo, vemos

[X,Z]=2i(0ii0)=2iY[X,Z] = -2i\begin{pmatrix}0 & -i \\ i & 0\end{pmatrix}=-2iY

Nossa relação de incerteza se torna então

ΔXΔZY.\Delta X \Delta Z \geq |\langle Y \rangle|.

Verifique seu entendimento

Leia a pergunta abaixo, pense na sua resposta e depois clique no triângulo para revelar a solução.

Determine [X,Y][X,Y] e [Y,Z][Y,Z]. Use isso para escrever as relações de incerteza entre XX e YY, e entre YY e ZZ.

Resposta:

[X,Y]=XYYX=(0110)(0ii0)(0ii0)(0110)=2(i00i)=2iZ[X,Y] = XY-YX = \begin{pmatrix}0 & 1 \\ 1 & 0\end{pmatrix}\begin{pmatrix}0 & -i \\ i & 0\end{pmatrix}-\begin{pmatrix}0 & -i \\ i & 0\end{pmatrix}\begin{pmatrix}0 & 1 \\ 1 & 0\end{pmatrix} = 2 \begin{pmatrix}i & 0 \\ 0 & -i\end{pmatrix}=2iZ[Y,Z]=YZZY=(0ii0)(1001)(1001)(0ii0)=2(0ii0)=2iX[Y,Z] = YZ-ZY = \begin{pmatrix}0 & -i \\ i & 0\end{pmatrix}\begin{pmatrix}1 & 0 \\ 0 & -1\end{pmatrix}-\begin{pmatrix}1 & 0 \\ 0 & -1\end{pmatrix}\begin{pmatrix}0 & -i \\ i & 0\end{pmatrix} = 2 \begin{pmatrix}0 & i \\ i & 0\end{pmatrix}=2iX

Combinando com a relação de incerteza geral, temos

ΔXΔYZ,\Delta X \Delta Y \geq |\langle Z \rangle|,ΔYΔZX.\Delta Y \Delta Z \geq |\langle X \rangle|.

Verificar consistência

Antes de prosseguir, vamos verificar se isso foi consistente com o que encontramos anteriormente. Usamos o estado ψ=12(11).|\psi\rangle = \frac{1}{\sqrt{2}}\begin{pmatrix} 1 \\ 1 \end{pmatrix}. E encontramos que ΔXΔZ=0.171.\Delta X \Delta Z = 0.171. Agora sabemos que esse produto deve ser maior ou igual a

Y=12(11)(0ii0)12(11)|\langle Y \rangle|=\frac{1}{\sqrt{2}}\begin{pmatrix} 1 & 1 \end{pmatrix}\begin{pmatrix}0 & -i \\ i & 0\end{pmatrix}\frac{1}{\sqrt{2}}\begin{pmatrix} 1 \\ 1 \end{pmatrix} Y=12(11)(ii)=12(i+i)=0.|\langle Y \rangle| = \frac{1}{2}\begin{pmatrix} 1 & 1 \end{pmatrix}\begin{pmatrix} -i \\ i \end{pmatrix} = \frac{1}{2}(-i+i) = 0.

Portanto, de fato, ΔXΔZ=0.171Y=0\Delta X \Delta Z = 0.171 \geq |\langle Y \rangle|=0

Use as perguntas abaixo para desenvolver intuição sobre esses resultados:

Verifique seu entendimento

Leia as perguntas abaixo, pense nas suas respostas e depois clique nos triângulos para revelar as soluções.

Responda aos itens a seguir em conjunto:

(a) Quais estados você esperaria ter incerteza zero em XX?

(b) Quais estados você esperaria ter incerteza zero em ZZ?

(c) Em quais estados você obteria um valor esperado zero Y\langle Y \rangle?

(d) As respostas às perguntas acima são consistentes com o caso ΔXΔZY\Delta X \Delta Z \geq |\langle Y \rangle|?

(e) Escreva código para verificar isso explicitamente usando o estimator.

Respostas:

(a) Poderíamos esperar que os autoestados do operador XX resultassem em incerteza zero em XX. De fato, usando ψ=+x,|\psi\rangle = |+\rangle_x, temos ΔX=1X2=112=0.\Delta X = \sqrt{1-\langle X \rangle^2} = \sqrt{1-1^2} = 0.

(b) Poderíamos esperar que os autoestados do operador ZZ resultassem em incerteza zero em ZZ. De fato, usando ψ=1,|\psi\rangle = |1\rangle, temos ΔZ=1Z2=1(1)2=0.\Delta Z = \sqrt{1-\langle Z \rangle^2} = \sqrt{1-(-1)^2} = 0.

(c) Esperamos encontrar Y=0\langle Y \rangle=0 para quaisquer estados que, ao serem medidos, produzam uma projeção positiva no eixo yy com a mesma frequência que uma projeção negativa. Isso inclui os autoestados de XX e ZZ.

(d) Sim. Esperaríamos um valor muito pequeno para o produto das incertezas ΔXΔZ\Delta X \Delta Z para autoestados de XX ou ZZ: ΔXΔZ0.\Delta X \Delta Z \approx 0. Isso pode se manter porque também esperaríamos Y=0\langle Y \rangle=0 para esses mesmos estados. Portanto, a relação de incerteza poderia ser satisfeita.

(e) Um código como o seguinte verificaria isso:

obs1 = SparsePauliOp.from_list(
[("X", 1.000)]
)
obs2 = SparsePauliOp.from_list(
[("Y", 1.000)]
)
obs3 = SparsePauliOp.from_list(
[("Z", 1.000)]
)
qc = QuantumCircuit(1,1)
qc.ry(pi/2,0)

job = estimator.run([(qc, [[obs1], [obs2], [obs3]])], precision=0.001)
res=job.result()

Onde o resultado retorna todos os valores esperados. Para recuperar todos os valores esperados e calcular as incertezas, poderíamos usar:

xs=res[0].data.evs[0]
ys=abs(res[0].data.evs[1])
zs=res[0].data.evs[2]

import math
prodxz=((1-xs[i]*xs[i])**0.5)*(1-zs[i]*zs[i])**0.5

Responda aos itens a seguir em conjunto:

(a) Você consegue pensar em um estado no qual teria um valor esperado grande Y\langle Y \rangle?

(b) Você esperaria que esse mesmo estado tivesse incerteza grande ou pequena em XX?

(c) Você esperaria que esse mesmo estado tivesse incerteza grande ou pequena em ZZ?

(d) As respostas às perguntas acima são consistentes com o caso ΔXΔZY\Delta X \Delta Z \geq |\langle Y \rangle|?

(e) Escreva código para verificar isso explicitamente usando o estimator.

Respostas:

(a) Esperamos encontrar Y1\langle Y \rangle\approx 1 para o autoestado de YY: +y|+\rangle_y.

(b) Poderíamos esperar que XX tivesse grande incerteza no estado +y,|+\rangle_y, já que medir XX nesse estado produziria um resultado positivo e negativo com igual frequência/probabilidade.

(c) Poderíamos esperar que ZZ tivesse grande incerteza no estado +y,|+\rangle_y, já que medir ZZ nesse estado produziria um resultado positivo e negativo com igual frequência/probabilidade.

(d) Sim. Esperaríamos um valor grande para o produto das incertezas ΔXΔZ\Delta X \Delta Z para autoestados de YY, e para +y|+\rangle_y especificamente. Também esperaríamos Y1\langle Y \rangle\approx 1 para esse mesmo estado. Portanto, tanto Y\langle Y \rangle quanto ΔXΔZ\Delta X \Delta Z são bastante grandes nesse estado, e é plausível que a relação de incerteza possa ser satisfeita novamente.

(e) Um código como o seguinte verificaria isso:

obs1 = SparsePauliOp.from_list(
[("X", 1.000)]
)
obs2 = SparsePauliOp.from_list(
[("Y", 1.000)]
)
obs3 = SparsePauliOp.from_list(
[("Z", 1.000)]
)
qc = QuantumCircuit(1,1)
qc.rx(-pi/2,0)

job = estimator.run([(qc, [[obs1], [obs2], [obs3]])], precision=0.001)
res=job.result()

Onde o resultado retorna todos os valores esperados. Para recuperar todos os valores esperados e calcular as incertezas, poderíamos usar:

xs=res[0].data.evs[0]
ys=abs(res[0].data.evs[1])
zs=res[0].data.evs[2]

import math
prodxz=((1-xs[i]*xs[i])**0.5)*(1-zs[i]*zs[i])**0.5

Testando as relações de incerteza

O teste acima demonstrou apenas a validade da relação de incerteza para uma única escolha de vetor de estado ψ=+x|\psi\rangle = |+\rangle_x. Para nos convencer de que isso é geralmente consistente com o experimento, devemos realizar cálculos similares usando o estimador para muitas escolhas de vetor de estado. Vamos começar rotacionando nosso vetor de estado para longe do eixo zz, usando uma porta RY para produzir diferentes estados iniciais com um parâmetro θ\theta.

# The calculation below uses approximately 3-4 minutes of QPU time.
# Step 1: Map the problem into a quantum circuit

from qiskit.circuit import Parameter
import numpy as np

# Specify observables
obs1 = SparsePauliOp("X")
obs2 = SparsePauliOp("Y")
obs3 = SparsePauliOp("Z")

# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(1, "c")
qc = QuantumCircuit(qr, cr)

# Rotate away from |0>
theta = Parameter("θ")
qc.ry(theta, 0)

params = np.linspace(0, 2, num=21)

# Step 2: Transpile the circuit

pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)
obs1_isa = obs1.apply_layout(layout=qc_isa.layout)
obs2_isa = obs2.apply_layout(layout=qc_isa.layout)
obs3_isa = obs3.apply_layout(layout=qc_isa.layout)

# Step 3: Run the circuit on a real quantum computer

with Batch(backend=backend) as batch:
estimator = Estimator(mode=batch)
pubs = [(qc_isa, [[obs1_isa], [obs2_isa], [obs3_isa]], [params])]
job = estimator.run(pubs, precision=0.01)
res = job.result()

batch.close()

# Run the job on the Aer simulator with noise model from real backend

# job = noisy_estimator.run([(qc, [[obs1], [obs2], [obs3]], [params])])
# res=job.result()
# Step 4: Post-processing and classical analysis.
xs = res[0].data.evs[0]
ys = abs(res[0].data.evs[1])
zs = res[0].data.evs[2]

# Calculate uncertainties

delx = []
delz = []
prodxz = []
for i in range(len(xs)):
delx.append(abs((1 - xs[i] * xs[i])) ** 0.5)
delz.append(abs((1 - zs[i] * zs[i])) ** 0.5)
prodxz.append(delx[i] * delz[i])
# Here we can plot the results from this simulation.
import matplotlib.pyplot as plt

plt.plot(params, delx, label=r"$\Delta$ X")
plt.plot(params, ys, label=r"$\langle$ Y $\rangle$")
plt.plot(params, delz, label=r"$\Delta$ Z")
plt.plot(params, prodxz, label=r"$\Delta$X $\Delta$Z")
plt.xlabel(r"$\theta$")
plt.ylabel("Expectation/Uncertainty Values")
plt.legend()
plt.show()

Saída da célula de código anterior

Note que a curva vermelha (ΔXΔZ)(\Delta X \Delta Z) é sempre maior que a curva laranja Y.\langle Y \rangle. Em alguns momentos, o produto das incertezas cai e fica relativamente próximo do limite; em outros, sobe e fica mais distante do limite — mas sempre obedece à relação de incerteza.

É claro que esse pode não ser o melhor teste da relação de incerteza, já que nosso limite Y\langle Y \rangle fica sempre muito próximo de zero. Vamos usar um estado quântico que tenha uma projeção maior nos autoestados de YY. Especificamente, ainda vamos rotacionar 0|0\rangle para longe do eixo zz por ângulos variados, mas agora também vamos rotacionar o estado resultante em torno de zz por algum ângulo, talvez π/4\pi/4, e ver o que acontece.

# The calculation below uses approximately 3-4 minutes of QPU time.
from qiskit.circuit import Parameter
import numpy as np

# Step 1: Map the problem to a quantum circuit

# Specify observables
obs1 = SparsePauliOp("X")
obs2 = SparsePauliOp("Y")
obs3 = SparsePauliOp("Z")

# Define registers
qr = QuantumRegister(1, "q")
cr = ClassicalRegister(1, "c")
qc = QuantumCircuit(qr, cr)

# Rotate away from |0> along one plane, and then along a transverse direction.
theta = Parameter("θ")
qc.ry(theta, 0)
qc.rz(pi / 4, 0)

params = np.linspace(0, 2, num=21)

# Step 2: Transpile the circuit

pm = generate_preset_pass_manager(target=target, optimization_level=3)
qc_isa = pm.run(qc)

obs1_isa = obs1.apply_layout(layout=qc_isa.layout)
obs2_isa = obs2.apply_layout(layout=qc_isa.layout)
obs3_isa = obs3.apply_layout(layout=qc_isa.layout)

# Step 3: Run the circuit on a real quantum computer

with Batch(backend=backend) as batch:
estimator = Estimator(mode=batch)
pubs = [(qc_isa, [[obs1_isa], [obs2_isa], [obs3_isa]], [params])]
job = estimator.run(pubs, precision=0.01)
res = job.result()

batch.close()

# Run the job on the Aer simulator with noise model from real backend

# job = noisy_estimator.run([(qc, [[obs1], [obs2], [obs3]], [params])])
# res=job.result()
# Step 4: Post-processing and classical analysis.
xs = res[0].data.evs[0]
ys = abs(res[0].data.evs[1])
zs = res[0].data.evs[2]

# Calculate uncertainties

delx = []
delz = []
prodxz = []
for i in range(len(xs)):
delx.append(abs((1 - xs[i] * xs[i])) ** 0.5)
delz.append(abs((1 - zs[i] * zs[i])) ** 0.5)
prodxz.append(delx[i] * delz[i])
# Here we can plot the results from this simulation.
import matplotlib.pyplot as plt

plt.plot(params, delx, label=r"$\Delta$ X")
plt.plot(params, ys, label=r"$\langle$ Y $\rangle$")
plt.plot(params, delz, label=r"$\Delta$ Z")
plt.plot(params, prodxz, label=r"$\Delta$X $\Delta$Z")
plt.xlabel(r"$\theta$")
plt.ylabel("Expectation/Uncertainty Values")
plt.legend()
plt.show()

Saída da célula de código anterior

Agora vemos que o limite da incerteza (ΔXΔZ)(\Delta X \Delta Z) está sendo posto à prova! A curva vermelha se aproxima muito mais da curva laranja do que antes. Na verdade, na ausência de ruído, a relação de incerteza seria exatamente saturada ((ΔXΔZ)=Y(\Delta X \Delta Z) = \langle Y \rangle) em um ponto. Na presença de ruído e erro de leitura, não deve surpreender se uma execução ocasionalmente produzir (ΔXΔZ)(\Delta X \Delta Z) levemente maior que Y.\langle Y \rangle. Isso não é uma verdadeira violação da incerteza; é apenas um artefato do erro não nulo.

Verifique sua compreensão

Leia as perguntas abaixo, pense nas suas respostas e depois clique nos triângulos para revelar as soluções.

Como você faria para levar isso ao limite absoluto, tornando Y\langle Y \rangle o maior possível?

Resposta:

O código atualmente possui linhas que rotacionam o estado inicial padrão 0|0\rangle para longe do eixo zz por um ângulo parametrizado θ\theta e, em seguida, também em torno do eixo zz por um ângulo π/4,\pi/4, o que rotaciona o vetor de estado parte do caminho em direção ao eixo yy.

qc.ry(theta,0)

qc.rz(pi/4,0)

Poderíamos mudar a rotação em torno de zz de π/4\pi/4 para π/2\pi/2, rotacionando completamente até um autoestado de YY:

qc.ry(theta,0)

qc.rz(pi/2,0)

Nenhuma outra alteração seria necessária.

Altere o código ou copie-o e implemente essa verificação da relação de incerteza com o valor esperado de Y maximizado. A relação de incerteza é válida?

Resposta:

Usaríamos exatamente o código do exemplo acima, com

qc.rz(pi/2,0)

substituindo

qc.rz(pi/4,0).

O gráfico resultante deve se parecer com o mostrado abaixo e, sim, o princípio da incerteza ainda deve ser válido.

Um gráfico comparando a incerteza ao valor esperado máximo do operador Y.

Modifique o código acima para fazer um gráfico similar, demonstrando que, a partir de medições no computador quântico, o produto ΔXΔY\Delta X \Delta Y se comporta como deveria. Escolha qualquer conjunto de estados que preferir.

Resposta:

Usaríamos exatamente o código do exemplo acima e, de fato, poderíamos usar os mesmos resultados de antes, apenas usando os valores esperados para calcular incertezas diferentes. Por exemplo, poderíamos usar

xs=res[0].data.evs[0]
ys=res[0].data.evs[1]
zs=abs(res[0].data.evs[2])
import math
delx = []
dely = []
prodxy=[]
for i in range(len(xs)):
delx.append((1-xs[i]*xs[i])**0.5)
dely.append((1-ys[i]*ys[i])**0.5)
prodxy.append(((1-xs[i]*xs[i])**0.5)*(1-ys[i]*ys[i])**0.5)

e poderíamos plotar

import matplotlib.pyplot as plt
plt.plot(params, delx, label=r'$\Delta$ X')
plt.plot(params, dely, label=r'$\langle$ Y $\rangle$')
plt.plot(params, zs, label=r'$\Delta$ Z')
plt.plot(params, prodxy, label=r'$\Delta$X $\Delta$Z')
plt.xlabel(r'$\theta$')
plt.ylabel('Expectation/Uncertainty Values')
plt.legend()
plt.show()

Desafio: Escreva um código para varrer muitos valores de ϕ\phi, assim como varremos muitos valores de θ\theta, e faça um gráfico 3D mostrando que a relação de incerteza nunca é violada. Escolha quaisquer observáveis que preferir.

Questões

Instrutores podem solicitar versões desses notebooks com gabaritos e orientações sobre como inseri-los em currículos comuns preenchendo esta pesquisa rápida sobre como os notebooks estão sendo utilizados.

Conceitos fundamentais:

  • Existem relações de incerteza entre muitos conjuntos de observáveis físicos, incluindo posição e momento linear, e componentes de spin.
  • As matrizes de Pauli não comutam. Isso é um reflexo matemático do fato de que nem todos os componentes do spin podem ser simultaneamente conhecidos/determinados.
  • A computação quântica faz uso intenso dos operadores/matrizes de Pauli, portanto é útil conhecer a relação de incerteza para os operadores de Pauli, bem como os operadores de spin intimamente relacionados.
  • Uma fórmula geral para a incerteza de dois operadores AA e BB é ΔAΔB12[A,B].\Delta A \Delta B \geq \frac{1}{2}|\langle [A,B] \rangle|.
  • Um autoestado a|a\rangle de algum operador AA produz incerteza zero no observável físico associado a esse operador. Mesmo experimentalmente, aAa0.\langle a|A|a\rangle \approx 0.
  • Um autoestado a|a\rangle de algum operador AA produzirá uma incerteza maior para um operador BB que não comuta com AA.
  • Resultados experimentais usando um computador quântico real confirmam a intuição que obtemos das representações matriciais dos operadores físicos.

Questões V/F:

  1. V/F É possível medir XX e YY simultaneamente, mas não ZZ.
  2. V/F É possível medir XX e ZZ simultaneamente, mas não YY.
  3. V/F Os operadores de posição linear e momento linear não comutam.
  4. V/F Os computadores quânticos da IBM medem ao longo de ZZ por padrão, portanto uma rotação deve ser realizada para medir ao longo de qualquer outra direção.
  5. V/F O circuito abaixo efetivamente mede ZZ e depois XX.

Um diagrama de circuito mostrando uma medição, uma porta Hadamard e depois outra medição.

Questões de múltipla escolha:

  1. O diagrama abaixo demonstra qual das seguintes relações de incerteza?

    • a. ΔXΔYZ\Delta X \Delta Y \geq |\langle Z \rangle|
    • b. ΔYΔZX\Delta Y \Delta Z \geq |\langle X \rangle|
    • c. ΔZΔXY\Delta Z \Delta X \geq |\langle Y \rangle|
    • d. Nenhuma das anteriores

Um gráfico comparando a incerteza ao valor esperado máximo do operador Y.

  1. Qual das alternativas a seguir representa a sequência padrão para realizar uma medição ao longo de xx?

    • a. Apenas qc.measure()
    • b. qc.h() e depois qc.measure()
    • c. qc.h(), qc.h() e depois qc.measure()
    • d. qc.h(), qc.s, qc.h() e depois qc.measure()
    • e. qc.sdg(), qc.h(), qc.s e depois qc.measure()
    • f. qc.sdg(), qc.h(), qc.s, qc.h() e depois qc.measure()
  2. Qual dos seguintes estados produz o maior valor esperado X\langle X \rangle?

    • a. +x|+\rangle_x
    • b. x|-\rangle_x
    • c. +y|+\rangle_y também chamado de +i|+i\rangle
    • d. y|-\rangle_y também chamado de i|-i\rangle
    • e. 0|0\rangle também chamado de |\uparrow\rangle
    • f. 1|1\rangle também chamado de |\downarrow\rangle
  3. Qual dos seguintes estados produz a maior incerteza ΔX\Delta X?

    • a. +x|+\rangle_x
    • b. +y|+\rangle_y também chamado de +i|+i\rangle
    • c. 0|0\rangle também chamado de |\uparrow\rangle
    • d. a e b estão empatados
    • e. b e c estão empatados
    • f. a, b e c estão empatados

Questões para discussão:

  1. Esse conceito de incerteza entra em conflito de alguma forma com a noção de spin como uma seta vetorial no espaço cartesiano? E na esfera de Bloch?

  2. Suponha que você oriente um dispositivo de medição ao longo de uma direção a meio caminho entre os eixos xx e yy. O que acontece? Você consegue fazer uma medição nessa direção? Como isso se relaciona com a incerteza em XX e YY?