矩陣運算和複數運算
阿新 • • 發佈:2019-01-12
功能說明
- 實現了矩陣的加法、減法、乘法,並使用冪法求解矩陣的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;
}