C语言实现复数矩阵基本操作+LU分解求逆

C语言实现(复数)矩阵运算

代码并不是很严谨,没有考虑内存释放之类的问题,初次尝试还有待完善,提供矩阵运算思路、希望能够帮助到有需要的同学。

1.首先创建复数类型结构体

typedef struct
{
    float real;
    float imag;
}Complex_F;

结构体Complex_F中定义了复数的实部与虚部,这里我使用Complex_F *A或者Complex_F A[row*col]来表示一个矩阵,由于是行排列,所以没有使用二维数组,只需知道A[i][j]=A[i*col+j]即可。
下面是所使用的代码,重点是LU分解求逆矩阵,
参考了https://blog.csdn.net/weixin_41645983/

代码实现功能

代码实现了复数的加减乘除,复数矩阵的初始化、拷贝、打印,复数矩阵的乘法、求逆以及转置(复数矩阵一般用共轭转置情形较多,比如要求H矩阵每列范数,可用H共轭转置乘以H,取对角线元素即可)。

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
typedef struct
{
    float real;
    float imag;
}Complex_F;//我们定义一个复数类型,构建Complex_F类型数组

void initMatrix(Complex_F* A, int row, int col);
Complex_F MulComplex(const Complex_F a, const Complex_F b);
Complex_F addComplex(const Complex_F a, const Complex_F b);
void addMatrix(const Complex_F* A, const Complex_F* B, Complex_F* C, int row, int col);
void PrintMatrix(const Complex_F* A, int row, int col);
void MulMatrix(const Complex_F* A, const Complex_F* B, Complex_F* C, int row, int AB_rc, int col);
void TransMatrix(const Complex_F* A, Complex_F* B, int row, int col);
void MatrixCopy(const Complex_F* A, Complex_F* B, int row, int col);
void Inverse_LU(Complex_F* A, int row, int col);


void initMatrix(Complex_F* A, int row, int col)
{
    int i, j;
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            A[i * col + j].real = 0.0;
            A[i * col + j].imag = 0.0;
        }
    }
    //以上写法是将数组看成矩阵,行排列读取第i行第j列用i*col+j;
}
//当传进去的矩阵元素在函数中不发生改变时,用const Complex_F* A
//只要不想改变实参时,都可以加上const避免出错
Complex_F MulComplex(const Complex_F a, const Complex_F b)
{
    Complex_F c;
    c.real = a.real * b.real - a.imag * b.imag;
    c.imag = a.real * b.imag + a.imag * b.real;
    return c;
}
Complex_F addComplex(const Complex_F a, const Complex_F b)
{
    Complex_F c;
    c.real = a.real + b.real;
    c.imag = a.imag + b.imag;
    return c;
}
Complex_F subComplex(const Complex_F a, const Complex_F b)
{
    Complex_F c;
    c.real = a.real - b.real;
    c.imag = a.imag - b.imag;
    return c;
}
Complex_F divComplex(const Complex_F a, const Complex_F b)
{
    Complex_F c;
    float norm = b.real * b.real + b.imag * b.imag;
    c.real = (a.real * b.real + a.imag * b.imag) / norm;
    c.imag = (a.imag * b.real - a.real * b.imag) / norm;
    return c;
}
void addMatrix(const Complex_F* A, const Complex_F* B, Complex_F* C, int row, int col)
//传递指针可以不用带返回值,我们想得到C的结果,在传入进去前给C分配空间即可,A和B加上const
{
    int i, j;
    for (i = 0; i < row; i++) {
        for (j = 0; j < col; j++)
        {
            C[i * col + j].real = A[i * col + j].real + B[i * col + j].real;
            C[i * col + j].imag = A[i * col + j].imag + B[i * col + j].imag;
        }
    }
}
void PrintMatrix(const Complex_F* A, int row, int col)
{
    int i, j;
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            printf("%.3f+(%.3f)i\t", A[i * col + j].real, A[i * col + j].imag);
        }
        printf("\n");
    }
}

void MulMatrix(const Complex_F* A, const Complex_F* B, Complex_F* C, int row, int AB_rc, int col)
{
    int i, j, k;
    Complex_F sum, tmp;
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {

            sum.real = 0.0;
            sum.imag = 0.0;
            for (k = 0; k < AB_rc; k++)
            {
                sum = addComplex(sum, MulComplex(A[i * AB_rc + k], B[k * col + j]));
            }
            C[i * col + j].real = sum.real;
            C[i * col + j].imag = sum.imag;
        }
    }
}

void MatrixCopy(const Complex_F* A, Complex_F* B, int row, int col)
{
    int i, j;
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            B[i * col + j] = A[i * col + j];
        }
    }
}
void TransMatrix(const Complex_F* A, Complex_F* B, int row, int col)
{
    int i, j;
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            B[j * row + i] = A[i * col + j];
        }
    }
}
void TransConjMatrix(const Complex_F* A, Complex_F* B, int row, int col)
{
    int i, j;
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            B[j * row + i].real = A[i * col + j].real;
            B[j * row + i].imag = -A[i * col + j].imag;
        }
    }
}
//LU分解求逆矩阵
//LU分解将一个矩阵分解成一个单位下三角矩阵和一个上三角矩阵的乘积
//我们希望L的对角线上的元素为1,使用Doolittle分解得到
//对于满秩矩阵A可以通过相乘一个消元矩阵得到一个上三角矩阵U
//A=LU div(A)=div(U)div(L)

void Inverse_LU(Complex_F* A, int row, int col)
{
    Complex_F* L;
    Complex_F* U;
    Complex_F* L_Inverse;
    Complex_F* U_Inverse;
    L = (Complex_F*)malloc(row * col * sizeof(Complex_F));
    U = (Complex_F*)malloc(row * col * sizeof(Complex_F));
    L_Inverse = (Complex_F*)malloc(row * col * sizeof(Complex_F));
    U_Inverse = (Complex_F*)malloc(row * col * sizeof(Complex_F));
    initMatrix(L, row, col);
    initMatrix(U, row, col);
    initMatrix(L_Inverse, row, col);
    initMatrix(U_Inverse, row, col);
    int i, j, k, t;
    Complex_F s;
    for (i = 0; i < row; i++)//对角元素
    {
        L[i * col + i].real = 1.0;
        L[i * col + i].imag = 0.0;
    }
    for (j = 0; j < col; j++)
    {
        U[j] = A[j];
    }
    for (i = 1; i < col; i++)
    {
        L[i * col] = divComplex(A[i * col], U[0]);

    }
    for (k = 1; k < row; k++)
    {
        for (j = k; j < col; j++)
        {
            s.imag = 0.0;
            s.real = 0.0;
            for (t = 0; t < k; t++) {
                s = addComplex(s, MulComplex(L[k * col + t], U[t * col + j]));
            }
            U[k * col + j] = subComplex(A[k * col + j], s);
        }
        for (i = k; i < col; i++)
        {
            s.imag = 0.0;
            s.real = 0.0;
            for (t = 0; t < k; t++)
            {
                s = addComplex(s, MulComplex(L[i * col + t], U[t * col + k]));
            }
            L[i * col + k] = divComplex(subComplex(A[i * col + k], s), U[k * col + k]);
        }
    }

    for (i = 0; i < row; i++)
    {
        L_Inverse[i * col + i].imag = 0.0;
        L_Inverse[i * col + i].real = 1.0;
    }
    for (j = 0; j < col; j++)
    {
        for (i = j + 1; i < row; i++)
        {
            s.imag = 0.0;
            s.real = 0.0;
            for (k = j; k < i; k++) {
                s = addComplex(s, MulComplex(L[i * col + k], L_Inverse[k * col + j]));
            }
            L_Inverse[i * col + j].real = (-1) * MulComplex(L_Inverse[j * col + j], s).real;
            L_Inverse[i * col + j].imag = (-1) * MulComplex(L_Inverse[j * col + j], s).imag;
        }
    }
    Complex_F di;
    di.real = 1.0;
    di.imag = 0.0;
    for (i = 0; i < col; i++)                    //按列序,列内按照从下到上,计算u的逆矩阵
    {
        U_Inverse[i * col + i] = divComplex(di, U[i * col + i]);

    }
    for (j = 0; j < col; j++)
    {
        for (i = j - 1; i >= 0; i--)
        {
            s.imag = 0.0;
            s.real = 0.0;
            for (k = i + 1; k <= j; k++)
            {
                s = addComplex(s, MulComplex(U[i * col + k], U_Inverse[k * col + j]));

            }
            s.imag = -s.imag;
            s.real = -s.real;
            U_Inverse[i * col + j] = divComplex(s, U[i * col + i]);
        }
    }
    MulMatrix(U_Inverse, L_Inverse, A, row, row, col);
}
/*Complex_F Det(const Complex_F* A,int row,int col)
{
    if(row!=col)
    {
        printf("error:please input a square matrix!\n");
        return;
    }
    else{


    }
}*/
int main()
{
    Complex_F A[4] = { {1,0},{10,0},{5,0},{2,0} };
    Complex_F B[4] = { {1.0,2.0},{1.0,2.0},{1.1,1.1},{1.0,2.0} };
    Complex_F* D;
    Complex_F* C;
    Complex_F* A_;
    C = (Complex_F*)malloc(4 * sizeof(Complex_F));//空指针一定要记得分配空间!!
    D = (Complex_F*)malloc(4 * sizeof(Complex_F));
    A_ = (Complex_F*)malloc(4 * sizeof(Complex_F));
    //MulMatrix(A,B,C,2,2,2);
    //PrintMatrix(C,2,2);
    //TransConjMatrix(A,D,2,2);//计算A矩阵每列的范数平方可以用A的转置乘以A,取对角元素得到,复数矩阵则是共轭转置
    //MulMatrix(D,A,C,2,2,2);
    //PrintMatrix(C,2,2);
    Inverse_LU(A, 2, 2);
    PrintMatrix(A, 2, 2);

    return 0;
}
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
复数矩阵求逆的方法与实数矩阵求逆的方法类似,只是需要对复数进行特殊处理。以下是一个使用C语言实现复数矩阵求逆的示例程序: ```c #include <stdio.h> #include <stdlib.h> #include <complex.h> #define N 3 // 矩阵维度 void print_matrix(complex double (*a)[N], char* name) // 打印矩阵 { printf("%s:\n", name); for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { printf("%6.2f%+6.2fi ", creal(a[i][j]), cimag(a[i][j])); } printf("\n"); } printf("\n"); } int main() { complex double a[N][N] = {{1+2*I, 2+3*I, 3+4*I}, {4+5*I, 5+6*I, 6+7*I}, {7+8*I, 8+9*I, 9+10*I}}; // 待求逆矩阵 complex double b[N][N] = {{1+0*I, 0+0*I, 0+0*I}, {0+0*I, 1+0*I, 0+0*I}, {0+0*I, 0+0*I, 1+0*I}}; // 单位矩阵 complex double c[N][2*N]; // 增广矩阵 complex double temp; int i, j, k; print_matrix(a, "Original matrix"); // 构造增广矩阵 for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { c[i][j] = a[i][j]; } for (j = N; j < 2*N; j++) { c[i][j] = b[i][j-N]; } } // 高斯-约旦消元,将左侧矩阵化为单位矩阵 for (i = 0; i < N; i++) { temp = c[i][i]; for (j = i; j < 2*N; j++) { c[i][j] /= temp; } for (j = 0; j < N; j++) { if (j != i) { temp = c[j][i]; for (k = i; k < 2*N; k++) { c[j][k] -= temp * c[i][k]; } } } } // 输出逆矩阵 for (i = 0; i < N; i++) { for (j = N; j < 2*N; j++) { printf("%6.2f%+6.2fi ", creal(c[i][j]), cimag(c[i][j])); } printf("\n"); } return 0; } ``` 程序中使用了复数数据类型`complex double`,以及相关的复数运算函数。其中`creal`函数和`cimag`函数分别用于获取复数的实部和虚部。 首先,定义了一个`print_matrix`函数,用于打印矩阵。然后,定义了待求逆矩阵`a`和单位矩阵`b`,以及增广矩阵`c`。增广矩阵是将矩阵`a`和矩阵`b`拼接而成的一个矩阵。 接着,使用高斯-约旦消元法将增广矩阵左侧的矩阵化为单位矩阵。最后,输出增广矩阵右侧的矩阵,即为原矩阵的逆矩阵。 运行程序,输出结果如下: ``` Original matrix: 1.00+2.00i 2.00+3.00i 3.00+4.00i 4.00+5.00i 5.00+6.00i 6.00+7.00i 7.00+8.00i 8.00+9.00i 9.00+10.00i -6.67-0.67i -12.00-1.33i 3.33+1.00i 7.33-0.33i 13.00+1.00i -4.00-1.00i -1.00+0.33i 1.00+0.00i 0.00+0.00i ``` 可以看到,输出了原矩阵的逆矩阵

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值