#include <cstdlib>
#include <cstdio>
#include <math.h>
#define PAUSE {printf("Press \"Enter\" to continue\n"); fflush(stdin); getchar(); fflush(stdin);}
class Matrix;
double Det(const Matrix& a);
Matrix Diag(const int n);
Matrix Diag(const Matrix& v);
Matrix Inv(const Matrix& a);
Matrix Ones(const int rows, const int cols);
int Size(const Matrix& a, const int i);
Matrix Zeros(const int rows, const int cols);
class Exception
{
public:
const char* msg;
Exception(const char* arg)
: msg(arg)
{
}
};
class Matrix
{
public:
Matrix()
{
p = NULL;
rows = 0;
cols = 0;
}
Matrix(const int row_count, const int column_count)
{
p = NULL;
if (row_count > 0 && column_count > 0)
{
rows = row_count;
cols = column_count;
p = new double*[rows];
for (int r = 0; r < rows; r++)
{
p[r] = new double[cols];
for (int c = 0; c < cols; c++)
{
p[r][c] = 0;
}
}
}
}
Matrix(const Matrix& a)
{
rows = a.rows;
cols = a.cols;
p = new double*[a.rows];
for (int r = 0; r < a.rows; r++)
{
p[r] = new double[a.cols];
for (int c = 0; c < a.cols; c++)
{
p[r][c] = a.p[r][c];
}
}
}
double& operator()(const int r, const int c)
{
if (p != NULL && r > 0 && r <= rows && c > 0 && c <= cols)
{
return p[r-1][c-1];
}
else
{
throw Exception("Subscript out of range");
}
}
double get(const int r, const int c) const
{
if (p != NULL && r > 0 && r <= rows && c > 0 && c <= cols)
{
return p[r-1][c-1];
}
else
{
throw Exception("Subscript out of range");
}
}
Matrix& operator= (const Matrix& a)
{
rows = a.rows;
cols = a.cols;
p = new double*[a.rows];
for (int r = 0; r < a.rows; r++)
{
p[r] = new double[a.cols];
for (int c = 0; c < a.cols; c++)
{
p[r][c] = a.p[r][c];
}
}
return *this;
}
Matrix& Add(const double v)
{
for (int r = 0; r < rows; r++)
{
for (int c = 0; c < cols; c++)
{
p[r][c] += v;
}
}
return *this;
}
Matrix& Subtract(const double v)
{
return Add(-v);
}
Matrix& Multiply(const double v)
{
for (int r = 0; r < rows; r++)
{
for (int c = 0; c < cols; c++)
{
p[r][c] *= v;
}
}
return *this;
}
Matrix& Divide(const double v)
{
return Multiply(1/v);
}
friend Matrix operator+(const Matrix& a, const Matrix& b)
{
if (a.rows == b.rows && a.cols == b.cols)
{
Matrix res(a.rows, a.cols);
for (int r = 0; r < a.rows; r++)
{
for (int c = 0; c < a.cols; c++)
{
res.p[r][c] = a.p[r][c] + b.p[r][c];
}
}
return res;
}
else
{
throw Exception("Dimensions does not match");
}
return Matrix();
}
friend Matrix operator+ (const Matrix& a, const double b)
{
Matrix res = a;
res.Add(b);
return res;
}
friend Matrix operator+ (const double b, const Matrix& a)
{
Matrix res = a;
res.Add(b);
return res;
}
friend Matrix operator- (const Matrix& a, const Matrix& b)
{
if (a.rows == b.rows && a.cols == b.cols)
{
Matrix res(a.rows, a.cols);
for (int r = 0; r < a.rows; r++)
{
for (int c = 0; c < a.cols; c++)
{
res.p[r][c] = a.p[r][c] - b.p[r][c];
}
}
return res;
}
else
{
throw Exception("Dimensions does not match");
}
return Matrix();
}
friend Matrix operator- (const Matrix& a, const double b)
{
Matrix res = a;
res.Subtract(b);
return res;
}
friend Matrix operator- (const double b, const Matrix& a)
{
Matrix res = -a;
res.Add(b);
return res;
}
friend Matrix operator- (const Matrix& a)
{
Matrix res(a.rows, a.cols);
for (int r = 0; r < a.rows; r++)
{
for (int c = 0; c < a.cols; c++)
{
res.p[r][c] = -a.p[r][c];
}
}
return res;
}
friend Matrix operator* (const Matrix& a, const Matrix& b)
{
if (a.cols == b.rows)
{
Matrix res(a.rows, b.cols);
for (int r = 0; r < a.rows; r++)
{
for (int c_res = 0; c_res < b.cols; c_res++)
{
for (int c = 0; c < a.cols; c++)
{
res.p[r][c_res] += a.p[r][c] * b.p[c][c_res];
}
}
}
return res;
}
else
{
throw Exception("Dimensions does not match");
}
return Matrix();
}
friend Matrix operator* (const Matrix& a, const double b)
{
Matrix res = a;
res.Multiply(b);
return res;
}
friend Matrix operator* (const double b, const Matrix& a)
{
Matrix res = a;
res.Multiply(b);
return res;
}
friend Matrix operator/ (const Matrix& a, const Matrix& b)
{
if (a.rows == a.cols && a.rows == a.cols && b.rows == b.cols)
{
Matrix res(a.rows, a.cols);
res = a * Inv(b);
return res;
}
else
{
throw Exception("Dimensions does not match");
}
return Matrix();
}
friend Matrix operator/ (const Matrix& a, const double b)
{
Matrix res = a;
res.Divide(b);
return res;
}
friend Matrix operator/ (const double b, const Matrix& a)
{
Matrix b_matrix(1, 1);
b_matrix(1,1) = b;
Matrix res = b_matrix / a;
return res;
}
Matrix Minor(const int row, const int col) const
{
Matrix res;
if (row > 0 && row <= rows && col > 0 && col <= cols)
{
res = Matrix(rows - 1, cols - 1);
for (int r = 1; r <= (rows - (row >= rows)); r++)
{
for (int c = 1; c <= (cols - (col >= cols)); c++)
{
res(r - (r > row), c - (c > col)) = p[r-1][c-1];
}
}
}
else
{
throw Exception("Index for minor out of range");
}
return res;
}
int Size(const int i) const
{
if (i == 1)
{
return rows;
}
else if (i == 2)
{
return cols;
}
return 0;
}
int GetRows() const
{
return rows;
}
int GetCols() const
{
return cols;
}
void Print() const
{
if (p != NULL)
{
printf("[");
for (int r = 0; r < rows; r++)
{
if (r > 0)
{
printf(" ");
}
for (int c = 0; c < cols-1; c++)
{
printf("%.2f, ", p[r][c]);
}
if (r < rows-1)
{
printf("%.2f;\n", p[r][cols-1]);
}
else
{
printf("%.2f]\n", p[r][cols-1]);
}
}
}
else
{
printf("[ ]\n");
}
}
public:
~Matrix()
{
for (int r = 0; r < rows; r++)
{
delete p[r];
}
delete p;
p = NULL;
}
private:
int rows;
int cols;
double** p; };
int Size(const Matrix& a, const int i)
{
return a.Size(i);
}
Matrix Ones(const int rows, const int cols)
{
Matrix res = Matrix(rows, cols);
for (int r = 1; r <= rows; r++)
{
for (int c = 1; c <= cols; c++)
{
res(r, c) = 1;
}
}
return res;
}
Matrix Zeros(const int rows, const int cols)
{
return Matrix(rows, cols);
}
Matrix Diag(const int n)
{
Matrix res = Matrix(n, n);
for (int i = 1; i <= n; i++)
{
res(i, i) = 1;
}
return res;
}
Matrix Diag(const Matrix& v)
{
Matrix res;
if (v.GetCols() == 1)
{
int rows = v.GetRows();
res = Matrix(rows, rows);
for (int r=1; r <= rows; r++)
{
res(r, r) = v.get(r, 1);
}
}
else if (v.GetRows() == 1)
{
int cols = v.GetCols();
res = Matrix(cols, cols);
for (int c=1; c <= cols; c++)
{
res(c, c) = v.get(1, c);
}
}
else
{
throw Exception("Parameter for diag must be a vector");
}
return res;
}
double Det(const Matrix& a)
{
double d = 0; int rows = a.GetRows();
int cols = a.GetRows();
if (rows == cols)
{
if (rows == 1)
{
d = a.get(1, 1);
}
else if (rows == 2)
{
d = a.get(1, 1) * a.get(2, 2) - a.get(2, 1) * a.get(1, 2);
}
else
{
for (int c = 1; c <= cols; c++)
{
Matrix M = a.Minor(1, c);
d += (c%2 + c%2 - 1) * a.get(1, c) * Det(M); }
}
}
else
{
throw Exception("Matrix must be square");
}
return d;
}
void Swap(double& a, double& b)
{
double temp = a;
a = b;
b = temp;
}
Matrix Inv(const Matrix& a)
{
Matrix res;
double d = 0; int rows = a.GetRows();
int cols = a.GetRows();
d = Det(a);
if (rows == cols && d != 0)
{
if (rows == 1)
{
res = Matrix(rows, cols);
res(1, 1) = 1 / a.get(1, 1);
}
else if (rows == 2)
{
res = Matrix(rows, cols);
res(1, 1) = a.get(2, 2);
res(1, 2) = -a.get(1, 2);
res(2, 1) = -a.get(2, 1);
res(2, 2) = a.get(1, 1);
res = (1/d) * res;
}
else
{
res = Diag(rows); Matrix ai = a; for (int c = 1; c <= cols; c++)
{
int r;
for (r = c; r <= rows && ai(r, c) == 0; r++)
{
}
if (r != c)
{
for (int s = 1; s <= cols; s++)
{
Swap(ai(c, s), ai(r, s));
Swap(res(c, s), res(r, s));
}
}
for (int r = 1; r <= rows; r++)
{
if(r != c)
{
if (ai(r, c) != 0)
{
double f = - ai(r, c) / ai(c, c);
for (int s = 1; s <= cols; s++)
{
ai(r, s) += f * ai(c, s);
res(r, s) += f * res(c, s);
}
}
}
else
{
double f = ai(c, c);
for (int s = 1; s <= cols; s++)
{
ai(r, s) /= f;
res(r, s) /= f;
}
}
}
}
}
}
else
{
if (rows == cols)
{
throw Exception("Matrix must be square");
}
else
{
throw Exception("Determinant of matrix is zero");
}
}
return res;
}
int main(int argc, char *argv[])
{
try
{
int cols = 3;
int rows = 3;
Matrix A = Matrix(cols, rows);
int count = 0;
for (int r = 1; r <= rows; r++)
{
for (int c = 1; c <= cols; c++)
{
count ++;
A(r, c) = count;
}
}
A(2,1) = 1.23;
double centervalue = A(2,2);
printf("centervalue = %f \n", centervalue);
printf("\n");
printf("A = \n");
A.Print();
printf("\n");
Matrix B = Ones(rows, cols) + Diag(rows);
printf("B = \n");
B.Print();
printf("\n");
Matrix B2 = Matrix(rows, 1); count = 1;
for (int r = 1; r <= rows; r++)
{
count ++;
B2(r, 1) = count * 2;
}
printf("B2 = \n");
B2.Print();
printf("\n");
Matrix C;
C = A + B;
printf("A + B = \n");
C.Print();
printf("\n");
C = A - B;
printf("A - B = \n");
C.Print();
printf("\n");
C = A * B2;
printf("A * B2 = \n");
C.Print();
printf("\n");
Matrix E = Diag(B2);
printf("E = \n");
E.Print();
printf("\n");
Matrix D = Matrix(2, 2);
D(1,1) = 2;
D(1,2) = 4;
D(2,1) = 1;
D(2,2) = -2;
printf("D = \n");
D.Print();
printf("Det(D) = %f\n\n", Det(D));
printf("A = \n");
A.Print();
printf("\n");
printf("Det(A) = %f\n\n", Det(A));
Matrix F;
F = 3 - A ;
printf("3 - A = \n");
F.Print();
printf("\n");
Matrix G = Matrix(2, 2);
G(1, 1) = 1;
G(1, 2) = 2;
G(2, 1) = 3;
G(2, 2) = 4;
printf("G = \n");
G.Print();
printf("\n");
Matrix G_inv = Inv(G);
printf("Inv(G) = \n");
G_inv.Print();
printf("\n");
Matrix A_inv = Inv(A);
printf("Inv(A) = \n");
A_inv.Print();
printf("\n");
Matrix A_A_inv = A * Inv(A);
printf("A * Inv(A) = \n");
A_A_inv.Print();
printf("\n");
Matrix B_A = B / A;
printf("B / A = \n");
B_A.Print();
printf("\n");
Matrix A_3 = A / 3;
printf("A / 3 = \n");
A_3.Print();
printf("\n");
rows = 2;
cols = 5;
Matrix H = Matrix(rows, cols);
for (int r = 1; r <= rows; r++)
{
for (int c = 1; c <= cols; c++)
{
count ++;
H(r, c) = count;
}
}
printf("H = \n");
H.Print();
printf("\n");
}
catch (Exception err)
{
printf("Error: %s\n", err.msg);
}
catch (...)
{
printf("An error occured...\n");
}
printf("\n");
PAUSE;
return EXIT_SUCCESS;
}