1. 程式人生 > >矩陣運算和複數運算

矩陣運算和複數運算

功能說明

  • 實現了矩陣的加法、減法、乘法,並使用冪法求解矩陣的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;
}