OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4273|回复: 8

【原创】高斯消元法--基于STM32串口调试

[复制链接]

15

主题

72

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
348
金钱
348
注册时间
2015-5-2
在线时间
29 小时
发表于 2015-12-8 22:51:42 | 显示全部楼层 |阅读模式

/* Created by mazirong */
/*2015-12-8 */
1 高斯消去法

1.1 基本思想及计算过程

高斯(Gauss)消去法是解线性方程组最常用的方法之一,它的基本思想是通过逐步消元,把方程组化为系数矩阵为三角形矩阵的同解方程组,然后用回代法解此三角形方程组得原方程组的解。

为便于叙述,先以一个三阶线性方程组为例来说明高斯消去法的基本思想。

把方程(IV)乘()后加到方程(I)上去,把方程(IV)乘()后加到方程(II)上去,把方程(IV)乘()后加到方程(III)上去,即可消去方程(I、(II)、(III)中的x1,得同解方程组

将方程(III)乘()后加于方程(II),将方程(III)乘()后加于方程(I),得同解方程组:

将方程(II)乘()后加于方程(I),得同解方程组:

由回代公式(3.5)得,x3 = 1x2 = 1x1 = 1

 

 

 

 

1.2 编程思路

高斯消元法解线性方程组,算法很简单,但过程很复杂,我在网上几乎没看到过正确的高斯消元法C程序,有程序也是没有注释,看起来非常费力。于是我硬着头皮自己来写,花了1天时间终于完工了。以求如下行列式为例详解编程思路:

1.把第1行进行优化(优化成第1行第1列元素为1的行列式),然后用来与第2至第4行的第1列元素消为0,如图1

  

1

2.保持第1行不变。对图一中第2行元素进行优化(优化成第2行第2列元素为1的行列式),然后用来与第3行至第4行的第2列元素消为0,如图2

  

2

3.保持前2行不变。对图二中第3行元素进行优化(优化成第3行第3列元素为1的行列式),然后用来与第4行的第3列元素消为0,如图3

  

3

4.保持前3行不变。对图三中第4行元素进行优化(优化成第4行第4列元素为1的行列),如图四:

  

4

5.通过回代分别求出x1x2x3x4的值,如图5

  

5

 

1.3 具体实现过程

由于我的电脑上没有安装Visual Studio,于是使用单片机来实现,通过将程序烧录到单片机中,然后将运算的数据结果通过串口发送给上位机打印输出。运行效果如图6

  

如图6

程序主要有3个文件组成:gs_elim.h,gs_elim.c,main.c。程序不限于平台,稍稍修改就能移植到其他开发环境中。

 

gs_elim.h

 

#ifndef __GS_ELIM_H

#define __GS_ELIM_H

 

#include "usart.h"

 

 

// 定义矩阵为N

#define N 4 

 

 

void Gs_Elim(void);

 

#endif

 

gs_elim.c

#include "gs_elim.h"

 

// k:提取原数组特定位置值,防止运算一次被覆盖

// m:优化前一行矩阵

double k,m;

 

// i:行

// j:列

// t:消元次数

// 注意:数值是以0开始,所以实际值应该加1

int i,j,t;

 

// 定义一个N*N列的矩阵A

// |1   2   1   2|

// |3   5   2   1|

// |2   3  -1   1|

// |4  -1   3  -2|

double A[N][N] = { 1,  2,  1,  2,

       3,  5,  2,  1,

   2,  3, -1,  1,

   4, -1,  3, -2};

 

// 定义矩阵的增广部分B

// |16| 

// |23|

// |9 |

// |3 |

double B[N] = {16, 23, 9, 3};

 

// 未知数X数组

double X[N+1] = {0};

 

 

// 高斯消元法函数

void Gs_Elim(void)

{

/********************显示待解的增广矩阵**********************/

printf("待解的增广矩阵为:\n");

for(i=0;i<N;i++)

{   

// 循环打印第i行系数

for(j=0;j<N;j++)

printf("%12lf  ",A[j]); // %12lf:输出场宽为12的浮点数,其中小数点占1,数据右对齐。

// 打印第i行增广数

printf("|%12lf\r\n",B);

}

printf("\r\n");


/*******************消元化简*********************/

do{

printf("%d次消元结果:\r\n", t+1);


/**********显示第(1)行至第(t)行(若t=0不执行)*****************/

for(i=0; i<t; i++)

{

for(j=0; j<N; j++)

{

printf("%12lf  ", A[j]);

}

printf("|%12lf\r\n", B);

}


/****************显示优化后的第(t+1)************************/

k = A[t][t]; // A[t][t]先提取出来,防止运算一次被数组覆盖

for(j=0; j<N; j++)

{

A[t][j] = A[t][j] / k;    // 得到优化后的第(t+1)行矩阵值

printf("%12lf  ", A[t][j]);

}

B[t] = B[t] / k; // n为第t+1行的增广部分

printf("|%12lf\r\n", B[t]); // 显示第(t+1)行的增广部分


/****************显示消元后的第(t+2)行至第(N)****************/

for(i=t+1; i<N; i++)

{

k = A[t]; // A[t]先提取出来,防止运算一次被数组覆盖

for(j=0; j<N; j++) // 循环输出消元后的第1N

{

m = A[t][j] / A[t][t]; // (t+1)行元素同时除以A[t][t]   

A[j] = A[j] - k*m; // 消除运算及覆盖原数组

printf("%12lf  ", A[j]); // 显示第(i+1)行第(j+1)列数组值

}

B = B - B[t]*k;

printf("|%12lf\r\n", B); // 显示第(i+1)行的增广部分

}


/**********************************************************/

t++;

}while(t<N);

printf("\r\n");


/***********************回代求X***********************************/

// X[4] = B[N-1];

// X[3] = B[N-2] - A[N-2][N-1]*X[4]; 

// X[2] = B[N-3] - A[N-3][N-1]*X[4] - A[N-3][N-2]*X[3];

// X[1] = B[N-4] - A[N-4][N-1]*X[4] - A[N-4][N-2]*X[3] - A[N-4][N-3]*X[2];

for(i=N-1;i>=0;i--)

{

X[i+1] = B;

for(j=0;j<(N-i-1);j++)

{

X[i+1] -= A[N-j-1]*X[4-j];

}

}

printf(" X[1] = %lf  ", X[1]);

printf(" X[2] = %lf  ", X[2]);

printf(" X[3] = %lf  ", X[3]);

printf(" X[4] = %lf  ", X[4]);

}

 

main.c

#include "led.h"

#include "key.h"

#include "bsp_lcd.h"

#include "delay.h"

#include "sys.h"

#include "usart.h"

//#include "includes.h"

#include "malloc.h"

#include "myiic.h"

#include "24cxx_iic.h"

#include "oled_iic.h"

 

#include "gs_elim.h"

 

 

int main(void)

{

delay_init();      // 延时函数初始化   

NVIC_Configuration();  // 设置NVIC中断分组2:2位抢占优先级,2位响应优先级

uart_init(9600);   // 串口初始化为9600

LED_Init();     

KEY_Init();

LCD_Init();


// 高斯消元函数

Gs_Elim();

 

while(1);

}

 




最后使用ptc_mathcad直接计算一个矩阵:

ptc_mathcad求解矩阵方法.pdf

1.24 MB, 下载次数: 121

高斯消元法代码_文档_视频_ma.7z

21.74 MB, 下载次数: 96

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

15

主题

786

帖子

5

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3223
金钱
3223
注册时间
2015-7-26
在线时间
811 小时
发表于 2015-12-9 08:03:47 | 显示全部楼层
不明觉厉,谢谢分享!!
我的博客:http://blog.csdn.net/itdo_just
回复 支持 反对

使用道具 举报

13

主题

296

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2067
金钱
2067
注册时间
2012-5-26
在线时间
292 小时
发表于 2015-12-9 08:33:36 | 显示全部楼层
不明觉厉,还以为是matlab什么的
活着才是王道!健康是一切的前提!
回复 支持 反对

使用道具 举报

15

主题

72

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
348
金钱
348
注册时间
2015-5-2
在线时间
29 小时
 楼主| 发表于 2015-12-9 10:20:04 | 显示全部楼层
回复【3楼】lison0103:
---------------------------------
谢谢支持
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-12-9 23:25:03 | 显示全部楼层
看上去高大上.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

15

主题

72

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
348
金钱
348
注册时间
2015-5-2
在线时间
29 小时
 楼主| 发表于 2015-12-10 23:28:37 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
原子哥不出两小时就可以写出来
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-12-11 00:20:30 | 显示全部楼层
回复【6楼】ndzhzsdw:
---------------------------------
我真不会,呵呵
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

93

主题

746

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1850
金钱
1850
注册时间
2012-9-16
在线时间
286 小时
发表于 2015-12-11 08:37:54 | 显示全部楼层
可用到实际工程中吗?比其他有何优势!
纵浪大化中,不喜亦不惧;应尽便须尽,无复独多虑!
回复 支持 反对

使用道具 举报

5

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
91
金钱
91
注册时间
2014-11-6
在线时间
4 小时
发表于 2015-12-11 10:57:30 | 显示全部楼层
看着很是高级啊
人生为棋,我愿为卒,行动虽慢,未退一步
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-21 05:58

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表