Explorer l'incertitude
Pour ce module Qiskit en classe, les étudiants doivent disposer d'un environnement Python fonctionnel avec les paquets suivants installés :
qiskitv2.1.0 ou plus récentqiskit-ibm-runtimev0.40.1 ou plus récentqiskit-aerv0.17.0 ou plus récentqiskit.visualizationnumpypylatexenc
Pour configurer et installer les paquets ci-dessus, voir le guide d' installation de Qiskit. Afin d'exécuter des tâches sur de véritables ordinateurs quantiques, les étudiants devront créer un compte sur IBM Quantum® en suivant les étapes du guide Configurer votre compte IBM Cloud.
Ce module a été testé et a utilisé 8 minutes de temps de QPU. Il s'agit uniquement d'une estimation. L'utilisation réelle peut varier. Deux calculs qui prennent du temps sont signalés comme tels dans les commentaires de l'en-tête et peuvent être effectués sur des simulateurs si les étudiants n'ont pas assez de temps à consacrer à la QPU. Une fois ces éléments enlevés, le module ne nécessite plus que 30 secondes de temps QPU.
# 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'Regardez la présentation du module par le Dr. Katie McCormick ci-dessous, ou cliquez ici pour la regarder sur YouTube.
Présentation
Vous avez probablement entendu parler du principe d'incertitude, même en dehors de vos cours de physique. Une formulation familière de l'incertitude est la suivante : "En regardant quelque chose, vous l'influencez" C'est certainement vrai. Mais une façon plus physique de décrire l'incertitude est qu'il existe certaines observables physiques qui présentent une incompatibilité qui les empêche d'être connues simultanément avec une précision arbitraire. De nombreux étudiants rencontrent d'abord la paire de variables incompatibles et , c'est-à-dire la position le long d'un axe appelé l'axe , et la quantité de mouvement linéaire le long de cette direction, respectivement. Pour ces variables, la contrainte d'incertitude s'écrit Ici, est appelé "incertitude dans ", qui a la même définition que l'écart-type en statistique, et peut être défini comme suit est définie de la même manière. Nous ne déduirons pas ici cette relation d'incertitude, mais nous soulignerons qu'elle est cohérente avec notre compréhension des ondes classiques. En d'autres termes, une onde ayant vraiment une fréquence parfaite et une longueur d'onde continuerait à l'infini sous la forme d'une sinusoïde parfaite. Du point de vue de la mécanique quantique, cela correspondrait à une connaissance parfaite de la quantité de mouvement, conformément à l'hypothèse de Broglie : . Mais pour savoir où se trouve une particule ondulatoire, l'onde qui la décrit doit avoir un pic plus net dans l'espace, comme une gaussienne très étroite, par exemple. Nous savons que nous pouvons exprimer n'importe quelle fonction continue, y compris les fonctions d'onde à pente raide, sous la forme d'une série de Fourier de fonctions sinusoïdales de longueurs d'onde différentes. Mais lorsque la fonction d'onde présente un pic plus marqué (et que la position est mieux connue), il faut davantage de termes dans la série de Fourier, ce qui signifie un mélange d'un plus grand nombre de longueurs d'onde (et donc, en mécanique quantique, d'un plus grand nombre de valeurs de la quantité de mouvement).
Plus simplement, un état dont la quantité de mouvement est bien définie (une sinusoïde parfaite dans l'espace) a une position très incertaine. Un état dont la position est bien définie (comme une distribution delta de Dirac) a une quantité de mouvement très incertaine.
D'autres variables présentent une telle incompatibilité. Par exemple, le spin d'une particule peut avoir une projection bien définie le long d'un axe, mais nous ne savons rien de la projection sur un axe orthogonal. Par exemple, l'état (pour un qubit ou une particule spin-1/2 ) a une projection définie le long de l'axe (de 1 dans le contexte d'un qubit, et de dans le contexte d'une particule spin-1/2 ). Mais cet état peut être écrit comme une superposition de deux états dont chacun a une projection bien définie sur l'axe : ou de manière équivalente a une projection bien définie sur , tout comme . Ainsi, si nous spécifions la projection d'un état le long de l'axe , nous ne connaissons pas la projection le long de l'axe . Et si nous spécifions la projection sur l'axe , nous ne connaissons pas la projection le long de . Il existe des différences mineures lorsque l'on aborde ce sujet dans le contexte du spin et des qubits. Mais d'une manière générale, les états propres des matrices de Pauli ont une relation intéressante que nous pouvons explorer. Tout au long de cette leçon, nous vérifierons expérimentalement notre intuition concernant l'incertitude de ces variables incompatibles, et nous vérifierons que les relations d'incertitude sont valables sur les ordinateurs quantiques IBM®.
Simple vérification de l'intuition
Dans cette première expérience et tout au long du module, nous utiliserons un cadre pour l'informatique quantique connu sous le nom de "modèles Qiskit", qui décompose les flux de travail en plusieurs étapes :
- Etape 1 : Tracer un problème quantique à partir d'entrées classiques
- Étape 2 : Optimisation du problème pour l'exécution quantique
- Étape 3 : Exécution à l'aide des primitives « IBM Quantum »
- Étape 4 : Post-traitement et analyse classique
Nous suivons généralement ces étapes, même si nous ne les mentionnons pas toujours explicitement.
Commençons par charger les paquets nécessaires, y compris les primitives Runtime. Nous choisirons également l'ordinateur quantique le moins occupé dont nous disposons.
Le code ci-dessous vous permet de sauvegarder vos données d'identification lors de la première utilisation. Veillez à supprimer ces informations du bloc-notes après l'avoir enregistré dans votre environnement, afin que vos informations d'identification ne soient pas accidentellement partagées lorsque vous partagez le bloc-notes. Voir Configurer votre compte IBM Cloud et Initialiser le service dans un environnement non fiable pour plus d'informations.
from numpy import pi
# Load IBM Quantum Compute 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)Output:
ibm_sherbrooke
Si un étudiant épuise son temps de calcul quantique disponible pendant la leçon, les lignes ci-dessous peuvent être décommentées et utilisées pour mettre en place un simulateur qui imite en partie le comportement du bruit de l'ordinateur quantique sélectionné ci-dessus.
# 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}})Vous vous souvenez peut-être qu'un état propre d'un opérateur, Z, n'est pas un état propre d'un autre opérateur, X. Nous allons maintenant l'observer expérimentalement en effectuant des mesures le long des axes et . Pour la mesure le long de , nous utilisons simplement qc.measure (), parce que les ordinateurs quantiques IBM sont structurés pour mesurer le long de . Mais pour mesurer le long de , nous devons faire pivoter le système pour déplacer l'axe jusqu'à l'orientation le long de laquelle nous effectuons la mesure. Cette opération est réalisée à l'aide d'une porte de Hadamard. Une étape similaire est nécessaire pour les mesures le long de . Les étapes nécessaires sont rassemblées ici pour plus de commodité :
- Pour mesurer le long de :
qc.measure() - Pour mesurer le long de :
qc.h()puisqc.measure() - Pour mesurer le long de :
qc.sdg(),qc.h(),qc.spuisqc.measure()
Étape 1 : Mettre en correspondance les entrées classiques avec un problème quantique
Dans ce cas, l'étape de mise en correspondance consiste simplement à exprimer les mesures et les rotations décrites ci-dessus dans un circuit quantique :
# 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")Output:
Étape 2 : Optimiser le problème pour l'exécution quantique
Cette étape prend les opérations que nous voulons effectuer et les exprime en termes de fonctionnalité d'un ordinateur quantique spécifique. Il permet également de faire correspondre notre problème à la configuration de l'ordinateur quantique.
# 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)Étape 3 : Exécution à l'aide des primitives « IBM Quantum »
Nous pouvons utiliser un échantillonneur pour recueillir des données statistiques sur les mesures. Nous allons mettre au point la primitive Sampler afin qu'elle puisse fonctionner sur un véritable ordinateur quantique à l'aide de mode = backend. Il existe d'autres modes adaptés à d'autres flux de travail, et nous en utiliserons un ci-dessous. Le Sampler sera utilisé en appelant sa méthode run() avec une liste de « pubs » (Primitive Unified Blocs). Chaque enregistrement contient jusqu'à trois éléments qui, ensemble, définissent une unité de travail que l'estimateur doit traiter : les circuits, les observables et les paramètres. Vous pouvez également fournir une liste de circuits, une liste de grandeurs observables et une liste de paramètres. Pour plus d'informations, consultez la présentation des PUB.
Nous voulons utiliser un véritable ordinateur quantique, afin de réaliser une véritable expérience de physique quantique. Si vous épuisez le temps qui vous est imparti sur les ordinateurs quantiques réels, vous pouvez commenter le code ci-dessous pour l'ordinateur quantique, et décommenter le code pour l'exécution sur un simulateur.
# 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()Étape 4 : Post-traitement
Il s'agit d'un cas particulièrement simple de post-traitement, dans lequel nous visualisons simplement les comptages.
Notez que Qiskit ordonne les qubits, les mesures et d'autres éléments en listant l'élément le moins élevé en dernier / à droite, une convention appelée "little-endian". Cela signifie que la colonne ci-dessous intitulée "10" se réfère aux comptages pour lesquels la première mesure a donné un "0" et la deuxième mesure a donné un "1".
# Step 4: Post-process
from qiskit.visualization import plot_histogram
plot_histogram(counts)Output:
Si cette convention ne vous convient pas, vous pouvez utiliser marginal_counts pour visualiser les résultats de chaque mesure séparément :
from qiskit.result import marginal_counts
plot_histogram(
marginal_counts(counts, indices=[0]), title="Counts after first measurement"
)Output:
plot_histogram(
marginal_counts(counts, indices=[1]), title="Counts after second measurement"
)Output:
Par défaut, les états dans Qiskit sont initialisés à l'état . Il n'est donc pas surprenant que presque toutes les premières mesures aient donné . Notez cependant que la deuxième mesure (celle qui donne des informations sur les projections de l'état sur ) a donné des résultats presque identiques. Il semble que cet état qui nous donne un résultat très prévisible des mesures le long de nous donne un ensemble de résultats très imprévisibles pour les mesures le long de . Explorons cela.
Que se passe-t-il si l'on effectue les mesures dans l'ordre inverse? Nous pourrions commencer par utiliser la porte de Hadamard pour obtenir des statistiques sur la probabilité que soit mesuré dans . Puis, pour la deuxième mesure, nous reviendrons à la base en utilisant une deuxième porte de 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")Output:
# 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)Output:
Ici, il semble que nous ayons encore moins de prévisibilité! Auparavant, nous savions au moins quel serait le résultat de la première mesure, alors qu'aujourd'hui, nous disposons d'une distribution relativement homogène de tous les états possibles. Il n'est pas difficile de comprendre pourquoi cela s'est produit. Nous avons commencé par , qui est un mélange 50-50 de et , selon Il est donc évident que la probabilité d'obtenir l'état + ou - (correspondant à 0 et 1 dans le tableau) pour la première mesure doit être égale. La mesure le long de effondre l'état dans un état propre ou dans l'état propre . Chacun de ces états est un mélange 50-50 de et , conformément à Ainsi, une fois que le système se trouve dans un état propre de , il est clair que les mesures effectuées le long de produiront à la fois et , et ce avec une probabilité à peu près égale. Notre premier exemple nous a donc montré que certains États auront des résultats très prévisibles pour certaines mesures, mais des résultats imprévisibles pour d'autres mesures. L'exemple actuel nous montre que nous pouvons faire pire que cela. Il existe des états qui peuvent nous donner des résultats imprévisibles pour les deux mesures, même si tout ce que nous faisons est d'intervertir l'ordre des mesures. Examinons le degré de certitude ou d'incertitude d'une quantité pour un état donné.
Calcul de l'incertitude
Nous pouvons quantifier ce phénomène à l'aide de l'incertitude ou de la variance. L'"incertitude" est souvent définie comme la racine carrée de la "variance" d'une distribution. En d'autres termes, l'incertitude pour une observable est notée et est donnée par
Dans le cas des matrices de Pauli, pour lesquelles , cela devient
Appliquons cela à un exemple concret. Commençons par l'état et déterminons l'incertitude de l'observable dans cet état.
Vérifiez votre compréhension
Calculer à la main l'incertitude de dans l'état .
Dans l'état donné, cela donne :
Nous pouvons créer un état initial arbitraire en utilisant qc.initialize(). Notez que la syntaxe de l'unité imaginaire est ici .
# 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)Output:
-0.02408454165642664
Selon l'équation ci-dessus, Restons dans le même état, mais trouvons la valeur espérée de , maintenant :
# 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)Output:
0.04958271968581247
Nous pourrions faire les mêmes calculs que précédemment, mais nous verrions que la variance est à nouveau très proche de 1.0. Nous pourrions conclure que . En effet, ceci est approximativement correct pour l'état que nous avons choisi. Mais pouvons-nous faire mieux? Ou pire?
Rappelons qu'il existe une relation d'incertitude entre la position dans une direction, et la quantité de mouvement dans la même direction, Pour ces variables, mais la forme la plus familière est probablement la suivante Si c'est tout ce dont nous nous souvenons, nous pourrions être tentés de penser que et pourraient également avoir une limite aussi fondamentale sur l'incertitude. Peut-être est-il impossible que le produit atteigne zéro? Essayons un autre État et voyons si cela tient la route. Cette fois-ci, nous utiliserons . Voyons ce qui se passe. Notez que dans le code ci-dessous, l'estimateur peut accepter deux ensembles de circuits et d'observables dans la même soumission de travail.
# 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)Output:
The expectation value of the first observable is: 1.0011036174126302
The expectation value of the second observable is: 0.0029429797670141016
La valeur attendue de devrait être proche de 1.0, mais ne devrait pas dépasser 1.0. Ne vous inquiétez pas si elle dépasse 1.0 de très peu. Cela peut être attribué à des facteurs tels que le bruit et/ou l'erreur de lecture. Bien qu'il s'agisse d'un sujet très important, nous pouvons l'ignorer pour l'instant.
Nous avons obtenu une valeur d'espérance de très proche de 1.0 (correspondant à une variance très faible pour ). Le produit des deux variances est donc assez faible :
Bien que cette valeur ne soit pas exactement nulle, elle est de plus en plus faible par rapport aux valeurs propres des opérateurs de Pauli ( ). Vous vous souvenez peut-être que la relation d'incertitude entre la position linéaire et la quantité de mouvement peut être écrite différemment, en utilisant explicitement la relation de commutation entre les opérateurs et :
où
est le commutateur de et .
C'est la forme qui peut être le plus facilement étendue aux opérateurs de Pauli. En général, pour deux opérateurs et ,
Et dans le cas des matrices de Pauli et , nous avons besoin de pour calculer
Nous le montrons ici et laissons au lecteur le soin d'effectuer des calculs similaires à titre d'exercice :
Cette réponse est tout à fait acceptable, mais si l'on fait un pas de plus, on constate que
Notre relation d'incertitude devient donc
Vérifiez votre compréhension
Déterminez et . Utilisez ceci pour écrire les relations d'incertitude entre & , et & .
En combinant avec la relation d'incertitude générale, nous avons
Vérifier la cohérence
Avant de poursuivre, vérifions que cela est cohérent avec notre constatation précédente. Nous avons utilisé l'état et nous avons trouvé que Nous savons maintenant que ce produit doit être supérieur ou égal à
En effet,
Utilisez les questions ci-dessous pour vous faire une idée de ces résultats :
Vérifiez votre compréhension
Répondez aux questions suivantes ensemble :
(a) Quels sont les états pour lesquels vous vous attendez à ce que l'incertitude soit nulle à l'adresse ?
(b) Quels sont les états pour lesquels vous vous attendez à ce que l'incertitude soit nulle à l'adresse ?
(c) Dans quels états obtiendriez-vous une valeur d'espérance nulle ?
(d) Les réponses aux questions ci-dessus sont-elles cohérentes avec l'affaire ?
(e) Ecrire un code pour vérifier explicitement ceci en utilisant l'estimateur.
(a) Nous pourrions nous attendre à ce que les états propres de l'opérateur produisent une incertitude nulle dans . En effet, en utilisant , nous avons
(b) Nous pourrions nous attendre à ce que les états propres de l'opérateur produisent une incertitude nulle dans . En effet, en utilisant , nous avons
(c) Nous nous attendons à trouver pour tous les états qui, lorsqu'ils sont mesurés, produisent une projection positive sur l'axe aussi souvent qu'une projection négative. Il s'agit notamment des états propres de et .
(d) Oui. On peut s'attendre à une valeur très faible du produit des incertitudes pour les états propres de ou : Cela peut être le cas parce que nous nous attendons également à ce que soit utilisé pour ces mêmes états. La relation d'incertitude peut donc être satisfaite.
(e) Un code tel que le suivant permettrait de le vérifier :
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()Lorsque les résultats renvoient toutes les valeurs attendues. Pour récupérer toutes les valeurs attendues et calculer les incertitudes, nous pourrions utiliser :
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
Répondez aux questions suivantes ensemble :
(a) Pouvez-vous penser à un état dans lequel vous auriez une grande valeur d'espérance ?
(b) Vous attendriez-vous à ce que ce même état ait une grande ou une petite incertitude dans ?
(c) Vous attendriez-vous à ce que ce même état ait une grande ou une petite incertitude dans ?
(d) Les réponses aux questions ci-dessus sont-elles cohérentes avec l'affaire ?
(e) Ecrire un code pour vérifier explicitement ceci en utilisant l'estimateur.
(a) Nous nous attendons à trouver pour l'état propre de : .
(b) On peut s'attendre à ce que ait une grande incertitude dans l'état puisque la mesure de dans cet état donnerait un résultat positif et négatif avec une fréquence/probabilité égale.
(c) On peut s'attendre à ce que ait une grande incertitude dans l'état puisque la mesure de dans cet état donnerait un résultat positif et négatif avec une fréquence/probabilité égale.
(d) Oui. On s'attendrait à une valeur élevée du produit des incertitudes pour les états propres de et pour en particulier. Nous nous attendons également à ce que soit utilisé pour ce même État. Ainsi, et sont tous deux assez importants dans cet état, et il est plausible que la relation d'incertitude soit à nouveau satisfaite.
(e) Un code tel que le suivant permettrait de le vérifier :
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()Lorsque les résultats renvoient toutes les valeurs attendues. Pour récupérer toutes les valeurs attendues et calculer les incertitudes, nous pourrions utiliser :
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
Tester les relations d'incertitude
Le test ci-dessus n'a démontré la validité de la relation d'incertitude que pour un seul choix du vecteur d'état . Pour nous convaincre que cette relation est généralement cohérente avec l'expérience, nous devrions effectuer des calculs similaires en utilisant l'estimateur pour de nombreux choix du vecteur d'état. Commençons par faire tourner notre vecteur d'état à l'opposé de l'axe , en utilisant une porte RY pour produire différents états initiaux à l'aide d'un paramètre .
# 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()Output:
Notez que la courbe rouge est toujours plus grande que la courbe orange . Parfois, le produit d'incertitude baisse et se rapproche de la limite, d'autres fois il augmente et s'éloigne de la limite, mais il obéit toujours à la relation d'incertitude.
Bien sûr, ce n'est peut-être pas le meilleur test de la relation d'incertitude, puisque notre limite est toujours très proche de zéro. Utilisons un état quantique qui a une projection plus importante sur les états propres de . Plus précisément, nous allons toujours faire pivoter vers le bas à partir de l'axe selon des angles variables, mais nous allons également faire pivoter l'état résultant autour de selon un certain angle, peut-être , et voir ce qui se passe.
# 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()Output:
Nous voyons maintenant que la limite de l'incertitude est mise à l'épreuve! La courbe rouge se rapproche beaucoup plus de la courbe orange qu'auparavant. En fait, en l'absence de bruit, la relation d'incertitude serait exactement saturée ( ) en un point. En présence de bruit et d'erreurs de lecture, il ne faut pas s'étonner si une série donne parfois des résultats légèrement supérieurs à Il ne s'agit pas d'une véritable violation du principe d'incertitude, mais simplement d'un artefact dû à une erreur non nulle.
Vérifiez votre compréhension
Expliquez comment vous repousseriez cette limite au maximum, en maximisant la valeur de .
Le code comporte actuellement des lignes qui font pivoter l'état initial par défaut , vers le bas à partir de l'axe d'un angle paramétré , puis autour de l'axe d'un angle , ce qui fait pivoter le vecteur d'état en partie jusqu'à l'axe .
qc.ry(theta,0)qc.rz(pi/4,0)Nous pourrions changer la rotation autour de de à , en tournant jusqu'à un état propre de :
qc.ry(theta,0)qc.rz(pi/2,0)Aucune autre modification n'est nécessaire.
Modifiez le code ou copiez-le et mettez en œuvre cette vérification de la relation d'incertitude avec la valeur d'espérance de Y maximisée. La relation d'incertitude est-elle maintenue?
Nous utiliserions exactement le même code que dans l'exemple ci-dessus, avec
qc.rz(pi/2,0)échangé pour remplacer
qc.rz(pi/4,0).La figure obtenue devrait ressembler à celle ci-dessous, et oui, le principe d'incertitude devrait toujours être valable.

Modifiez le code ci-dessus pour obtenir une image similaire, démontrant que, d'après les mesures effectuées sur l'ordinateur quantique, le produit se comporte comme il se doit. Choisissez l'ensemble d'états que vous souhaitez.
Nous utiliserions exactement le code de l'exemple ci-dessus et, en face, nous pourrions utiliser les mêmes résultats que ci-dessus, en utilisant simplement les valeurs d'espérance pour calculer les différentes incertitudes. Par exemple, nous pourrions utiliser
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)et nous pourrions tracer
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()
Défi : Écrire un code pour parcourir de nombreuses valeurs de , tout comme nous avons parcouru de nombreuses valeurs de , et réaliser un graphique en 3D montrant que la relation d'incertitude n'est jamais violée. Choisissez les observables que vous souhaitez.
Questions
Les enseignants peuvent demander des versions de ces cahiers avec les corrigés et des conseils sur le placement dans les programmes d'études communs en répondant à cette enquête rapide sur la façon dont les cahiers sont utilisés.
Concepts essentiels :
- Il existe des relations d'incertitude entre de nombreux ensembles d'observables physiques, notamment la position et la quantité de mouvement linéaire, ainsi que les composantes du spin.
- Les matrices de Pauli ne sont pas commutées. Il s'agit d'un reflet mathématique du fait que toutes les composantes du spin ne peuvent pas être connues/déterminées simultanément.
- L'informatique quantique fait un usage intensif des opérateurs/matrices de Pauli. Il est donc utile de connaître la relation d'incertitude pour les opérateurs de Pauli, ainsi que pour les opérateurs de spin qui leur sont étroitement liés.
- Une formule générale pour l'incertitude de deux opérateurs et est la suivante
- Une é d'un état propre d'un opérateur entraîne une incertitude nulle sur l'observable physique associée à cet opérateur. Même d'un point de vue expérimental,
- Un état propre d'un opérateur produira une plus grande incertitude pour un opérateur qui ne commute pas avec .
- Les résultats expérimentaux obtenus à l'aide d'un véritable ordinateur quantique confirment l'intuition que nous avons des représentations matricielles des opérateurs physiques.
Questions vrai/faux :
- T/F On peut mesurer simultanément et , mais pas .
- T/F On peut mesurer simultanément et , mais pas .
- T/F Les opérateurs de position linéaire et de quantité de mouvement linéaire ne commutent pas.
- T/F IBM Les ordinateurs quantiques mesurent par défaut le long de , de sorte qu'une rotation doit être effectuée pour mesurer dans une autre direction.
- T/F Le circuit ci-dessous mesure effectivement puis .
Questions du MC :
-
Le diagramme ci-dessous illustre laquelle des relations d'incertitude suivantes?
- a.
- b.
- c.
- d. Aucune des réponses ci-dessus
-
Laquelle des séquences suivantes est la séquence standard pour effectuer une mesure le long de ?
- a. Seulement
qc.measure() - b.
qc.h()Ensuiteqc.measure() - c.
qc.h(),qc.h()Ensuiteqc.measure() - d.
qc.h(),qc.s,qc.h()puisqc.measure() - e.
qc.sdg()qc.h(),qc.spuisqc.measure() - f.
qc.sdg(),qc.h(),qc.s,qc.h()puisqc.measure()
- a. Seulement
-
Parmi les états suivants, lequel produit la plus grande valeur d'espérance ?
- a.
- b.
- c. également appelé
- d. également appelé
- e. également appelé
- f. également appelé
-
Parmi les états suivants, lequel produit la plus grande incertitude ?
- a.
- b. également appelé
- c. également appelé
- d. a et b sont à égalité
- e. b et c sont à égalité
- f. a, b et c sont à égalité
Questions à débattre :
-
Ce concept d'incertitude est-il en contradiction avec la notion de spin en tant que flèche vectorielle dans l'espace cartésien? Qu'en est-il de la sphère de Bloch?
-
Supposons que vous orientez un appareil de mesure le long d'une direction située à mi-chemin entre les axes et . Que se passe-t-il? Pouvez-vous effectuer une mesure dans cette direction? Quel est le lien avec l'incertitude dans les sites et ?
-
Quelles expériences supplémentaires souhaiteriez-vous réaliser pour vous convaincre des résultats obtenus ici?