//sucin int sucin (p_TMatrix ptm1, p_TMatrix ptm2) { int code, i = 0, j = 0, k = 0; if (ptm1->m != ptm2->n) return RET_INP; TMatrix tmp; tmp.n = ptm1->n; tmp.m = ptm2->m; if ((code = allocMat (&tmp)) != RET_OK) return code; zeroMat (&tmp); for (i = 0; i < tmp.n; i++) for (j = 0; j < tmp.m; j++) for (k = 0; k < ptm1->m; k++) tmp.add[i][j] += (ptm1->add[i][k] * ptm2->add[k][j]); vypisMat (&tmp); freeMat (&tmp); return RET_OK; }
//krizova rotacia int crot (p_TMatrix ptm1) { int code, i = 0, j = 0; int l; TMatrix tmp1; tmp1.n = ptm1->n; tmp1.m = ptm1->m; //pomocna matica 1 if ((code = allocMat (&tmp1)) != RET_OK) return code; zeroMat (&tmp1); //spravnim indexovanim naplnime pomocnu maticu posunutymi riadkami for (i = 0; i < tmp1.n; i++) { l = ptm1->add[i][0]; l = l % (ptm1->m); for (j = 0; j < ptm1->m; j++) tmp1.add[i][j] = ptm1->add[i][(j - l + ptm1->m) % (ptm1->m)]; } //podobne posunieme stlpce TMatrix tmp2; tmp2.n = ptm1->n; tmp2.m = ptm1->m; if ((code = allocMat (&tmp2)) != RET_OK) return code; zeroMat (&tmp2); for (i = 0; i < tmp1.m; i++) { l = tmp1.add[0][i]; l = l % (ptm1->n); for (j = 0; j < ptm1->n; j++) tmp2.add[j][i] = tmp1.add[(j - l + ptm1->n) % (ptm1->n)][i]; } vypisMat (&tmp2); freeMat (&tmp1); freeMat (&tmp2); return RET_OK; }
//将矩阵拟上三角化 void hessenbergMat(double **a) { int r, i, j; double c, d, h, t, u[10], p[10], q[10], w[10]; for (r = 0; r<8; r++) { zeroMat(a); c = 0; d = 0; h = 0; for (i = r + 2; i<10; i++) d += a[i][r] * a[i][r]; if (d == 0) continue; else { d += a[r + 1][r] * a[r + 1][r]; d = pow(d, 0.5); if (a[r + 1][r] != 0) c = -fabs(a[r + 1][r]) / a[r + 1][r] * d; else c = d; h = c*c - c*a[r + 1][r]; for (i = 0; i<r + 1; i++) u[i] = 0; u[r + 1] = a[r + 1][r] - c; for (i = r + 2; i<10; i++) u[i] = a[i][r]; for (i = 0; i<10; i++) { p[i] = 0; q[i] = 0; for (j = 0; j<10; j++) { p[i] += a[j][i] * u[j] / h; q[i] += a[i][j] * u[j] / h; } } t = 0; for (i = 0; i<10; i++) t += p[i] * u[i] / h; for (i = 0; i<10; i++) w[i] = q[i] - t*u[i]; for (i = 0; i<10; i++) { for (j = 0; j<10; j++) a[i][j] -= (w[i] * u[j] + u[i] * p[j]); } } } printf("A(n-1)\n"); zeroMat(a); printMat(a); }
//QR分解中的迭代运算 void iterate(double **M, double **a, int m) { int r, i, j; double c, d, h, t, u[10], v[10], p[10], q[10], w[10]; for (r = 0; r<m - 1; r++) { zeroMat(M); c = 0; d = 0; h = 0; for (i = r + 1; i<m; i++) d += M[i][r] * M[i][r]; if (fabs(d) == 0) continue; else { d += M[r][r] * M[r][r]; d = pow(d, 0.5); if (M[r][r] != 0) c = -fabs(M[r][r]) / M[r][r] * d; else c = d; h = c*c - c*M[r][r]; for (i = 0; i<r; i++)u[i] = 0; u[r] = M[r][r] - c; for (i = r + 1; i<m; i++) u[i] = M[i][r]; for (i = 0; i<m; i++) { v[i] = 0; for (j = 0; j<m; j++) v[i] += M[j][i] * u[j] / h; } for (i = 0; i<m; i++) { p[i] = 0; q[i] = 0; for (j = 0; j<m; j++) { M[i][j] -= u[i] * v[j]; p[i] += a[j][i] * u[j] / h; q[i] += a[i][j] * u[j] / h; } } t = 0; for (i = 0; i<m; i++) t += p[i] * u[i] / h; for (i = 0; i<m; i++) w[i] = q[i] - t*u[i]; for (i = 0; i<m; i++) { for (j = 0; j<m; j++) { a[i][j] -= (w[i] * u[j] + u[i] * p[j]); } } } } }
int plough (p_TMatrix ptm1) { int code = 0, i = 0, j = 0, k = 0, l = 0; TMatrix tmp; tmp.n = ptm1->n; tmp.m = ptm1->m; //Alokacia pomocnej matice if ((code = allocMat (&tmp)) != RET_OK) return code; zeroMat (&tmp); code = start; /* v zdrojovej matici sa pohybujeme premennymi k,l v kazdej iteracii zistujeme ci nedoslo k zmene podmienky daneho stavu ak ano prepneme na novy smer */ for (i = 0; i < ptm1->n; i++) for (j = 0; j < ptm1->m; j++) if (!((k == ptm1->n - 1) && (l == ptm1->m - 1))) { switch (code) { case start: tmp.add[i][j] = ptm1->add[k][l]; code = right; break; case right: l++; tmp.add[i][j] = ptm1->add[k][l]; if (k == 0) code = down_left; if (k == ptm1->n - 1) code = up_right; break; case down_left: k++; l--; tmp.add[i][j] = ptm1->add[k][l]; if ((k == ptm1->n - 1)) code = right; else if ((l == 0) && (k != ptm1->n - 1)) code = down; else code = down_left; break; case down: k++; tmp.add[i][j] = ptm1->add[k][l]; if (l == 0) code = up_right; if (l == ptm1->m - 1) code = down_left; break; case up_right: k--; l++; tmp.add[i][j] = ptm1->add[k][l]; if ((l == ptm1->m - 1)) code = down; else if ((k == 0) && (k != ptm1->m - 1)) code = right; else code = up_right; break; } } vypisMat (&tmp); freeMat (&tmp); return RET_OK; }
/** * 11. * @brief Create an zero matrix of the requested size. * @param[in] n The dimension of the zero matrix. * @return Zero matrix of the required size. */ static matrix_type zeros(int m, int n) { matrix_type zeroMat(m,n); elem::Zero(zeroMat); return zeroMat; }
//带双布位移的QR分解方法 void QRmethod(double **a) { int k, m, i, j, r; double s, t, det; double **M; ComplexNumber L[10]; M = (double**)malloc(10 * sizeof(double *)); for (k = 0; k<10; k++) M[k] = (double*)malloc(10 * sizeof(double)); m = 9; r = 0; for (k = 0; k<Max; k++) { if (m == 0) { L[r].Re = a[m][m]; L[r].Im = 0; break; } else if (m < 0) { break; } if (fabs(a[m][m - 1])<e) { L[r].Re = a[m][m]; L[r].Im = 0; m--; r++; } else { if (m == 1) { det = (a[m][m] + a[m - 1][m - 1])*(a[m][m] + a[m - 1][m - 1]) - 4 * (a[m][m] * a[m - 1][m - 1] - a[m - 1][m] * a[m][m - 1]); if (det > 0) { L[r].Re = (a[m][m] + a[m - 1][m - 1]) / 2 + sqrt(det) / 2; L[r].Im = 0; L[r + 1].Re = (a[m][m] + a[m - 1][m - 1]) / 2 - sqrt(det) / 2; L[r + 1].Im = 0; } else { L[r].Re = (a[m][m] + a[m - 1][m - 1]) / 2; L[r].Im = sqrt(-det) / 2; L[r + 1].Re = (a[m][m] + a[m - 1][m - 1]) / 2; L[r + 1].Im = -sqrt(-det) / 2; } m -= 2; r += 2; continue; } else if (fabs(a[m - 1][m - 2])<e) { det = (a[m][m] + a[m - 1][m - 1])*(a[m][m] + a[m - 1][m - 1]) - 4 * (a[m][m] * a[m - 1][m - 1] - a[m - 1][m] * a[m][m - 1]); if (det>0) { L[r].Re = (a[m][m] + a[m - 1][m - 1]) / 2 + sqrt(det) / 2; L[r].Im = 0; L[r + 1].Re = (a[m][m] + a[m - 1][m - 1]) / 2 - sqrt(det) / 2; L[r + 1].Im = 0; } else { L[r].Re = (a[m][m] + a[m - 1][m - 1]) / 2; L[r].Im = sqrt(-det) / 2; L[r + 1].Re = (a[m][m] + a[m - 1][m - 1]) / 2; L[r + 1].Im = -sqrt(-det) / 2; } m -= 2; r += 2; continue; } else { s = a[m - 1][m - 1] + a[m][m]; t = a[m - 1][m - 1] * a[m][m] - a[m][m - 1] * a[m - 1][m]; muiltiplyMat(a, a, M, m + 1); for (i = 0; i<10; i++) { for (j = 0; j<10; j++) M[i][j] -= s*a[i][j]; M[i][i] += t; } iterate(M, a, m + 1); zeroMat(a); } } } zeroMat(a); printf("after QR method\n"); printMat(a); for (int r = 0; r<10; r++) { printf("\n"); if (L[r].Im == 0) { printf("lambda[%d] = (%.12e + i*%.12e)\n", r + 1, L[r].Re, L[r].Im); gauss(L[r].Re); } else { printf("lambda[%d] = (%.12e + i*%.12e)\n", r + 1, L[r].Re, L[r].Im); } } for (int i = 0; i < 10; i++) { free(M[i]); } free(M); }
//求Q、R和RQ void QR_and_RQ(double **a) { int i, j, r; double c, d, h, w[10], p[10], u[10]; double **Q, **R, **RQ; Q = (double **)malloc(10 * sizeof(double *)); for (i = 0; i < 10; i++) Q[i] = (double *)malloc(11 * sizeof(double)); R = (double **)malloc(10 * sizeof(double *)); for (i = 0; i < 10; i++) R[i] = (double *)malloc(11 * sizeof(double)); RQ = (double **)malloc(10 * sizeof(double *)); for (i = 0; i<10; i++) RQ[i] = (double *)malloc(11 * sizeof(double)); for(i = 0; i < 10; i++) { for(j = 0; j < 10; j++){ if(i == j) Q[i][i] = 1; else Q[i][j] = 0; } } for(i = 0; i < 10; i++) { for(j = 0; j < 10; j++) R[i][j] = a[i][j]; } zeroMat(R); for(r = 0; r < 9; r++){ d = 0; for(i = r + 1; i < 10; i++) d += R[i][r] * R[i][r]; if(fabs(d) == 0) continue; else { d += R[r][r] * R[r][r]; d = sqrt(d); if (R[r][r] == 0) c = d; else c = -sgn(R[r][r]) * d; h = c * c - c * R[r][r]; for(i = 0; i < r; i++) u[i] = 0; u[r] = R[r][r] - c; for(i = r + 1; i < 10; i++) u[i] = R[i][r]; for(i = 0; i < 10; i++) { w[i] = 0; for(j = 0; j < 10; j++) w[i] += Q[i][j] * u[j]; } for(i = 0; i < 10; i++) { for(j = 0; j < 10; j++) Q[i][j] -= w[i] * u[j] / h; } for(i = 0; i < 10; i++){ p[i] = 0; for(j = 0; j < 10; j ++ ) p[i] += R[j][i] * u[j] / h; } for(i = 0; i < 10; i++){ for(j = 0; j < 10; j++) R[i][j] -= u[i] * p[j]; } } } zeroMat(R); zeroMat(Q); zeroMat(RQ); printf("Q:\n"); printMat(Q); printf("R:\n"); printMat(R); muiltiplyMat(R, Q, RQ, 10); printf("RQ:\n"); printMat(RQ); for (i = 0; i < 10; i++) free(Q[i]); free(Q); for (i = 0; i < 10; i++) free(R[i]); free(R); for (i = 0; i<10; i++) free(RQ[i]); free(RQ); }