掃き出し
別に掃除するってわけじゃあないよ
ガウスの消去法のプログラム。
ピボット選択をとれば、単純消去法にチェンジ出来る!(する必要はないけど)
#include <stdio.h> #include <stdlib.h> #include <math.h> #define N 3 void print_vector(double b[], int n); void print_matrix(double a[], int n); int gauss(double a[], double b[], double x[], int n); int main(void) { double a[N*N] = { 2, 3, -1, 1, 1, 1, 3, -1, -2 }; double b[N] = {-2, 7, 0}; double x[N]; int i; printf("A = \n"); print_matrix(a, N); printf("b = \n"); print_vector(b, N); if (gauss(a, b, x, N)) for (i = 0;i < N;i++) printf("x%d = %6.2f\n", i+1, x[i]); else printf("計算できませんでした.\n"); return 0; } void print_vector(double b[], int n) { int i; for (i = 0;i < n;i++) printf("%6.2f ", b[i]); printf("\n"); } void print_matrix(double a[], int n) { int i; for (i = 0;i < n;i++) print_vector(&a[i*n], n); } int gauss(double a[], double b[], double x[], int n) { int i, j, k, idx; double pivot, tmp; double eps = 0.00001; for (i = 0;i < n;i++) { //ピボットの選択 pivot = a[i*n+i]; idx = i; for (j = i+1;j < n;j++) { if (pivot < a[j*n+i]) { pivot = a[j*n+i]; idx = j; } } //ピボットが0しかなかったら計算できないのでリターン if (fabs(pivot) < eps) return 0; //行の交換 if (idx != i) { tmp = b[i]; b[i] = b[idx]; b[idx] = tmp; for (j = i;j < n;j++) { tmp = a[idx*n+j]; a[idx*n+j] = a[i*n+j]; a[i*n+j] = tmp; } } //前進消去 b[i] /= a[i*n+i]; for (j = n-1;j >= i;j--) a[i*n+j] /= a[i*n+i]; for (j = i+1;j < n;j++) { b[j] -= b[i] * a[j*n+i] / a[i*n+i]; for (k = n-1;k >= i;k--) a[j*n+k] -= a[i*n+k] * a[j*n+i] / a[i*n+i]; } } //後退代入 for (i = n-1;i >= 0;i--) { x[i] = b[i]; for (j = n-1;j > i;j--) x[i] -= x[j] * a[i*n+j]; } return 1; }
なんか微妙にインデントがずれてるんだが・・・・・
今度はガウス・ザイデルとSORをやると思う