Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef QUCOSI_QUBIT_H
00018 #define QUCOSI_QUBIT_H
00019
00020 #include <cstdlib>
00021 #include <vector>
00022
00023 #include "Aux"
00024 #include "Vector"
00025
00026 namespace QuCoSi {
00027
00028 class Qubit : public Vector {
00029 public:
00030 inline Qubit() : Vector(2) {}
00031
00032 inline Qubit(const int dim) : Vector(dim) {}
00033
00034 inline Qubit(const field& c0, const field& c1) : Vector(c0, c1) {}
00035
00036 inline Qubit(const int x, const int n) : Vector(std::pow(2,n))
00037 {
00038 (*this)(x) = field(1,0);
00039 }
00040
00041 inline Qubit& operator=(const VectorXc& v)
00042 {
00043 VectorXc::operator=(v);
00044 return *this;
00045 }
00046
00047 inline Qubit& operator=(const Vector& v)
00048 {
00049 Vector::operator=(v);
00050 return *this;
00051 }
00052
00053 inline bool isPureState() const
00054 {
00055 for (int i = 0; i < size(); ++i) {
00056 if (is_one(std::pow(std::abs((*this)(i)),2))) {
00057 return true;
00058 }
00059 }
00060 return false;
00061 }
00062
00063 inline Qubit first(const int j) const
00064 {
00065 int dim_total = size();
00066 int dim_first = std::pow(2,j);
00067 int dim_last = dim_total/dim_first;
00068
00069 int pos = 0;
00070 for (; pos < dim_total; ++pos) {
00071 if (!is_zero(std::abs((*this)(pos)))) {
00072 pos %= dim_last;
00073 break;
00074 }
00075 }
00076
00077 Qubit q(dim_first);
00078 for (int i = 0; i < dim_first; ++i) {
00079 q(i) = (*this)(i*dim_last + pos);
00080 }
00081 return q;
00082 }
00083
00084 inline Qubit last(const int j) const
00085 {
00086 int dim_total = size();
00087 int dim_last = std::pow(2,j);
00088
00089 int pos = 0;
00090 for (; pos < dim_total; ++pos) {
00091 if (!is_zero(std::abs((*this)(pos)))) {
00092 pos -= pos%dim_last;
00093 break;
00094 }
00095 }
00096
00097 Qubit q(dim_last);
00098 for (int i = 0; i < dim_last; ++i) {
00099 q(i) = (*this)(pos+i);
00100 }
00101 return q;
00102 }
00103
00104 inline Qubit& measure()
00105 {
00106 int n = size();
00107 std::vector<fptype> p(n);
00108
00109 for (int i = 0; i < n; ++i) {
00110 p[i] = std::pow(std::abs((*this)(i)),2);
00111 if (is_one(p[i])) {
00112 return *this;
00113 }
00114 }
00115
00116 fptype s = 0., r = fptype(std::rand())/RAND_MAX;
00117 for (int j = 0; j < n; ++j) {
00118 s += p[j];
00119 if (s >= r) {
00120 field c = (*this)(j)/std::abs((*this)(j));
00121 setZero();
00122 (*this)(j) = c;
00123 return *this;
00124 }
00125 }
00126 return *this;
00127 }
00128
00129 inline Qubit& measurePartial(const int p)
00130 {
00131 int n = log2(size());
00132 int q = n-p;
00133 int pn = std::pow(2,p);
00134 int qn = std::pow(2,q);
00135 std::vector<fptype> pj(pn);
00136
00137 for (int j = 0; j < pn; ++j) {
00138 pj[j] = 0.;
00139 for (int r = 0; r < qn; ++r) {
00140 pj[j] += std::pow(std::abs((*this)(j*qn+r)),2);
00141 }
00142 }
00143
00144 fptype s = 0., t = fptype(std::rand())/RAND_MAX;
00145 for (int j = 0; j < pn; ++j) {
00146 s += pj[j];
00147 if (s >= t) {
00148 Qubit rq(qn);
00149 for (int r = 0; r < qn; ++r) {
00150 rq += (*this)(j*qn+r)/std::sqrt(pj[j])*Qubit(r,q);
00151 }
00152 *this = Qubit(j,p).tensorDot(rq);
00153 return *this;
00154 }
00155 }
00156 return *this;
00157 }
00158 };
00159
00160 }
00161
00162 #endif // QUCOSI_QUBIT_H
00163
00164