You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
207 lines
5.4 KiB
207 lines
5.4 KiB
#pragma once
|
|
#include "vector.hpp"
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <string>
|
|
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]; }
|
|
};
|