一、前言

  1. 由于实数矩阵的运算较简单,因此在本章中,我只给出复数矩阵的相关运算,一般的实数矩阵,类似炮制即可;
  2. 复数矩阵的加/减/乘运算涉及到其复数元胞(cell)的相加减运算,由于complex.h头文件中只给出了复数乘法运算,故而复数的加减运算函数需要自己定义功能。

二、矩阵加/减法运算

复数矩阵与复数矩阵之间的加/减法运算:

/* Complex Matrix Add: matrixC = matrixA + matrixB */
void AddMatrix(const Matrix* matrix_A, const Matrix* matrix_B, Matrix* matrix_C)
{// Size Incompatabilityif (matrix_A->row == matrix_B->row || matrix_A->column == matrix_B->column){puts("ERROE: An incompatable matrix!\n");return;}// Validity of Known Matriceelse if (IsNullComplexMatrix(matrix_A) || IsNullComplexMatrix(matrix_B)){puts("ERROE: An invalid matrix!\n");return;}else{ComplexType tempCell_C;int indexC;for (int row_i = 0; row_i < matrix_C->row; row_i++){for (int column_j = 0; column_j < matrix_C->column; column_j++){tempCell_C = AddComplex(matrix_A->arrayComplex[row_i * matrix_A->column + column_j],matrix_B->arrayComplex[row_i * matrix_B->column + column_j]);indexC = row_i * matrix_C->column + column_j;matrix_C->arrayComplex[indexC] = tempCell_C;// matrix_C->arrayComplex[i * matrix_C->row + j]._Val[0] = \// creal(matrix_A->arrayComplex[i * matrix_A->row + j]) + creal(matrix_B->arrayComplex[i * matrix_A->row + j]);// matrix_C->arrayComplex[i * matrix_C->row + j]._Val[1] = \// cimag(matrix_A->arrayComplex[i * matrix_A->row + j]) + cimag(matrix_B->arrayComplex[i * matrix_A->row + j]);}}}
}

说明
加减法运算简单,笔者这里就不给出测试了!!!

三、矩阵乘法运算

矩阵乘法运算用到非常多!!!

1.复数加法运算

复数与复数之间对应实/虚部相加:

/* Add Complex: Complex_C = Complex_A + Complex_B */
ComplexType AddComplex(const ComplexType Complex_A, const ComplexType Complex_B)
{ComplexType Complex_C;Complex_C._Val[0] = creal(Complex_A) + creal(Complex_B);Complex_C._Val[1] = cimag(Complex_A) + cimag(Complex_B);return Complex_C;
}

说明
后续的矩阵乘法运算用到加法函数,故而不单独测试。

2.复数减法运算

复数与复数之间对应实/虚部相减:

/* Subvision Complex: Complex_C = Complex_A - Complex_B */
ComplexType SubComplex(const ComplexType Complex_A, const ComplexType Complex_B)
{ComplexType Complex_C;   // Change Pointer to a VariableComplex_C._Val[0] = creal(Complex_A) - creal(Complex_B);Complex_C._Val[1] = cimag(Complex_A) - cimag(Complex_B);return Complex_C;
}

说明
后续的矩阵乘法运算用到减法函数,故而不单独测试。

3.矩阵数乘运算

数乘运算,也就是复数矩阵与实数复数矩阵与复数的乘法运算:

/* Point Multiple: Complex matrixB = Complex matrixA .* Complex_c */
void MatrixPointMulComplex(const Matrix* matrixA, ComplexType c, Matrix* matrixB)
{if (IsNullComplexMatrix(matrixA)){puts("ERROE: An invalid matrix!\n");return;}else{int row_i, column_j;for (row_i = 0; row_i < matrixB->row; ++row_i)for (column_j = 0; column_j < matrixB->column; ++column_j){matrixB->arrayComplex[row_i * matrixB->column + column_j] =_Cmulcc(matrixA->arrayComplex[row_i * matrixA->column + column_j], c);}}
}/* Point Multiple: Complex matrixB = Complex matrixA .* Double_c */
void MatrixPointMulDouble(const Matrix* matrixA, DoubleType c, Matrix* matrixB)
{if (IsNullComplexMatrix(matrixA)){puts("ERROE: An invalid matrix!\n");return;}int row_i, column_j;for (row_i = 0; row_i < matrixB->row; ++row_i)for (column_j = 0; column_j < matrixB->column; ++column_j){matrixB->arrayComplex[row_i * matrixB->column + column_j] = \_Cmulcr(matrixA->arrayComplex[row_i * matrixA->column + column_j], c);}
}

说明
(1) 这里笔者贴上复数矩阵与复数复数矩阵与实数的点乘运算两个函数;
(2) 核心就是调用复数与复数乘法函数_Cmulcc()和复数与实数乘法函数_Cmulcr(),其函数原型:

_ACRTIMP _Dcomplex __cdecl _Cmulcc(_In_ _Dcomplex _X, _In_ _Dcomplex _Y);
_ACRTIMP _Dcomplex __cdecl _Cmulcr(_In_ _Dcomplex _X, _In_ double _Y);

(3) 同样在主程序之前都加上一个if判断语句,用于保证传入的实参矩阵是有效,才有计算的意义;
(4) 结合前面的函数,这里我给出测试复数矩阵与数乘的demo,顺便把第一章中的几个函数也测试了:

#include<stdio.h>
#include<stdlib.h>
#include<complex.h>typedef _Dcomplex ComplexType;
typedef double DoubleType;typedef struct
{int row, column;  ComplexType* arrayComplex;
}Matrix;typedef struct
{int row, column;  // SizeDoubleType* arrayDouble;
}Matrix2Double;typedef enum
{False = 0, True = 1
}Bool;  // Boolean/*Validity of Complex Matrix
*/
Bool IsNullComplexMatrix(const Matrix* matrix)
{int size = matrix->row * matrix->column;if (size <= 0 || matrix->arrayComplex == NULL){return True;}return False;
}/*Initiation of Complex Number*/
void InitComplex(ComplexType* Complex)
{Complex->_Val[0] = 0.0;Complex->_Val[1] = 0.0;}/*Initiation of Complex Number*/
void InitComplexMatrix(Matrix* matrix, int row, int column)
{int size = row * column * sizeof(ComplexType);if (size <= 0){puts("ERROE: An invalid matrix!\n");return;}matrix->arrayComplex = (ComplexType*)malloc(size);if (matrix->arrayComplex){matrix->row = row;matrix->column = column;for (int row_i = 0; row_i < row; ++row_i){for (int column_j = 0; column_j < column; ++column_j){InitComplex(matrix->arrayComplex + row_i * matrix->column + column_j);}}}
}/*Free Memory of Complex Matrix
*/
void DestroyComplexMatrix(Matrix* matrix)
{if (!IsNullComplexMatrix(matrix)){free(matrix->arrayComplex); matrix->arrayComplex = NULL;}matrix->row = matrix->column = 0;
}/*Return Matrix Row Size
*/
int MatrixRow(const Matrix* matrix)
{return matrix->row;
}/*Return Matrix Column Size
*/
int MatrixColumn(const Matrix* matrix)
{return matrix->column;
}/*Return Complex Matrix Size
*/
int MatrixSize(const Matrix* matrix)
{return MatrixRow(matrix) * MatrixColumn(matrix);   // Size Refers to Numbers of Cell of Matrix
}/*Point Multiple: Complex matrixB = Complex matrixA .* Complex_c
*/
void MatrixPointMulComplex(const Matrix* matrixA, ComplexType c, Matrix* matrixB)
{if (IsNullComplexMatrix(matrixA)){puts("ERROE: An invalid matrix!\n");return;}else{int row_i, column_j;for (row_i = 0; row_i < matrixB->row; ++row_i)for (column_j = 0; column_j < matrixB->column; ++column_j){matrixB->arrayComplex[row_i * matrixB->column + column_j] =_Cmulcc(matrixA->arrayComplex[row_i * matrixA->column + column_j], c);}}
}/*Point Multiple : Complex matrixB = Complex matrixA.*Double_c
*/
void MatrixPointMulDouble(const Matrix * matrixA, DoubleType c, Matrix * matrixB)
{if (IsNullComplexMatrix(matrixA)){puts("ERROE: An invalid matrix!\n");return;}int row_i, column_j;for (row_i = 0; row_i < matrixB->row; ++row_i)for (column_j = 0; column_j < matrixB->column; ++column_j){matrixB->arrayComplex[row_i * matrixB->column + column_j] = \_Cmulcr(matrixA->arrayComplex[row_i * matrixA->column + column_j], c);}
}int main(void)
{Matrix matrix_A;InitComplexMatrix(&matrix_A, 3, 3);matrix_A.arrayComplex[0]._Val[0] = 2; matrix_A.arrayComplex[0]._Val[1] = 2;matrix_A.arrayComplex[1]._Val[0] = 3; matrix_A.arrayComplex[1]._Val[1] = 7;matrix_A.arrayComplex[2]._Val[0] = 3; matrix_A.arrayComplex[2]._Val[1] = -6;matrix_A.arrayComplex[3]._Val[0] = 6; matrix_A.arrayComplex[3]._Val[1] = 2;matrix_A.arrayComplex[4]._Val[0] = -4; matrix_A.arrayComplex[4]._Val[1] = 14;matrix_A.arrayComplex[5]._Val[0] = 3; matrix_A.arrayComplex[5]._Val[1] = 6;matrix_A.arrayComplex[6]._Val[0] = -4; matrix_A.arrayComplex[6]._Val[1] = 9;matrix_A.arrayComplex[7]._Val[0] = -5; matrix_A.arrayComplex[7]._Val[1] = 4;matrix_A.arrayComplex[8]._Val[0] = 3; matrix_A.arrayComplex[8]._Val[1] = -7;ComplexType complex;complex._Val[0] = 3.5;complex._Val[1] = -7.25;Matrix matrix_B;InitComplexMatrix(&matrix_B, MatrixRow(&matrix_A), MatrixColumn(&matrix_A));MatrixPointMulComplex(&matrix_A, complex, &matrix_B);for (int row_i = 0; row_i < matrix_B.row; ++row_i)for (int column_j = 0; column_j < matrix_B.column; ++column_j){int index = row_i * matrix_B.row + column_j;printf("%lf, %lf\n", creal(matrix_B.arrayComplex[index]), cimag(matrix_B.arrayComplex[index]));}printf("\n\n\n\n");DoubleType dl = 2.45;Matrix matrix_C;InitComplexMatrix(&matrix_C, MatrixRow(&matrix_A), MatrixColumn(&matrix_A));MatrixPointMulDouble(&matrix_A, dl, &matrix_C);for (int index = 0; index < matrix_C.row * matrix_C.column; ++index){printf("%lf, %lf\n", creal(matrix_C.arrayComplex[index]), cimag(matrix_C.arrayComplex[index]));}// free memoryDestroyComplexMatrix(&matrix_A);DestroyComplexMatrix(&matrix_B);DestroyComplexMatrix(&matrix_C);return 0;
}

测试结果我直接通过截图的形式给出,VS C(上)和matlab(下):


4.复数矩阵乘法运算

矩阵乘法运算,即复数矩阵与复数矩阵的运算:

/*Complex Matrix Multiple: matrixC = matrixA * matrixB
*/
void MatrixMulMatrix(const Matrix* matrixA, const Matrix* matrixB, Matrix* matrixC)
{if (IsNullComplexMatrix(matrixA) || IsNullComplexMatrix(matrixB))  // Validity of Known Matrice{puts("ERROE: An invalid matrix!\n");return;}else if (matrixA->column != matrixB->row)  // Incompatability of Size{puts("ERROE: An incompatable matrix!\n");return;}else {int row_i, column_j, ij;int indexA, indexB, indexC;ComplexType tempCell_C;   // Save Temp Value of Cell of Matrix Cfor (row_i = 0; row_i < matrixC->row; ++row_i){for (column_j = 0; column_j < matrixC->column; ++column_j){tempCell_C._Val[0] = 0;tempCell_C._Val[1] = 0;for (ij = 0; ij < matrixA->column; ++ij){indexA = row_i * matrixA->column + ij;indexB = ij * matrixB->column + column_j;tempCell_C = AddComplex(tempCell_C, \_Cmulcc(matrixA->arrayComplex[indexA], matrixB->arrayComplex[indexB]));
/*                  temp._Val[0] = creal(temp) + creal(_Cmulcc(matrixA->arrayComplex[indexA], matrixB->arrayComplex[indexB]));temp._Val[1] = cimag(temp) + cimag(_Cmulcc(matrixA->arrayComplex[indexA], matrixB->arrayComplex[indexB]));
*/}indexC = row_i * matrixC->column + column_j;matrixC->arrayComplex[indexC] = tempCell_C;}}}
}

说明
(1) 这里我加入了多个if-else语句来约束矩阵乘法运算的行列大小要求,保障运算安全;
(2) 中途注释掉的是我之前没有调用_Cmulcc()函数自行实现的复数乘法运算,读者可以忽略;
(3) 测试此函数:

#include<stdio.h>
#include<stdlib.h>
#include<complex.h>
typedef _Dcomplex ComplexType;typedef struct   // Matrix Structor
{int row, column;  // SizeComplexType* arrayComplex;     // Pointer to Cell
}Matrix;/*Initiation of Complex Number*/
void InitComplex(ComplexType* Complex)  // Transmiss of Pointer
{Complex->_Val[0] = 0.0;Complex->_Val[1] = 0.0;}/*Initiation of Complex Matrix*/
void InitComplexMatrix(Matrix* matrix, int row, int column)  // Transmiss of Pointer
{int size = row * column * sizeof(ComplexType);if (size <= 0){puts("ERROE: An invalid matrix!\n");return;}matrix->arrayComplex = (ComplexType*)malloc(size); // initiate pointer/rowif (matrix->arrayComplex){matrix->row = row;matrix->column = column;for (int row_i = 0; row_i < row; ++row_i){for (int column_j = 0; column_j < column; ++column_j){InitComplex(matrix->arrayComplex + row_i * matrix->column + column_j);}}}
}/*Add Complex: Complex_C = Complex_A + Complex_B
*/
ComplexType AddComplex(const ComplexType Complex_A, const ComplexType Complex_B)
{ComplexType Complex_C;Complex_C._Val[0] = creal(Complex_A) + creal(Complex_B);Complex_C._Val[1] = cimag(Complex_A) + cimag(Complex_B);return Complex_C;
}/*Subvision Complex: Complex_C = Complex_A - Complex_B
*/
ComplexType SubComplex(const ComplexType Complex_A, const ComplexType Complex_B)
{ComplexType Complex_C;   // Change Pointer to a VariableComplex_C._Val[0] = creal(Complex_A) - creal(Complex_B);Complex_C._Val[1] = cimag(Complex_A) - cimag(Complex_B);return Complex_C;
}/*Complex Matrix Multiple: matrixC = matrixA * matrixB
*/
void MatrixMulMatrix(const Matrix* matrixA, const Matrix* matrixB, Matrix* matrixC)
{if (matrixA->column != matrixB->row)  // Incompatability of Size{puts("ERROE: An incompatable matrix!\n");return;}else{int row_i, column_j, ij;int indexA, indexB, indexC;ComplexType tempCell_C;   // Save Temp Value of Cell of Matrix Cfor (row_i = 0; row_i < matrixC->row; ++row_i){for (column_j = 0; column_j < matrixC->column; ++column_j){tempCell_C._Val[0] = 0;tempCell_C._Val[1] = 0;for (ij = 0; ij < matrixA->column; ++ij){indexA = row_i * matrixA->column + ij;indexB = ij * matrixB->column + column_j;tempCell_C = AddComplex(tempCell_C, \_Cmulcc(matrixA->arrayComplex[indexA], matrixB->arrayComplex[indexB]));indexC = row_i * matrixC->column + column_j;matrixC->arrayComplex[indexC] = tempCell_C;}}}}
}int main(void)
{Matrix C;InitComplexMatrix(&C, 3, 2);  // 3 * 2    C.arrayComplex[0]._Val[0] = 2;  C.arrayComplex[0]._Val[1] = 2;C.arrayComplex[1]._Val[0] = 3;  C.arrayComplex[1]._Val[1] = 7;C.arrayComplex[2]._Val[0] = 3;  C.arrayComplex[2]._Val[1] = -6;C.arrayComplex[3]._Val[0] = 6;  C.arrayComplex[3]._Val[1] = 2;C.arrayComplex[4]._Val[0] = -7; C.arrayComplex[4]._Val[1] = 7;C.arrayComplex[5]._Val[0] = 0;  C.arrayComplex[5]._Val[1] = 6;Matrix D;InitComplexMatrix(&D, 2, 4);  // 2 * 4D.arrayComplex[0]._Val[0] = 6;   D.arrayComplex[0]._Val[1] = 4;D.arrayComplex[1]._Val[0] = -7;  D.arrayComplex[1]._Val[1] = 5;D.arrayComplex[2]._Val[0] = -10; D.arrayComplex[2]._Val[1] = -3;D.arrayComplex[3]._Val[0] = -5;  D.arrayComplex[3]._Val[1] = 4;D.arrayComplex[4]._Val[0] = 10;  D.arrayComplex[4]._Val[1] = 6;D.arrayComplex[5]._Val[0] = 0;   D.arrayComplex[5]._Val[1] = 9;D.arrayComplex[6]._Val[0] = -4;  D.arrayComplex[6]._Val[1] = 13;D.arrayComplex[7]._Val[0] = -5;  D.arrayComplex[7]._Val[1] = -4;Matrix E;InitComplexMatrix(&E, C.row, D.column);  // 3 * 4MatrixMulMatrix(&C, &D, &E);for (int i = 0; i < E.row; i++)for (int j = 0; j < E.column; j++)printf("%lf, %lf\n", creal(E.arrayComplex[i * E.column + j]), cimag(E.arrayComplex[i * E.column + j]));return 0;
}

测试结果我直接通过截图的形式给出,VS C(上)和matlab(下):

四、总结

矩阵之间的加/减/乘法运算较为简单,是矩阵运算最常见的功能,复数域和实数域的矩阵计算类似。下一章我将给出矩阵的转置、复制、代数余子式、逆的功能实现code,敬请期待…
传送门:(三)…

C语言实现实数和复数矩阵及其各种运算(二)相关推荐

  1. C语言实现实数和复数矩阵及其各种运算(一)

    一.前言 本连载文章主要内容是实现复数矩阵的各种运算,并利用matlab进行联写.联调,验证C语言编写的各个矩阵运算函数的正确性.其难点笔者认为在于矩阵的各种运算,C++中有Eigen库可用,以前在学 ...

  2. C语言实现实数和复数矩阵及其各种运算(三)

    一.前言 本章开始,详细讲解实数和复数矩阵的转置.复制.行列式.代数余子式.逆等运算,由简入繁,并给出函数和测试demo的C代码,以及与matlab计算的结果: 并且,本章出现了我在编写函数.后期与m ...

  3. C语言实现实数和复数矩阵及其各种运算(四)

    一.前言 本章开始,笔者将详细讲解实数和复数矩阵的模(范数).协方差等运算,并给出函数和测试demo的C代码,以及与matlab计算的结果: 并且,本章也出现了我在编写函数.后期与matlab联调跑数 ...

  4. 向量、矩阵、实数、复数之间的各种运算方法

    向量.矩阵.实数.复数之间的各种运算方法 1.复数的乘法 复数 z1 = a + bi. 复数 z2 = c + di. z1和z2的乘积:(ac-bd)+(bc+ad)i. 以下为代码实现: //复 ...

  5. 两复数乘积C语言,C语言程序(两复数矩阵相乘)改错求助

    C语言程序(两复数矩阵相乘)改错求助 哪位高手帮我修改一下下面这段程序的错误,我看了实在是改不出.急用...先谢谢了! double bucmul(double ar,double ai,double ...

  6. fortran——实数和复数(矢量)运算

    因为用到了复数和实数之间的运算,还有矢量之间的运算,不确定fortran的运算规则,进行了一系列验证(和matlab)和写了一些函数以便调用 复数运算 复数定义 Real(16), dimension ...

  7. 将两个实数矩阵合并为一个复数矩阵

    问题描述:有时需要把两个实数矩阵,一个作为实部,一个作为虚部,合并为一个复数矩阵,该如何操作? 解决办法: 假如是在第二个维度上进行合并(real: Data[:, 0, :, :] imag: Da ...

  8. 【打通复数域】复数矩阵的实数等效表示

    在通信中,大部分的问题都是复数问题, 而大部分其他领域的问题都是实数问题, 也导致许多方法直观上看并不能简单地拓展到复数域来解决通信的问题. 然而事实上, 绝大部分的实数算法都可以拓展到复数域,其核心 ...

  9. 复数矩阵分解的拆解思路(矩阵求逆/特征值分解)

    作者:桂. 时间:2017-10-26  07:11:02 链接:http://www.cnblogs.com/xingshansi/p/7735016.html 前言 主要记录特征值分解的硬件实现思 ...

最新文章

  1. 上升沿_不懂上升、下降沿的我,高兴惨了!
  2. yii required 字段去除*号
  3. springboot使用maven打包无法打进本地包解决方法
  4. 洛谷P2766-最长递增子序列问题
  5. C# Get network adapter info.
  6. mysql恢复root密码
  7. 成功解决An error ocurred while starting the kernel
  8. C语言再学习 -- Linux下find命令用法
  9. 一维数组名与二维数组名的关联
  10. iOS_9_scrollView分页
  11. 计算机网络(四)网络层
  12. linux lvm 磁盘管理
  13. java并发临界资源管理
  14. 安装Oracle 11g 出现交换空间不够
  15. android ril移植,Quectel_Android_RIL_SR01A40V36 EC20安卓移植资料和相关代码 - 下载 - 搜珍网...
  16. Python之路-Day2
  17. DNS加密 防止被DNS劫持 保护网络安全
  18. 量子计算机能做到0延迟吗,延迟选择量子擦除实验
  19. MFC技术内幕系列之(二)---MFC文档视图结构内幕
  20. js逆向学习路线指南

热门文章

  1. 社保公积金提取转移手续
  2. 结绳4.0【基本功能】
  3. 【DL】第 11 章:自动驾驶汽车的深度学习
  4. Python:对图片批量进行重命名
  5. Linux(安装apache,设置端口,基于端口的配置方法)
  6. android 实现漫天飞舞雪花以及下雨天的效果
  7. rj45 千兆接口定义_rj45接口定义,大神教你秒懂rj45的接线方法【详细方法】
  8. 解决更新页面数据回显时时间不匹配问题:The specified value “Fri Nov 05 08:00:00 CST 2021“ does not conform to the requir
  9. 监控POE供电交换机最大传输距离有多远?
  10. python代码实现时间从12小时制到24小时制的转换