gslpp_matrix_complex.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 HEPfit Collaboration
3  * All rights reserved.
4  *
5  * For the licensing terms see doc/COPYING.
6  */
7 
8 #include <math.h>
9 #ifndef __GSL_BLAS_H__
10 #include <gsl/gsl_blas.h>
11 #endif
12 #ifndef __GSL_LINALG_H__
13 #include <gsl/gsl_linalg.h>
14 #endif
15 #ifndef __GSL_EIGEN_H__
16 #include <gsl/gsl_eigen.h>
17 #endif
18 #ifndef GSLPP_MATRIX_COMPLEX_H
19 #include "gslpp_matrix_complex.h"
20 #endif
21 
22 namespace gslpp
23 {
25  matrix<complex>::matrix(const size_t& size_i, const size_t& size_j, const complex& z)
26  {
27  _matrix = gsl_matrix_complex_alloc(size_i, size_j);
28  gsl_matrix_complex_set_all(_matrix, z.as_gsl_type());
29  }
30 
31  matrix<complex>::matrix(const size_t& size_i, const complex& z)
32  {
33  _matrix = gsl_matrix_complex_alloc(size_i, size_i);
34  gsl_matrix_complex_set_all(_matrix, z.as_gsl_type());
35  }
36 
37  matrix<complex>::matrix(const size_t& size_i, const size_t& size_j, const double& a)
38  {
39  complex z(a);
40  _matrix = gsl_matrix_complex_alloc(size_i, size_j);
41  gsl_matrix_complex_set_all(_matrix, z.as_gsl_type());
42  }
43 
44  matrix<complex>::matrix(const size_t& size_i, const double& a)
45  {
46  complex z(a);
47  _matrix = gsl_matrix_complex_alloc(size_i, size_i);
48  gsl_matrix_complex_set_all(_matrix, z.as_gsl_type());
49  }
52  {
53  _matrix = gsl_matrix_complex_alloc(m.size_i(), m.size_j());
54  gsl_matrix_complex_memcpy(_matrix, m.as_gsl_type_ptr());
55  }
56 
58  {
59  size_t i, j, size_i, size_j;
60  size_i=m.size_i();
61  size_j=m.size_j();
62  _matrix = gsl_matrix_complex_alloc(size_i, size_j);
63  for(i=0; i<size_i; ++i)
64  for(j=0; j<size_j; ++j)
65  gsl_matrix_complex_set(_matrix, i, j, m(i,j)+0.*complex::i());
66  }
67 
69  {
70  size_t i, size = v.size();
71  complex z(0,0,false);
72  _matrix = gsl_matrix_complex_alloc(size, size);
73  gsl_matrix_complex_set_all(_matrix, z.as_gsl_type());
74  for(i=0; i<size; ++i)
75  gsl_matrix_complex_set(_matrix, i, i, v(i));
76  }
77 
79  {
80  size_t i, size = v.size();
81  complex z(0,0,false);
82  _matrix = gsl_matrix_complex_alloc(size, size);
83  gsl_matrix_complex_set_all(_matrix, z.as_gsl_type());
84  for(i=0; i<size; ++i)
85  gsl_matrix_complex_set(_matrix, i, i, v(i)+0.*complex::i());
86  }
87 
88  matrix<complex>::matrix(const gsl_matrix_complex& m)
89  {
90  _matrix = gsl_matrix_complex_alloc(m.size1, m.size2);
91  gsl_matrix_complex_memcpy(_matrix, &m);
92  }
93 
94  matrix<complex>::matrix(const gsl_matrix_complex* m)
95  {
96  _matrix = gsl_matrix_complex_alloc(m->size1, m->size2);
97  gsl_matrix_complex_memcpy(_matrix, m);
98  }
99 
102  {
103  gsl_matrix_complex_free(_matrix);
104  }
105 
107  const complex matrix<complex>::operator()(const size_t& i, const size_t& j) const
108  {
109  gsl_complex *x = gsl_matrix_complex_ptr(_matrix, i, j);
110  return complex(x);
111  }
112 
114 // complex& matrix<complex>::operator()(const size_t& i, const size_t& j)
115 // {
116 // gsl_complex *x = gsl_matrix_complex_ptr(_matrix, i, j);
117 // return complex(x);
118 // }
119 
122  {
123  if(size_i()==m.size_i() && size_j()==m.size_j())
124  gsl_matrix_complex_memcpy(_matrix, m.as_gsl_type_ptr());
125  else
126  {
127  std::cout << "\n ** Wrong size assign in matrix<complex> operator =" << std::endl;
128  exit(EXIT_FAILURE);
129  }
130  return *this;
131  }
132 
134  void matrix<complex>::assign(const size_t& i, const size_t& j, const complex& z)
135  {
136  gsl_complex *x = gsl_matrix_complex_ptr(_matrix, i, j);
137  *x = z.as_gsl_type();
138  }
139 
140  void matrix<complex>::assign(const size_t& i, const size_t& j,const double& a)
141  {
142  gsl_complex *x = gsl_matrix_complex_ptr(_matrix, i, j);
143  *x = complex(a).as_gsl_type();
144  }
145 
146  void matrix<complex>::assignre(const size_t& i, const size_t& j,const double& a)
147  {
148  gsl_complex *x = gsl_matrix_complex_ptr(_matrix, i, j);
149  GSL_SET_REAL(x,a);
150  }
151 
152  void matrix<complex>::assignim(const size_t& i, const size_t& j,const double& a)
153  {
154  gsl_complex *x = gsl_matrix_complex_ptr(_matrix, i, j);
155  GSL_SET_IMAG(x,a);
156  }
157 
159  void matrix<complex>::assign(const size_t& i, const size_t& j, const matrix<complex>& z)
160  {
161  size_t ki,kj;
162  gsl_complex *x;
163  if(i+z.size_i() <= size_i() && j+z.size_j() <= size_j())
164  for(ki=i;ki<i+z.size_i();ki++)
165  for(kj=j;kj<j+z.size_j();kj++)
166  {
167  x = gsl_matrix_complex_ptr(_matrix, ki, kj);
168  *x = z(ki-i,kj-j).as_gsl_type();
169  }
170  else
171  {
172  std::cout << "\n ** Wrong size assign in matrix<complex> assign submatrix" << std::endl;
173  exit(EXIT_FAILURE);
174  }
175  }
176 
177  void matrix<complex>::assign(const size_t& i, const size_t& j, const matrix<double>& a)
178  {
179  matrix<complex> z(a);
180  assign(i,j,z);
181  }
182 
184  size_t matrix<complex>::size_i() const
185  {
186  return _matrix->size1;
187  }
188 
189  size_t matrix<complex>::size_j() const
190  {
191  return _matrix->size2;
192  }
193 
196  {
197  return matrix<double>::Id(size) * (1.+0.*complex::i());
198  }
199 
202  {
203  matrix<complex> m1(size_j(), size_i(), 0.);
204  if (gsl_matrix_complex_transpose_memcpy(m1.as_gsl_type_ptr(), _matrix))
205  {
206  std::cout << "\n ** Error in matrix<complex> transpose" << std::endl;
207  exit(EXIT_FAILURE);
208  }
209  return m1;
210  }
211 
214  {
215  matrix<complex> m1(*this);
216  gsl_complex z1, z2;
217 
218  GSL_SET_COMPLEX(&z1,1.,0.);
219  GSL_SET_COMPLEX(&z2,0.,0.);
220 
221  if(gsl_blas_zgemm(CblasConjTrans,CblasNoTrans, z1, _matrix,
222  Id(size_j()).as_gsl_type_ptr(), z2, m1.as_gsl_type_ptr()) != 0)
223  {
224  std::cout << "\n ** Error in matrix<complex> conjugate" << std::endl;
225  exit(EXIT_FAILURE);
226  }
227 
228  return m1;
229  }
230 
233  {
234  matrix<complex> m1(_matrix);
235  matrix<complex> m2(_matrix);
236  int signum;
237  gsl_permutation *p;
238 
239  if (size_j() != size_i())
240  {
241  std::cout << "\n ** Size mismatch in matrix<complex> inverse" << std::endl;
242  exit(EXIT_FAILURE);
243  }
244 
245  if ((p = gsl_permutation_alloc(size_i())) == NULL)
246  {
247  std::cout << "\n ** Error in matrix<complex> inverse" << std::endl;
248  exit(EXIT_FAILURE);
249  }
250 
251  if(gsl_linalg_complex_LU_decomp (m1.as_gsl_type_ptr(), p, &signum))
252  {
253  std::cout << "\n ** Error in matrix<complex> inverse" << std::endl;
254  gsl_permutation_free(p);
255  exit(EXIT_FAILURE);
256  }
257 
258  if(gsl_linalg_complex_LU_invert(m1.as_gsl_type_ptr(), p,
259  m2.as_gsl_type_ptr()))
260  {
261  std::cout << "\n ** Error in matrix<complex> inverse" << std::endl;
262  gsl_permutation_free(p);
263  exit(EXIT_FAILURE);
264  }
265  gsl_permutation_free(p);
266  return m2;
267  }
268 
271  {
272  matrix<double> res(size_i(), size_j());
273  for(size_t i = 0; i < size_i(); i++) {
274  gsl_vector_complex_view tmp = gsl_matrix_complex_row(_matrix, i);
275  gsl_vector_view tmpd = gsl_vector_complex_real(&tmp.vector);
276  gsl_matrix_set_row(res.as_gsl_type_ptr(),i,&tmpd.vector);
277  }
278  return res;
279  }
280 
283  {
284  matrix<double> res(size_i(), size_j());
285  for(size_t i = 0; i < size_i(); i++) {
286  gsl_vector_complex_view tmp = gsl_matrix_complex_row(_matrix, i);
287  gsl_vector_view tmpd = gsl_vector_complex_imag(&tmp.vector);
288  gsl_matrix_set_row(res.as_gsl_type_ptr(),i,&tmpd.vector);
289  }
290  return res;
291  }
292 
294  {
295  matrix<complex> m(*this);
296 
297  gsl_eigen_hermv_workspace *ws;
298 
299  ws = gsl_eigen_hermv_alloc(size_i());
300 
301  gsl_eigen_hermv(m.as_gsl_type_ptr(), S.as_gsl_type_ptr(), U.as_gsl_type_ptr(), ws);
302 
303  gsl_eigen_hermv_sort(S.as_gsl_type_ptr(), U.as_gsl_type_ptr(),
304  GSL_EIGEN_SORT_VAL_ASC);
305 
306  gsl_eigen_hermv_free(ws);
307  }
308 
310  vector<double> &S) const
311  {
312  size_t i;
313  matrix<complex> m(*this);
314  vector<complex> v1(size_i(),0.);
315 
316  m = (*this)*hconjugate();
317  m.eigensystem(U, S);
318  m = hconjugate()*(*this);
319  m.eigensystem(V, S);
320  m = U.hconjugate()*(*this)*V;
321  for(i=0; i<m.size_i(); i++)
322  {
323  v1.assign(i,complex(1.,-m(i,i).arg(),true));
324  S(i)=m(i,i).abs();
325  }
326  V=V*matrix<complex>(v1);
327  }
328 
330  gsl_matrix_complex* matrix<complex>::as_gsl_type_ptr() const
331  {
332  return _matrix;
333  }
334 
335  gsl_matrix_complex& matrix<complex>::as_gsl_type()
336  {
337  return const_cast<gsl_matrix_complex&>(*_matrix);
338  }
339 
340  const gsl_matrix_complex& matrix<complex>::as_gsl_type() const
341  {
342  return const_cast<gsl_matrix_complex&>(*_matrix);
343  }
344 
345 // bool matrix<complex>::is_equal(const matrix<complex>& m1, const matrix<complex>& m2){
346 // return gsl_matrix_complex_equal(m1.as_gsl_type_ptr(),m2.as_gsl_type_ptr());
347 // }
348 
351  {
352  matrix<complex> m1(_matrix);
353  gsl_complex z1;
354  GSL_SET_COMPLEX(&z1,-1.,0.);
355  if (gsl_matrix_complex_scale(m1.as_gsl_type_ptr(), z1))
356  {
357  std::cout << "\n ** Error in matrix<complex> unary -" << std::endl;
358  exit(EXIT_FAILURE);
359  }
360  return m1;
361  }
362 
365  {
366  matrix<complex> m1(_matrix);
367  if (gsl_matrix_complex_add(m1.as_gsl_type_ptr(), m.as_gsl_type_ptr()))
368  {
369  std::cout << "\n ** Error in matrix<complex> +" << std::endl;
370  exit(EXIT_FAILURE);
371  }
372  return m1;
373  }
376  {
377  matrix<complex> m1(_matrix);
378  matrix<complex> m2 = -m;
379  if (gsl_matrix_complex_add(m1.as_gsl_type_ptr(), m2.as_gsl_type_ptr()))
380  {
381  std::cout << "\n ** Error in matrix<complex> +" << std::endl;
382  exit(EXIT_FAILURE);
383  }
384  return m1;
385  }
386 
389  {
390  matrix<complex> m1(_matrix);
391  gsl_complex z1, z2;
392 
393  if (size_j() != m.size_i())
394  {
395  std::cout << "\n ** Size mismatch in matrix<complex> *" << std::endl;
396  exit(EXIT_FAILURE);
397  }
398  GSL_SET_COMPLEX(&z1,1.,0.);
399  GSL_SET_COMPLEX(&z2,0.,0.);
400  if(gsl_blas_zgemm(CblasNoTrans,CblasNoTrans, z1, _matrix,
401  m.as_gsl_type_ptr(), z2, m1.as_gsl_type_ptr()))
402  {
403  std::cout << "\n ** Error in matrix<complex> *" << std::endl;
404  exit(EXIT_FAILURE);
405  }
406  return m1;
407  }
408 
411  {
412  matrix<complex> m1(_matrix);
413  matrix<complex> m2(m);
414  if (gsl_matrix_complex_add(m1.as_gsl_type_ptr(), m2.as_gsl_type_ptr()))
415  {
416  std::cout << "\n ** Error in matrix<complex> +" << std::endl;
417  exit(EXIT_FAILURE);
418  }
419  return m1;
420  }
423  {
424  matrix<complex> m1(_matrix);
425  matrix<complex> m2(-m);
426  if (gsl_matrix_complex_add(m1.as_gsl_type_ptr(), m2.as_gsl_type_ptr()))
427  {
428  std::cout << "\n ** Error in matrix<complex> +" << std::endl;
429  exit(EXIT_FAILURE);
430  }
431  return m1;
432  }
433 
436  {
437  matrix<complex> m1(m);
438  return *this * m1;
439  }
440 
443  {
444  gsl_complex z1, z2;
445  vector<complex> v1(size_i(),0.);
446 
447  if (size_j() != v.size())
448  {
449  std::cout << "\n ** Size mismatch in matrix<complex> * (vector complex)"
450  << std::endl;
451  exit(EXIT_FAILURE);
452  }
453  GSL_SET_COMPLEX(&z1, 1., 0.);
454  GSL_SET_COMPLEX(&z2, 0., 0.);
455  if(gsl_blas_zgemv(CblasNoTrans, z1, _matrix, v.as_gsl_type_ptr(),
456  z2, v1.as_gsl_type_ptr()))
457  {
458  std::cout << "\n ** Error in matrix<complex> * (vector complex)"
459  << std::endl;
460  exit(EXIT_FAILURE);
461  }
462  return v1;
463  }
464 
467  {
468  vector<complex> v1(v);
469  return *this * v1;
470  }
471 
474  {
475  *this = *this + m;
476  return *this;
477  }
480  {
481  *this = *this - m;
482  return *this;
483  }
484 
487  {
488  if (!((size_i() == size_j()) && (size_i() == m.size_i()) &&
489  (size_j() == m.size_j())))
490  {
491  std::cout << "\n ** Size mismatch in matrix<complex> *= (matrix)"
492  << std::endl;
493  exit(EXIT_FAILURE);
494  }
495  *this = *this * m;
496  return *this;
497  }
498 
501  {
502  matrix<complex> m1(_matrix);
503  if (gsl_matrix_complex_add_constant(_matrix, z.as_gsl_type()))
504  {
505  std::cout << "\n ** Error in matrix<complex> + (complex)" << std::endl;
506  exit(EXIT_FAILURE);
507  }
508  return m1;
509  }
510 
513  {
514  matrix<complex> m1(_matrix);
515  if (gsl_matrix_complex_add_constant(_matrix, (-z).as_gsl_type()))
516  {
517  std::cout << "\n ** Error in matrix<complex> - (complex)" << std::endl;
518  exit(EXIT_FAILURE);
519  }
520  return m1;
521  }
522 
525  {
526  matrix<complex> m1(_matrix);
527  if (gsl_matrix_complex_scale(m1.as_gsl_type_ptr(), z.as_gsl_type()))
528  {
529  std::cout << "\n ** Error in matrix<complex> * (complex)" << std::endl;
530  exit(EXIT_FAILURE);
531  }
532  return m1;
533  }
534 
537  {
538  matrix<complex> m1(_matrix);
539  if (gsl_matrix_complex_scale(m1.as_gsl_type_ptr(), z.inverse().as_gsl_type()))
540  {
541  std::cout << "\n ** Error in matrix<complex> / (complex)" << std::endl;
542  exit(EXIT_FAILURE);
543  }
544  return m1;
545  }
546 
549  {
550  *this = *this + z;
551  return *this;
552  }
555  {
556  *this = *this - z;
557  return *this;
558  }
561  {
562  *this = *this * z;
563  return *this;
564  }
567  {
568  *this = *this / z;
569  return *this;
570  }
571 
574  {
575  complex z(a);
576  return *this + z;
577  }
578 
581  {
582  complex z(a);
583  return *this - z;
584  }
585 
588  {
589  complex z(a);
590  return *this * z;
591  }
592 
595  {
596  complex z(a);
597  return *this / z;
598  }
601  {
602  *this = *this + a;
603  return *this;
604  }
607  {
608  *this = *this - a;
609  return *this;
610  }
613  {
614  *this = *this * a;
615  return *this;
616  }
619  {
620  *this = *this / a;
621  return *this;
622  }
624  std::ostream& operator<<(std::ostream& output, const matrix<complex>& m)
625  {
626  size_t i,j;
627  for (i=0; i<m.size_i(); i++)
628  {
629  output << std::endl;
630  output << "\t(";
631  for (j=0; j<m.size_j()-1; j++)
632  output << m(i,j) << ",";
633  output << m(i,j) << ")";
634  }
635  return output;
636  }
637 
639  return m2 + m1;
640  }
641 
643  return -m2 + m1;
644  }
645 
647  {
648  return m + z;
649  }
650 
652  {
653  return -m + z;
654  }
655 
657  {
658  return m * z;
659  }
660 
662  {
663  return m.transpose() * v;
664  }
665 
667  {
668  return m.transpose() * v;
669  }
670 
671  matrix<complex> operator+(const double& a, const matrix<complex> m)
672  {
673  return m + a;
674  }
675 
676  matrix<complex> operator-(const double& a, const matrix<complex> m)
677  {
678  return -m + a;
679  }
680 
681  matrix<complex> operator*(const double& a, const matrix<complex> m)
682  {
683  return m * a;
684  }
685 }
complex operator*(const double &x1, const complex &z2)
A class for the form factor in .
gsl_complex & as_gsl_type()
A class for constructing and defining operations on real matrices.
A base class for defining operations on matrices, both real and complex.
matrix< complex > hconjugate() const
gsl_matrix * as_gsl_type_ptr() const
complex inverse() const
static const complex & i()
matrix< complex > operator*(const double &a, const matrix< complex > m)
A class for constructing and defining operations on complex vectors.
void assign(const size_t &i, const complex &z)
matrix< complex > operator-(const double &a, const matrix< complex > m)
A class for constructing and defining operations on complex matrices.
gsl_matrix_complex * as_gsl_type_ptr() const
void eigensystem(matrix< complex > &U, vector< double > &S) const
gsl_matrix_complex & as_gsl_type()
matrix< complex > operator+(const double &a, const matrix< complex > m)
complex operator/(const double &x1, const complex &z2)
matrix< complex > transpose() const
gsl_vector_complex * as_gsl_type_ptr() const
A class for constructing and defining operations on real vectors.
complex operator+(const double &x1, const complex &z2)
A class for defining operations on and functions of complex numbers.
Definition: gslpp_complex.h:35
complex operator-(const double &x1, const complex &z2)
Complex number, vector and matrix manipulation using GSL.
gsl_vector * as_gsl_type_ptr() const