234 lines
6.4 KiB
C
234 lines
6.4 KiB
C
|
#ifndef DESCSS_Matrix_h
|
|||
|
#define DESCSS_Matrix_h
|
|||
|
|
|||
|
#include <iostream>
|
|||
|
#define swap2(x, y) ((x)=(x)^(y),(y)=(x)^(y),(x)=(x)^(y))
|
|||
|
|
|||
|
class matrix {
|
|||
|
public:
|
|||
|
matrix(int n, int m);
|
|||
|
matrix(const matrix&);
|
|||
|
~matrix();
|
|||
|
|
|||
|
void Input(double* p);
|
|||
|
void Output();
|
|||
|
int rows() const { return n; };
|
|||
|
int cols() const { return m; };
|
|||
|
|
|||
|
double& operator()(int i, int j) const;
|
|||
|
matrix& operator=(const matrix&);
|
|||
|
matrix operator+(const matrix&) const;
|
|||
|
matrix operator*(const matrix&) const;
|
|||
|
matrix operator+(const double&) const;
|
|||
|
matrix operator*(const double&) const;
|
|||
|
matrix operator/(const double&) const;
|
|||
|
|
|||
|
matrix I();
|
|||
|
matrix T();
|
|||
|
|
|||
|
protected:
|
|||
|
int n, m;
|
|||
|
double** element;
|
|||
|
};
|
|||
|
|
|||
|
matrix::matrix(int n, int m) {
|
|||
|
if (m < 0 || n < 0) std::cout << "Rows and Cols must be >= 0 " << std::endl;
|
|||
|
if ((m == 0 || n == 0) && (m != 0 || n != 0))
|
|||
|
std::cout << "Either both or neither rows and columns should be zero " << std::endl;
|
|||
|
this->m = m, this->n = n;
|
|||
|
element = new double*[n];
|
|||
|
for (int i = 0; i < n; i++) element[i] = new double[m];
|
|||
|
for (int i = 0; i < n; i++)
|
|||
|
for (int j = 0; j < m; j++) element[i][j] = 0;
|
|||
|
}
|
|||
|
|
|||
|
matrix::matrix(const matrix& A) {
|
|||
|
n = A.n, m = A.m;
|
|||
|
element = new double*[n];
|
|||
|
for (int i = 0; i < n; i++) element[i] = new double[m];
|
|||
|
for (int i = 0; i < n; i++)
|
|||
|
for (int j = 0; j < m; j++) element[i][j] = A.element[i][j];
|
|||
|
}
|
|||
|
|
|||
|
matrix::~matrix() {}
|
|||
|
|
|||
|
matrix& matrix::operator=(const matrix& A) {
|
|||
|
if (this != &A) {
|
|||
|
delete[] element;
|
|||
|
n = A.n, m = A.m;
|
|||
|
element = new double*[n];
|
|||
|
for (int i = 0; i < n; i++) element[i] = new double[m];
|
|||
|
for (int i = 0; i < n; i++)
|
|||
|
for (int j = 0; j < m; j++) element[i][j] = A.element[i][j];
|
|||
|
}
|
|||
|
return *this;
|
|||
|
}
|
|||
|
|
|||
|
void matrix::Input(double* p) {
|
|||
|
for (int i = 0; i < n; i++)
|
|||
|
for (int j = 0; j < m; j++) this->element[i][j] = *(p++);
|
|||
|
}
|
|||
|
|
|||
|
void matrix::Output() {
|
|||
|
for (int i = 0; i < n; i++) {
|
|||
|
for (int j = 0; j < m; j++) std::cout << element[i][j] << " ";
|
|||
|
std::cout << std::endl;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
double& matrix::operator()(int i, int j) const {
|
|||
|
if (i < 0 || i > n - 1 || j < 0 || j > m - 1) std::cout << "Matrix Index Out Of Bounds " << std::endl;
|
|||
|
return element[i][j];
|
|||
|
}
|
|||
|
|
|||
|
matrix matrix::operator+(const matrix& A) const {
|
|||
|
if (n != A.n || m != A.m) std::cout << "Matrix Size is Out of batch " << std::endl;
|
|||
|
matrix w(n, m);
|
|||
|
for (int i = 0; i < n; i++)
|
|||
|
for (int j = 0; j < m; j++) w.element[i][j] = element[i][j] + A.element[i][j];
|
|||
|
return w;
|
|||
|
}
|
|||
|
|
|||
|
matrix matrix::operator+(const double& C) const {
|
|||
|
matrix w(n, m);
|
|||
|
for (int i = 0; i < n; i++)
|
|||
|
for (int j = 0; j < m; j++) w.element[i][j] = element[i][j] + C;
|
|||
|
return w;
|
|||
|
}
|
|||
|
|
|||
|
matrix matrix::operator*(const matrix& A) const {
|
|||
|
if (m != A.n) std::cout << "Matrix Style is Out of batch " << std::endl;
|
|||
|
matrix w(n, A.m);
|
|||
|
for (int i = 0; i < n; i++)
|
|||
|
for (int j = 0; j < A.m; j++) {
|
|||
|
w.element[i][j] = 0;
|
|||
|
for (int k = 0; k < m; k++) w.element[i][j] += element[i][k] * A.element[k][j];
|
|||
|
}
|
|||
|
return w;
|
|||
|
}
|
|||
|
|
|||
|
matrix matrix::operator*(const double& C) const {
|
|||
|
matrix w(n, m);
|
|||
|
for (int i = 0; i < n; i++)
|
|||
|
for (int j = 0; j < m; j++) w.element[i][j] = element[i][j] * C;
|
|||
|
return w;
|
|||
|
}
|
|||
|
|
|||
|
matrix matrix::operator/(const double& C) const {
|
|||
|
matrix w(n, m);
|
|||
|
for (int i = 0; i < n; i++)
|
|||
|
for (int j = 0; j < m; j++) w.element[i][j] = element[i][j] / C;
|
|||
|
return w;
|
|||
|
}
|
|||
|
|
|||
|
BOOL LUPDescomposition(matrix mA, matrix& mL, matrix& mU, int* P)
|
|||
|
{
|
|||
|
int n = mA.rows();
|
|||
|
int row = 0, tmp;
|
|||
|
double L, U, tmp2;
|
|||
|
for (int i = 0; i < n; i++) P[i] = i;
|
|||
|
for (int i = 0; i < n - 1; i++) {
|
|||
|
tmp2 = 0.;
|
|||
|
for(int j = i; j < n; j++)
|
|||
|
if (std::abs(mA(j, i)) > tmp2) {
|
|||
|
tmp2 = std::abs(mA(j, i));
|
|||
|
row = j;
|
|||
|
}
|
|||
|
|
|||
|
if (tmp2 == 0) {
|
|||
|
AfxMessageBox((CString)"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>죬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
tmp = P[i], P[i] = P[row], P[row] = tmp;
|
|||
|
|
|||
|
for (int j = 0; j < n; j++)
|
|||
|
tmp2 = mA(i, j), mA(i, j) = mA(row, j), mA(row, j) = tmp2;
|
|||
|
|
|||
|
U = mA(i, i), L = 0;
|
|||
|
for (int j = i + 1; j < n; j++) {
|
|||
|
L = mA(j, i) / U;
|
|||
|
mA(j, i) = L;
|
|||
|
for (int k = i + 1; k < n; k++)
|
|||
|
mA(j, k) = mA(j, k) - mA(i, k) * L;
|
|||
|
}
|
|||
|
}
|
|||
|
for (int i = 0; i < n; i++) {
|
|||
|
mL(i, i) = 1;
|
|||
|
for (int j = 0; j < i; j++) mL(i, j) = mA(i, j);
|
|||
|
for (int j = i; j < n; j++) mU(i, j) = mA(i, j);
|
|||
|
}
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
matrix LUPSolve(matrix& mL, matrix& mU, int* P, double* b) {
|
|||
|
int n = mL.rows();
|
|||
|
matrix mX(n, 1);
|
|||
|
double* y = new double[n]();
|
|||
|
|
|||
|
for (int i = 0; i < n; i++) {
|
|||
|
y[i] = b[P[i]];
|
|||
|
for (int j = 0; j < i; j++) y[i] -= mL(i, j) * y[j];
|
|||
|
}
|
|||
|
|
|||
|
for (int i = n - 1; i >= 0; i--) {
|
|||
|
mX(i, 0) = y[i];
|
|||
|
for (int j = n - 1; j > i; j--) mX(i, 0) -= mU(i, j) * mX(j, 0);
|
|||
|
mX(i, 0) /= mU(i, i);
|
|||
|
}
|
|||
|
|
|||
|
return mX;
|
|||
|
}
|
|||
|
|
|||
|
// Inverse
|
|||
|
matrix matrix::I() {
|
|||
|
matrix mX(n, 1);
|
|||
|
matrix mL(n, m);
|
|||
|
matrix mU(n, m);
|
|||
|
matrix mMir(n, m);
|
|||
|
matrix mInv(n, m);
|
|||
|
int* P = new int[n]();
|
|||
|
double* b = new double[n]();
|
|||
|
|
|||
|
if (n != m) {
|
|||
|
AfxMessageBox((CString)"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD>");
|
|||
|
return mInv;
|
|||
|
}
|
|||
|
|
|||
|
for (int j = 0; j < n; j++)
|
|||
|
for (int k = 0; k < m; k++) mMir.element[j][k] = element[j][k];
|
|||
|
LUPDescomposition(mMir, mL, mU, P);
|
|||
|
|
|||
|
for (int i = 0; i < n; i++) {
|
|||
|
for (int j = 0; j < n; j++) b[j] = 0;
|
|||
|
b[i] = 1;
|
|||
|
|
|||
|
mX = LUPSolve(mL, mU, P, b);
|
|||
|
for (int j = 0; j < n; j++) mInv(j, i) = mX(j, 0);
|
|||
|
}
|
|||
|
return mInv;
|
|||
|
}
|
|||
|
|
|||
|
// Transposition
|
|||
|
matrix matrix::T() {
|
|||
|
matrix w(m, n);
|
|||
|
for (int i = 0; i < m; i++)
|
|||
|
for (int j = 0; j < n; j++) w.element[i][j] = element[j][i];
|
|||
|
return w;
|
|||
|
}
|
|||
|
|
|||
|
double Gaussian(double x, double A, double mean, double sigma) {
|
|||
|
return A * exp(-(x - mean) * (x - mean) / (2 * sigma * sigma));
|
|||
|
}
|
|||
|
|
|||
|
matrix Jacobian(int n, double* X, double A, double mean, double sigma) {
|
|||
|
matrix J(n, 3);
|
|||
|
for (int i = 0; i < n; i++) {
|
|||
|
J(i, 0) = -Gaussian(X[i], A, mean, sigma) / A;
|
|||
|
J(i, 1) = -(X[i] - mean) * Gaussian(X[i], A, mean, sigma) / (sigma * sigma);
|
|||
|
J(i, 2) = -(X[i] - mean) * (X[i] - mean) * Gaussian(X[i], A, mean, sigma) / (sigma * sigma * sigma);
|
|||
|
}
|
|||
|
return J;
|
|||
|
}
|
|||
|
|
|||
|
#endif
|