Commit 16130be9 by dwuggh

### structurize

parent 916f1777
 import numpy as np from functools import reduce from utils import * from QOperator import * from QChannel import * from .utils import * from .QOperator import * from .QChannel import * class DensityOperator(QOperator): ... ... @@ -61,20 +61,31 @@ class DensityOperator(QOperator): return result # bell measurement: only result 00 and 11 will be reserved ''' In the paper, measurement error is modeled by perfect measurement preceded by inversion of the state with probability $p_m$. ''' def bell_measure(self, q1, q2, pauli, p_m = 0): channel1 = measure_x(q1) if pauli == 'x' else measure_z(q2) channel2 = measure_x(q1) if pauli == 'x' else measure_z(q2) # the 4 projection operator P_00 = multiply(channel1.kraus_operators[0], channel2.kraus_operators[0]) P_01 = multiply(channel1.kraus_operators[0], channel2.kraus_operators[1]) P_10 = multiply(channel1.kraus_operators[1], channel2.kraus_operators[0]) P_11 = multiply(channel1.kraus_operators[1], channel2.kraus_operators[1]) p1 = (1 - p_m) ** 2 + p_m ** 2 p2 = 2 * p_m * (1 - p_m) p1 = np.sqrt(p1) p2 = np.sqrt(p2) # this channel will cause probability loss because of post-selection loss_channel = QChannel([P_00, P_11]) # self.print() loss_channel = QChannel([P_00.scale_to(p1), P_01.scale_to(p2), P_10.scale_to(p2), P_11.scale_to(p1)]) self.channel(loss_channel) # self.print() operator = self.partial_trace([q1, q2]) self.operator = operator.operator self.qubits = operator.qubits # self.print() ... ...
 import numpy as np from functools import reduce from utils import * from QOperator import * from .utils import * from .QOperator import * class QChannel(object): ... ... @@ -23,6 +23,13 @@ class QChannel(object): # op = op.broadcast(qnum) ''' depolarizing channel for $n$ qubits $$ε(ρ) = (1 - p)ρ + \\frac{ρ}{4^n - 1} \sum (⊗ A_i) ρ (⊗ A_i^\dagger)$$ ''' def depolarizing_channel(p, qubits = [0]) -> QChannel: operators = [] qnum = len(qubits) ... ... @@ -32,7 +39,7 @@ def depolarizing_channel(p, qubits = [0]) -> QChannel: operators.append(QOperator(qubits, E_0)) # 4 ** qnum - 1 other operators for i in range(4 ** qnum): # i = 0 is just the identity operator, which has already been considered above # the i = 0 case is just I, which has already been considered above if i == 0: continue indices = np.flip(get_n_digits(i, 4, qnum)) ... ...
 import numpy as np from utils import * from .utils import * class QOperator(object): def __init__(self, qubits, operator: np.ndarray): ... ... @@ -26,6 +26,11 @@ class QOperator(object): qubits = np.array(qubits) return QOperator(qubits, self.operator) # scale this operator by a scalar. def scale_to(self, scalar): operator = self.operator * scalar return QOperator(self.qubits, operator) # construct gate in the big hilbert space # G = I ⊗ G def broadcast(self, qnum: int): ... ...
 from .utils import * from .QOperator import * from .QChannel import * from .DensityOperator import * from .fidelity import * from .purify_circuits import * # from os.path import dirname, basename, isfile # import glob # from importlib import reload # modules = glob.glob(dirname(__file__)+"/*.py") # __all__ = [ basename(f)[:-3] for f in modules if isfile(f) and not f.endswith('__init__.py')] # from . import * # for module in __all__: # reload(module) # del dirname, basename, isfile, glob, modules
 from .QOperator import * from .DensityOperator import * def entanglement_fidelity(ρ1: DensityOperator, ρ2: DensityOperator): return np.matmul(ρ1.operator, ρ2.operator).trace() def bell_fidelity(ρ: DensityOperator): perfect_bell = bell_pair(0, [0, 1]) return entanglement_fidelity(perfect_bell, ρ)
 import numpy as np from functools import reduce from utils import * from QOperator import * from QChannel import * from DensityOperator import * from fidelity import * from .utils import * from .QOperator import * from .QChannel import * from .DensityOperator import * from .fidelity import * ... ... @@ -18,10 +18,10 @@ q4 ---|-----∎--⊤--M(x) q3 ---∎--⊤-----Z--M(x) data2 ------σ------------ ''' def nickerson_1(ρ: DensityOperator, err_model: ErrorModel, data1, data2, q1, q2, q3 ,q4, pauli): def bell_purify_1(ρ: DensityOperator, err_model: ErrorModel, data1, data2, q1, q2, q3 ,q4, pauli): ρ1 = bell_pair(err_model.p_n, [q1, q3]) ρ.merge(ρ1) ρ.print() # ρ.print() # 2 control-pauli gate c1 = cpauli(pauli, [q1, data1]) ... ... @@ -29,7 +29,7 @@ def nickerson_1(ρ: DensityOperator, err_model: ErrorModel, data1, data2, q1, q2 ρ.evolution(c1, err_model.p_g) ρ.evolution(c2, err_model.p_g) ρ.print() # ρ.print() ρ2 = bell_pair(err_model.p_n, [q2, q4]) ρ.merge(ρ2) ... ... @@ -48,7 +48,7 @@ def nickerson_1(ρ: DensityOperator, err_model: ErrorModel, data1, data2, q1, q2 ''' q1, q2, q3, q4 are the 4 ancilla qubits stringent_plus indicates whether the blank-separated region is performed stringent indicates whether the blank-separated region is performed q2 ------∎--⊤--M(x)--∎--⊤--M(x)---- --∎--⊤--M(x)-- ------ q1 ---∎--|--X--------|--Z-------⊤-- --|--Z-------- --M(x) data1 ---|--|-----------|----------σ-- --|----------- ------ ... ... @@ -57,7 +57,7 @@ q4 ---|--∎--⊤--M(x)--∎--⊤--M(x)---- --∎--⊤--M(x)-- ------ q3 ---∎-----X-----------Z-------⊤-- -----Z-------- --M(x) data2 -----------------------------σ-- -------------- ------ ''' def nickerson_2(ρ: DensityOperator, err_model: ErrorModel, data1, data2, q1, q2, q3 ,q4, pauli, stringent_plus = True): def bell_purify_2(ρ: DensityOperator, err_model: ErrorModel, data1, data2, q1, q2, q3 ,q4, pauli, stringent = True): # for efficiency improvement ρ1 = bell_pair(err_model.p_n, [q1, q3]) ... ... @@ -90,7 +90,7 @@ def nickerson_2(ρ: DensityOperator, err_model: ErrorModel, data1, data2, q1, q2 ρ.evolution(c5, err_model.p_g) ρ.evolution(c6, err_model.p_g) if stringent_plus: if stringent: ρ4 = bell_pair(err_model.p_n, [q2, q4]) ρ.merge(ρ4) ... ... @@ -106,17 +106,22 @@ def nickerson_2(ρ: DensityOperator, err_model: ErrorModel, data1, data2, q1, q2 ρ.bell_measure(q1, q3, 'x', err_model.p_m) ''' qubit indexing: 2 5 1 4 0 3 ''' def make_bell(err_model: ErrorModel, stringent = True, stringent_plus = True): ρ = bell_pair(err_model.p_n, [0, 3]) nickerson_1(ρ, err_model, 0, 3, 1, 2, 4, 5, 'z') nickerson_1(ρ, err_model, 0, 3, 1, 2, 4, 5, 'x') bell_purify_1(ρ, err_model, 0, 3, 1, 2, 4, 5, 'z') print(bell_fidelity(ρ)) bell_purify_1(ρ, err_model, 0, 3, 1, 2, 4, 5, 'x') print(bell_fidelity(ρ)) if stringent: nickerson_2(ρ, err_model, 0, 3, 1, 2, 4, 5, 'z', stringent_plus) nickerson_2(ρ, err_model, 0, 3, 1, 2, 4, 5, 'x', stringent_plus) bell_purify_2(ρ, err_model, 0, 3, 1, 2, 4, 5, 'z', stringent) print(bell_fidelity(ρ)) bell_purify_2(ρ, err_model, 0, 3, 1, 2, 4, 5, 'x', stringent) print(bell_fidelity(ρ)) return ρ ... ...
File moved
 from QOperator import pauli from utils import ErrorModel import calc_channel as cc import numpy as np ... ... @@ -28,9 +26,6 @@ D: 9, 10, 11 def test_1(): np.set_printoptions(edgeitems=16, linewidth=200, # formatter=dict(float=lambda x: "%.3g" % x) ) err_model = cc.ErrorModel() ρ1 = cc.bell_pair(err_model.p_n, [1, 3]) ρ2 = cc.bell_pair(err_model.p_n, [2, 4]) ... ... @@ -71,9 +66,12 @@ if __name__ == "__main__": # a = test_1() # test_3() np.set_printoptions(edgeitems=16, linewidth=200, formatter=dict(float=lambda x: "%5.6g" % x) formatter=dict(float=lambda x: "%6.4g" % x) ) err_model = cc.ErrorModel(0.1, 0.01) ρ = cc.make_bell(err_model, True, False) ρ.print() # test_2() perfect_bell = cc.bell_pair(0, [0, 1]) err_model = cc.ErrorModel(0.1, 0.005, 0.005) noise_bell = cc.bell_pair(err_model.p_n, [0, 1]) print("no purification: ", cc.entanglement_fidelity(perfect_bell, noise_bell)) ρ = cc.make_bell(err_model, False, False) print("with purification: ", cc.entanglement_fidelity(perfect_bell, ρ))
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!