fork download
  1. #include <stdio.h>
  2. #include <math.h>
  3. #define N 4 // 行列の次元を設定
  4.  
  5. void householderHB(double A[N][N], double H[N][N]) {
  6. int i, j, k;
  7. double norm;
  8. double Cop[N][N];
  9.  
  10. // A マトリックス表示
  11. for (i = 0; i < N; i++) {
  12. for (j = 0; j < N; j++) {
  13. printf("A1[%d][%d]=%lf ", i, j, A[i][j]);
  14. }
  15. putchar('\n');
  16. }
  17.  
  18.  
  19. for (k = 0; k < N-1; k++) {
  20.  
  21. // H マトリックスを単位行列に初期化
  22. for (i = 0; i < N; i++) {
  23. for (j = 0; j < N; j++) {
  24. H[i][j] = (i == j) ? 1.0 : 0.0;
  25. printf("H[%d][%d]=%lf ", i, j, H[i][j]);
  26. }
  27. putchar('\n');
  28. }
  29.  
  30. // x ベクトルと v ベクトルの計算
  31. double x[N]={0.0}, v[N]={0.0}, u[N]={0.0}, alpha, beta;
  32. norm = 0.0;
  33.  
  34. for (i = k+1; i < N; i++) {
  35. x[i] = A[i][k];
  36. norm += x[i]*x[i];
  37. }
  38. printf("k=%d ", k);
  39. norm = sqrt(norm);
  40. printf("norm=%lf ", norm);
  41.  
  42. // alpha の計算
  43. alpha = (x[k+1] > 0) ? -norm : norm;
  44. printf("alpha=%lf ", alpha);
  45.  
  46. // v ベクトルの計算
  47. for (i = 0; i < N ; i++) {
  48. if (i==k+1)
  49. v[i] = x[i]-alpha;
  50. else if (i<=k)
  51. v[i] = v[i];
  52. else
  53. v[i] = x[i];
  54. x[i] = 0.0;
  55. printf("v[%d]=%lf ", i, v[i]);
  56. }
  57. putchar('\n');
  58.  
  59. // u ベクトルの計算 (正規化された v)
  60. beta = 1.0/sqrt(alpha*(-v[k+1]));
  61. printf("beta=%lf ", beta);
  62.  
  63. for (j = 0; j <= k; j++) {
  64. u[j] += beta * v[j];
  65. printf("u[%d]=%lf ", j, u[j]);
  66. v[j]=0.0;}
  67. for (j = k+1; j < N; j++) {
  68. u[j] += beta * v[j];
  69. printf("u[%d]=%lf ", j, u[j]);
  70. v[j]=0.0;}
  71. putchar('\n');
  72.  
  73. // H の更新
  74. for (i = 0; i < N; i++) {
  75. for (int j = 0; j < N; j++) {
  76. H[i][j]-=u[i]*u[j];
  77. }
  78. }
  79.  
  80. // H の表示
  81. for (i = 0; i < N; i++) {
  82. for (j = 0; j < N; j++) {
  83. printf("H1[%d][%d]=%lf ", i, j, H[i][j]);
  84. }
  85. putchar('\n');
  86. }
  87.  
  88.  
  89. // A の更新
  90. for (i = 0; i < N; i++) {
  91. for (j = 0; j < N; j++) {
  92. for (int l = 0; l < N; l++) {
  93. Cop[i][j] += H[i][l]*A[l][j];
  94. }
  95. }
  96. }
  97.  
  98. // A の初期化
  99. for (i = k; i < N; i++) {
  100. for (j = k; j < N; j++) {
  101. A[i][j] = Cop[i][j];
  102. printf("A[%d][%d]=%lf ", i, j, A[i][j]);
  103. Cop[i][j] = 0.0;
  104. }
  105. putchar('\n');
  106. }
  107.  
  108. // H の初期化
  109. for (i = 0; i < N; i++) {
  110. for (j = 0; j < N; j++) {
  111. printf("H[%d][%d]=%lf ", i, j, H[i][j]);
  112. H[i][j] = 0.0;
  113. }
  114. putchar('\n');
  115. }
  116. }
  117. }
  118.  
  119. void gram_schmidt_qr(double A[N][N], double Q[N][N], double R[N][N]) {
  120. double H[N][N];
  121.  
  122. householderHB(A,H);
  123.  
  124. int i, j, k;
  125. double temp;
  126.  
  127. for (j = 0; j < N; j++) {
  128. for (i = 0; i < N; i++) {
  129. Q[i][j] = A[i][j];
  130. }
  131. for (k = 0; k < j; k++) {
  132. temp = 0.0;
  133. for (i = 0; i < N; i++) {
  134. temp += Q[i][j] * Q[i][k];
  135. }
  136. for (i = 0; i < N; i++) {
  137. Q[i][j] -= temp * Q[i][k];
  138. }
  139. }
  140. temp = 0.0;
  141. for (i = 0; i < N; i++) {
  142. temp += Q[i][j] * Q[i][j];
  143. }
  144. temp = sqrt(temp);
  145. for (i = 0; i < N; i++) {
  146. Q[i][j] /= temp;
  147. }
  148. for (i = 0; i <= j; i++) {
  149. temp = 0.0;
  150. for (k = 0; k < N; k++) {
  151. temp += A[k][j] * Q[k][i];
  152. }
  153. R[i][j] = temp;
  154. }
  155. for (i = j + 1; i < N; i++) {
  156. R[i][j] = 0.0;
  157. }
  158. }
  159. }
  160.  
  161. int main() {
  162. double A[N][N] = {{16.0, -1.0, 1.0, 2.0},
  163. {2.0, 12.0, 1.0, -1.0},
  164. {1.0, 3.0, -24.0, 2.0},
  165. {4.0, -2.0, 1.0, 20.0}};
  166. double R[N][N];
  167. double Q[N][N];
  168.  
  169. gram_schmidt_qr(A,Q,R);
  170.  
  171.  
  172. // ハウスホルダー変換後の行列 A を表示
  173. printf("Householder変換後の行列 A:\n");
  174. for (int i = 0; i < N; i++) {
  175. for (int j = 0; j < N; j++) {
  176. printf("%lf ", A[i][j]);
  177. }
  178. printf("\n");
  179. }
  180.  
  181. // QR分解後の行列 Q を表示
  182. printf("QR分解後の行列 Q:\n");
  183. for (int i = 0; i < N; i++) {
  184. for (int j = 0; j < N; j++) {
  185. printf("Q[%d][%d]=%lf ",i,j, Q[i][j]);
  186. }
  187. printf("\n");
  188. }
  189. // QR分解後の行列 R を表示
  190. printf("QR分解後の行列 R:\n");
  191. for (int i = 0; i < N; i++) {
  192. for (int j = 0; j < N; j++) {
  193. printf("R[%d][%d]=%lf ",i,j, R[i][j]);
  194. }
  195. printf("\n");
  196. }
  197. return 0;
  198. }
Success #stdin #stdout 0s 5280KB
stdin
Standard input is empty
stdout
A1[0][0]=16.000000 A1[0][1]=-1.000000 A1[0][2]=1.000000 A1[0][3]=2.000000 
A1[1][0]=2.000000 A1[1][1]=12.000000 A1[1][2]=1.000000 A1[1][3]=-1.000000 
A1[2][0]=1.000000 A1[2][1]=3.000000 A1[2][2]=-24.000000 A1[2][3]=2.000000 
A1[3][0]=4.000000 A1[3][1]=-2.000000 A1[3][2]=1.000000 A1[3][3]=20.000000 
H[0][0]=1.000000 H[0][1]=0.000000 H[0][2]=0.000000 H[0][3]=0.000000 
H[1][0]=0.000000 H[1][1]=1.000000 H[1][2]=0.000000 H[1][3]=0.000000 
H[2][0]=0.000000 H[2][1]=0.000000 H[2][2]=1.000000 H[2][3]=0.000000 
H[3][0]=0.000000 H[3][1]=0.000000 H[3][2]=0.000000 H[3][3]=1.000000 
k=0 norm=4.582576 alpha=-4.582576 v[0]=0.000000 v[1]=6.582576 v[2]=1.000000 v[3]=4.000000 
beta=0.182074 u[0]=0.000000 u[1]=1.198514 u[2]=0.182074 u[3]=0.728295 
H1[0][0]=1.000000 H1[0][1]=0.000000 H1[0][2]=0.000000 H1[0][3]=0.000000 
H1[1][0]=0.000000 H1[1][1]=-0.436436 H1[1][2]=-0.218218 H1[1][3]=-0.872872 
H1[2][0]=0.000000 H1[2][1]=-0.218218 H1[2][2]=0.966849 H1[2][3]=-0.132603 
H1[3][0]=0.000000 H1[3][1]=-0.872872 H1[3][2]=-0.132603 H1[3][3]=0.469587 
A[0][0]=16.000000 A[0][1]=-1.000000 A[0][2]=1.000000 A[0][3]=2.000000 
A[1][0]=-4.582576 A[1][1]=-4.146140 A[1][2]=3.927922 A[1][3]=-17.457431 
A[2][0]=0.000000 A[2][1]=0.547139 A[2][2]=-23.555201 A[2][3]=-0.500151 
A[3][0]=0.000000 A[3][1]=-11.811442 A[3][2]=2.779195 A[3][3]=9.999397 
H[0][0]=1.000000 H[0][1]=0.000000 H[0][2]=0.000000 H[0][3]=0.000000 
H[1][0]=0.000000 H[1][1]=-0.436436 H[1][2]=-0.218218 H[1][3]=-0.872872 
H[2][0]=0.000000 H[2][1]=-0.218218 H[2][2]=0.966849 H[2][3]=-0.132603 
H[3][0]=0.000000 H[3][1]=-0.872872 H[3][2]=-0.132603 H[3][3]=0.469587 
H[0][0]=1.000000 H[0][1]=0.000000 H[0][2]=0.000000 H[0][3]=0.000000 
H[1][0]=0.000000 H[1][1]=1.000000 H[1][2]=0.000000 H[1][3]=0.000000 
H[2][0]=0.000000 H[2][1]=0.000000 H[2][2]=1.000000 H[2][3]=0.000000 
H[3][0]=0.000000 H[3][1]=0.000000 H[3][2]=0.000000 H[3][3]=1.000000 
k=1 norm=11.824108 alpha=-11.824108 v[0]=0.000000 v[1]=0.000000 v[2]=12.371247 v[3]=-11.811442 
beta=0.082682 u[0]=0.000000 u[1]=0.000000 u[2]=1.022875 u[3]=-0.976589 
H1[0][0]=1.000000 H1[0][1]=0.000000 H1[0][2]=0.000000 H1[0][3]=0.000000 
H1[1][0]=0.000000 H1[1][1]=1.000000 H1[1][2]=0.000000 H1[1][3]=0.000000 
H1[2][0]=0.000000 H1[2][1]=0.000000 H1[2][2]=-0.046273 H1[2][3]=0.998929 
H1[3][0]=0.000000 H1[3][1]=0.000000 H1[3][2]=0.998929 H1[3][3]=0.046273 
A[1][1]=-4.146140 A[1][2]=3.927922 A[1][3]=-17.457431 
A[2][1]=-11.824108 A[2][2]=3.866193 A[2][3]=10.011830 
A[3][1]=-0.000000 A[3][2]=-23.401367 A[3][3]=-0.036911 
H[0][0]=1.000000 H[0][1]=0.000000 H[0][2]=0.000000 H[0][3]=0.000000 
H[1][0]=0.000000 H[1][1]=1.000000 H[1][2]=0.000000 H[1][3]=0.000000 
H[2][0]=0.000000 H[2][1]=0.000000 H[2][2]=-0.046273 H[2][3]=0.998929 
H[3][0]=0.000000 H[3][1]=0.000000 H[3][2]=0.998929 H[3][3]=0.046273 
H[0][0]=1.000000 H[0][1]=0.000000 H[0][2]=0.000000 H[0][3]=0.000000 
H[1][0]=0.000000 H[1][1]=1.000000 H[1][2]=0.000000 H[1][3]=0.000000 
H[2][0]=0.000000 H[2][1]=0.000000 H[2][2]=1.000000 H[2][3]=0.000000 
H[3][0]=0.000000 H[3][1]=0.000000 H[3][2]=0.000000 H[3][3]=1.000000 
k=2 norm=23.401367 alpha=23.401367 v[0]=0.000000 v[1]=0.000000 v[2]=0.000000 v[3]=-46.802734 
beta=0.030216 u[0]=0.000000 u[1]=0.000000 u[2]=0.000000 u[3]=-1.414214 
H1[0][0]=1.000000 H1[0][1]=0.000000 H1[0][2]=0.000000 H1[0][3]=0.000000 
H1[1][0]=0.000000 H1[1][1]=1.000000 H1[1][2]=0.000000 H1[1][3]=0.000000 
H1[2][0]=0.000000 H1[2][1]=0.000000 H1[2][2]=1.000000 H1[2][3]=0.000000 
H1[3][0]=0.000000 H1[3][1]=0.000000 H1[3][2]=0.000000 H1[3][3]=-1.000000 
A[2][2]=3.866193 A[2][3]=10.011830 
A[3][2]=23.401367 A[3][3]=0.036911 
H[0][0]=1.000000 H[0][1]=0.000000 H[0][2]=0.000000 H[0][3]=0.000000 
H[1][0]=0.000000 H[1][1]=1.000000 H[1][2]=0.000000 H[1][3]=0.000000 
H[2][0]=0.000000 H[2][1]=0.000000 H[2][2]=1.000000 H[2][3]=0.000000 
H[3][0]=0.000000 H[3][1]=0.000000 H[3][2]=0.000000 H[3][3]=-1.000000 
Householder変換後の行列 A:
16.000000 -1.000000 1.000000 2.000000 
-4.582576 -4.146140 3.927922 -17.457431 
0.000000 -11.824108 3.866193 10.011830 
0.000000 -0.000000 23.401367 0.036911 
QR分解後の行列 Q:
Q[0][0]=0.961347 Q[0][1]=-0.093351 Q[0][2]=0.027524 Q[0][3]=-0.257566 
Q[1][0]=-0.275340 Q[1][1]=-0.325934 Q[1][2]=0.096099 Q[1][3]=-0.899288 
Q[2][0]=0.000000 Q[2][1]=-0.940772 Q[2][2]=-0.036025 Q[2][3]=0.337120 
Q[3][0]=0.000000 Q[3][1]=-0.000000 Q[3][2]=0.994339 Q[3][3]=0.106256 
QR分解後の行列 R:
R[0][0]=16.643317 R[0][1]=0.180253 R[0][2]=-0.120168 R[0][3]=6.729428 
R[1][0]=0.000000 R[1][1]=12.568513 R[1][2]=-5.010803 R[1][3]=-3.915578 
R[2][0]=0.000000 R[2][1]=0.000000 R[2][2]=23.534600 R[2][3]=-1.946561 
R[3][0]=0.000000 R[3][1]=0.000000 R[3][2]=0.000000 R[3][3]=18.563242