15#include "..\include\core\matrix.h"
16#include "..\include\core\safememory.hpp"
30Matrix::Matrix(
int rows,
int cols)
32 this->create(rows, cols);
37 for (
int i = 0; i < M.
m_rows; i++)
38 memcpy(m_val[i], M.
m_val[i], M.
m_cols *
sizeof(NAFLOAT));
40Matrix::Matrix(
int m,
int n, NAFLOAT
const* val) {
43 for (int32_t i = 0; i < m; i++)
44 for (int32_t j = 0; j < n; j++)
45 m_val[i][j] = val[k++];
54int Matrix::cols()
const {
58int Matrix::rows()
const {
63Matrix Matrix::getMat(
int i1,
int j1,
int i2,
int j2 ) {
65 if (i2 == -1) i2 = m_rows - 1;
66 if (j2 == -1) j2 = m_cols - 1;
67 if (i1 < 0 || i2 >= m_rows || j1 < 0 || j2 >= m_cols || i2 < i1 || j2 < j1) {
68 std::cerr <<
"ERROR: Cannot get submatrix [" << i1 <<
".." << i2 <<
69 "] x [" << j1 <<
".." << j2 <<
"]" <<
70 " of a (" << m_rows <<
"x" << m_cols <<
") matrix." << std::endl;
73 Matrix M(i2 - i1 + 1, j2 - j1 + 1);
74 for (int32_t i = 0; i < M.
m_rows; i++)
75 for (int32_t j = 0; j < M.
m_cols; j++)
76 M.
m_val[i][j] = m_val[i1 + i][j1 + j];
81void Matrix::setMat(
const Matrix& M,
int i1,
int j1) {
82 if (i1<0 || j1<0 || i1 + M.m_rows>m_rows || j1 + M.
m_cols>m_cols) {
83 std::cerr <<
"ERROR: Cannot set submatrix [" << i1 <<
".." << i1 + M.
m_rows - 1 <<
84 "] x [" << j1 <<
".." << j1 + M.
m_cols - 1 <<
"]" <<
85 " of a (" << m_rows <<
"x" << m_cols <<
") matrix." << std::endl;
88 for (int32_t i = 0; i < M.
m_rows; i++)
89 for (int32_t j = 0; j < M.
m_cols; j++)
90 m_val[i1 + i][j1 + j] = M.
m_val[i][j];
93void Matrix::setMatrixEye(
Matrix& mat,
const int m) {
97 for (
int i = 0; i < m; i++)
98 mat.
m_val[i][i] = 1.0;
117 for (k = 0; k < rows - 1; ++k) {
119 for (i = k + 1; i < rows; ++i) {
121 for (j = k + 1; j < cols; ++j) {
122 q[i][j] -= (q[i][k] * q[k][j]);
128 for (i = 0; i < rows; ++i) {
129 for (j = 0; j < i; ++j) {
135 for (j = i + 1; j < cols; ++j) {
147 setMatrixEye(Q, rows);
153 double u, alpha, w, t;
156 for (k = 0; k < ncols; ++k) {
158 for (i = k; i < rows; ++i) {
159 w = std::fabs(a[i][k]);
165 for (i = k; i < rows; ++i) {
171 alpha = u * std::sqrtf(alpha);
173 u = std::sqrtf(2.0 * alpha * (alpha - a[k][k]));
175 a[k][k] = (a[k][k] - alpha) / u;
177 for (i = k + 1; i < rows; ++i)
180 for (j = 0; j < rows; ++j) {
182 for (i = k; i < rows; ++i)
183 t += a[i][k] * q[i][j];
184 for (i = k; i < rows; ++i)
185 q[i][j] -= 2.0 * t * a[i][k];
187 for (j = k + 1; j < cols; ++j) {
189 for (i = k; i < rows; ++i)
190 t += a[i][k] * a[i][j];
191 for (i = k; i < rows; ++i)
192 a[i][j] -= 2.0 * t * a[i][k];
195 for (i = k + 1; i < rows; ++i)
198 for (i = 0; i < ncols; ++i) {
199 for (j = i + 1; j < rows; ++j) {
207static NAFLOAT SIGN(NAFLOAT a, NAFLOAT b) {
210 return -std::fabs(a);
213static NAFLOAT SQR(NAFLOAT a) {
219NAFLOAT pythag(NAFLOAT a, NAFLOAT b) {
224 return absa * std::sqrt(1.0 + SQR(absb / absa));
226 return (absb == 0.0 ? 0.0 : absb * sqrt(1.0 + SQR(absa / absb)));
243 NAFLOAT* w = (NAFLOAT*)malloc(n *
sizeof(NAFLOAT));
244 NAFLOAT* rv1 = (NAFLOAT*)malloc(n *
sizeof(NAFLOAT));
246 int32_t flag, i, its, j, jj, k, l, nm;
247 NAFLOAT anorm, c, f, g, h, s, scale, x, y, z;
249 g = scale = anorm = 0.0;
250 for (i = 0; i < n; i++) {
255 for (k = i; k < m; k++) scale += fabs(U.
m_val[k][i]);
257 for (k = i; k < m; k++) {
258 U.
m_val[k][i] /= scale;
262 g = -SIGN(sqrt(s), f);
264 U.
m_val[i][i] = f - g;
265 for (j = l; j < n; j++) {
266 for (s = 0.0, k = i; k < m; k++) s += U.
m_val[k][i] * U.
m_val[k][j];
268 for (k = i; k < m; k++) U.
m_val[k][j] += f * U.
m_val[k][i];
270 for (k = i; k < m; k++) U.
m_val[k][i] *= scale;
275 if (i < m && i != n - 1) {
276 for (k = l; k < n; k++) scale += fabs(U.
m_val[i][k]);
278 for (k = l; k < n; k++) {
279 U.
m_val[i][k] /= scale;
283 g = -SIGN(sqrt(s), f);
285 U.
m_val[i][l] = f - g;
286 for (k = l; k < n; k++) rv1[k] = U.
m_val[i][k] / h;
287 for (j = l; j < m; j++) {
288 for (s = 0.0, k = l; k < n; k++) s += U.
m_val[j][k] * U.
m_val[i][k];
289 for (k = l; k < n; k++) U.
m_val[j][k] += s * rv1[k];
291 for (k = l; k < n; k++) U.
m_val[i][k] *= scale;
294 anorm = std::max(anorm, (std::fabs(w[i]) + std::fabs(rv1[i])));
296 for (i = n - 1; i >= 0; i--) {
299 for (j = l; j < n; j++)
301 for (j = l; j < n; j++) {
302 for (s = 0.0, k = l; k < n; k++) s += U.
m_val[i][k] * V.
m_val[k][j];
303 for (k = l; k < n; k++) V.
m_val[k][j] += s * V.
m_val[k][i];
306 for (j = l; j < n; j++) V.
m_val[i][j] = V.
m_val[j][i] = 0.0;
312 for (i = std::min(m, n) - 1; i >= 0; --i) {
315 for (j = l; j < n; j++) U.
m_val[i][j] = 0.0;
318 for (j = l; j < n; j++) {
319 for (s = 0.0, k = l; k < m; k++) s += U.
m_val[k][i] * U.
m_val[k][j];
320 f = (s / U.
m_val[i][i]) * g;
321 for (k = i; k < m; k++) U.
m_val[k][j] += f * U.
m_val[k][i];
323 for (j = i; j < m; j++) U.
m_val[j][i] *= g;
325 else for (j = i; j < m; j++) U.
m_val[j][i] = 0.0;
328 for (k = n - 1; k >= 0; k--) {
329 for (its = 0; its < 30; its++) {
331 for (l = k; l >= 0; l--) {
333 if ((NAFLOAT)(fabs(rv1[l]) + anorm) == anorm) { flag = 0;
break; }
334 if ((NAFLOAT)(fabs(w[nm]) + anorm) == anorm) {
break; }
339 for (i = l; i <= k; i++) {
342 if ((NAFLOAT)(fabs(f) + anorm) == anorm)
break;
349 for (j = 0; j < m; j++) {
352 U.
m_val[j][nm] = y * c + z * s;
353 U.
m_val[j][i] = z * c - y * s;
361 for (j = 0; j < n; j++) V.
m_val[j][k] = -V.
m_val[j][k];
366 NA_Assert(its != 29,
"ERROR in SVD: No convergence in 30 iterations");
372 f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y);
374 f = ((x - z) * (x + z) + h * ((y / (f + SIGN(g, f))) - h)) / x;
376 for (j = l; j <= nm; j++) {
390 for (jj = 0; jj < n; jj++) {
393 V.
m_val[jj][j] = x * c + z * s;
394 V.
m_val[jj][i] = z * c - x * s;
405 for (jj = 0; jj < m; jj++) {
408 U.
m_val[jj][j] = y * c + z * s;
409 U.
m_val[jj][i] = z * c - y * s;
423 NAFLOAT* su = (NAFLOAT*)malloc(m *
sizeof(NAFLOAT));
424 NAFLOAT* sv = (NAFLOAT*)malloc(n *
sizeof(NAFLOAT));
425 do { inc *= 3; inc++; }
while (inc <= n);
428 for (i = inc; i < n; i++) {
430 for (k = 0; k < m; k++) su[k] = U.
m_val[k][i];
431 for (k = 0; k < n; k++) sv[k] = V.
m_val[k][i];
433 while (w[j - inc] < sw) {
435 for (k = 0; k < m; k++) U.
m_val[k][j] = U.
m_val[k][j - inc];
436 for (k = 0; k < n; k++) V.
m_val[k][j] = V.
m_val[k][j - inc];
441 for (k = 0; k < m; k++) U.
m_val[k][j] = su[k];
442 for (k = 0; k < n; k++) V.
m_val[k][j] = sv[k];
445 for (k = 0; k < n; k++) {
447 for (i = 0; i < m; i++)
if (U.
m_val[i][k] < 0.0) s2++;
448 for (j = 0; j < n; j++)
if (V.
m_val[j][k] < 0.0) s2++;
449 if (s2 > (m + n) / 2) {
450 for (i = 0; i < m; i++) U.
m_val[i][k] = -U.
m_val[i][k];
451 for (j = 0; j < n; j++) V.
m_val[j][k] = -V.
m_val[j][k];
456 W =
Matrix(std::min(m, n), 1, w);
459 U2.
setMat(U.
getMat(0, 0, m - 1, std::min(m - 1, n - 1)), 0, 0);
472 if (DecompositionMethod::GaussiaJordan == flag) {
473 x = A.
inv(DecompositionMethod::GaussiaJordan) * b;
477Matrix Matrix::zeros(
int rows,
int cols) {
483void Matrix::create(
int rows,
int cols)
486 std::cout <<
"内存申请\n";
490 int temp = m_cols % 32;
494 m_step = m_cols + 32 - temp;
495 size_t nSize =
static_cast<size_t> (m_rows) * m_step;
496 m_data =
new NAFLOAT[nSize];
497 m_val =
new NAFLOAT * [m_rows];
499 for (
int i = 1; i < m_rows; i++)
500 m_val[i] = m_val[i - 1] + m_step;
503void Matrix::release()
506 std::cout <<
"内存释放\n";
513void Matrix::fill(
const NAFLOAT& value)
516 for (i = 0; i < m_cols; ++i) {
519 size_t nLen =
static_cast<size_t>(m_cols *
sizeof(NAFLOAT));
520 for (i = 1; i < m_rows; ++i) {
521 memcpy(m_val[i], m_val[i - 1], nLen);
526NAFLOAT** Matrix::getValPtr()
const
531const NAFLOAT** Matrix::getConstValPtr()
const {
532 return const_cast<const NAFLOAT**
>(m_val);
537 for (
int i = 0; i < m_rows; i++)
538 for (int32_t j = 0; j < m_cols; j++)
539 C.
m_val[j][i] = m_val[i][j];
551 for (
int i = 0; i < M.
m_rows; i++)
552 memcpy(m_val[i], M.
m_val[i], m_step *
sizeof(NAFLOAT));
558const NAFLOAT* Matrix::operator[](
int row)
const {
559 return const_cast<const NAFLOAT*
>(m_val[row]);
567 for (
int i = 0; i < m_rows; i++)
568 for (
int j = 0; j < m_cols; j++)
579 for (
int i = 0; i < m_rows; i++)
580 for (
int j = 0; j < m_cols; j++)
592 for (
int i = 0; i < A.
m_rows; i++)
593 for (
int j = 0; j < B.
m_cols; j++)
594 for (
int k = 0; k < A.
m_cols; k++)
604 for (
int i = 0; i < m_rows; i++)
605 for (
int j = 0; j < m_cols; j++)
612 for (
int i = 0; i < m_rows; i++)
613 for (
int j = 0; j < m_cols; j++)
614 C.
m_val[i][j] = m_val[i][j] * b;
624static int GaussiaJordanInv(
const Matrix& src,
Matrix& dst) {
625 int rows = src.
rows();
626 int cols = src.
cols();
633 std::vector<int> is(rows);
634 std::vector<int> js(cols);
637 for (k = 0; k < rows; ++k) {
639 for (i = k; i < rows; ++i) {
640 for (j = k; j < cols; ++j) {
641 p = std::fabs(data[i][j]);
652 for (j = 0; j < cols; ++j) {
654 data[k][j] = data[temp][j];
660 for (i = 0; i < rows; ++i) {
662 data[i][k] = data[i][temp];
667 data[k][k] = 1.0 / data[k][k];
669 for (j = 0; j < cols; ++j) {
672 data[k][j] *= data[k][k];
675 for (i = 0; i < rows; ++i) {
678 for (j = 0; j < cols; ++j) {
681 data[i][j] -= data[i][k] * data[k][j];
684 for (i = 0; i < rows; ++i) {
687 data[i][k] *= (-data[k][k]);
692 for (k = rows - 1; k >= 0; --k) {
695 for (j = 0; j < cols; ++j) {
697 data[k][j] = data[temp][j];
703 for (i = 0; i < rows; ++i) {
705 data[i][k] = data[i][temp];
718 if (GaussiaJordan == flag) {
719 GaussiaJordanInv(*
this, invMat);
726NAFLOAT Matrix::det()
const {
729 double f, detVal, q, d;
736 for (k = 0; k < n - 1; ++k) {
738 for (i = k; i < n; ++i) {
739 for (j = k; j < n; ++j) {
740 d = std::fabs(a[i][j]);
754 for (j = k; j < n; ++j) {
763 for (i = k; i < n; ++i) {
771 for (i = k + 1; i < n; ++i) {
772 d = a[i][k] / a[k][k];
773 for (j = k + 1; j < n; ++j) {
774 a[i][j] -= d * a[k][j];
778 detVal *= f * a[n - 1][n - 1];
783int Matrix::rank()
const {
784 int i, j, k, nn, is, js, cycle;
789 nn = std::min(m_rows, m_cols);
791 for (cycle = 0; cycle < nn; ++cycle) {
793 for (i = 1; i < m_rows; ++i) {
794 for (j = 1; j < m_cols; ++j) {
795 d = std::fabs(a[i][j]);
809 for (j = 1; j < m_cols; ++j) {
811 a[cycle][j] = a[is][j];
816 for (i = 1; i < m_rows; ++i) {
818 a[i][js] = a[i][cycle];
822 for (i = cycle + 1; i < m_rows; ++i) {
823 d = a[i][cycle] / a[cycle][cycle];
824 for (j = cycle + 1; j < m_cols; ++j) {
825 a[i][j] -= d * a[cycle][j];
839 for (
int i = 0; i < m.
rows(); i++) {
840 for (
int j = 0; j < m.
cols(); j++) {
847std::ostream& operator<< (std::ostream& out,
const Matrix& M){
849 out <<
"[empty matrix]";
853 for (
int i = 0; i < M.
m_rows; i++) {
854 for (
int j = 0; j < M.
m_cols; j++) {
855 sprintf_s(buffer,
"%12.7f ", M.
m_val[i][j]);
885void CMatrix::create(
int rows,
int cols) {
888 int temp = m_cols % 32;
892 m_step = m_cols + 32 - temp;
893 size_t nSize =
static_cast<size_t> (m_rows) * m_step;
895 m_redata =
new NAFLOAT[nSize];
896 m_reval =
new NAFLOAT * [m_rows];
897 m_reval[0] = m_redata;
898 for (
int i = 1; i < m_rows; i++)
899 m_reval[i] = m_reval[i - 1] + m_step;
900 m_imdata =
new NAFLOAT[nSize];
901 m_imval =
new NAFLOAT * [m_rows];
902 m_imval[0] = m_imdata;
903 for (
int i = 1; i < m_rows; i++)
904 m_imval[i] = m_imval[i - 1] + m_step;
913void CMatrix::release() {
Matrix getMat(int i1, int j1, int i2=-1, int j2=-1)
获取当前矩阵的子矩阵
void create(int rows, int cols)
申请内存
Matrix inv(int flag=GaussiaJordan) const
实现矩阵的求逆
void setMat(const Matrix &M, int i, int j)
设置当前矩阵
NAFLOAT ** getValPtr() const
获取值的指针
void fill(const NAFLOAT &value)
用value填充Matrix的全部内容
#define NA_Assert(expr)
当表达式非法,抛出异常
std::istream & operator>>(std::istream &is, Matrix &m)
#define NA_EPS
定义一个极小的正数 smallest such that 1.0+DBL_EPSILON != 1.0
bool isNan(_Tp x)
判断一个数是否是Not a number
void deleteArraySafe(_T *&p)
deleteArraySafe 安全释放 xxx * a = new xxx[num];申请的内存