關於 Gauss Jordan (不知道是不是這麼拼) 消去法
基本上大家都知道怎麼做,
這裡的 code 分二段,一段是用高斯消去法求反矩陣(MINVERSE),
另一段是用高期消去法求連立方程式之解
以下的 code 便是實現其作法
若對 code 有問題,歡迎回覆進行討論

// =======================================
// author  : edison.shih.
// filename: matrix.cpp
// date    : 2010/2/7
// mail    : forget72@hotmail.com
// ** all copyright reverve **
// =======================================
// ==============================
// 計算反矩陣
/*
use gauss jodarn method.
return value:
-1: have a row all 0
0 : exist inverse
1 : have a col all 0
*/
int MINVERSE( double **a,
             unsigned dim,
             double **_result)
{
    unsigned i, j;
    double x=0.0;
    SetUnitMatrix(_result, dim);
   
    double **tmp = (double**)malloc(sizeof(double*)*dim);
    for(i=0; i<dim; i++) tmp[i] = (double*)malloc(sizeof(double)*dim);
   
    CopyMatrix(tmp, a, dim, dim);
   
    for(i=0; i<dim; i++){
       
        // 該列全為0, return -1
        if(IsRi0(tmp, i, dim)) return -1;
       
        if(tmp[i][i]==0.0){
            // 交換至該元素為非0
            bool flag = false;
            for(j=i+1; j<dim; j++){
                Rij(tmp, i, j, dim);
                Rij(_result, i, j, dim);
                if(tmp[i][i]!=0.0) {
                    break;
                    flag = true;
                }
            }
            // 交換不到非0 元素,return 1
            if(flag==false) return 1;
        }
       
        // 以下精華
        x = 1.0 / tmp[i][i];
        Rix(tmp, i, x, dim);
        Rix(_result, i, x, dim);
       
        for(j=0; j<dim; j++){
            if(i==j) continue;
            x = -tmp[j][i] / tmp[i][i];
            Rijx(tmp, i, j, x, dim);
            Rijx(_result, i, j, x, dim);
        }
    }
   
    for(i=0; i<dim; i++) free(tmp[i]);
    free(tmp);
    return 0;
}

// ==============================
// 使用 gauss jordan 求連立方程式
/*
return  value:
-1: 無解
0 : 有一解
1 : 無限多解
*/
int GAUSSJORDAN(double **a,
                double *ans,
                unsigned dim)
{
   
    unsigned i, j;
    double x=0.0;
   
    double **tmp = (double**)malloc(sizeof(double*)*dim);
    for(i=0; i<dim; i++) tmp[i] = (double*)malloc(sizeof(double)*(dim+1));
   
    CopyMatrix(tmp, a, dim, dim+1);
   
    for(i=0; i<dim; i++){
       
        // 該列全為0, 無限多解, return 1
        if(IsRi0(tmp, i, dim+1)) return -1;
       
        if(tmp[i][i]==0.0){
            // 交換至該元素為非0
            bool flag = false;
            for(j=i+1; j<dim; j++){
                Rij(tmp, i, j, dim+1);
                if(tmp[i][i]!=0.0) {
                    break;
                    flag = true;
                }
            }
            // 交換不到非0 元素,無解, return -1
            if(flag==false) return -1;
        }
       
        // 以下精華
        x = 1.0 / tmp[i][i];
        Rix(tmp, i, x, dim+1);
       
        for(j=0; j<dim; j++){
            if(i==j) continue;
            x = -tmp[j][i] / tmp[i][i];
            Rijx(tmp, i, j, x, dim+1);
        }
    }
    for(i=0; i<dim; i++) {
        ans[i] = tmp[i][dim];
    }
   
    for(i=0; i<dim; i++) free(tmp[i]);
    free(tmp);
    return 0;
}

arrow
arrow
    全站熱搜

    Edison 發表在 痞客邦 留言(6) 人氣()