23 #ifndef COM_DAFER45_TBTK_MATRIX
24 #define COM_DAFER45_TBTK_MATRIX
32 template<
typename DataType,
unsigned int ROWS = 0,
unsigned int COLS = 0>
58 const DataType&
at(
unsigned int row,
unsigned int col)
const;
61 DataType&
at(
unsigned int row,
unsigned int col);
70 DataType data[ROWS*COLS];
73 template<
typename DataType>
80 Matrix(
unsigned int rows,
unsigned int cols);
98 const DataType&
at(
unsigned int row,
unsigned int col)
const;
101 DataType&
at(
unsigned int row,
unsigned int col);
125 class Matrix<std::complex<double>, 0, 0>{
131 Matrix(
unsigned int rows,
unsigned int cols);
134 Matrix(
const Matrix<std::complex<double>, 0, 0> &matrix);
144 const Matrix<std::complex<double>, 0, 0> &rhs
149 Matrix<std::complex<double>, 0, 0> &&rhs
153 const std::complex<double>&
at(
159 std::complex<double>&
at(
unsigned int row,
unsigned int col);
169 const Matrix<std::complex<double>, 0, 0> &rhs
176 std::complex<double> determinant();
179 std::complex<double> *data;
188 template<
typename DataType,
unsigned int ROWS,
unsigned int COLS>
192 template<
typename DataType,
unsigned int ROWS,
unsigned int COLS>
194 for(
unsigned int n = 0; n < ROWS*COLS; n++)
195 data[n] = matrix.data[n];
198 template<
typename DataType,
unsigned int ROWS,
unsigned int COLS>
200 for(
unsigned int n = 0; n < ROWS*COLS; n++)
201 data[n] = matrix.data[n];
204 template<
typename DataType>
209 template<
typename DataType>
213 data =
new DataType[rows*cols];
216 template<
typename DataType>
220 data =
new DataType[rows*cols];
221 for(
unsigned int n = 0; n < rows*cols; n++)
222 data[n] = matrix.data[n];
225 template<
typename DataType>
230 matrix.data =
nullptr;
240 data =
new std::complex<double>[rows*cols];
244 const Matrix<std::complex<double>, 0, 0> &matrix
248 data =
new std::complex<double>[rows*cols];
249 for(
unsigned int n = 0; n < rows*cols; n++)
250 data[n] = matrix.data[n];
254 Matrix<std::complex<double>, 0, 0> &&matrix
259 matrix.data =
nullptr;
262 template<
typename DataType,
unsigned int ROWS,
unsigned int COLS>
266 template<
typename DataType>
277 template<
typename DataType,
unsigned int ROWS,
unsigned int COLS>
282 for(
unsigned int n = 0; n < ROWS*COLS; n++)
283 data[n] = rhs.data[n];
289 template<
typename DataType,
unsigned int ROWS,
unsigned int COLS>
294 for(
unsigned int n = 0; n < ROWS*COLS; n++)
295 data[n] = rhs.data[n];
301 template<
typename DataType>
312 data =
new DataType[rows*cols];
313 for(
unsigned int n = 0; n < rows*cols; n++)
314 data[n] = rhs.data[n];
320 template<
typename DataType>
348 data =
new std::complex<double>[rows*cols];
349 for(
unsigned int n = 0; n < rows*cols; n++)
350 data[n] = rhs.data[n];
373 template<
typename DataType,
unsigned int ROWS,
unsigned int COLS>
378 return data[row + ROWS*col];
381 template<
typename DataType>
386 return data[row + rows*col];
393 return data[row + rows*col];
396 template<
typename DataType,
unsigned int ROWS,
unsigned int COLS>
401 return data[row + ROWS*col];
404 template<
typename DataType>
409 return data[row + rows*col];
416 return data[row + rows*col];
419 template<
typename DataType,
unsigned int ROWS,
unsigned int COLS>
424 template<
typename DataType>
433 template<
typename DataType,
unsigned int ROWS,
unsigned int COLS>
438 template<
typename DataType>
447 template<
typename DataType>
453 "Matrix::operator*()",
454 "Incompatible matrix dimensions.",
455 "The matrix dimensions are " << rows <<
"x" << cols <<
" and "
456 << rhs.rows <<
"x" << rhs.cols <<
"\n"
460 for(
unsigned int row = 0; row < rows; row++){
461 for(
unsigned int col = 0; col < rhs.cols; col++){
462 result.
at(row, col) = 0.;
464 for(
unsigned int n = 0; n < cols; n++){
466 +=
at(row, n)*rhs.
at(n, col);
479 "Matrix::operator*()",
480 "Incompatible matrix dimensions.",
481 "The matrix dimensions are " << rows <<
"x" << cols <<
" and "
482 << rhs.rows <<
"x" << rhs.cols <<
"\n"
486 for(
unsigned int row = 0; row < rows; row++){
487 for(
unsigned int col = 0; col < rhs.cols; col++){
488 result.
at(row, col) = 0.;
490 for(
unsigned int n = 0; n < cols; n++){
492 += at(row, n)*rhs.at(n, col);
504 std::complex<double> *A,
511 std::complex<double> *A,
514 std::complex<double> *work,
524 "Invalid matrix dimension. Only square matrices can be"
525 <<
" inverted, but the matrix has size " << rows <<
"x" << cols
530 int *ipiv =
new int[std::min(rows, cols)];
531 int lwork = rows*cols;
532 std::complex<double> *work =
new std::complex<double>[lwork];
535 zgetrf_((
int*)&rows, (
int*)&cols, data, (
int*)&rows, ipiv, &info);
540 "Argument '" << -info <<
"' to zgetrf_() is invlid.",
541 "This should never happen, contact the developer."
547 "Unable to invert matrix since it is signular.",
552 zgetri_((
int*)&rows, data, (
int*)&rows, ipiv, work, &lwork, &info);
556 "Inversion failed with error code 'INFO = " << info <<
"'.",
557 "See the documentation for the lapack function zgetri_() for"
558 <<
" further information."
568 "Matrix::determinant()",
569 "Invalid matrix dimension. The determinant can only be"
570 <<
" calculated for square matrices, but the matrix has size "
571 << rows <<
"x" << cols <<
"\n",
575 std::complex<double> *copy =
new std::complex<double>[rows*cols];
576 for(
unsigned int n = 0; n < rows*cols; n++)
579 int *ipiv =
new int[std::min(rows, cols)];
584 zgetrf_((
int*)&rows, (
int*)&cols, copy, (
int*)&rows, ipiv, &info);
588 "Matrix::determinant()",
589 "Argument '" << -info <<
"' to zgetrf_() is invlid.",
590 "This should never happen, contact the developer."
595 "Matrix::determinant()",
596 "Unable to invert matrix since it is signular.",
601 std::complex<double> det = 1.;
602 for(
unsigned int n = 0; n < rows; n++){
604 if(ipiv[n]-1 == (
int)n)
605 det *= copy[rows*n + n];
607 det *= -copy[rows*n + n];