矩阵运算和复数运算

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_32862515/article/details/84887498

功能说明

  • 实现了矩阵的加法、减法、乘法,并使用幂法求解矩阵的2-范数(原理我还不理解)。
  • 实现了复数的加法、减法、乘法、除法和求解复数的模。

代码

matrix.h

#pragma once

struct matrix {
	int row;
	int col;
	double **p;
};

void initial_matrix(struct matrix *m);
void mul_matrix(struct matrix *m, struct matrix *n);
void sub_matrix(struct matrix *m, struct matrix *n);
void add_matrix(struct matrix *m, struct matrix *n);
void input_matrix(struct matrix *m);
void initial_matrix(struct matrix *m);
void destroy_matrix(struct matrix *m);
void display_matrix(struct matrix *m);
struct matrix transpose_matrix(struct matrix *m);
double norm2_matrix(struct matrix *m);
double max(double *v, int col);
void mul(struct matrix *r, double *v);

matrix.cpp

#include "matrix.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

// 矩阵乘法
void mul_matrix(struct matrix *m, struct matrix *n)
{
	if (m->col != n->row)
	{
		printf("不满足矩阵相乘条件\n");
		return;
	}

	struct matrix r;
	r.row = m->row;
	r.col = n->col;

	initial_matrix(&r);

	int i, j;
	for (i = 0; i < r.row; i++)
	{
		for (j = 0; j < r.col; j++)
		{
			r.p[i][j] = 0;
			for (int k = 0; k < m->col; k++)
			{
				r.p[i][j] += m->p[i][k] * n->p[k][j];
			}
		}
	}

	display_matrix(&r);

	destroy_matrix(&r);
}

// 矩阵减法
void sub_matrix(struct matrix *m, struct matrix *n)
{
	if (m->row != n->row || m->col != n->col)
	{
		printf("不满足矩阵相减条件\n");
		return;
	}

	struct matrix r;
	r.row = m->row;
	r.col = m->col;

	initial_matrix(&r);

	int i, j;
	for (i = 0; i < r.row; i++)
	{
		for (j = 0; j < r.col; j++)
		{
			r.p[i][j] = m->p[i][j] - n->p[i][j];
		}
	}

	display_matrix(&r);

	destroy_matrix(&r);
}

// 矩阵加法
void add_matrix(struct matrix *m, struct matrix *n)
{
	if (m->row != n->row || m->col != n->col)
	{
		printf("不满足矩阵相加条件\n");
		return;
	}

	struct matrix r;
	r.row = m->row;
	r.col = m->col;

	initial_matrix(&r);

	int i, j;
	for (i = 0; i < r.row; i++)
	{
		for (j = 0; j < r.col; j++)
		{
			r.p[i][j] = m->p[i][j] + n->p[i][j];
		}
	}

	display_matrix(&r);

	destroy_matrix(&r);
}

// 输入矩阵
void input_matrix(struct matrix *m)
{
	int i, j;
	for (i = 0; i < m->row; i++)
	{
		for (j = 0; j < m->col; j++)
		{
			scanf("%lf", &m->p[i][j]);
		}
	}
}

// 初始化矩阵,给矩阵分配内存
void initial_matrix(struct matrix *m)
{
	m->p = (double**)malloc(sizeof(double*)*m->row);

	int i;
	for (i = 0; i < m->row; i++)
	{
		m->p[i] = (double*)malloc(sizeof(double)*m->col);
	}
}

// 销毁矩阵,释放矩阵的内存
void destroy_matrix(struct matrix *m)
{
	int i;
	for (i = 0; i < m->row; i++)
		free(m->p[i]);

	free(m->p);
}

// 打印矩阵
void display_matrix(struct matrix *m)
{
	int i, j;
	for (i = 0; i < m->row; i++)
	{
		for (j = 0; j < m->col; j++)
		{
			printf("%.2lf ", m->p[i][j]);
		}
		printf("\n");
	}
}

// 矩阵的转置
struct matrix transpose_matrix(struct matrix *m)
{
	int i, j;
	struct matrix r;
	r.row = m->col;
	r.col = m->row;

	initial_matrix(&r);
	for (i = 0; i < r.row; i++)
	{
		for (j = 0; j < r.col; j++)
		{
			r.p[i][j] = m->p[j][i];
		}
	}

	return r;
}

// 矩阵2-范数
double norm2_matrix(struct matrix *m)
{
	struct matrix t;
	t = transpose_matrix(m);

	struct matrix r;
	r.row = t.row;
	r.col = m->col;

	initial_matrix(&r);

	int i, j;
	for (i = 0; i < r.row; i++)
	{
		for (j = 0; j < r.col; j++)
		{
			r.p[i][j] = 0;
			for (int k = 0; k < t.col; k++)
			{
				r.p[i][j] += t.p[i][k] * m->p[k][j];
			}
		}
	}

	// 使用幂法求解 r 的最大特征值
	double *v;
	v = (double*)malloc(sizeof(double)*r.col);
	for (i = 0; i < r.col; i++)
	{
		v[i] = 1;
	}

	double m0 = 0, m1 = INT_MAX;
	while (fabs(m1 - m0) > 1E-10)
	{
		mul(&r, v);
		m0 = m1;
		m1 = max(v, r.col);
		
		for (i = 0; i < r.col; i++)
		{
			v[i] /= m1;
		}
	}

	free(v);
	destroy_matrix(&t);
	destroy_matrix(&r);

	return sqrt(m1);
}

double max(double *v, int col)
{
	double max = v[0];
	for (int i = 1; i < col; i++)
	{
		max = max > v[i] ? max : v[i];
	}
	return max;
}

void mul(struct matrix *r, double *v)
{
	double *tmp = (double*)malloc(sizeof(double)*r->col);

	int i, j;
	for (i = 0; i < r->row; i++)
	{
		tmp[i] = 0;
		for (j = 0; j < r->col; j++)
		{
			tmp[i] += r->p[i][j] * v[j];
		}
	}

	for (i = 0; i < r->col; i++)
		v[i] = tmp[i];

	free(tmp);
}

complex.h

#pragma once

struct complex_number {

	// z = a + bi
	double a;
	double b;
};

void add_complex_number(struct complex_number m, struct complex_number n);
void sub_complex_number(struct complex_number m, struct complex_number n);
void mul_complex_number(struct complex_number m, struct complex_number n);
void div_complex_number(struct complex_number m, struct complex_number n);
void modulus_of_complex_number(struct complex_number m);

complex.cpp

#include "complex.h"
#include <stdio.h>
#include <math.h>

void add_complex_number(struct complex_number m, struct complex_number n)
{
	printf("(%.2lf + %.2lfi) + (%.2lf + %.2lfi) = %.2lf + %.2lfi\n", m.a, m.b, n.a, n.b, m.a + n.a, m.b + n.b);
}
void sub_complex_number(struct complex_number m, struct complex_number n)
{
	printf("(%.2lf + %.2lfi) - (%.2lf + %.2lfi) = %.2lf + %.2lfi\n", m.a, m.b, n.a, n.b, m.a - n.a, m.b - n.b);
}
void mul_complex_number(struct complex_number m, struct complex_number n)
{
	printf("(%.2lf + %.2lfi) * (%.2lf + %.2lfi) = %.2lf + %.2lfi\n", m.a, m.b, n.a, n.b,
		m.a*n.a - m.b*n.b, m.a*n.b + m.b*n.a);
}
void div_complex_number(struct complex_number m, struct complex_number n) 
{
	printf("(%.2lf + %.2lfi) / (%.2lf + %.2lfi) = %.2lf + %.2lfi\n", m.a, m.b, n.a, n.b,
		(m.a*n.a + m.b*n.b) / (n.a*n.a + n.b*n.b),
		(m.b*n.a - m.a*n.b) / (n.a*n.a + n.b*n.b));
}
void modulus_of_complex_number(struct complex_number m)
{
	printf("%.2lf + %.2lfi 的模是 %.2lf\n", m.a, m.b, sqrt(m.a*m.a + m.b*m.b));
}

main.cpp

#include "matrix.h"
#include "complex.h"
#include <stdio.h>

int main()
{
	// 矩阵demo
	struct matrix m, n;
	printf("请输入第一个矩阵的行数:");
	scanf("%d", &m.row);
	printf("请输入第一个矩阵的列数:");
	scanf("%d", &m.col);
	
	initial_matrix(&m);
	printf("请输入第一个矩阵:\n");
	input_matrix(&m);

	printf("请输入第二个矩阵的行数:");
	scanf("%d", &n.row);
	printf("请输入第二个矩阵的列数:");
	scanf("%d", &n.col);
	initial_matrix(&n);
	printf("请输入第二个矩阵:\n");
	input_matrix(&n);

	printf("\n两个矩阵的和是:\n");
	add_matrix(&m, &n);
	printf("\n两个矩阵的差是:\n");
	sub_matrix(&m, &n);
	printf("\n两个矩阵的积是:\n");
	mul_matrix(&m, &n);

	printf("第一个矩阵的2-范数是:%10.8lf\n", norm2_matrix(&m));
	printf("第二个矩阵的2-范数是:%10.8lf\n", norm2_matrix(&n));

	destroy_matrix(&m);
	destroy_matrix(&n);

	// 复数demo
	/*struct complex_number p, q;
	printf("请输入第一个复数的实部和虚部:");
	scanf("%lf %lf", &p.a, &p.b);
	printf("请输入第二个复数的实部和虚部:");
	scanf("%lf %lf", &q.a, &q.b);

	printf("两个复数的和是:");
	add_complex_number(p, q);
	printf("两个复数的差是:");
	sub_complex_number(p, q);
	printf("两个复数的积是:");
	mul_complex_number(p, q);
	printf("两个复数的商是:");
	div_complex_number(p, q);

	printf("第一个复数的模是:");
	modulus_of_complex_number(p);
	printf("第二个复数的模是:");
	modulus_of_complex_number(q);*/

	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_32862515/article/details/84887498