25#define Complex double _Complex
33 static Complex one() {Complex out; out = 1.0 + 0*I;
return out; }
34 static Complex zero() {Complex out; out = 0 + 0*I;
return out;}
36 static void sq(Complex& v)
38 Complex v2 = creal(v) - cimag(v)*I;
41 static Complex construct(
double theta)
43 Complex out = cos(theta) + sin(theta)*I;
47 static Complex power(Complex& base,
int e)
51 double real = log( sqrt( creal(base)*creal(base)* + cimag(base)*cimag(base)));
52 double imag = atan2(cimag(base), creal(base));
59 Complex result = construct(cimag(a));
62 Complex r2 = creal(result)*exp(real) + cimag(result)*real*I;
67 static Complex add(Complex& a, Complex& b)
71 static Complex subtract(Complex& a, Complex& b)
76 static Complex mult(Complex& a, Complex& b)
81 static Complex invert(Complex& a)
84 double d = creal(a)*creal(a) + cimag(a)*cimag(a);
86 out = creal(a) / d - cimag(a)/d *I;
110 varName = std::string(_name);
119 if(r == 0 || c == 0 || !m.elements)
122 elements =
new Complex[n];
126 for(
int i=0; i<n; ++i)
127 elements[i] = m.elements[i];
131 void saveToFile(
const std::string& filename);
132 void saveToFile(std::ofstream& f);
134 bool loadFromFile(
const std::string& filename);
135 bool loadFromFile(std::ifstream& f);
139 if(!elements || r != m.r || c != m.c)
146 if(r == 0 || c == 0 || !m.elements)
148 throw std::string(
"operator= error.\n");
152 elements =
new Complex[n];
157 throw std::string(
"operator= error 2.\n");
161 for(
int i=0; i<n; ++i)
162 elements[i] = m.elements[i];
171 if(elements && !noCleanup)
186 for(
int i=0; i<n; ++i)
188 elements[i] = 0.0+0.0*I;
199 if(getCols() < getRows())
202 Complex one = 1.0+0.0*I;
204 for(
int i=0; i<dim; ++i)
205 this->setDirect(i,i,one);
210 Complex c = 0.0 + 0.0*I;
211 for(
int i=0; i<getRows(); ++i)
213 c = c + (*this)(i,i);
218 void clear(Complex value)
222 for(
int i=0; i<n; ++i)
226 bool create(
int _r,
int _c, Complex* _elements)
233 elements = _elements;
237 bool create(
int _r,
int _c)
239 if(_r <= 0 || _c <= 0)
241 if(elements && r == _r && c == _c)
249 elements =
new Complex[r*c];
258 return create(_r, _r);
261 Complex& operator() (
int row,
int col)
265 if(!elements || _r >= r || _c >= c || _r < 0 || _c < 0)
267 std::cout <<
"Error 5 (" << elements <<
", " << _r <<
", " << r <<
", " << _c <<
", " << c <<
")\n";
268 std::cout <<
"Name = " << varName <<
"\n";
269 throw(std::string(
"Algebra Error 5.1"));
274 return elements[_c*r + _r];
277 void random_unitary(
const std::vector <double>& phi_v,
const std::vector <double>& psi_v,
const std::vector <double>& chi_v,
double alpha);
278 bool eigenValues(std::vector <double>& values);
279 double safeLog(
double x)
283 return log(x)/log(2.0);
287 std::vector<double> ev;
292 for(
int i=0; i < ev.size(); ++i)
294 sum = sum - ev[i] * safeLog(ev[i]);
301 Complex getDirect(
int row,
int col)
305 if(!elements || _r >= r || _c >= c || _r < 0 || _c < 0)
307 std::cout <<
"Error 5 (" << elements <<
", " << _r <<
", " << r <<
", " << _c <<
", " << c <<
")\n";
308 throw(std::string(
"Algebra Error 5.2"));
313 return elements[_c*r + _r];
316 void setDirect(
int _n, Complex data)
318 if(!elements || _n >= n)
321 throw(std::string(
"Algebra Error 5.3"));
329 void setDirect(
int row,
int col, Complex data)
333 if(!elements || _r >= r || _c >= c || _r < 0 || _c < 0)
335 std::cout <<
"Error 5 (" << elements <<
", " << _r <<
", " << r <<
", " << _c <<
", " << c <<
")\n";
336 throw(std::string(
"Algebra Error 5.4"));
341 elements[_c*r + _r] = data;
344 void setDirect(
int row,
int col,
double re,
double im)
348 if(!elements || _r >= r || _c >= c || _r < 0 || _c < 0)
350 std::cout <<
"Error 5 (" << elements <<
", " << _r <<
", " << r <<
", " << _c <<
", " << c <<
")\n";
351 throw(std::string(
"Algebra Error 5.4"));
356 elements[_c*r + _r] = re + im*I;
360 if(!elements || _n >= n)
362 std::cout <<
"Error 2 (" << elements <<
", " << _n <<
", " << n <<
")\n";
369 Complex* getElements()
374 void print(std::ostream& f,
bool printAll=
false)
378 int rStart = 0, cStart=0;
384 int rows = alg_min(10, r);
385 int cols = alg_min(10, c);
392 for(
int _r=rStart; _r < rows; ++_r)
394 for(
int _c=cStart; _c<cols; ++_c)
396 f << creal((*
this)(_r,_c)) <<
"+" << cimag((*
this)(_r,_c)) <<
"i\t";
404 void multiplyScalar(Complex& c)
409 for(
int i=0; i<n; ++i)
411 elements[i] = ComplexHelper::mult(elements[i], c);
417 if(!elements || c != r)
419 throw(std::string(
"Algebra error 1.2"));
424 for(
long row=0; row<r; ++row)
426 for(
long col=row; col<c; ++col)
430 temp = getDirect(row,col);
431 setDirect(row,col, getDirect(col,row));
432 setDirect(col,row, temp);
442 for(
int _r=0; _r<r; ++_r)
444 for(
int _c=0; _c<c; ++_c)
446 Complex c = (*this)(_r, _c);
447 B(_c, _r) = creal(c) - cimag(c)*I;
453 void subtract(Complex& c)
458 for(
int i=0; i<n; ++i)
460 elements[i] = elements[i] = c;
469 if(!elements || !B->getElements() || getRows() != B->getRows() || getCols() != B->getCols())
471 throw std::string(
"Error - cannot subtract matrix\n");
475 output->create(getRows(), getCols());
477 for(
int i=0; i<n; ++i)
479 output->elements[i] = elements[i] - B->getElements()[i];
488 if(!elements || !B->getElements() || getRows() != B->getRows() || getCols() != B->getCols())
490 throw std::string(
"Error - cannot add matrix\n");
494 output->create(getRows(), getCols());
496 for(
int i=0; i<n; ++i)
498 output->elements[i] = elements[i] + B->getElements()[i];
502 void random(
double smallValue,
double largeValue);
509 if(!elements || !B->getElements() || getRows() != B->getRows() || getCols() != B->getCols())
511 throw std::string(
"Error - cannot add matrix\n");
517 for(
int i=0; i<n; ++i)
519 output->elements[i] = elements[i] + B->getElements()[i];
523 void dot(
matrix* B, Complex& output);
525 bool multiply(
matrix& B,
matrix& output,
char TRANSB=
'N');
542 int alg_min(
int a,
int b)
544 return (a < b) ? a : b;
546 int alg_max(
int a,
int b)
548 return (a > b) ? a : b;