Saltar al contenido principal

Explorando la incertidumbre

Para este módulo de Qiskit en el aula, los estudiantes deben tener un entorno de Python funcional con los siguientes paquetes instalados:

  • qiskit v2.1.0 o más reciente
  • qiskit-ibm-runtime v0.40.1 o más reciente
  • qiskit-aer v0.17.0 o más reciente
  • qiskit.visualization
  • numpy
  • pylatexenc

Para configurar e instalar los paquetes anteriores, consulta la guía Instalar Qiskit. Para ejecutar trabajos en ordenadores cuánticos reales, los estudiantes deberán crear una cuenta en IBM Quantum® siguiendo los pasos de la guía Configura tu cuenta de IBM Cloud.

Este módulo fue probado y utilizó 8 minutos de tiempo de QPU. Esta es solo una estimación; tu uso real puede variar. Dos cálculos que consumen más tiempo están marcados como tales en los comentarios de cabecera y pueden ejecutarse en simuladores si los estudiantes tienen poco tiempo de QPU. Sin ellos, el módulo requiere solo ~30 segundos de tiempo 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'

Mira el recorrido del módulo por la Dra. Katie McCormick a continuación, o haz clic aquí para verlo en YouTube.


Introducción

Probablemente hayas oído hablar del principio de incertidumbre, incluso fuera de tus clases de física. Una reformulación coloquial habitual de la incertidumbre es "Al observar algo, lo influyes." Eso es cierto, sin duda. Pero una forma más física de describir la incertidumbre es que existen ciertas observables físicas con una incompatibilidad que les impide ser conocidas simultáneamente con precisión arbitraria. Muchos estudiantes encuentran por primera vez el par de variables incompatibles xx y pxp_x, es decir, la posición a lo largo de un eje llamado eje xx y el momento lineal a lo largo de esa dirección, respectivamente. Para esas variables, la restricción sobre la incertidumbre se escribe ΔxΔpx2.\Delta x \Delta p_x \geq \frac{\hbar}{2}. Aquí, Δx\Delta x se llama "incertidumbre en xx", que tiene la misma definición que la desviación estándar en estadística, y puede definirse como Δx=x2x2.\Delta x = \sqrt{\langle x^2 \rangle - \langle x \rangle^2}. Δpx\Delta p_x se define de la misma manera. No derivaremos aquí esta relación de incertidumbre; señalaremos que es consistente con nuestra comprensión de las ondas clásicas. Es decir, una onda con verdaderamente una sola frecuencia perfecta ff y longitud de onda λ\lambda se extendería indefinidamente como un seno perfecto. Cuánticamente, esto correspondería a conocer el momento de manera perfecta según la hipótesis de De Broglie: λ=h/p\lambda = h/p. Pero para saber doˊndedónde está localizada una partícula ondulatoria, la onda que la describe debe volverse más pronunciada en el espacio, como una gaussiana muy estrecha, por ejemplo. Sabemos que podemos expresar cualquier función continua, incluidas tales funciones de onda muy pronunciadas, como una serie de Fourier de funciones sinusoidales con distintas longitudes de onda. Pero a medida que la función de onda se vuelve más pronunciada (y la posición se conoce mejor), necesitaremos más términos en la serie de Fourier, lo que significa una mezcla de más longitudes de onda (y por lo tanto, cuánticamente, más valores de momento).

Dicho de manera más simple: un estado con momento bien definido (un seno perfecto en el espacio) tiene una posición muy incierta. Un estado con posición bien definida (como una distribución delta de Dirac) tiene un momento muy incierto.

Hay otras variables que presentan dicha incompatibilidad. Por ejemplo, la proyección del espín de una partícula puede estar bien definida a lo largo de un eje, pero entonces no sabemos nada sobre la proyección en un eje ortogonal. Por ejemplo, el estado 0|0\rangle \sim |\uparrow\rangle (para un qubit o una partícula de espín-1/2) tiene una proyección definida a lo largo del eje zz (de 1 en el contexto de un qubit, y de /2\hbar/2 en el contexto de una partícula de espín-1/2). Pero este estado puede escribirse como una superposición de dos estados, cada uno con una proyección bien definida sobre el eje xx: 0=12(+x+x)|0\rangle = \frac{1}{\sqrt{2}}(|+\rangle_x+|-\rangle_x) o de manera equivalente (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 tiene una proyección bien definida sobre xx, igual que x|-\rangle_x. Así que si especificamos la proyección de un estado sobre el eje xx, no conocemos la proyección sobre el eje zz. Y si especificamos la proyección sobre el eje zz, no conocemos la proyección sobre xx. Existen diferencias menores al tratar esto en el contexto del espín y en el de los qubits. Pero en general, los autoestados de las matrices de Pauli tienen una relación interesante que podemos explorar. A lo largo de esta lección, verificaremos experimentalmente nuestra intuición sobre la incertidumbre en estas variables incompatibles, y comprobaremos que las relaciones de incertidumbre se cumplen en los ordenadores cuánticos de IBM®.

Comprobación sencilla de la intuición

En este primer experimento y a lo largo del módulo, usaremos un marco de trabajo para la computación cuántica conocido como "patrones de Qiskit", que divide los flujos de trabajo en los siguientes pasos:

  • Paso 1: Mapear las entradas clásicas a un problema cuántico
  • Paso 2: Optimizar el problema para su ejecución cuántica
  • Paso 3: Ejecutar usando las primitivas de Qiskit Runtime
  • Paso 4: Posprocesamiento y análisis clásico

En general seguiremos estos pasos, aunque no siempre los etiquetaremos explícitamente.

Empecemos cargando algunos paquetes necesarios, incluidas las primitivas de Runtime. También seleccionaremos el ordenador cuántico menos ocupado disponible.

El código de abajo incluye instrucciones para guardar tus credenciales la primera vez que lo uses. Asegúrate de eliminar esa información del notebook después de guardarla en tu entorno, para que tus credenciales no se compartan accidentalmente al compartir el notebook. Consulta Configura tu cuenta de IBM Cloud e Inicializa el servicio en un entorno no confiable para más orientación.

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

Si un estudiante agota su tiempo disponible de computación cuántica durante la lección, las líneas siguientes pueden descomentarse y usarse para configurar un simulador que imita parcialmente el comportamiento de ruido del ordenador cuántico seleccionado anteriormente.

# 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}})

Puede que recuerdes que un autoestado de un operador, Z, no es un autoestado de otro operador X. Lo observaremos ahora, experimentalmente, realizando medidas a lo largo de los ejes xx y zz. Para la medida a lo largo de zz, simplemente usamos qc.measure(), porque los ordenadores cuánticos de IBM están diseñados para medir a lo largo de zz. Pero para medir a lo largo de xx, debemos rotar el sistema para llevar efectivamente el eje xx a la orientación sobre la que se mide. Esto se logra con una puerta Hadamard. Se requiere un paso similar para las medidas a lo largo de yy. Los pasos necesarios se recogen aquí para mayor comodidad:

  • Para medir a lo largo de zz: qc.measure()
  • Para medir a lo largo de xx: qc.h() y luego qc.measure()
  • Para medir a lo largo de yy: qc.sdg(), qc.h(), qc.s y luego qc.measure()

Paso 1: Mapear las entradas clásicas a un problema cuántico

En este caso, el paso de mapeo consiste simplemente en expresar las medidas y rotaciones descritas anteriormente en un circuito cuá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")

Salida de la celda de código anterior

Paso 2: Optimizar el problema para su ejecución cuántica

Este paso toma las operaciones que queremos realizar y las expresa en términos de la funcionalidad de un ordenador cuántico específico. También mapea nuestro problema al diseño del ordenador cuá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)

Paso 3: Ejecutar usando las primitivas de Qiskit Runtime

Podemos usar el Sampler para recopilar estadísticas de las medidas. Construiremos la primitiva Sampler para ejecutarse en un ordenador cuántico real usando mode = backend. Existen otros modos para otros flujos de trabajo, y usaremos uno más adelante. El Sampler se invoca llamando a su método run() con una lista de "pubs" (Primitive Unified Blocs). Cada pub contiene hasta tres valores que, juntos, definen una unidad de trabajo que el estimador debe completar: circuitos, observables, parámetros. También puedes proporcionar una lista de circuitos, una lista de observables y una lista de parámetros. Para más información, consulta la Descripción general de los PUBs.

Queremos ejecutarlo en un ordenador cuántico real para llevar a cabo un experimento de física cuántica real. Si agotás tu tiempo asignado en ordenadores cuánticos reales, puedes comentar el código de abajo para el ordenador cuántico y descomentar el código para ejecutar en un 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()

Paso 4: Posprocesamiento

Este es un caso especialmente simple de posprocesamiento, en el que simplemente visualizamos los conteos.

Ten en cuenta que Qiskit ordena los qubits, las medidas y otros elementos listando el de número más bajo al final / a la derecha, una convención conocida como "little-endian". Esto significa que la columna etiquetada como "10" a continuación se refiere a los conteos donde la primera medida dio "0" y la segunda medida dio "1".

# Step 4: Post-process

from qiskit.visualization import plot_histogram

plot_histogram(counts)

Salida de la celda de código anterior

Si esta convención no te convence, puedes usar marginal_counts para visualizar los resultados de cada medida por separado:

from qiskit.result import marginal_counts

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

Salida de la celda de código anterior

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

Salida de la celda de código anterior

Por defecto, los estados en Qiskit se inicializan al estado 0|0\rangle. Así que no sorprende que casi todas las primeras medidas hayan dado 0|0\rangle. Sin embargo, observa que hubo una división casi equitativa en la segunda medida (la que proporciona información sobre las proyecciones del estado sobre xx). Parece que este estado, que nos da un resultado muy predecible de las medidas a lo largo de zz, nos da un conjunto muy impredecible de resultados para las medidas a lo largo de xx. Exploremos esto.

¿Qué ocurre si realizamos las medidas en el orden opuesto? Podríamos empezar usando la puerta Hadamard para obtener estadísticas sobre la probabilidad de que 0|0\rangle se mida en ±x|\pm\rangle_x. Luego, para la segunda medida, volveríamos a la base zz usando una segunda puerta 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")

Salida de la celda 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)

Salida de la celda de código anterior

Aquí, ¡parece que tenemos aún menos predecibilidad! Antes, al menos sabíamos cuál sería el resultado de la primera medida; ahora tenemos una distribución bastante uniforme entre todos los estados posibles. No es difícil entender por qué ocurrió esto. Empezamos en 0|0\rangle, que es una mezcla 50-50 de +x|+\rangle_x y x|-\rangle_x, según 0=12(+x+x)|0\rangle=\frac{1}{\sqrt{2}}(|+\rangle_x+|-\rangle_x) Así que claramente debe haber igual probabilidad de obtener el estado + o - (mapeados a 0 y 1 en el gráfico) en la primera medida. La medida a lo largo de xx colapsa el estado hacia un autoestado +x|+\rangle_x o el autoestado x|-\rangle_x. Cada uno de esos estados es una mezcla 50-50 de 0|0\rangle y 1|1\rangle, según +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) Así que una vez que el sistema está en un autoestado de xx, claramente las medidas a lo largo de zz darán tanto 0|0\rangle como 1|1\rangle, y lo harán con probabilidad aproximadamente igual. Nuestro primer ejemplo nos mostró que algunos estados tendrán resultados muy predecibles para ciertas medidas, pero impredecibles para otras. El ejemplo actual nos muestra que podemos ir más allá. Hay estados que pueden darnos resultados impredecibles para ambas medidas, aunque lo único que hagamos sea invertir el orden de las medidas. Investiguemos qué tan cierta o incierta es una magnitud para un estado dado.

Calculando la incertidumbre

Podemos cuantificar esto usando la incertidumbre, o varianza. La "incertidumbre" se define generalmente como la raíz cuadrada de la "varianza" de una distribución. Es decir, la incertidumbre de un observable SS se denota ΔS\Delta S y viene 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 el caso de las matrices de Pauli, en las que S2=IS^2 = I, esto se convierte en

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

Apliquemos esto a un ejemplo concreto. Comencemos con el estado ψ=+y=12(1i),|\psi\rangle = |+\rangle_y = \frac{1}{\sqrt{2}}\begin{pmatrix} 1 \\ i \end{pmatrix}, y determinemos la incertidumbre del observable XX en ese estado.

Comprueba tu comprensión

Lee la pregunta a continuación, piensa en tu respuesta y luego haz clic en el triángulo para ver la solución.

Calcula la incertidumbre de XX en el estado +y=+i|+\rangle_y = |+i\rangle, a mano.

Respuesta:

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

En el estado dado, esto produce:

Δ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 crear un estado inicial arbitrario usando qc.initialize(). Ten en cuenta que la sintaxis para la unidad imaginaria aquí es 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

Según nuestra ecuación anterior, (Δ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... Mantengamos ese mismo estado, pero calculemos ahora el 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

Podríamos hacer la misma operación matemática que antes, pero veríamos que la varianza es de nuevo muy cercana a 1.0. Podríamos concluir que ΔXΔZ1.0\Delta X \Delta Z \approx 1.0. Esto es aproximadamente correcto para el estado que elegimos. ¿Pero podemos hacerlo mejor? ¿O peor?

Recuerda que existe una relación de incertidumbre entre la posición a lo largo de una dirección, x,x, y el momento a lo largo de esa misma dirección, px.p_x. Para esas variables, la forma más familiar es probablemente ΔxΔpx/2\Delta x \Delta p_x \geq \hbar/2 Si esto es todo lo que recordamos, podríamos caer en la tentación de pensar que ΔX\Delta X y ΔZ\Delta Z también podrían tener un límite fundamental similar en la incertidumbre. ¿Quizás es imposible que el producto ΔXΔZ\Delta X \Delta Z llegue a cero? Probemos con otro estado y veamos si esto se cumple. Esta vez usaremos ψ=12(11).|\psi\rangle = \frac{1}{\sqrt{2}}\begin{pmatrix} 1 \\ 1 \end{pmatrix}. Veamos qué ocurre. Ten en cuenta que en el código siguiente, el estimator puede aceptar dos conjuntos de circuitos y observables en la misma entrega de trabajo.

# 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

El valor esperado de XX debería ser cercano a 1.0, pero no debería superar 1.0. No te preocupes si lo supera por una cantidad muy pequeña. Esto puede atribuirse a factores como el ruido y/o errores de lectura. Aunque este es un tema muy importante, podemos ignorarlo por ahora.

Obtuvimos un valor esperado de XX muy cercano a 1.0 (correspondiente a una varianza muy baja para XX). Esto hace que el producto de las dos varianzas sea bastante bajo:

Δ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.

Aunque esto no es exactamente cero, este valor se está volviendo pequeño en comparación con los valores propios de los operadores de Pauli (±1\pm 1). Bien, puede que recuerdes que la relación de incertidumbre entre la posición lineal y el momento puede escribirse de otra forma, usando explícitamente la relación de conmutación entre los operadores xx y pxp_x:

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

donde

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

es el conmutador de xx y pxp_x.

Esta es la forma que más fácilmente puede extenderse a los operadores de Pauli. En general, para dos operadores AA y BB,

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

Y en el caso de las matrices de Pauli XX y ZZ, necesitamos [X,Z][X,Z] para calcular

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

Mostramos esto a continuación y dejamos cálculos similares al lector como ejercicio:

[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 es una respuesta perfectamente válida, pero con un paso más vemos que

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

Nuestra relación de incertidumbre se convierte entonces en

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

Comprueba tu comprensión

Lee la pregunta a continuación, piensa en tu respuesta y luego haz clic en el triángulo para ver la solución.

Determina [X,Y][X,Y] y [Y,Z][Y,Z]. Usa esto para escribir las relaciones de incertidumbre entre XX & YY, y entre YY & ZZ.

Respuesta:

[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 con la relación de incertidumbre general, tenemos

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

Verificar consistencia

Antes de continuar, comprobemos que esto fue consistente con nuestro hallazgo anterior. Usamos el estado ψ=12(11).|\psi\rangle = \frac{1}{\sqrt{2}}\begin{pmatrix} 1 \\ 1 \end{pmatrix}. Y encontramos que ΔXΔZ=0.171.\Delta X \Delta Z = 0.171. Ahora sabemos que este producto debería ser mayor o igual que

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.

Efectivamente, ΔXΔZ=0.171Y=0\Delta X \Delta Z = 0.171 \geq |\langle Y \rangle|=0 Usa las preguntas a continuación para desarrollar intuición sobre estos resultados:

Comprueba tu comprensión

Lee las preguntas a continuación, piensa en tus respuestas y luego haz clic en los triángulos para ver las soluciones.

Responde los siguientes puntos en conjunto:

(a) ¿Para qué estados esperarías tener incertidumbre cero en XX?

(b) ¿Para qué estados esperarías tener incertidumbre cero en ZZ?

(c) ¿En qué estados obtendrías un valor esperado Y\langle Y \rangle igual a cero?

(d) ¿Son consistentes las respuestas anteriores con el caso ΔXΔZY\Delta X \Delta Z \geq |\langle Y \rangle|?

(e) Escribe código para verificar esto explícitamente usando estimator.

Respuestas:

(a) Podríamos esperar que los estados propios del operador XX produzcan incertidumbre cero en XX. En efecto, usando ψ=+x,|\psi\rangle = |+\rangle_x, tenemos ΔX=1X2=112=0.\Delta X = \sqrt{1-\langle X \rangle^2} = \sqrt{1-1^2} = 0.

(b) Podríamos esperar que los estados propios del operador ZZ produzcan incertidumbre cero en ZZ. En efecto, usando ψ=1,|\psi\rangle = |1\rangle, tenemos Δ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 cualquier estado que, al medirse, produzca una proyección positiva sobre el eje yy con la misma frecuencia que una negativa. Esto incluye los estados propios de XX y ZZ.

(d) Sí. Cabría esperar un valor muy pequeño para el producto de incertidumbres ΔXΔZ\Delta X \Delta Z en los estados propios de XX o ZZ: ΔXΔZ0.\Delta X \Delta Z \approx 0. Esto puede cumplirse porque también esperaríamos Y=0\langle Y \rangle=0 para esos mismos estados. Así que la relación de incertidumbre podría satisfacerse.

(e) Un código como el siguiente permitiría verificarlo:

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()

Donde el resultado devuelve todos los valores esperados. Para recuperar todos los valores esperados y calcular las incertidumbres, podrí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

Responde los siguientes puntos en conjunto:

(a) ¿Puedes pensar en un estado en el que tendrías un valor esperado Y\langle Y \rangle grande?

(b) ¿Esperarías que ese mismo estado tenga una incertidumbre grande o pequeña en XX?

(c) ¿Esperarías que ese mismo estado tenga una incertidumbre grande o pequeña en ZZ?

(d) ¿Son consistentes las respuestas anteriores con el caso ΔXΔZY\Delta X \Delta Z \geq |\langle Y \rangle|?

(e) Escribe código para verificar esto explícitamente usando estimator.

Respuestas:

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

(b) Podríamos esperar que XX tenga una incertidumbre grande en el estado +y,|+\rangle_y, ya que medir XX en ese estado produciría un resultado positivo y uno negativo con igual frecuencia/probabilidad.

(c) Podríamos esperar que ZZ tenga una incertidumbre grande en el estado +y,|+\rangle_y, ya que medir ZZ en ese estado produciría un resultado positivo y uno negativo con igual frecuencia/probabilidad.

(d) Sí. Cabría esperar un valor grande para el producto de incertidumbres ΔXΔZ\Delta X \Delta Z en los estados propios de Y,Y, y en particular para +y|+\rangle_y. También esperaríamos Y1\langle Y \rangle\approx 1 para ese mismo estado. Por tanto, tanto Y\langle Y \rangle como ΔXΔZ\Delta X \Delta Z son bastante grandes en ese estado, y es plausible que la relación de incertidumbre vuelva a satisfacerse.

(e) Un código como el siguiente permitiría verificarlo:

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()

Donde el resultado devuelve todos los valores esperados. Para recuperar todos los valores esperados y calcular las incertidumbres, podrí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

Probando las relaciones de incertidumbre

La prueba anterior solo demostró la validez de la relación de incertidumbre para una única elección del vector de estado ψ=+x|\psi\rangle = |+\rangle_x. Para convencernos de que esto es generalmente consistente con el experimento, deberíamos realizar cálculos similares usando el estimador para muchas elecciones del vector de estado. Empecemos rotando nuestro vector de estado alejándolo del eje zz, usando una compuerta RY para producir distintos estados iniciales mediante un 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()

Salida de la celda de código anterior

Observa que la curva roja (ΔXΔZ)(\Delta X \Delta Z) es siempre mayor que la curva naranja Y.\langle Y \rangle. A veces el producto de incertidumbre desciende y se acerca bastante al límite, y otras veces sube y se aleja más del límite, pero siempre obedece la relación de incertidumbre.

Por supuesto, esta puede no ser la mejor prueba de la relación de incertidumbre, ya que nuestro límite Y\langle Y \rangle está siempre muy cercano a cero. Usemos un estado cuántico que tenga una proyección mayor sobre los autoestados de YY. En concreto, seguiremos rotando 0|0\rangle hacia abajo desde el eje zz con ángulos variables, pero ahora también rotaremos ese estado resultante alrededor de zz un cierto ángulo, quizás π/4\pi/4, y veremos qué ocurre.

# 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()

Salida de la celda de código anterior

¡Ahora vemos que el límite sobre la incertidumbre (ΔXΔZ)(\Delta X \Delta Z) está siendo puesto a prueba! La curva roja se acerca mucho más a la curva naranja que antes. De hecho, en ausencia de ruido, la relación de incertidumbre quedaría exactamente saturada ((ΔXΔZ)=Y(\Delta X \Delta Z) = \langle Y \rangle) en un punto. En presencia de ruido y error de lectura, no debería sorprendernos que una ejecución ocasionalmente arroje un valor de (ΔXΔZ)(\Delta X \Delta Z) ligeramente mayor que Y.\langle Y \rangle. Esto no es una violación real de la incertidumbre; es simplemente un artefacto de un error no nulo.

Comprueba tu comprensión

Lee las preguntas a continuación, piensa en tus respuestas y luego haz clic en los triángulos para ver las soluciones.

¿Cómo llevarías esto al límite absoluto, haciendo Y\langle Y \rangle lo más grande posible?

Respuesta:

El código actualmente tiene líneas que rotan el estado inicial por defecto 0|0\rangle hacia abajo desde el eje zz un ángulo parametrizado θ\theta y luego también alrededor del eje zz un ángulo π/4,\pi/4, lo que rota el vector de estado parte del camino hacia el eje yy.

qc.ry(theta,0)

qc.rz(pi/4,0)

Podríamos cambiar la rotación alrededor de zz de π/4\pi/4 a π/2\pi/2, rotando completamente hasta un autoestado de YY:

qc.ry(theta,0)

qc.rz(pi/2,0)

No se requeriría ningún otro cambio.

Modifica el código o cópialo e implementa esa verificación de la relación de incertidumbre con el valor esperado de Y maximizado. ¿Se cumple la relación de incertidumbre?

Respuesta:

Usaríamos exactamente el código del ejemplo anterior, con

qc.rz(pi/2,0)

reemplazando a

qc.rz(pi/4,0).

La figura resultante debería verse como la que aparece a continuación, y sí, el principio de incertidumbre debería seguir siendo válido.

Un gráfico que compara la incertidumbre con el valor esperado máximo del operador Y.

Modifica el código anterior para hacer una imagen similar, demostrando que a partir de mediciones en el computador cuántico el producto ΔXΔY\Delta X \Delta Y se comporta como debería. Elige cualquier conjunto de estados que quieras.

Respuesta:

Usaríamos exactamente el código del ejemplo anterior, y de hecho podríamos usar los mismos resultados de arriba, calculando simplemente distintas incertidumbres a partir de los valores esperados. Por ejemplo, podrí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)

y podríamos graficar

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()

Desafío: Escribe código para recorrer muchos valores de ϕ\phi, tal como recorrimos muchos valores de θ\theta, y crea un gráfico en 3D que muestre que la relación de incertidumbre nunca se viola. Elige cualquier observable que quieras.

Preguntas

Los instructores pueden solicitar versiones de estos cuadernos con claves de respuestas y orientación sobre su ubicación en currículos comunes completando esta encuesta rápida sobre cómo se están usando los cuadernos.

Conceptos clave:

  • Existen relaciones de incertidumbre entre muchos conjuntos de observables físicos, incluyendo la posición y el momento lineal, y las componentes del espín.
  • Las matrices de Pauli no conmutan. Esto es un reflejo matemático del hecho de que no todas las componentes del espín pueden conocerse/determinarse simultáneamente.
  • La computación cuántica hace un uso intensivo de los operadores/matrices de Pauli, por lo que resulta útil conocer la relación de incertidumbre para los operadores de Pauli, así como los operadores de espín estrechamente relacionados.
  • Una fórmula general para la incertidumbre de dos operadores AA y BB es ΔAΔB12[A,B].\Delta A \Delta B \geq \frac{1}{2}|\langle [A,B] \rangle|.
  • Un autoestado a|a\rangle de algún operador AA produce incertidumbre cero en el observable físico asociado a ese operador. Incluso experimentalmente, aAa0.\langle a|A|a\rangle \approx 0.
  • Un autoestado a|a\rangle de algún operador AA producirá una mayor incertidumbre para un operador BB que no conmute con AA.
  • Los resultados experimentales obtenidos con un computador cuántico real confirman la intuición que obtenemos de las representaciones matriciales de los operadores físicos.

Preguntas V/F:

  1. V/F Se pueden medir XX e YY simultáneamente, pero no ZZ.
  2. V/F Se pueden medir XX y ZZ simultáneamente, pero no YY.
  3. V/F Los operadores de posición lineal y momento lineal no conmutan.
  4. V/F Los computadores cuánticos de IBM miden a lo largo de ZZ por defecto, por lo que debe realizarse una rotación para medir a lo largo de cualquier otra dirección.
  5. V/F El circuito de abajo mide efectivamente ZZ y luego XX.

Un diagrama de circuito que muestra una medición, una compuerta Hadamard y luego otra medición.

Preguntas de opción múltiple:

  1. El diagrama a continuación demuestra cuál de las siguientes relaciones de incertidumbre:

    • 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. Ninguna de las anteriores

Un gráfico que compara la incertidumbre con el valor esperado máximo del operador Y.

  1. ¿Cuál de las siguientes es la secuencia estándar para realizar una medición a lo largo de xx?

    • a. Solo qc.measure()
    • b. qc.h() y luego qc.measure()
    • c. qc.h(), qc.h() y luego qc.measure()
    • d. qc.h(), qc.s, qc.h() y luego qc.measure()
    • e. qc.sdg(), qc.h(), qc.s y luego qc.measure()
    • f. qc.sdg(), qc.h(), qc.s, qc.h() y luego qc.measure()
  2. ¿Cuál de los siguientes estados produce el mayor valor esperado X\langle X \rangle?

    • a. +x|+\rangle_x
    • b. x|-\rangle_x
    • c. +y|+\rangle_y también llamado +i|+i\rangle
    • d. y|-\rangle_y también llamado i|-i\rangle
    • e. 0|0\rangle también llamado |\uparrow\rangle
    • f. 1|1\rangle también llamado |\downarrow\rangle
  3. ¿Cuál de los siguientes estados produce la mayor incertidumbre ΔX\Delta X?

    • a. +x|+\rangle_x
    • b. +y|+\rangle_y también llamado +i|+i\rangle
    • c. 0|0\rangle también llamado |\uparrow\rangle
    • d. a y b están empatados
    • e. b y c están empatados
    • f. a, b y c están empatados

Preguntas de discusión:

  1. ¿Este concepto de incertidumbre entra en conflicto de alguna manera con la noción del espín como una flecha vectorial en el espacio cartesiano? ¿Y en la esfera de Bloch?

  2. Supón que orientas un dispositivo de medición a lo largo de una dirección a medio camino entre los ejes xx e yy. ¿Qué ocurre? ¿Puedes hacer una medición a lo largo de esa dirección? ¿Cómo se relaciona esto con la incertidumbre en XX e YY?