2009-04-28 17:56

[C語言] 高斯消去法-特約化矩陣(RREF)

  1. #include<stdio.h> 
  2. #include<stdlib.h> 
  3.  
  4. /*高斯消去法 - 特約化矩陣*/ 
  5. double **matrix_rref(double **matrix, int m, int n){ 
  6.    double zero=0.00000001; 
  7.    double temp; 
  8.  
  9.    int x=0,y=0,j,i; 
  10.    while(x<n && y<m){ 
  11.        // 如果列首為零,則找尋可以互換的列 
  12.        while(x<n && matrix[y][x]<zero && matrix[y][x]>(-zero)){ 
  13.            j=y+1; 
  14.            while(j<m && matrix[j][x]<zero && matrix[j][x]>(-zero)){j++;} 
  15.  
  16.            // 此行都為零,移至下一行 
  17.            if(j >= m){ x++; continue; } 
  18.  
  19.            // 找到列首不為零的列,兩列互換 
  20.            for(i=x; i<n; i++){ 
  21.                temp=matrix[j][i]; 
  22.                matrix[j][i]=matrix[y][i]; 
  23.                matrix[y][i]=temp; 
  24.            } 
  25.            // 互換結束跳出迴圈 
  26.            break; 
  27.        } 
  28.        if(x>=n){ break; } 
  29.  
  30.        // 所有列值都除以列首,列首為(1)處理 
  31.        for(i=n-1; i>x; i--){ 
  32.            matrix[y][i]/=matrix[y][x]; 
  33.        } 
  34.        matrix[y][x]=1; 
  35.  
  36.        // 消去上下列 
  37.        for(j=0; j<m; j++){ 
  38.            // 跳過選取的列 
  39.            if(j == y){ continue; } 
  40.  
  41.            // 選取的列消去其他列 
  42.            for(i=n-1; i>=x; i--){ 
  43.                matrix[j][i]-=matrix[y][i]*matrix[j][x]; 
  44.            } 
  45.        } 
  46.  
  47.        x++;  y++; 
  48.    } 
  49.    return matrix; 
  50. } 
  51.  
  52.  
  53.  
  54. /* 
  55. input.txt 
  56. 4 5 
  57. 1 2 3 7 55 
  58. 1 3 2 4 76 
  59. 3 2 1 6 43 
  60. 4 6 5 3 34 
  61. */ 
  62.  
  63. /*主程式*/ 
  64. int main(){ 
  65.    int m,n,i,j; 
  66.    FILE *in; 
  67.    // 開啟檔案 
  68.    in=fopen("input.txt","r"); 
  69.  
  70.    // 讀取 m,n 值 
  71.    fscanf(in,"%d\n",&m); 
  72.    fscanf(in,"%d\n",&n); 
  73.  
  74.    // 利用 malloc 配置二維空間 。 
  75.    double **mar= (double**) malloc(m * sizeof(double*)); 
  76.    for (i=0; i<m; i++){ 
  77.        mar[i] = (double*) malloc(n * sizeof(double)); 
  78.    } 
  79.  
  80.    // 讀取矩陣 
  81.    for(i=0;i<m;i++){ 
  82.        for(j=0;j<n;j++){ 
  83.            fscanf(in,"%lf",&mar[i][j]); 
  84.        } 
  85.    } 
  86.  
  87.    // 高斯消去法 
  88.    mar=matrix_rref(mar,m,n); 
  89.  
  90.    // 列印結果 
  91.    for(i=0;i<m;i++){ 
  92.        for(j=0;j<n;j++){ 
  93.            printf("%.2lf ",mar[i][j]); 
  94.        } 
  95.        printf("\n"); 
  96.    } 
  97.  
  98.    _getch(); 
  99.  
  100.    return 0; 
  101. } 

6 回應:

匿名 提到...

請問你的列首是對角線元素嗎?
1 0 1
0 1 1
1 0 0
的話 第一列與第二列都不用換
可是第三列卻要跟第一列換

Jax Hu 提到...

永遠只從下方找非零的列做交換
所以不會出現你說的狀況

Unknown 提到...

您好:想請問
while(x(-zero))
為什麼要這樣使用
不直接使用
matrix[y][x]==0就好

Unknown 提到...
作者已經移除這則留言。
Jax Hu 提到...

這是浮點數誤差的問題,一個例子:
float a = 10/2/5
//a => 1.00000000001

Unknown 提到...

謝謝您的解惑!!