4#include "QuantumEvalOp.h"
5#include "IntGenotype.h"
14const int numExtraA = 0;
16const int T = extraA+numExtraA;
20const int extraB = T+3;
21const int numExtraB = 0;
23const int E = extraB+numExtraB;
25const int NUM_WIRES = E+1;
31bool CONDITIONING =
true;
32bool COMPUTE_ACTUAL_RATE =
false;
38#include "Quantum/Quantum.h"
42std::vector <algebra::mat> EVec;
47 for(
int i=0; i<EVec.size(); ++i)
59 const int nGateTypes = 3;
69 const int nGateTypes = 4;
81 const int nGateTypes = 4;
107 double p, theta, psi;
111double SafeLog(
double x)
115 return log(x) / log(2.0);
117double entropy(
double x)
119 return -x*SafeLog(x) - (1-x)*SafeLog(1-x);
121double entropy(
double a,
double b,
double c,
double d)
123 return -a*SafeLog(a) - b*SafeLog(b) - c*SafeLog(c) - d*SafeLog(d);
128double ComputeFitness(std::list <QKD::Gate>& A, std::list <QKD::Gate>& B)
139 case QKD::Hadamard: dl.applyHadamard(target, control);
142 case QKD::NOT: dl.applyNOT(target, control);
145 case QKD::Measure: Measure: dl.measure(target);
151 case QKD::Hadamard: dl.applyHadamard(target, control);
154 case QKD::NOT: dl.applyNOT(target, control);
157 case QKD::Pi8: dl.applyPiOver8(target, control);
160 case QKD::Measure: dl.measure(target);
166 case QKD::Hadamard: dl.applyHadamard(target, control);
169 case QKD::NOT: dl.applyNOT(target, control);
172 case QKD::SU2: dl.applySU2(target, control, G.p, G.theta, G.psi);
175 case QKD::Measure: dl.measure(target);
181double ComputeFitness(std::list <QKD::Gate>& A, std::list <QKD::Gate>& B)
185 for(
int i=0; i<NUM_WIRES; ++i){
187 dl.dimension.push_back(2);
189 dl.dimension.push_back(4);
194 dl.density.push_back(kb);
198 std::list<QKD::Gate>::iterator Iter;
199 for(Iter = A.begin(); Iter != A.end(); ++Iter){
200 int target = Iter->target;
201 int control = Iter->control;
202 if(!Iter->controlMode)
206 if(target > ASpace || control > ASpace)
208 if(target == E || control == E)
211 if(Iter->controlMode && control == target)
214 applyGate(dl, target, control, *Iter);
231 dl.applyAttackOp(T, E);
235 std::list<QKD::Gate>::iterator Iter;
236 for(Iter = B.begin(); Iter != B.end(); ++Iter){
237 int target = Iter->target;
238 int control = Iter->control;
239 if(!Iter->controlMode)
243 if(target < T || (control < T && control >= 0))
245 if(target == E || control == E)
248 if(Iter->controlMode && control == target)
251 applyGate(dl, target, control, *Iter);
275 if(CONDITIONING ==
true) {
281 if(dl.density.empty())
289 while(!atk->getNext(EVec[0], EVec[1], EVec[2], EVec[3])){
291 double paccept = dl.trace(EVec, E);
292 if(paccept <= 0.00000001)
296 double p00 = dl.calculatePr(keyA, 0, keyB, 0, EVec, E);
297 double p01 = dl.calculatePr(keyA, 0, keyB, 1, EVec, E);
298 double p10 = dl.calculatePr(keyA, 1, keyB, 0, EVec, E);
299 double p11 = dl.calculatePr(keyA, 1, keyB, 1, EVec, E);
301 double HAB = entropy(p00, p01, p10, p11);
302 double HB = entropy(p00 + p10);
306 for(
int w=keyA+1; w<E; ++w)
313 double SAE = dl.entropy(EVec, E);
315 double SE = dl.entropy(EVec, E);
318 if(COMPUTE_ACTUAL_RATE)
319 rate = (SAE - SE) - (HAB - HB);
321 rate = paccept * ( (SAE-SE) - (HAB-HB) );
334 std::list <QKD::Gate> A, B;
344 std::list <QKD::Gate> A, B;
348 g.controlMode =
false;
352 g.type = QKD::Hadamard;
354 g.controlMode =
false;
360 g.controlMode =
true;
369 g.controlMode =
true;
375 g.controlMode =
false;
380 std::cout <<
"Test 1: key-rate (should be 1) = " << ComputeFitness(A,B) <<
"\n\n";
385 std::list <QKD::Gate> A, B;
390 g.controlMode =
false;
395 g.controlMode =
true;
401 g.controlMode =
false;
409 g.controlMode =
true;
414 g.controlMode =
false;
419 std::cout <<
"Test 1: key-rate = " << ComputeFitness(A,B) <<
"\n\n";
429 state->getRegistry()->registerEntry(
"noise", (voidP) (
new double(0.1)), ECF::DOUBLE,
"symmetric channel noise level");
430 state->getRegistry()->registerEntry(
"CONDITIONING", (voidP) (
new uint(1)), ECF::UINT,
"conditioning");
431 state->getRegistry()->registerEntry(
"COMPUTE_ACTUAL_RATE", (voidP) (
new uint(0)), ECF::UINT,
"COMPUTE_ACTUAL_RATE");
432 state->getRegistry()->registerEntry(
"CHANNEL", (voidP) (
new std::string(
"symmetric")), ECF::STRING,
"symmetric testChannel1 testChannel2");
448 voidP sptr = state->getRegistry()->getEntry(
"noise");
449 double noise = *((
double*)sptr.get());
451 sptr = state->getRegistry()->getEntry(
"CONDITIONING");
452 CONDITIONING = *((uint*)sptr.get()) ?
true :
false;
454 sptr = state->getRegistry()->getEntry(
"COMPUTE_ACTUAL_RATE");
455 COMPUTE_ACTUAL_RATE = *((uint*)sptr.get()) ?
true :
false;
457 sptr = state->getRegistry()->getEntry(
"CHANNEL");
458 std::string channel = *((std::string*)sptr.get());
463 if(channel ==
"testChannel1")
464 stats.testChannel1();
465 else if(channel ==
"testChannel2")
466 stats.testChannel2();
468 stats.symmetric(noise);
470 setupAttackVectors(stats);
474 std::cout <<
"Above value should be = " << stats.BB84Rate() <<
"\n";
481extern bool evaluateVerbose;
493 std::list <QKD::Gate> A, B;
496 for(uint i = 0; i < nGatesA; i++) {
498 gate.type = genType->intValues[i] % QKD::nGateTypes;
499 gate.target = genTarget->intValues[i] % nWiresA;
500 gate.controlMode = bitstr->bits[i];
501 gate.control = genControl->intValues[i] % nWiresA;
503 if(gate.type == QKD::Rotation) {
505 gate.theta = flpoint->
realValue[i * 3 + 1] * 2 * 3.1415926535;
506 gate.psi = flpoint->
realValue[i * 3 + 2] * 2 * 3.1415926535;
512 for(uint i = nGatesA; i < (nGatesA + nGatesB); i++) {
514 gate.type = genType->intValues[i] % QKD::nGateTypes;
515 gate.target = T + genTarget->intValues[i] % nWiresB;
516 gate.controlMode = bitstr->bits[i];
517 gate.control = T + genControl->intValues[i] % nWiresB;
519 if(gate.type == QKD::Rotation) {
521 gate.theta = flpoint->
realValue[i * 3 + 1];
522 gate.psi = flpoint->
realValue[i * 3 + 2];
528 fitness->setValue(ComputeFitness(A, B));
530 if(evaluateVerbose) {
532 ss <<
"Gates A:" << endl;
533 std::list<QKD::Gate>::iterator Iter;
534 for(Iter = A.begin(); Iter != A.end(); ++Iter) {
535 ss <<
"type " << Iter->type <<
" target " << Iter->target <<
" mode " << Iter->controlMode <<
" control: " << Iter->control;
536 if(Iter->type == QKD::Rotation)
537 ss <<
" p: " << Iter->p <<
" theta: " << Iter->theta <<
" psi: " << Iter->psi;
540 ss <<
"Gates B:" << endl;
541 for(Iter = B.begin(); Iter != B.end(); ++Iter) {
542 ss <<
"type " << Iter->type <<
" target " << Iter->target <<
" mode " << Iter->controlMode <<
" control: " << Iter->control;
543 if(Iter->type == QKD::Rotation)
544 ss <<
" p: " << Iter->p <<
" theta: " << Iter->theta <<
" psi: " << Iter->psi;
547 ECF_LOG(state_, 1, ss.str());
BitString class - implements genotype as a series of bits.
Fitness for maximization problems.
FloatingPoint class - implements genotype as a vector of floating point values.
void registerParameters(StateP)
Register evaluator parameters. Called before EvaluateOp::initialize method.
bool initialize(StateP)
Initialize the evaluator. Called before first evaluation occurs.
FitnessP evaluate(IndividualP individual)
Evaluate a single individual. Method must create and return a Fitness object.
std::vector< double > realValue
vector of floating point values