This repository was archived by the owner on Dec 15, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathQbit.cxx
More file actions
141 lines (117 loc) · 4.89 KB
/
Qbit.cxx
File metadata and controls
141 lines (117 loc) · 4.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//
// Created by Filippo Valle on 15/11/2018.
//
#include "Qbit.h"
/// default constructor for qbit
Qbit::Qbit(bool islogic) : fIsLogic(islogic) {
if(Qbit::DEBUG) printf("\nCreating qbit..\n");
if(fIsLogic) fPhysicsQbits = 3;
else fPhysicsQbits = 1;
fTheta = new double[fPhysicsQbits];
for(int qbit = 0; qbit < fPhysicsQbits; qbit++) fTheta[qbit] = 0.;
fBase = ZeroOne;
fState = false; // il Qbit di default è costruito con polarizzazione orizzontale: base=ZeroOne, polarizzazione=0
}
///copy constructor
Qbit::Qbit(const Qbit &qbit) : fPhysicsQbits(qbit.fPhysicsQbits),
fBase(qbit.fBase),
fState(qbit.fState),
fIsLogic(qbit.fIsLogic)
{
if(Qbit::DEBUG) printf("\nCopying qbit..\n");
fTheta=new double[qbit.fPhysicsQbits];
PrepareTheta();
}
Qbit &Qbit::operator=(const Qbit &source) {
if(this == &source) return *this;
this->~Qbit();
new(this) Qbit(source);
return *this;
}
Qbit::~Qbit() {
if(Qbit::DEBUG) printf("\nDestroying qbit..\n");
delete[] fTheta;
}
//Force state to be in a particular condition (aka preparation)
void Qbit::PrepareState(base b, polarization pol){
if(Qbit::DEBUG) printf("\nPreparing qbit..\n");
fBase = b;
fState = pol;
PrepareTheta();
}
//define theta basing on base and polarization
void Qbit::PrepareTheta() {
if (Qbit::DEBUG) printf("\nPreparing qbit\n");
double angleToSet = 0.;
if (fBase == ZeroOne) {
if (fState) {
//base ZeroOne up --> preparing state |1>
angleToSet = TMath::PiOver2();
}else {
//base ZeroOne down --> preparing state |0>
angleToSet = 0.;
}
}else{
if (fState) {
//base PlusMinus up --> preparing state |+>
angleToSet = TMath::PiOver4();
}else {
//base PlusMinus down --> preparing state |->
angleToSet = -TMath::PiOver4();
}
}
//note: logic qbits have all 3 physical qbits identical during preparation
for (int qbit = 0; qbit < fPhysicsQbits; qbit++) fTheta[qbit] = angleToSet;
}
/// measure a state: base collapse in measured base
/// and state collapsed up or down with a certain probability
void Qbit::MeasureState(base b) {
if (Qbit::DEBUG) printf("\nMeasuring qbit\n");
fBase = b; //Qbit collapse to the base used for measure
// Measuring base PlusMinus is the same as measuring with a ZeroOne filter
// a qubit rotated by 45grad anticlockwise
if (b == PlusMinus) for(int iqbit = 0; iqbit < fPhysicsQbits; iqbit++) fTheta[iqbit] += TMath::PiOver4();
if (!fIsLogic) { //if qbit is physical I simply measure it
fState = MeasurePhisicalqbit(0);
}else{ //if qbit is logic I measure all qbits and then extimate syndrome
polarization measures[fPhysicsQbits];
for (int iqbit = 0; iqbit < fPhysicsQbits; iqbit++) measures[iqbit] = MeasurePhisicalqbit(iqbit);
bool syndrome01 = measures[0] == measures[1];
bool syndrome12 = measures[1] == measures[2];
if(syndrome01){//0 e 1 are the same --> measure first qbit (eg 001)
fState = measures[0];
}else{//0 e 1 are different
if(syndrome12){ //1 e 2 are the same --> measure second qbit (011)
fState = measures[1];
}else{//both 0 and 1 , 1 and 2 are different --> measure first qbit (010)
fState = measures[0];
}
}
}
// after measure angle has to be set to inial condition
PrepareTheta();
}
polarization Qbit::MeasurePhisicalqbit(int q) { // q = index of qbit we want measure
double cosTheta = TMath::Cos(fTheta[q]);
//Return the polarization of the object
//if base is ZeroOne state is cos() |0> + sin() |1>
//it is zero (aka down or false) with probability cos*cos
return gRandom->Rndm() > cosTheta * cosTheta;
}
bool Qbit::operator==(const Qbit &qitCompared) const {
if(fBase == qitCompared.fBase){// confronto due qbit: se hanno la stessa base --> guardo lo stato
if(fState) return qitCompared.fState; //se primo è vero, sono uguali se secondo è vero
else return !qitCompared.fState; //se primo è falso sono uguali se secondo è !vero
}else{
return false;
}
}
ostream& operator<<(ostream& os, const Qbit q){ //prende una referenza a un tipo ostrem e restituisce una referenza a un tipo ostream
os << (q.fIsLogic?"logic":"physic") << " qbit"<< ", state: " <<q.fState << ", base: "<<q.fBase<<std::endl;
for(int qbit = 0; qbit < q.fPhysicsQbits; qbit++) os <<"\ntheta "<< q.fTheta[qbit]<<std::endl<<std::endl<<std::endl;
return os;
}
void Qbit::AddNoise(std::function<double()> pdfNoise) {
// la pdf aggiunge rumore indipendentemente a ogni qbit fisico
for (int iqbit = 0; iqbit < fPhysicsQbits; iqbit++) fTheta[iqbit]+=pdfNoise();
}