#pragma once #include "vector.hpp" #include #include #include using namespace std; class matrix { private: long long num_cols; long long num_rows; vector *cols; public: matrix(const long long num_rows, const long long num_cols) { this->num_cols = num_cols; this->num_rows = num_rows; this->cols = (vector *)calloc(sizeof(vector), num_cols); for (long long i = 0; i < num_cols; i++) { this->cols[i] = vector(num_rows); } } matrix(const matrix &m) { this->num_cols = m.num_cols; this->num_rows = m.num_rows; this->cols = (vector *)calloc(sizeof(vector), m.num_cols); for (long long i = 0; i < m.num_cols; i++) { this->cols[i] = m[i]; } } ~matrix() { this->num_cols = 0; this->num_rows = 0; free(this->cols); this->cols = NULL; } const cnumber determinant() const { cnumber dsum(1,0); cnumber osum(1,0); vector diag = this->get_diagonal(); vector odiag = this->get_off_diagonal(); for (long long i = 0; i < diag.get_dimention(); i++) { dsum = dsum * diag[i]; osum = osum * odiag[i]; } return dsum - osum; } const vector get_diagonal() const { long long diag_len = this->num_rows; if (this->num_cols < diag_len) { diag_len = this->num_cols; } vector v(diag_len); for (long long i = 0; i < this->num_cols; i++) { for (long long j = 0; j < this->num_rows; j++) { if (i == j) { v[i] = this->cols[i][j]; } } } return v; } const vector get_off_diagonal() const { long long diag_len = this->num_rows; if (this->num_cols < diag_len) { diag_len = this->num_cols; } vector v(diag_len); for (long long i = 0; i < this->num_cols; i++) { for (long long j = 0; j < this->num_rows; j++) { if (i + j == this->num_rows - 1) { v[i] = this->cols[i][j]; } } } return v; } const vector get_row(long long index) const { return this->cols[index]; } const vector get_column(long long index) const { vector v(this->num_rows); for (long long j = 0; j < this->num_rows; j++) { v[j] = this->cols[j][index]; } return v; } const matrix rotate_ninety() const { matrix m(this->num_cols, this->num_rows); return m; } const matrix transpose() const { matrix n(this->num_rows, this->num_cols); for (long long i = 0; i < this->num_cols; i++) { for (long long j = 0; j < this->num_rows; j++) { n[j][i] = this->cols[i][j]; } } return n; } const matrix conjugate() const { matrix n(this->num_cols, this->num_rows); for (long long i = 0; i < this->num_cols; i++) { for (long long j = 0; j < this->num_rows; j++) { n[i][j] = this->cols[i][j].conjugate(); } } return n; } const matrix hermitian_conjugate() const { return this->transpose().conjugate(); } const bool is_hermitian() const { if (this->num_rows != this->num_cols) return false; matrix m = this->hermitian_conjugate(); bool equal = true; for (long long i = 0; i < m.num_cols; i++) { for (long long j = 0; j < m.num_rows; j++) { if (m[i][j] != this->cols[i][j]) { equal = false; } } } return equal; } friend ostream &operator<<(ostream &os, const matrix &m) { char last = '\0'; for (long long i = 0; i < m.num_cols; i++) { for (long long j = 0; j < m.num_rows; j++) { string symbols[3]; symbols[0] = "|"; ostringstream oss; oss << " " << m.cols[i][j] << " "; symbols[1] = oss.str(); symbols[2] = "|"; for (int i = 0; i < 3; i++) { int len = symbols[i].length() - 1; char cur = symbols[i][0]; if (cur != last) { os << symbols[i]; } last = symbols[i][len]; } } if (i != m.num_cols - 1) os << endl << "|"; } return os; } const bool operator==(const matrix &m) const { bool equal = true; for (long long i = 0; i < this->num_cols; i++) { for (long long j = 0; j < this->num_rows; j++) { if (this->cols[i][j] != m[i][j]) { equal = false; } } } return equal; } const vector operator[](const long long index) const { return this->cols[index]; } const matrix operator*(const cnumber z) const { matrix n(this->num_cols, this->num_rows); for (long long i = 0; i < this->num_cols; i++) { n[i] = this->cols[i] * z; } return n; } const matrix operator*(const matrix m) const { matrix n(this->num_cols, m.num_rows); // if (this->num_cols != m.num_rows && m.num_cols != this->num_rows) // return n; for (long long i = 0; i < this->num_rows; i++) { for (long long j = 0; j < this->num_rows; j++) { n[i][j] = this->get_row(i) * m.get_column(j); } } return n; } const matrix operator+(const matrix &m) const { matrix n(this->num_cols, this->num_rows); for (long long i = 0; i < this->num_cols; i++) { n[i] = this->cols[i] + m[i]; } return n; } const matrix operator-(const matrix &m) const { matrix n(this->num_cols, this->num_rows); for (long long i = 0; i < this->num_cols; i++) { n[i] = this->cols[i] - m[i]; } return n; } // FIXME: Figure out how to make sure you do not try to access something // outside of the index vector &operator[](const long long index) { return this->cols[index]; } };