求解逆矩阵

#include <stdio.h>
#include <stdlib.h>

#define true 1
#define false 0

double** expand_matrix;
double** new_matrix;

void initExpandMatrix(double ** mat, double ** expand_mat, int);
int adjustMatrix(double ** expand_mat, int len);
void calculateExpandMatrix(double ** expand_mat, int len);
void getNewMatrix(double ** expand_mat, double ** new_mat, int len);
void printMatrix(double ** mat, int len);
double** getProductMatrix(double ** init_mat, double ** new_mat, int len);
double** getInvMatrix(double ** mat, int len);

int main() {
    int len;
    scanf("%d", &len);
    double** init_mat = (double **)malloc(sizeof(double *) * len);
    for (int i = 0; i < len; i++) {
        init_mat[i] = (double *)malloc(sizeof(double) * len);
    }
     /* 测试示例
        1 2 -1
        3 4 -2
        5 -4 1
     */
    for (int i = 0; i < len; i++) {
        for (int j = 0; j < len; j++) {
            scanf("%lf", &init_mat[i][j]);
        }
    }
    printf("====== init_matrix ======\n");
    printMatrix(init_mat, len);

    printf("==== inverse matrix ====\n\n");
    double ** new_mat = getInvMatrix(init_mat, len);
    printMatrix(new_mat, len);

    printf("====== init * inv ======\n\n");
    double** product_mat = getProductMatrix(init_mat, new_mat, len);
    printMatrix(product_mat, len);
    return 0;
}

// inverse matrix
double** getInvMatrix(double ** mat, int len) {
    // 扩展矩阵定义 //
    expand_matrix = (double**)malloc(sizeof(double *) * len);
    for (int i = 0; i < len; i++) {
        expand_matrix[i] = (double *)malloc(sizeof(double ) * (len * 2));
    }

    // 逆矩阵定义 //
    new_matrix = (double**)malloc(sizeof(double *) * len);
    for (int i = 0; i < len; i++) {
        new_matrix[i] = (double *)malloc(sizeof(double ) * len);
    }

    // init
    initExpandMatrix(mat, expand_matrix, len);

    // adjust
    int canAdjust = adjustMatrix(expand_matrix, len);

    if (canAdjust == 0) {
        return NULL;
    }

    // calc expand
    calculateExpandMatrix(expand_matrix, len);

    // 取后面的N*N矩阵,即为所求 //
    getNewMatrix(expand_matrix, new_matrix, len);

    return new_matrix;
}


// init expand_matrix
void initExpandMatrix(double ** mat, double ** expand_mat, int len) {
    for (int i = 0; i < len; i++) {
        for (int j = 0; j < len * 2; j++) {
            if (j < len) {
                expand_mat[i][j] = mat[i][j];
            } else {
                if (j == len + i) {
                    expand_mat[i][j] = 1;
                } else {
                    expand_mat[i][j] = 0;
                }
            }
        }
    }
}


// adjust expand matrix
int adjustMatrix(double ** expand_mat, int len) {

    for (int i = 0; i < len; i++) {
        if (expand_mat[i][i] == 0) {
            int j;
            for (j = 0; j < len; j++) {
                if (expand_mat[j][i] != 0) {
                    double* tmp = expand_mat[i];
                    expand_mat[i] = expand_mat[j];
                    expand_mat[j] = tmp;
                    break;
                }
            }
            if (j >= len) {
                printf("Inv Matrix does not exists\n");
                return false;
            }
        }
    }
    return true;
}


// calc
void calculateExpandMatrix(double ** expand_mat, int len) {
    for (int i = 0; i < len; i++) {
        double fir_ele = expand_mat[i][i];
        for (int j = 0; j < len * 2; j++) {
            expand_mat[i][j] /= fir_ele;  // 该行所有元素除以首元素 //
        }
        for (int m = 0; m < len; m++) {
            if (m == i) {
                continue;
            }
            // 倍数 //
            double times = expand_mat[m][i];
            for (int n = 0; n < len * 2; n++) {
                expand_mat[m][n] -= expand_mat[i][n] * times;
            }
        }
    }
}


// get res
void getNewMatrix(double ** expand_mat, double ** new_mat, int len) {
    for (int i = 0; i < len; i++) {
        for (int j = 0; j < len * 2; j++) {
            if (j >= len) {
                new_mat[i][j - len] = expand_mat[i][j];
            }
        }
    }
}


// print matrix
void printMatrix(double** mat, int len) {
    for (int i = 0; i < len; i++) {
        for (int j = 0; j < len; j++) {
            printf("%.1lf ", mat[i][j]);
        }
        putchar('\n');
    }
    putchar('\n');
}

// matrix multiplying
double** getProductMatrix(double** init_mat, double** new_mat, int len) {
    double** product_mat = (double**)malloc(sizeof(double*) * len);
    for (int i = 0; i < len; i++) {
        product_mat[i] = (double*)malloc(sizeof(double) * len);
    }
    // need initializing to zero
    for (int i = 0; i < len; i++) {
        for (int j = 0; j < len; j++) {
            product_mat[i][j] = 0;
        }
    }
    for (int i = 0; i < len; i++) {
        for (int j = 0; j < len; j++) {
            for (int k = 0; k < len; k++) {
                product_mat[i][j] += init_mat[i][k] * new_mat[k][j];
            }
        }
    }
    return product_mat;
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值