18void Basis::orthoganalize()
21 std::vector < std::vector <Complex> > u;
23 for(
unsigned int i=1; i<B.size(); ++i)
26 Complex top, bottom, p, c;
27 for(
unsigned int k=0; k<i; ++k)
29 top = innerProduct(B[i], u[k]);
30 p = innerProduct(u[k], u[k]);
31 bottom = algebra::ComplexHelper::invert(p);
32 p = algebra::ComplexHelper::mult(top, bottom);
33 for(
unsigned int j=0; j<B[i].size(); ++j)
35 c = algebra::ComplexHelper::mult(p, u[k][j]);
36 u[i][j] = u[i][j] - c;
41 for(
unsigned int i=0; i<B.size(); ++i)
43 double n = norm(u[i]);
47 for(
unsigned int j=0; j<B[i].size(); ++j)
54Complex KetBra::trace(std::vector <Basis>& basis)
56 unsigned int basisIndex = basis.size()+1;
57 for(
unsigned int i=0; i<basis.size(); ++i)
59 if(!basis[i].B.empty())
63 Complex tr=1, zero = 0;
65 for(
unsigned int i=0; i<ket.size(); ++i)
69 if(i != ket.size()-1 && ket[i] != bra[i])
76 for(
unsigned int j=0; j<basis[basis.size()-1].B[ket[i]].size(); ++j)
79 Complex b = conj(basis[basis.size()-1].B[ket[i]][j]);
81 Complex b2 = algebra::ComplexHelper::mult(basis[basis.size()-1].B[bra[i]][j], b);
86 b = algebra::ComplexHelper::mult(tr, sum);
91 Complex c = algebra::ComplexHelper::mult(p, tr);
96Complex KetBra::trace()
99 Complex tr=1, zero = 0;
101 for(
unsigned int i=0; i<ket.size(); ++i)
107 Complex c = algebra::ComplexHelper::mult(p, tr);
113void DensityList::applyOp(
int space)
121 std::list <KetBra>::iterator Iter;
122 std::list <KetBra> newDensity;
123 for(Iter=density.begin(); Iter != density.end(); ++Iter)
125 for(
int i=0; i<dimension[space]; ++i)
127 for(
int j=0; j<dimension[space]; ++j)
132 kb.ket[space+1] = Iter->ket[space]*dimension[space]+i;
134 kb.bra[space+1] = Iter->bra[space]*dimension[space]+j;
135 newDensity.push_back(kb);
140 density = newDensity;
143void DensityList::conditionalSet(std::vector <int>& targetSpace, std::vector <int>& targetVal, std::vector <int>& condSpace, std::vector <int>& condVal)
145 std::list <KetBra>::iterator Iter;
146 for(Iter = density.begin(); Iter != density.end(); ++Iter)
149 for(
int i=0; i<(int)condSpace.size(); ++i)
151 if(Iter->ket[condSpace[i]] != condVal[i])
156 for(
int i=0; i<(int)targetSpace.size(); ++i)
157 Iter->ket[targetSpace[i]] = targetVal[i];
161 for(
int i=0; i<(int)condSpace.size(); ++i)
163 if(Iter->bra[condSpace[i]] != condVal[i])
168 for(
int i=0; i<(int)targetSpace.size(); ++i)
169 Iter->bra[targetSpace[i]] = targetVal[i];
174void DensityList::applyOp(
int startSpace,
int endSpace)
179 for(
int i=startSpace; i<endSpace; ++i)
182 std::list <KetBra>::iterator Iter;
183 std::list <KetBra> newDensity;
184 for(Iter=density.begin(); Iter != density.end(); ++Iter)
187 int indexKet=0, indexBra = 0, dim=1;
188 for(
int i=startSpace; i<endSpace; ++i)
190 indexKet += dim*Iter->ket[i];
191 indexBra += dim*Iter->bra[i];
194 std::vector <int> k,b;
195 k.resize(endSpace-startSpace);
196 b.resize(endSpace-startSpace);
197 for(
int i=0; i<endSpace-startSpace; ++i)
202 for(
int i=0; i<N; ++i)
204 for(
int a=0; a<endSpace-startSpace; ++a)
207 for(
int j=0; j<N; ++j)
211 for(
int m=startSpace; m<endSpace; ++m)
213 kb.ket[m] = k[m-startSpace];
214 kb.bra[m] = b[m-startSpace];
216 kb.ket[endSpace] = indexKet*N+i;
217 kb.bra[endSpace] = indexBra*N+j;
218 newDensity.push_back(kb);
220 for(
int m=0; m<endSpace-startSpace; ++m)
223 if(b[m] >= dimension[m+startSpace])
229 for(
int m=0; m<endSpace-startSpace; ++m)
232 if(k[m] >= dimension[m+startSpace])
240 density = newDensity;
243void DensityList::trace(
int space, DensityList& output)
245 std::list <KetBra>::iterator Iter;
247 output.density.clear();
249 for(Iter=density.begin(); Iter != density.end(); ++Iter)
251 if(Iter->ket[space] == Iter->bra[space])
256 output.density.push_back(kb);
261void DensityList::trace(
int space)
264 std::list <KetBra>::iterator Iter;
266 output.density.clear();
268 for(Iter=density.begin(); Iter != density.end(); ++Iter)
270 if(Iter->ket[space] == Iter->bra[space])
275 output.density.push_back(kb);
278 density = output.density;
281void DensityList::applyOp(
int space1,
int space2, Basis& op)
283 std::list <KetBra>::iterator Iter;
284 std::list <KetBra> newDensity;
286 for(Iter=density.begin(); Iter != density.end(); ++Iter)
288 std::vector < std::vector <int> > newKets, newBras;
289 std::vector <Complex> pk, pb;
293 int index = Iter->ket[space1] * dimension[space2] + Iter->ket[space2];
296 for(
unsigned int i=0; i<op.B[index].size(); ++i)
298 std::vector <int> k = Iter->ket;
301 pk.push_back(op.B[index][i]);
302 newKets.push_back(k);
304 if(c2 >= dimension[space2])
312 index = Iter->bra[space1] * dimension[space2] + Iter->bra[space2];
316 for(
unsigned int i=0; i<op.B[index].size(); ++i)
318 std::vector <int> b = Iter->bra;
321 Complex c = conj(op.B[index][i]);
324 newBras.push_back(b);
326 if(c2 >= dimension[space2])
334 for(
unsigned int i=0; i<newKets.size(); ++i)
336 for(
unsigned int j=0; j<newBras.size(); ++j)
342 c = algebra::ComplexHelper::mult(pk[i], pb[j]);
343 kb.p = algebra::ComplexHelper::mult(Iter->p, c);
344 if(creal(kb.p) != 0 || cimag(kb.p) != 0)
345 newDensity.push_back(kb);
350 density = newDensity;
353void DensityList::applyOp(
int space1,
int space2,
int space3, Basis& op)
355 std::list <KetBra>::iterator Iter;
356 std::list <KetBra> newDensity;
358 for(Iter=density.begin(); Iter != density.end(); ++Iter)
360 std::vector < std::vector <int> > newKets, newBras;
361 std::vector <Complex> pk, pb;
365 int index = Iter->ket[space1] * dimension[space2] * dimension[space3] + Iter->ket[space2] * dimension[space3] + Iter->ket[space3];
367 int c1=0, c2=0, c3=0;
368 for(
unsigned int i=0; i<op.B[index].size(); ++i)
370 std::vector <int> k = Iter->ket;
374 pk.push_back(op.B[index][i]);
375 newKets.push_back(k);
377 if(c3 >= dimension[space3])
381 if(c2 >= dimension[space2])
390 index = Iter->bra[space1] * dimension[space2] * dimension[space3] + Iter->bra[space2] * dimension[space3] + Iter->bra[space3];
395 for(
unsigned int i=0; i<op.B[index].size(); ++i)
397 std::vector <int> b = Iter->bra;
401 Complex c = conj(op.B[index][i]);
404 newBras.push_back(b);
406 if(c3 >= dimension[space3])
410 if(c2 >= dimension[space2])
419 for(
unsigned int i=0; i<newKets.size(); ++i)
421 for(
unsigned int j=0; j<newBras.size(); ++j)
427 c = algebra::ComplexHelper::mult(pk[i], pb[j]);
428 kb.p = algebra::ComplexHelper::mult(Iter->p, c);
430 if(fabs(creal(kb.p)) >= 0.0000001 || fabs(cimag(kb.p)) >= 0.0000001)
431 newDensity.push_back(kb);
436 density = newDensity;
439void DensityList::applyConditionalOp(
int condSpace,
int cond,
int space,
algebra::mat& U)
441 std::list <KetBra>::iterator Iter;
443 std::list <KetBra> newDensity;
446 for(Iter=density.begin(); Iter != density.end(); ++Iter)
448 std::vector < std::vector <int> > ket, bra;
449 std::vector <Complex> pk, pb;
450 if(Iter->ket[condSpace] == cond)
452 std::vector <int> k = Iter->ket;
453 for(
int r=0; r<U.getRows(); ++r)
456 Complex c = U(r, Iter->ket[space]);
463 ket.push_back(Iter->ket);
467 if(Iter->bra[condSpace] == cond)
469 std::vector <int> b = Iter->bra;
470 for(
int r=0; r<U.getRows(); ++r)
473 Complex c = conj(U(r, Iter->bra[space]));
481 bra.push_back(Iter->bra);
485 for(
unsigned int i=0; i<ket.size(); ++i)
487 for(
unsigned int j=0; j<bra.size(); ++j)
493 c = algebra::ComplexHelper::mult(pk[i], pb[j]);
494 kb.p = algebra::ComplexHelper::mult(Iter->p, c);
495 if(creal(kb.p) != 0 || cimag(kb.p) != 0)
496 newDensity.push_back(kb);
501 density = newDensity;
506 std::list <KetBra>::iterator Iter;
508 std::list <KetBra> newDensity;
510 for(Iter=density.begin(); Iter != density.end(); ++Iter)
512 std::vector < std::vector <int> > ket, bra;
513 std::vector <Complex> pk, pb;
516 std::vector <int> k = Iter->ket;
517 for(
int r=0; r<U.getRows(); ++r)
520 Complex c = U(r, Iter->ket[space]);
533 std::vector <int> b = Iter->bra;
534 for(
int r=0; r<U.getRows(); ++r)
537 Complex c = conj(U(r, Iter->bra[space]));
549 for(
unsigned int i=0; i<ket.size(); ++i)
551 for(
unsigned int j=0; j<bra.size(); ++j)
557 c = algebra::ComplexHelper::mult(pk[i], pb[j]);
558 kb.p = algebra::ComplexHelper::mult(Iter->p, c);
559 if(creal(kb.p) != 0 || cimag(kb.p) != 0)
560 newDensity.push_back(kb);
565 density = newDensity;
571void DensityList::applyOp(
algebra::mat& U,
int transitSpace)
573 std::list <KetBra>::iterator Iter;
575 std::list <KetBra> newDensity;
577 for(Iter=density.begin(); Iter != density.end(); ++Iter)
579 std::vector < std::vector <int> > ket, bra;
580 std::vector <Complex> pk, pb;
582 std::vector <int> k = Iter->ket;
583 int n = dimension[transitSpace+2];
584 int a = Iter->ket[transitSpace+2];
585 int g = Iter->ket[transitSpace+1];
586 int t = Iter->ket[transitSpace];
587 int col = a+g*n+2*n*t;
589 for(
int a2 = 0; a2<n; ++a2){
590 for(
int g2=0; g2<2; ++g2){
591 for(
int t2=0; t2<2; ++t2){
592 int row = a2+g2*n+2*n*t2;
593 Complex c = U(row, col);
594 k[transitSpace] = t2;
595 k[transitSpace+1] = g2;
596 k[transitSpace+2] = a2;
605 std::vector <int> b = Iter->bra;
606 int n = dimension[transitSpace+2];
607 int a = Iter->bra[transitSpace+2];
608 int g = Iter->bra[transitSpace+1];
609 int t = Iter->bra[transitSpace];
610 int col = a+g*n+2*n*t;
612 for(
int a2 = 0; a2<n; ++a2){
613 for(
int g2=0; g2<2; ++g2){
614 for(
int t2=0; t2<2; ++t2){
615 int row = a2+g2*n+2*n*t2;
616 Complex c = conj(U(row, col));
617 b[transitSpace] = t2;
618 b[transitSpace+1] = g2;
619 b[transitSpace+2] = a2;
627 for(
unsigned int i=0; i<ket.size(); ++i)
629 for(
unsigned int j=0; j<bra.size(); ++j)
635 c = algebra::ComplexHelper::mult(pk[i], pb[j]);
636 kb.p = algebra::ComplexHelper::mult(Iter->p, c);
637 if(creal(kb.p) != 0 || cimag(kb.p) != 0)
638 newDensity.push_back(kb);
643 density = newDensity;
647void DensityList::project(
int space,
int state, DensityList& output)
649 std::list <KetBra>::iterator Iter;
651 output.density.clear();
653 for(Iter=density.begin(); Iter != density.end(); ++Iter)
655 if(Iter->ket[space] == Iter->bra[space] && Iter->ket[space] == state)
658 output.density.push_back(kb);
663void DensityList::project(
int space,
int state)
665 std::list <KetBra>::iterator Iter;
666 std::list <KetBra> newDensity;
668 for(Iter=density.begin(); Iter != density.end(); ++Iter)
670 if(Iter->ket[space] == Iter->bra[space] && Iter->ket[space] == state)
673 newDensity.push_back(kb);
677 density = newDensity;
680void DensityList::applyHadamard(
int space)
684 H(0,0) = 1.0/sqrt(2.0);
685 H(0,1) = 1.0/sqrt(2.0);
686 H(1,0) = 1.0/sqrt(2.0);
687 H(1,1) = -1.0/sqrt(2.0);
691void DensityList::applyRotation(
int space,
double rotation)
699 R(1,1) = cexp(rotation);
703void DensityList::applySU2(
int space,
double p,
double theta,
double psi)
712 R(0,0) = sqrt(p)*cexp(I*theta);
713 R(0,1) = -sqrt(1-p)*cexp(-I*psi);
714 R(1,0) = sqrt(1-p)*cexp(I*psi);
715 R(1,1) = sqrt(p)*cexp(-I*theta);
722void DensityList::applyHadamard(
int target,
int control)
726 H(0,0) = 1.0/sqrt(2.0);
727 H(0,1) = 1.0/sqrt(2.0);
728 H(1,0) = 1.0/sqrt(2.0);
729 H(1,1) = -1.0/sqrt(2.0);
731 applyConditionalOp(control, 1, target, H);
736void DensityList::applyPiOver8(
int target,
int control)
743 H(1,1) = cos(3.1415/4.0) + I*sin(3.1415/4.0);
745 applyConditionalOp(control, 1, target, H);
751void DensityList::applySU2(
int target,
int control,
double p,
double theta,
double psi)
760 R(0,0) = sqrt(p)*cexp(I*theta);
761 R(0,1) = -sqrt(1-p)*cexp(-I*psi);
762 R(1,0) = sqrt(1-p)*cexp(I*psi);
763 R(1,1) = sqrt(p)*cexp(-I*theta);
767 applyConditionalOp(control, 1, target, R);
772void DensityList::applyNOT(
int target,
int control)
775 CNOT(control, target);
783void DensityList::CNOT(
int controlSpace,
int targetSpace)
785 if(controlSpace == targetSpace)
787 std::list <KetBra>::iterator Iter;
790 for(Iter=density.begin(); Iter != density.end(); ++Iter)
792 if(Iter->ket[controlSpace] == 1)
793 Iter->ket[targetSpace] = 1-Iter->ket[targetSpace];
794 if(Iter->bra[controlSpace] == 1)
795 Iter->bra[targetSpace] = 1-Iter->bra[targetSpace];
799void DensityList::NOT(
int space)
801 std::list <KetBra>::iterator Iter;
804 for(Iter=density.begin(); Iter != density.end(); ++Iter)
806 Iter->ket[space] = 1-Iter->ket[space];
807 Iter->bra[space] = 1-Iter->bra[space];
811void DensityList::splitAndSave(
double p1,
double p2,
int space)
813 std::list <KetBra>::iterator Iter;
814 std::list <KetBra> newDensity;
816 for(Iter = density.begin(); Iter != density.end(); ++Iter)
822 newDensity.push_back(kb);
825 newDensity.push_back(kb);
828 density = newDensity;
830void DensityList::swap(
int space1,
int space2)
832 std::list <KetBra>::iterator Iter;
834 for(Iter = density.begin(); Iter != density.end(); ++Iter)
836 int temp = Iter->ket[space1];
837 Iter->ket[space1] = Iter->ket[space2];
838 Iter->ket[space2] = temp;
840 temp = Iter->bra[space1];
841 Iter->bra[space1] = Iter->bra[space2];
842 Iter->bra[space2] = temp;
846double DensityList::entropy()
849 computeDensityMat(M);
853double DensityList::ShannonEntropy()
856 computeDensityMat(M);
858 for(
int i=0; i<M.getRows(); ++i){
859 if(fabs(cimag(M(i,i))) > 0.0000001){
860 std::cout <<
"Density List Error: Negative eigenvalue.\n";
861 throw std::string(
"Error");
863 double e = creal( M(i,i) );
869void DensityList::measureAndSave(
int measureSpace,
int saveSpace)
872 std::list <KetBra>::iterator Iter;
873 std::list <KetBra> newDensity;
875 for(Iter = density.begin(); Iter != density.end(); ++Iter)
877 if(Iter->ket[measureSpace] == Iter->bra[measureSpace])
880 kb.ket[saveSpace] = Iter->ket[measureSpace];
881 kb.bra[saveSpace] = kb.ket[saveSpace];
882 newDensity.push_back(kb);
886 density = newDensity;
889void DensityList::measure(
int measureSpace)
892 std::list <KetBra>::iterator Iter;
893 std::list <KetBra> newDensity;
895 for(Iter = density.begin(); Iter != density.end(); ++Iter)
897 if(Iter->ket[measureSpace] == Iter->bra[measureSpace])
900 newDensity.push_back(kb);
904 density = newDensity;
907double DensityList::calculatePr(
int measureSpace,
int state)
910 std::list <KetBra>::iterator Iter;
911 std::list <KetBra> tempDensity;
913 for(Iter = density.begin(); Iter != density.end(); ++Iter)
915 if(Iter->ket[measureSpace] == state && Iter->ket[measureSpace] == Iter->bra[measureSpace])
918 tempDensity.push_back(kb);
922 if(tempDensity.empty())
928 for(Iter = tempDensity.begin(); Iter != tempDensity.end(); ++Iter)
937 for(Iter = density.begin(); Iter != density.end(); ++Iter)
943 c = algebra::ComplexHelper::invert(p2);
944 p2 = algebra::ComplexHelper::mult(c, p);
946 if(cimag(p2) > 0.00000001 || cimag(p2) < -0.00000001)
947 throw std::string(
"Trace error.");
951double DensityList::trace()
953 std::list <KetBra>::iterator Iter;
956 for(Iter = density.begin(); Iter != density.end(); ++Iter)
957 p2 += Iter->trace();;
959 if(cimag(p2) > 0.00000001 || cimag(p2) < -0.00000001)
960 throw std::string(
"Trace error.");
964double DensityList::calculatePr(
int space1,
int state1,
int space2,
int state2)
967 std::list <KetBra>::iterator Iter;
968 std::list <KetBra> tempDensity;
970 for(Iter = density.begin(); Iter != density.end(); ++Iter)
972 if(Iter->ket[space1] == state1 && Iter->ket[space1] == Iter->bra[space1] &&
973 Iter->ket[space2] == state2 && Iter->ket[space2] == Iter->bra[space2])
976 tempDensity.push_back(kb);
980 if(tempDensity.empty())
986 for(Iter = tempDensity.begin(); Iter != tempDensity.end(); ++Iter)
995 for(Iter = density.begin(); Iter != density.end(); ++Iter)
1001 c = algebra::ComplexHelper::invert(p2);
1002 p2 = algebra::ComplexHelper::mult(c, p);
1004 if(cimag(p2) > 0.00000001 || cimag(p2) < -0.00000001)
1005 throw std::string(
"Trace error.");
1009double DensityList::calculatePr(
const std::vector <int>& spaceList,
const std::vector <int>& stateList)
1012 std::list <KetBra>::iterator Iter;
1013 std::list <KetBra> tempDensity;
1015 for(Iter = density.begin(); Iter != density.end(); ++Iter)
1017 bool measure =
true;
1018 for(
unsigned int i=0; i<spaceList.size(); ++i)
1020 if(Iter->ket[spaceList[i]] != stateList[i])
1029 tempDensity.push_back(kb);
1033 if(tempDensity.empty())
1039 for(Iter = tempDensity.begin(); Iter != tempDensity.end(); ++Iter)
1048 for(Iter = density.begin(); Iter != density.end(); ++Iter)
1054 c = algebra::ComplexHelper::invert(p2);
1055 p2 = algebra::ComplexHelper::mult(c, p);
1057 if(cimag(p2) > 0.00000001 || cimag(p2) < -0.00000001)
1058 throw std::string(
"Trace error.");
1065 for(
unsigned int i=0; i<density.begin()->ket.size(); ++i)
1067 if(density.begin()->ket[i] != -1)
1071 int basisIndex = dimension.size()-1;
1073 for(basisIndex=dimension.size()-1; basisIndex>=0; --basisIndex){
1074 if(density.begin()->ket[basisIndex] != -1)
1083 std::list <KetBra>::iterator Iter;
1084 for(Iter = density.begin(); Iter != density.end(); ++Iter)
1090 int indexI=0, indexJ=0;
1091 for(
unsigned int i=0; i<Iter->ket.size(); ++i)
1093 if(Iter->ket[i] == -1 || i == basisIndex)
continue;
1094 indexI = indexI*dimension[i] + Iter->ket[i];
1095 indexJ = indexJ*dimension[i] + Iter->bra[i];
1098 int startRow = indexI*dimension[basisIndex];
1099 int startCol = indexJ*dimension[basisIndex];
1100 int i = Iter->ket[basisIndex];
1101 int j = Iter->bra[basisIndex];
1103 output(startRow+i, startCol+j) += Iter->p;
1117 Complex tr = output.trace();
1118 Complex tr2 = algebra::ComplexHelper::invert(tr);
1119 output.multiplyScalar(tr2);
1122void DensityList::computeDensityMat(
algebra::mat& output)
1126 for(
unsigned int i=0; i<density.begin()->ket.size(); ++i)
1128 if(density.begin()->ket[i] != -1)
1136 std::list <KetBra>::iterator Iter;
1139 int count = density.size();
1143 for(Iter = density.begin(); Iter != density.end(); ++Iter)
1154 for(
unsigned int i=0; i<Iter->ket.size(); ++i)
1156 if(Iter->ket[i] == -1)
continue;
1158 t.create(dimension[i], 1);
1159 t2.create(1, dimension[i]);
1161 t(Iter->ket[i], 0) = 1.0;
1163 k.tensor(&t, &temp);
1167 t2(0, Iter->bra[i]) = 1.0;
1169 b.tensor(&t2, &temp);
1174 k.multiply(b, temp);
1175 temp.multiplyScalar(Iter->p);
1177 output.add(&temp, &temp2);
1181 Complex tr = output.trace();
1182 Complex tr2 = algebra::ComplexHelper::invert(tr);
1183 output.multiplyScalar(tr2);
void computeDensityMatFast(algebra::mat &output)