from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
import numpy as np
Tehtävä 1 (7p)
Laske algebrallisesti lopputuloksena saatava kanava, kun seuraaviin kohteisiin käytetään Paulin pyöräytystä:
1) Bitinkääntökanava (bit-flip channel) $$ \Lambda_d (\rho) = (1-p) I \rho I + p (X \rho X)$$ 2) Koherentti kierto (coherent rotation) $$ \Lambda_r (\rho) = \cos^2{\left(\frac{\theta}{2}\right)} I \rho I + \sin^2{\left(\frac{\theta}{2}\right)} X \rho X + \frac{i}{2} (\sin{(\theta)} I \rho X - \sin{(\theta)} X \rho I)$$ 3) Amplitudinvaimennuskanava (amplitude damping channel) $$ \Lambda_a (\rho) = A_0 \rho A_0^\dagger + A_1 \rho A_1^\dagger$$ jossa $A_0 = \frac{(1+\sqrt{1-p})}{2} I + \frac{(1-\sqrt{1-p})}{2} Z$ ja $A_1 = \frac{\sqrt{p}}{2} (X + iY)$.
Kirjoita lopputuloksena saatavat kanavat Paulin kanavina.
Lasketaan ensin kanavien $\mathcal{P}$ toiminta Paulin operaattoreihin. \begin{align*} \mathcal{P}_i (I) &= I \\ \mathcal{P}_0 (\sigma_i) &= I \sigma_i I = \sigma_i \\ \mathcal{P}_1 (X) &= XXX = X \\ \mathcal{P}_2 (X) &= YXY = -X \\ \mathcal{P}_3 (X) &= ZXZ = -X \\ \end{align*}
- Bitinkääntökanava. \begin{align*} \widetilde{\Lambda}_d (\rho) &= \frac{1}{4}\sum_{i=0}^3 \mathcal{P}_i \Lambda_d \mathcal{P}^\dagger_i \rho \\ &= \frac{1}{4} \left(\sum_{i=0}^3 {\left[(1-p) \mathcal{P}_i I \rho I \mathcal{P}_i^\dagger + p (\mathcal{P}_i X \rho X \mathcal{P}_i^\dagger )\right]} \right) \\ &= \frac{1}{4} \left(\sum_{i=0}^3 {\left[(1-p) \mathcal{P}_i (I) \rho \mathcal{P}_i^\dagger (I) + p (\mathcal{P}_i (X) \rho \mathcal{P}_i^\dagger (X))\right]} \right) \\ &= \frac{1}{4} \left(4 (1-p) \rho + 4 p (X \rho X) \right) \\ &= \Lambda_d(\rho) \\ \end{align*} Kanava ei muutu pyöräytyksessä.
- Koherentti kierto. Yllä olevissa laskuissa huomattiin, että molemmat termit $I\rho I$ ja $X \rho X$ pysyvät muuttumattomina pyöräytyksestä. Huomattiin myös, että $\mathcal{P}$ ja $\mathcal{P}^\dagger$ toimivat samalla tavoin, joten käytetään siksi ainoastaan $\mathcal{P}$:tä. \begin{align*} \widetilde{\Lambda}_r (\rho) &= \cos^2{\left(\frac{\theta}{2}\right)} I \rho I + \sin^2{\left(\frac{\theta}{2}\right)} X \rho X + \frac{1}{4}\sum_{i=0}^3 \left[\frac{i}{2} (\sin{(\theta)} \mathcal{P}_i (I) \rho \mathcal{P}_i (X) - \sin{(\theta)} \mathcal{P}_i (X) \rho \mathcal{P}_i (I))\right]. \end{align*} Keskitytään summan viimeiseen termiin. \begin{align*} \frac{1}{4}\sum_{i=0}^3 \left[\frac{i}{2} (\sin{(\theta)} \mathcal{P}_i (I) \rho \mathcal{P}_i (X) - \sin{(\theta)} \mathcal{P}_i (X) \rho \mathcal{P}_i (I))\right] &= \frac{1}{4}\sum_{i=0}^3 \left[\frac{i}{2} (\sin{(\theta)} I \rho \mathcal{P}_i (X) - \sin{(\theta)} \mathcal{P}_i (X) \rho I)\right] \\ &= \frac{1}{4}\left(2\left[\frac{i}{2} (\sin{(\theta)} I \rho X - \sin{(\theta)} X \rho I)\right] - 2\left[\frac{i}{2} (\sin{(\theta)} I \rho X - \sin{(\theta)} X \rho I)\right]\right) \\ &= 0. \end{align*} Tämä tarkoittaa, että pyöräytetty kanava on yksinkertaisesti \begin{align*} \widetilde{\Lambda}_r (\rho) &= \cos^2{\left(\frac{\theta}{2}\right)} I \rho I + \sin^2{\left(\frac{\theta}{2}\right)} X \rho X, \end{align*} joka on Paulin kanavan muodossa.
- Amplitudinvaimennuskanava. Lasketaan muutama toiminta lisää kanavalle $\mathcal{P}$.
\begin{align*}
\mathcal{P}_1 (Y) &= XYX = -Y \\
\mathcal{P}_2 (Y) &= YYY = Y \\
\mathcal{P}_3 (Y) &= ZYZ = -Y \\
\mathcal{P}_1 (Z) &= XZX = -Z \\
\mathcal{P}_2 (Z) &= YZY = -Z \\
\mathcal{P}_3 (Z) &= ZZZ = Z \\
\end{align*}
Lasketaan nyt pyöräytetty amplitudinvaimennuskanava.
\begin{align*}
\widetilde{\Lambda}_a (\rho) &= \frac{1}{4}\sum_{i=0}^3 {\left[\mathcal{P}_i(A_0) \rho \mathcal{P}_i(A_0^\dagger) + \mathcal{P}_i(A_1) \rho \mathcal{P}_i(A_1^\dagger)\right]}.
\end{align*}
Lasketaan ensin pyöräytykset (Krausin) operaattoreille $A_0$.
\begin{align*}
\mathcal{P}_i(A_0) &= \frac{(1+\sqrt{1-p})}{2} \mathcal{P}_i(I) + \frac{(1-\sqrt{1-p})}{2} \mathcal{P}_i(Z) \\
&= \frac{(1+\sqrt{1-p})}{2} I + \frac{(1-\sqrt{1-p})}{2} \mathcal{P}_i(Z) \\
&= \mathcal{P}_i(A_0^\dagger)
\end{align*}
Toinen termi on negatiivinen, kun $i=1,2$ Jos sijoitamme tämän tuloksen kaavaan, saamme
\begin{align*} \frac{1}{4}\sum_{i=0}^3 {\left[\mathcal{P}_i(A_0) \rho \mathcal{P}_i(A_0^\dagger)\right]} &= \frac{1}{4} \left((1+\sqrt{1-p})^2 I \rho I + (1-\sqrt{1-p})^2 Z \rho Z + \frac{(1+\sqrt{1-p})(1-\sqrt{1-p})}{4} (2 (I \rho Z + Z \rho I) - 2(I \rho Z + Z \rho I)) \right) \\ &= \frac{1}{4} \left((1+\sqrt{1-p})^2 I \rho I + (1-\sqrt{1-p})^2 Z \rho Z\right) \\ &= \frac{1}{4} \left((1+\sqrt{1-p})^2 I \rho I + (1-\sqrt{1-p})^2 Z \rho Z\right) \\ \end{align*} Lasketaan nyt pyöräytykset Krausin operaattoreille $A_1$. \begin{align*} \mathcal{P}_i(A_1) &= {\frac{\sqrt{p}}{2} (\mathcal{P}_i(X) + i \mathcal{P}_i(Y))} \\ &= (\mathcal{P}_i(A_1^\dagger))^\dagger \end{align*} Sijoitetaan tämä kaavaan ja saadaan \begin{align*} \frac{1}{4}\sum_{i=0}^3 {\left[\mathcal{P}_i(A_1) \rho \mathcal{P}_i(A_1^\dagger)\right]} &= \frac{1}{4}\sum_{i=0}^3\frac{p}{4} { (\mathcal{P}_i(X) + i \mathcal{P}_i(Y))} \rho { (\mathcal{P}_i(X) - i \mathcal{P}_i(Y))} \\ &= \frac{1}{4}\frac{p}{4} {(4X\rho X + 4Y\rho Y - 2(i X\rho Y + i Y\rho X) + 2(i X\rho Y + i Y\rho X))} \\ &= \frac{p}{4} (X\rho X + Y\rho Y).\\ \end{align*} Summataan lopuksi nämä kaksi tulosta yhteen, jotta saadaan pyöräytetty amplitudinvaimennuskanava. \begin{align*} \widetilde{\Lambda}_a (\rho) &= \frac{1}{4} \left((1+\sqrt{1-p})^2 I \rho I + pX\rho X + pY\rho Y+ (1-\sqrt{1-p})^2 Z \rho Z\right). \end{align*} Nähdään, että pyöräytetty kanava on Paulin kanavan muodossa ja kaikki melukanavan ristitermit $\sigma_i \rho \sigma_j$, joissa $i\neq j$, kumoutuvat.
Tehtävä 2 (8p)
Kirjoita mukautettuja koe- ja analyysiluokkia, joilla saat poimittua tiheysmatriisit tilatomografian avulla melukanavien pyöräyttämisen jälkeen.
Voit käyttää tähän esimerkiksi qiskit-experiments-kehystä. Koeluokan tulisi hyväksyä syötteeksi vähintään yksi melukanavalla varustettu piiri, ja analyysiluokan tulisi palauttaa lopputuloksena tiheysmatriisi.
Tämän voi toteuttaa monella eri tavalla, mutta alla on malli, josta voi olla apua, jos miettii mistä aloittaa. Koeluokkasi pohjana voi olla BaseExperiment tai TomographyExperiment ja se voi käyttää __init__ ja circuit -metodeja tuottaakseen Paulin pyöräytykseen tarvittavat piirit. Analyysiluokan pohjana taas voi olla BaseAnalysis ja se voi käyttää _run_analysis -metodia ottaakseen tuloksista keskiarvon erilaisten pyöräytysten yli, joita kokeessa saadaan. Voit käyttää seuraavaa ohjetta apunasi: qiskit-experiments Documentation. Qiskit-experiments käyttää täysin avointa lähdekoodia, joten lähdekoodin tarkastelu voi myös olla hyödyksi.
from qiskit import QuantumCircuit
from copy import deepcopy
from itertools import chain
from typing import List, Optional, Sequence
from qiskit.providers.backend import Backend
from qiskit_experiments.framework import Options
from qiskit_experiments.library.tomography import TomographyExperiment, StateTomographyAnalysis
from typing import List
from qiskit_experiments.framework import (
BaseAnalysis,
Options,
ExperimentData,
AnalysisResultData
)
class TwirledStateTomographyAnalysis(BaseAnalysis):
"""Custom analysis class template."""
@classmethod
def _default_options(cls) -> Options:
"""Set default analysis options."""
options = super()._default_options()
return options
def _add_dicts(self, d1, d2):
"""Method to add two dictionaries.
"""
dtot = {key: 0 for key in set(chain(d1.keys(), d2.keys()))}
for key, val in chain(d1.items(), d2.items()):
dtot[key] += val
return dtot
def _run_analysis(
self,
experiment_data: ExperimentData
) -> List[AnalysisResultData]:
"""Run the analysis."""
# Dictionary for obtaining qiskit's measurement basis indexing
meas_keys = {'Z': 0, 'X': 1, 'Y': 2}
new_res = []
# Average the results obtained for each measurement basis over the twirls
for meas in ['Z', 'X', 'Y']:
# Create new data object that we can give to StateTomographyAnalysis
new_res_object = deepcopy(experiment_data.data()[0])
del new_res_object['job_id']
del new_res_object['meas_level']
del new_res_object['metadata']['twirl']
# Add 'm_idx' for StateTomographyAnalysis and 'twirled' for us to keep track
new_res_object['metadata'].update({'twirled': True, 'm_idx': [meas_keys[meas]]})
# Average the counts dictionaries
total_shots = 0
new_counts_dict = {}
for twirl_res in filter(lambda x: x['metadata']['m_idx'] == meas, experiment_data.data()):
new_counts_dict = self._add_dicts(new_counts_dict, twirl_res['counts'])
total_shots += twirl_res['shots']
new_res_object['counts'] = new_counts_dict
new_res_object['shots'] = total_shots
new_res.append(new_res_object)
# Replace the data in experiment_data with the averaged results
experiment_data._result_data = new_res
# Give experiment_data to StateTomographyAnalysis and run it
state_tomography = StateTomographyAnalysis()
result_tom = state_tomography._run_analysis(experiment_data)
return result_tom[0], []
class TwirledStateTomography(TomographyExperiment):
"""Custom experiment class template."""
def __init__(self,
circuit: QuantumCircuit,
state_prep: QuantumCircuit,
twirl_qubits: Sequence[int],
physical_qubits: Sequence[int] = None,
measurement_indices: Sequence[int] = None,
backend: Optional[Backend] = None):
"""Initialize the experiment."""
if physical_qubits is None:
physical_qubits = tuple(range(circuit.num_qubits))
super().__init__(circuit=circuit,
backend=backend,
physical_qubits=physical_qubits,
measurement_indices=measurement_indices,
analysis=TwirledStateTomographyAnalysis(),
)
self._twirl_qubits = twirl_qubits
# State preparation and noise channel circuit are kept separate
self._state_prep = state_prep
def circuits(self) -> List[QuantumCircuit]:
"""Generate the list of circuits to be run."""
circuits = []
# Prepare circuits for measurement and twirls
for meas in ['Z', 'X', 'Y']:
for pauli in ['I', 'X', 'Y', 'Z']:
for qubit in self._twirl_qubits:
circ = QuantumCircuit(self.num_qubits, len(self._meas_indices))
# Prepare state
circ = circ.compose(self._state_prep)
# Use metadata to tell qiskit what the circuits are
circ.metadata = {'twirl': pauli, 'm_idx': meas, "clbits": [0], "cond_clbits": []}
# Twirling and noise channel
circ.pauli(pauli, [qubit])
circ = circ.compose(self._circuit)
circ.pauli(pauli, [qubit])
# Pauli measurements
if meas == 'X':
circ.h(qubit)
if meas == 'Y':
circ.sdg(qubit)
circ.h(qubit)
circ.measure(qubit, qubit)
circuits.append(circ)
return circuits
@classmethod
def _default_experiment_options(cls) -> Options:
"""Set default experiment options here."""
options = super()._default_experiment_options()
return options
Tehtävä 3 (8p)
Alusta kubitti tilaan, jossa populaatiot ja koherenssit poikkeavat nollasta. Käytä jokaista alla listattua melukanavaa tähän kubittiin ja tee tilatomografia sekä pyöräyttäen kanavaa että ilman pyöräytystä. Piirrä kullekin melukanavalle samaan kuvaajaan $\rho_{00}$, $\rho_{11}$, $Re(\rho_{01})$ ja $Im(\rho_{01})$ sekä pyöräytetylle että pyöräyttämättömälle tapaukselle, eri $p$:n ja $\theta$:n arvoille.
Melukanavat :
- Bitinkääntö
- Paulin kanava arvoilla $(1-p, p, 0, 0)$.
- Koherentti kierto
- Käytä RX-porttia pienellä kulmalla.
- Amplitudinvaimennuskanava
Voit käyttää qiskit_aer.noise-moduuliin toteutettuja kohinamalleja. Voit käyttää myös aiempien projektien kohinakanavien toteutuksia, mutta huomioi, että saatat kohdata numeerisia epävakauksia.
p_values = np.linspace(0,0.99,10)
t_values = np.linspace(0,np.pi,10)
from qiskit_aer import AerSimulator
from qiskit_experiments.library.tomography import StateTomography
# Let us use the noise channels implemented in qiskit_aer.noise
from qiskit_aer.noise import amplitude_damping_error, pauli_error
import matplotlib.pyplot as plt
# Backend
backend = AerSimulator()
# Initial state
qc_s = QuantumCircuit(4,1)
qc_s.u(np.pi/4, np.pi/4, 0, 0)
Aloitetaan bitinkääntökanavasta.
rhos_bf_twirled = []
for p in p_values:
qc = QuantumCircuit(4)
# Append the noise channel explicitly to the circuit
error = pauli_error([("I", 1-p), ("X", p)])
qc.append(error, [0])
res_t = TwirledStateTomography(qc, qc_s, [0], measurement_indices=[0]).run(backend=backend).block_for_results()
rhos_bf_twirled.append(res_t.analysis_results('state').value)
rhos_bf = []
for p in p_values:
qc = qc_s.copy()
error = pauli_error([("I", 1-p), ("X", p)])
qc.append(error, [0])
res = StateTomography(qc, measurement_indices=[0]).run(backend=backend, shots=4096).block_for_results()
rhos_bf.append(res.analysis_results('state').value)
tomo_rhos_bf_twirled = np.zeros((2,2,len(p_values)), dtype=complex)
for (i, res) in enumerate(rhos_bf_twirled):
tomo_rhos_bf_twirled[:,:,i] = res
tomo_rhos_bf = np.zeros((2,2,len(p_values)), dtype=complex)
for (i, res) in enumerate(rhos_bf):
tomo_rhos_bf[:,:,i] = res
plt.figure(figsize=(10,6))
# Twirled results
plt.plot(p_values, np.real(tomo_rhos_bf_twirled[0,1,:]),"C0*", label='Re $\\rho_{01} twirled$')
plt.plot(p_values, np.imag(tomo_rhos_bf_twirled[0,1,:]),"C1*", label='Im $\\rho_{01} twirled$')
plt.plot(p_values, np.real(tomo_rhos_bf_twirled[0,0,:]),"C2x", label='$\\rho_{00} twirled$')
plt.plot(p_values, np.real(tomo_rhos_bf_twirled[1,1,:]),"C3x", label='$\\rho_{11} twirled$')
# Non-twirled results
plt.plot(p_values, np.real(tomo_rhos_bf[0,1,:]),"C0--", label='Re $\\rho_{01}$')
plt.plot(p_values, np.imag(tomo_rhos_bf[0,1,:]),"C1--", label='Im $\\rho_{01}$')
plt.plot(p_values, np.real(tomo_rhos_bf[0,0,:]),"C2--", label='$\\rho_{00}$')
plt.plot(p_values, np.real(tomo_rhos_bf[1,1,:]),"C3--", label='$\\rho_{11}$')
plt.xlabel('p')
plt.ylabel('$\\rho_{xx}$')
plt.legend()
plt.title("Twirling of bit-flip channel")
Nähdään, ettei pyöräytys muuta bitinkääntökanavan toimintaa. Tehdään seuraavaksi sama koherentille kierrolle.
rhos_cr_twirled = []
for t in t_values:
qc = QuantumCircuit(4,1)
qc.rx(t,0)
res_t = TwirledStateTomography(qc, qc_s, [0], measurement_indices=[0]).run(backend=backend).block_for_results()
rhos_cr_twirled.append(res_t.analysis_results('state').value)
rhos_cr = []
for t in t_values:
qc = qc_s.copy()
qc.rx(t,0)
res = StateTomography(qc, measurement_indices=[0]).run(backend=backend, shots=4096).block_for_results()
rhos_cr.append(res.analysis_results('state').value)
tomo_rhos_cr_twirled = np.zeros((2,2,len(t_values)), dtype=complex)
for (i, res) in enumerate(rhos_cr_twirled):
tomo_rhos_cr_twirled[:,:,i] = res
tomo_rhos_cr = np.zeros((2,2,len(t_values)), dtype=complex)
for (i, res) in enumerate(rhos_cr):
tomo_rhos_cr[:,:,i] = res
plt.figure(figsize=(10,6))
# Twirled results
plt.plot(t_values, np.real(tomo_rhos_cr_twirled[0,1,:]),"C0*", label='Re $\\rho_{01} twirled$')
plt.plot(t_values, np.imag(tomo_rhos_cr_twirled[0,1,:]),"C1*", label='Im $\\rho_{01} twirled$')
plt.plot(t_values, np.real(tomo_rhos_cr_twirled[0,0,:]),"C2x", label='$\\rho_{00} twirled$')
plt.plot(t_values, np.real(tomo_rhos_cr_twirled[1,1,:]),"C3x", label='$\\rho_{11} twirled$')
# Non-twirled results
plt.plot(t_values, np.real(tomo_rhos_cr[0,1,:]),"C0--", label='Re $\\rho_{01}$')
plt.plot(t_values, np.imag(tomo_rhos_cr[0,1,:]),"C1--", label='Im $\\rho_{01}$')
plt.plot(t_values, np.real(tomo_rhos_cr[0,0,:]),"C2--", label='$\\rho_{00}$')
plt.plot(t_values, np.real(tomo_rhos_cr[1,1,:]),"C3--", label='$\\rho_{11}$')
plt.xlabel(r'$\theta$')
plt.ylabel('$\\rho_{xx}$')
plt.legend()
plt.title("Twirling of coherent rotation")
Pyöräytys muuttaa diagonaalien vaihetta ja imaginääriosaa ei-diagonaalitermeissä $\theta$:n suhteen. Viimeisenä tehdään tämä amplitudinvaimennuskanavalle.
rhos_ad_twirled = []
for p in p_values:
qc = QuantumCircuit(4)
error = amplitude_damping_error(p)
qc.append(error, [0])
res_t = TwirledStateTomography(qc, qc_s, [0], measurement_indices=[0]).run(backend=backend).block_for_results()
rhos_ad_twirled.append(res_t.analysis_results('state').value)
rhos_ad = []
for p in p_values:
qc = qc_s.copy()
error = amplitude_damping_error(p)
qc.append(error, [0])
res = StateTomography(qc, measurement_indices=[0]).run(backend=backend, shots=4096).block_for_results()
rhos_ad.append(res.analysis_results('state').value)
tomo_rhos_ad_twirled = np.zeros((2,2,len(p_values)), dtype=complex)
for (i, res) in enumerate(rhos_ad_twirled):
tomo_rhos_ad_twirled[:,:,i] = res
tomo_rhos_ad = np.zeros((2,2,len(p_values)), dtype=complex)
for (i, res) in enumerate(rhos_ad):
tomo_rhos_ad[:,:,i] = res
plt.figure(figsize=(10,6))
# Twirled results
plt.plot(p_values, np.real(tomo_rhos_ad_twirled[0,1,:]),"C0*", label='Re $\\rho_{01} twirled$')
plt.plot(p_values, np.imag(tomo_rhos_ad_twirled[0,1,:]),"C1*", label='Im $\\rho_{01} twirled$')
plt.plot(p_values, np.real(tomo_rhos_ad_twirled[0,0,:]),"C2x", label='$\\rho_{00} twirled$')
plt.plot(p_values, np.real(tomo_rhos_ad_twirled[1,1,:]),"C3x", label='$\\rho_{11} twirled$')
# Non-twirled results
plt.plot(p_values, np.real(tomo_rhos_ad[0,1,:]),"C0--", label='Re $\\rho_{01}$')
plt.plot(p_values, np.imag(tomo_rhos_ad[0,1,:]),"C1--", label='Im $\\rho_{01}$')
plt.plot(p_values, np.real(tomo_rhos_ad[0,0,:]),"C2--", label='$\\rho_{00}$')
plt.plot(p_values, np.real(tomo_rhos_ad[1,1,:]),"C3--", label='$\\rho_{11}$')
plt.xlabel('p')
plt.ylabel('$\\rho_{xx}$')
plt.legend()
plt.title("Twirling of amplitude damping channel")
Kun amplitudinvaimennuskanavaa pyöräytetään, voidaan huomata, että tiheysmatriisi lähestyy samalla tavoin yksikkömatriisia kuin depolarisoivan kanavan tapauksessa.
Tehtävä 4 (7p)
Viimeisenä, käännetään tai vaimennetaan pyöräytetty melukanava, jotta saadaan tiheysmatriisi ilman melua. Pyöräyttämisen jälkeen melukanavan tulisi olla Paulin kanavan muodossa, joka on suhteellisen helppo kääntää, jos melukertoimet tunnetaan. Käännetty kanava ei välttämättä ole fysikaalinen, sillä kertoimet voivat olla negatiivisia. Menetelmä tavallisten melukanavien kääntämiseksi kuvaillaan tutkimuksessa S. Mangini, et al. EPJ Quantum Technol. 9, 29 (2022).
Yleisen Paulin kanavan käänteiskanava kertoimilla $(p_{0}, p_{x}, p_{y}, p_{z})$ on $$\begin{aligned} & \Lambda^{-1}_{\boldsymbol{p}}(\Lambda) = \beta _{0} \Lambda + \beta _{1} \sigma _{x} {\Lambda} \sigma _{x} + \beta _{2} \sigma _{y} {\Lambda} \sigma _{y} + \beta _{3} \sigma _{z} {\Lambda} \sigma _{z}\quad \text{with} \\ & \beta _{0} =\frac{1}{4} \biggl(1+\frac{1}{1-2(p_{x}+p_{y})}+ \frac{1}{1-2(p_{x}+p_{z})}+\frac{1}{1-2(p_{y}+p_{z})} \biggr), \\ & \beta _{1} = \frac{1}{4} \biggl(1-\frac{1}{1-2(p_{x}+p_{y})}- \frac{1}{1-2(p_{x}+p_{z})}+\frac{1}{1-2(p_{y}+p_{z})} \biggr), \\ & \beta _{2} = \frac{1}{4} \biggl(1-\frac{1}{1-2(p_{x}+p_{y})}+ \frac{1}{1-2(p_{x}+p_{z})}-\frac{1}{1-2(p_{y}+p_{z})} \biggr), \\ & \beta _{3} = \frac{1}{4} \biggl(1+\frac{1}{1-2(p_{x}+p_{y})}- \frac{1}{1-2(p_{x}+p_{z})}-\frac{1}{1-2(p_{y}+p_{z})} \biggr) . \end{aligned}$$
Käyttäen tehtävän 1 pyöräytettyjen melukanavien kertoimia, käännä kaikki tehtävässä 3 löytämäsi tiheysmatriisit (jokaiselle $p$ ja $\theta$ arvolle) ja vertaa termejä $\rho_{00}$, $\rho_{11}$, $Re(\rho_{01})$ ja $Im(\rho_{01})$ kääntämättömiin versioihin esimerkiksi kuvaajien avulla.
Vihje: Kaavat yksinkertaistuvat huomattavasti, jos sijoitat niihin vakiot tehtävästä 1.
import numpy as np
from qiskit.quantum_info import Pauli
I, X, Y, Z = (Pauli(pauli).to_matrix() for pauli in ['I', 'X', 'Y', 'Z'])
rhos_bf_inverted = []
for p, rho in zip(p_values, rhos_bf_twirled):
# the inversion coefficients
q0 = 1/2*(1+1/(1-2*p))
q1 = 1/2*(1-1/(1-2*p))
q2 = 0
q3 = 0
mit_rho = np.zeros((2,2), dtype=complex)
for q, P in zip([q0,q1,q2,q3], [I, X, Y, Z]):
mit_rho += q * P @ rho.data @ P
rhos_bf_inverted.append(mit_rho)
tomo_rhos_bf_twirled = np.zeros((2,2,len(p_values)), dtype=complex)
for (i, res) in enumerate(rhos_bf_twirled):
tomo_rhos_bf_twirled[:,:,i] = res
tomo_rhos_bf_inverted = np.zeros((2,2,len(p_values)), dtype=complex)
for (i, res) in enumerate(rhos_bf_inverted):
tomo_rhos_bf_inverted[:,:,i] = res
plt.figure(figsize=(10,6))
# Twirled results
plt.plot(p_values, np.real(tomo_rhos_bf_twirled[0,1,:]),"C0--", label='Re $\\rho_{01} twirled$')
plt.plot(p_values, np.imag(tomo_rhos_bf_twirled[0,1,:]),"C1--", label='Im $\\rho_{01} twirled$')
plt.plot(p_values, np.real(tomo_rhos_bf_twirled[0,0,:]),"C2--", label='$\\rho_{00} twirled$')
plt.plot(p_values, np.real(tomo_rhos_bf_twirled[1,1,:]),"C3--", label='$\\rho_{11} twirled$')
# Non-twirled results
plt.plot(p_values, np.real(tomo_rhos_bf_inverted[0,1,:]),"C0*", label='Re $\\rho_{01} inverted$')
plt.plot(p_values, np.imag(tomo_rhos_bf_inverted[0,1,:]),"C1*", label='Im $\\rho_{01} inverted$')
plt.plot(p_values, np.real(tomo_rhos_bf_inverted[0,0,:]),"C2x", label='$\\rho_{00} inverted$')
plt.plot(p_values, np.real(tomo_rhos_bf_inverted[1,1,:]),"C3x", label='$\\rho_{11} inverted$')
plt.xlabel('p')
plt.ylabel('$\\rho_{xx}$')
plt.legend()
plt.title("Inversion of bit-flip channel")
rhos_cr_inverted = []
for t, rho in zip(t_values, rhos_cr_twirled):
# the inversion coefficients
q0 = 1/2*(1+1/(1-2*np.sin(t/2)**2))
q1 = 1/2*(1-1/(1-2*np.sin(t/2)**2))
q2 = 0
q3 = 0
mit_rho = np.zeros((2,2), dtype=complex)
for q, P in zip([q0,q1,q2,q3], [I, X, Y, Z]):
mit_rho += q * P @ rho.data @ P
rhos_cr_inverted.append(mit_rho)
tomo_rhos_cr_twirled = np.zeros((2,2,len(p_values)), dtype=complex)
for (i, res) in enumerate(rhos_cr_twirled):
tomo_rhos_cr_twirled[:,:,i] = res
tomo_rhos_cr_inverted = np.zeros((2,2,len(p_values)), dtype=complex)
for (i, res) in enumerate(rhos_cr_inverted):
tomo_rhos_cr_inverted[:,:,i] = res
plt.figure(figsize=(10,6))
# Twirled results
plt.plot(t_values, np.real(tomo_rhos_cr_twirled[0,1,:]),"C0--", label='Re $\\rho_{01} twirled$')
plt.plot(t_values, np.imag(tomo_rhos_cr_twirled[0,1,:]),"C1--", label='Im $\\rho_{01} twirled$')
plt.plot(t_values, np.real(tomo_rhos_cr_twirled[0,0,:]),"C2--", label='$\\rho_{00} twirled$')
plt.plot(t_values, np.real(tomo_rhos_cr_twirled[1,1,:]),"C3--", label='$\\rho_{11} twirled$')
# Non-twirled results
plt.plot(t_values, np.real(tomo_rhos_cr_inverted[0,1,:]),"C0*", label='Re $\\rho_{01} inverted$')
plt.plot(t_values, np.imag(tomo_rhos_cr_inverted[0,1,:]),"C1*", label='Im $\\rho_{01} inverted$')
plt.plot(t_values, np.real(tomo_rhos_cr_inverted[0,0,:]),"C2x", label='$\\rho_{00} inverted$')
plt.plot(t_values, np.real(tomo_rhos_cr_inverted[1,1,:]),"C3x", label='$\\rho_{11} inverted$')
plt.xlabel(r'$\theta$')
plt.ylabel('$\\rho_{xx}$')
plt.legend()
plt.title("Inversion of coherent rotation")
rhos_ad_inverted = []
for p, rho in zip(p_values, rhos_ad_twirled):
# the inversion coefficients
q0 = 1/4*(1+1/np.sqrt(1-p))**2
q1 = 1/4*(1-1/(1-p))
q2 = 1/4*(1-1/(1-p))
q3 = 1/4*(1-1/np.sqrt(1-p))**2
mit_rho = np.zeros((2,2), dtype=complex)
for q, P in zip([q0,q1,q2,q3], [I, X, Y, Z]):
mit_rho += q * P @ rho.data @ P
rhos_ad_inverted.append(mit_rho)
tomo_rhos_ad_twirled = np.zeros((2,2,len(p_values)), dtype=complex)
for (i, res) in enumerate(rhos_ad_twirled):
tomo_rhos_ad_twirled[:,:,i] = res
tomo_rhos_ad_inverted = np.zeros((2,2,len(p_values)), dtype=complex)
for (i, res) in enumerate(rhos_ad_inverted):
tomo_rhos_ad_inverted[:,:,i] = res
plt.figure(figsize=(10,6))
# Twirled results
plt.plot(p_values, np.real(tomo_rhos_ad_twirled[0,1,:]),"C0--", label='Re $\\rho_{01} twirled$')
plt.plot(p_values, np.imag(tomo_rhos_ad_twirled[0,1,:]),"C1--", label='Im $\\rho_{01} twirled$')
plt.plot(p_values, np.real(tomo_rhos_ad_twirled[0,0,:]),"C2--", label='$\\rho_{00} twirled$')
plt.plot(p_values, np.real(tomo_rhos_ad_twirled[1,1,:]),"C3--", label='$\\rho_{11} twirled$')
# Non-twirled results
plt.plot(p_values, np.real(tomo_rhos_ad_inverted[0,1,:]),"C0*", label='Re $\\rho_{01} inverted$')
plt.plot(p_values, np.imag(tomo_rhos_ad_inverted[0,1,:]),"C1*", label='Im $\\rho_{01} inverted$')
plt.plot(p_values, np.real(tomo_rhos_ad_inverted[0,0,:]),"C2x", label='$\\rho_{00} inverted$')
plt.plot(p_values, np.real(tomo_rhos_ad_inverted[1,1,:]),"C3x", label='$\\rho_{11} inverted$')
plt.xlabel('p')
plt.ylabel('$\\rho_{xx}$')
plt.legend()
plt.title("Inversion of amplitude damping channel")
Nähdään, että kaikki melukanavat voidaan pyöräyttää siten, että lopputuloksena saadaan palautettua meluton tiheysmatriisi. Tämä voidaan tehdä tällä suhteellisen helpolla tavalla, kunhan melukanava on Paulin kanavan muodossa, eli yleisen melukanavan tapauksessa kanavaa on pitänyt pyöräyttää ensin. Löytämällä melukertoimet todellisen kvanttilaitteen tapauksessa voidaan siis kääntää jopa tämän todellisen laitteen melu! Näiden kertoimien löytäminen voi kuitenkin olla vaikeaa ja tämä ongelma tunnetaankin melun karakterisointina (noise characterization) tai melun oppimisena (noise learning). Käytännössä halutaan kääntää melu monen kubitin piireille, erityisesti meluisille CNOT-porteille. Näissä tapauksissa voidaan soveltaa monia samoja periaatteita, mutta tekniset yksityiskohdat ovat luonnollisesti monimutkaisempia. Melun kääntäminen esimerkiksi piirin keskellä vaatii lisätekniikoita, kuten todennäköisyysvirheen kumoamista (probabilistic error cancellation).