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

一、前言

  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 Incompatability
	if (matrix_A->row == matrix_B->row || matrix_A->column == matrix_B->column)
	{
		puts("ERROE: An incompatable matrix!\n");
		return;
	}
	// Validity of Known Matrice
	else 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 Variable
	Complex_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
#include
#include

typedef _Dcomplex ComplexType;
typedef double DoubleType;

typedef struct 
{
	int row, column;  
	ComplexType* arrayComplex;
}Matrix;

typedef struct
{
	int row, column;  // Size
	DoubleType* 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 memory
	DestroyComplexMatrix(&matrix_A);
	DestroyComplexMatrix(&matrix_B);
	DestroyComplexMatrix(&matrix_C);
	return 0;
}

测试结果我直接通过截图的形式给出,VS C(上)和matlab(下):
C语言实现实数和复数矩阵及其各种运算(二)_第1张图片
C语言实现实数和复数矩阵及其各种运算(二)_第2张图片
C语言实现实数和复数矩阵及其各种运算(二)_第3张图片

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 C

		for (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
#include
#include
typedef _Dcomplex ComplexType;

typedef struct   // Matrix Structor
{
	int row, column;  // Size
	ComplexType* 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/row
	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);

			}
		}

	}
}

/*
   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 Variable
	Complex_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 C

		for (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 * 4
	D.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 * 4
	MatrixMulMatrix(&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(下):
C语言实现实数和复数矩阵及其各种运算(二)_第4张图片
C语言实现实数和复数矩阵及其各种运算(二)_第5张图片

四、总结

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

你可能感兴趣的:(实习项目--C语言矩阵运算,matlab,线性代数,算法,c语言,矩阵)