16#include "Quantum/Algebra.h"
22 std::vector < std::vector < Complex > > B;
25 Complex innerProduct(std::vector < Complex >& a, std::vector < Complex >& b)
29 for(
int i=0; i<a.size(); ++i)
30 sum = sum + a[i] * conj(b[i]);
35 double norm(std::vector <Complex> & a)
39 for(
int i=0; i<a.size(); ++i){
40 b = a[i] * conj(a[i]);
50 double p00, p01, p10, p11;
56 double SafeLog(
double x)
60 return log(x)/log(2.0);
62 double entropy(
double x)
65 std::cout <<
"Entropy error: x = " << x <<
"\n";
70 return -x*SafeLog(x) - (1-x)*SafeLog(1-x);
72 double HAB(
double key00,
double key01,
double key10,
double key11)
74 double first = -key00*SafeLog(key00) - key01*SafeLog(key01) - key10*SafeLog(key10) - key11*SafeLog(key11);
76 if(key00+key10 > 1.00001)
77 std::cout <<
"HAB ERROR!\n";
78 double second = entropy(key00+key10);
85 void symmetric(
double Q);
123 void printChannel(std::ostream& f)
125 f <<
"CHANNEL STATS:\n";
126 f <<
"p00 = " << p00 <<
"\n";
127 f <<
"p01 = " << p01 <<
"\n";
128 f <<
"p10 = " << p10 <<
"\n";
129 f <<
"p11 = " << p11 <<
"\n\n";
131 f <<
"Qx = " << Qx <<
"\n";
132 f <<
"Qy = " << Qy <<
"\n\n";
134 f <<
"p0+ = " << p0a <<
"\n";
135 f <<
"p1+ = " << p1a <<
"\n";
136 f <<
"p+0 = " << pa0 <<
"\n\n";
138 f <<
"p0Y = " << p0b <<
"\n";
139 f <<
"p1Y = " << p1b <<
"\n";
140 f <<
"pY0 = " << pb0 <<
"\n\n";
143 double randFloat(
double small,
double large)
145 int r = rand()%RAND_MAX;
146 double r2 = r / (double)RAND_MAX;
148 return (large-small)*r2 + small;
151 void generateRandom(
double p01,
double p10);
152 void chooseRandomVector(
double minScale,
double maxScale, std::vector <Complex>& v,
int startIndex,
int endIndex);
157 static const double precision = .01;
182 double im03lb = -SafeSqrt(E00*E33 - ReE03*ReE03);
183 double im12lb = -SafeSqrt(E11*E22 - ReE12*ReE12);
185 E03 = creal(E03) + I*im03lb;
186 E12 = creal(E12) + I*im12lb;
199 done = buildAttackVec(e0, e1, e2, e3);
202 E12 = creal(E12) + I*(cimag(E12)+precision);
203 if(creal(E12*conj(E12)) > E11*E22){
204 double im12lb = -SafeSqrt(E11*E22 - ReE12*ReE12);
205 E12 = creal(E12) + I*im12lb;
207 E03 = creal(E03) + I*(cimag(E03) + precision);
208 if(creal(E03*conj(E03)) > E00*E33){
210 throw(std::string(
"NO ATTACKS"));
222 double SafeSqrt(
double x)
225 std::cout <<
"\n\nSafeSQRT Error: x = " << x <<
"\n\n";
226 throw(std::string(
"SafeSQRT Error; X negative."));
237 Complex a0 = SafeSqrt(stats.p00);
240 Complex a3 = E03 / creal(a0);
242 if(stats.p11 - creal(a3)*creal(a3) - cimag(a3)*cimag(a3) < 0)
244 Complex b3 = SafeSqrt(stats.p11 - creal(a3)*creal(a3) - cimag(a3)*cimag(a3));
248 Complex a1 = E01 / creal(a0);
249 Complex b1 = E13 - conj(a1)*a3;
250 b1 = b1 * (1.0/creal(b3));
252 if(creal(b3) < .0000001){
256 if(stats.p01 - creal(a1*conj(a1) + b1*conj(b1)) < 0)
259 Complex c1 = SafeSqrt(stats.p01 - creal(a1*conj(a1) + b1*conj(b1)));
263 Complex a2 = E02/creal(a0);
264 Complex b2 = E23 - conj(a2)*a3;
265 b2 = b2 * (1.0/creal(b3));
268 if(creal(b3) < .0000001){
270 Complex check = conj(a1)*a3;
271 if(fabs(creal(check) - creal(E13)) > .0000001 ||
272 fabs(cimag(check) - cimag(E13)) > .0000001){
279 Complex c2 = E12 - conj(a1)*a2 - conj(b1)*b2;
282 c2 = c2 * (1.0/creal(c1));
284 if(creal(c1) < .0000001){
286 Complex check = conj(a1)*a2 + conj(b1)*b2;
287 if(fabs(creal(check) - creal(E12)) > .0000001 ||
288 fabs(cimag(check) - cimag(E12)) > .0000001){
297 double test = stats.p10 - creal( a2*conj(a2) + b2*conj(b2) + c2*conj(c2) );
300 Complex d2 = SafeSqrt(test);
347 E01 = stats.p0a - .5 + I*(stats.p0b-.5);
348 E23 = stats.p1a - .5 + I*(stats.p1b-.5);
349 E02 = stats.pa0 - .5*(E00+E22) + I*(.5*(E00+E22)-stats.pb0);
352 ReE03 = 1 - stats.Qx - stats.Qy - .5*(creal(E01) + cimag(E01) + creal(E23) + cimag(E23));
353 ReE12 = stats.Qy - stats.Qx + .5*(cimag(E01) - creal(E01) + cimag(E23) - creal(E23));
362 double E00, E11, E22, E33;
363 Complex E01, E23, E02, E13;