计算方法——C语言实现——迭代法求解线性方程组

2023-10-26

最近在上计算方法这门课,要求是用MATLAB做练习题,但是我觉得C语言也很棒棒啊~

题目:

在这里插入图片描述
和直接法不同,迭代法是一种逐次逼近的方法,将复杂问题简单化,求比较大的方程组时一般都不会用直接法。迭代法有好几种,这里使用了Jacobi迭代与Gausse_Seidel迭代法。
使用VS2017,代码如下:

//使用Jacobi迭代法与Gausse_Seidel迭代法计算线性方程组
#include "stdafx.h"
#include<stdlib.h>
#include "math.h"

//根据用户输入的行列数,生成二维矩阵A L U D 向量 b x y ,并全部初始化为0
double **A, *b, *x, *y, **L, **U,**D;
double calculate_e = 0.0001;//默认精度为10^-4
unsigned int RANK = 4;
unsigned int makematrix()
{
	unsigned int r, c;

	printf("请输入矩阵行列数,用空格隔开:");
	scanf_s("%d %d", &r, &c);

	A = (double**)malloc(sizeof(double*)*r);//创建一个指针数组,把指针数组的地址赋值给a ,*r是乘以r的意思
	for (int i = 0; i < r; i++)
		A[i] = (double*)malloc(sizeof(double)*c);//给第二维分配空间
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < c; j++)
			A[i][j] = 0.0;
	}

	b = (double*)malloc(sizeof(double)*r);
	for (int i = 0; i < r; i++)
	{
		b[i] = 0.0;
	}
	x = (double*)malloc(sizeof(double)*c);
	for (int i = 0; i < c; i++)
	{
		x[i] = 0.0;
	}

	L = (double**)malloc(sizeof(double*)*r);//创建一个指针数组,把指针数组的地址赋值给a ,*r是乘以r的意思
	for (int i = 0; i < r; i++)
		L[i] = (double*)malloc(sizeof(double)*c);//给第二维分配空间
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < c; j++)
			L[i][j] = 0.0;
	}
	U = (double**)malloc(sizeof(double*)*r);//创建一个指针数组,把指针数组的地址赋值给a ,*r是乘以r的意思
	for (int i = 0; i < r; i++)
		U[i] = (double*)malloc(sizeof(double)*c);//给第二维分配空间
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < c; j++)
			U[i][j] = 0.0;
	}
	D = (double**)malloc(sizeof(double*)*r);//创建一个指针数组,把指针数组的地址赋值给a ,*r是乘以r的意思
	for (int i = 0; i < r; i++)
		D[i] = (double*)malloc(sizeof(double)*c);//给第二维分配空间
	for (int i = 0; i < r; i++) {
		for (int j = 0; j < c; j++)
			D[i][j] = 0.0;
	}
	y = (double*)malloc(sizeof(double)*c);
	for (int i = 0; i < c; i++)
	{
		y[i] = 0.0;
	}
	return r;
}
//提示用户输入一个方阵的内容 还有常数向量 计算精度
void getmatrix(void)//输入矩阵并呈现
{
	printf("请按行从左到右依次输入系数矩阵A,不同元素用空格隔开\n");
	for (int i = 0; i < RANK; i++)
	{
		for (int j = 0; j<RANK; j++)
		{
			scanf_s("%lf", &A[i][j]);
		}
	}
	printf("系数矩阵如下\n");
	for (int i = 0; i < RANK; i++)
	{
		for (int j = 0; j<RANK; j++)
		{
			printf("%g\t", A[i][j]);
		}
		printf("\n");
	}
	printf("请按从上到下依次输入常数列b,不同元素用空格隔开\n");
	for (int i = 0; i<RANK; i++)
	{
		scanf_s("%lf", &b[i]);
	}
	printf("常数列如下\n");
	for (int i = 0; i<RANK; i++)
	{
		printf("%g\t", b[i]);
	}printf("\n");
	printf("请输入计算精度:(例如:0.0001)\n");
	scanf_s("%lf", &calculate_e);
	printf("计算结果的精度为:%g\n", calculate_e);
}

bool Jacobi_calculation(void)//Jacobi迭代法解线性方程组
{
	double get_add = 0.0,get_e = 0.0;
	printf("利用以上A与b组成的增广阵进行Jacobi迭代法法计算方程组\n");
	for (int i = 0; i < RANK; i++) //初始迭代值为0
	{
		x[i] = 0.0;
		y[i] = 0.0;
	}
	for (int k = 0; k < 100; k++)//最大迭代100次,认为发散
	{
		for (int i = 0; i < RANK; i++)//存上一次的值 用于求误差
		{
			x[i] = y[i];
		}
		for (int i = 0; i < RANK; i++)//迭代一遍
		{
			get_add = 0;
			for (int j = 0; j < RANK; j++)
			{
				get_add = get_add + A[i][j] * x[j];
			}
			y[i] = (-get_add + A[i][i] * x[i] + b[i]) / A[i][i];
		}
		get_add = 0;
		for (int i = 0; i < RANK; i++)//求无穷大范数
		{
			get_add = (fabs(x[i] - y[i])>get_add)? fabs(x[i] - y[i]): get_add;
		}
		if (fabs(get_add) <= calculate_e)
		{
			printf ("迭代次数为:%d",k + 1);
			break;
		}
		if (k == 99)//失效
		{
			return false;
		}
	}
	for (int i = 0; i < RANK; i++) //交换xy
	{
		double temp;
		temp = x[i];
		x[i] = y[i];
		y[i] = temp;
	}
	printf("求解x,解得:\n");
	for (int i = 0; i<RANK; i++)
	{
		printf("x%d = %g\n", i + 1, x[i]);
	}
}

bool Gusse_Seidel_calculation(void)//Gausse_Seidel迭代法解线性方程组
{
	double get_add = 0.0, get_e = 0.0;
	printf("利用以上A与b组成的增广阵进行Gausse_Seidel迭代法法计算方程组\n");
	for (int i = 0; i < RANK; i++) //初始迭代值为0
	{
		x[i] = 0.0;
		y[i] = 0.0;
	}
	for (int k = 0; k < 100; k++)//最大迭代100次,认为发散
	{
		for (int i = 0; i < RANK; i++)//存上一次的值 用于求误差
		{
			y[i] = x[i];
		}
		for (int i = 0; i < RANK; i++)//迭代一遍
		{
			get_add = 0;
			for (int j = 0; j < RANK; j++)
			{
				get_add = get_add + A[i][j] * x[j];
			}
			x[i] = (-get_add + A[i][i] * x[i] + b[i]) / A[i][i];
		}
		get_add = 0;
		for (int i = 0; i < RANK; i++)//求无穷大范数
		{
			get_add = (fabs(x[i] - y[i])>get_add) ? (x[i] - y[i]) : get_add;
		}
		if (fabs(get_add) <= calculate_e)
		{
			printf("迭代次数为:%d", k + 1);
			break;
		}
		if (k == 99)//失效
		{
			return false;
		}
	}
	printf("求解x,解得:\n");
	for (int i = 0; i<RANK; i++)
	{
		printf("x%d = %g\n", i + 1, x[i]);
	}
}

int main()
{
	bool retry;

_again:
	RANK = makematrix();
	getmatrix();
	retry = Jacobi_calculation();
	if (retry == false)
	{
		printf("Jacobi迭代法失效,以下使用Gausse_Seidel迭代法计算\n");
	}
	retry = Gusse_Seidel_calculation();
	if (retry == false)
	{
		printf("Gausse_Seidel迭代法失效\n");
	}

	printf("计算完成,按回车退出程序或按1重新输入矩阵\n");
	getchar();
	if ('1' == getchar())	goto _again;
	return 0;
}

按设计的提示为所欲为 老老实实输入题目的系数矩阵和常数向量后,得到运行结果:
在这里插入图片描述
可以看到,通过不断迭代可以达到非常高的精度。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

计算方法——C语言实现——迭代法求解线性方程组 的相关文章

  • mysql 8.0以上版本,安装及解决忘记密码问题

    1 官网下载解压版MySQL数据库 下载链接 https dev mysql com downloads mysql 2 将下载的mysql放在自己喜欢的盘符 不一定是C盘 例如我的就是解压在D盘 D mysql mysql 8 0 18
  • 三角形设计测试用例

    三角形设计测试用例的问题在面试的时候经常遇到 假设输入三个整数a b c分别作为三边的边长构成三角形 通过程序判定所构成的三角形的类型 当此三角形为一般三角形 等腰三角形及等边三角形时 要求画出程序的流程图和时序图 并且用自己熟悉的一种语言
  • 解决Windows缺少api-ms-win-core-com-l1-1-0.dll文件问题

    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题 如果是新手第一时间会认为是软件或游戏出错了 其实并不是这样 其主要原因就是你电脑系统的该dll文件丢失了或者损坏了 这时你只需下载这个api ms win core com l1 1

随机推荐

  • 程切换问题

    处理器总处于以下状态中的一种 内核态 运行于进程上下文 内核代表进程运行于内核空间 内核态 运行于中断上下文 内核代表硬件运行于内核空间 用户态 运行于用户空间 一个进程的上下文可以分为三个部分 用户级上下文 寄存器上下文以及系统级上下文
  • SQL文本数据格式化的方法(sql-formatter)

    首先安装sql formatter npm install sql formatter save 或者 yarn add sql formatter 引入sql formatter import sqlFormatter from sql
  • JAVA语言功能的概述,JAVA语言概述总结

    J2ME 主要用于控制移动设备和信息家电等有限存储的设备 J2SE 整个Java技术的核心和基础 是J2ME和J2EE编程的基础 J2EE Java技术中应用最广泛的部分 J2EE提供了企业应用开发的完整解决方案 流行语言比较 1 c Mi
  • (二) 基本操作 - 图片的拉伸与缩放

    图片缩放用到的主要函数是 cv2 resize 它最简单的形式如下 cv2 resize img new width new height 其中 img为源图片 new width new height 为缩放后的宽度和高度 函数返回缩放后
  • 高速电路设计基本概念之——近端串扰和远端串扰

    以下内容摘自英文版的信号完整性分析一书 SIGNAL INTEGRITY By Eric Bogatin The noise between two adjacent transmission lines can be measured i
  • word的Ctrl+V与Mathtype冲突解决办法

    首先将所有的office软件关闭 一 打开mathtype的安装目录 找到其中的两个文件 MathPage wll E software MathType MathPage 64 MathType Commands 2016 dotm E
  • java jsch 密钥登陆_java – 使用JSch时“无效的私钥”

    我正在使用以下代码在 Java应用程序中使用 Git 我有一个有效的密钥 一直使用它 这个特定的代码以前使用相同的密钥和git存储库 但现在我得到以下异常 invalid privatekey B 59c40796 在这一行 jSch ad
  • 深度学习概念(术语):Fine-tuning、Knowledge Distillation, etc

    文章目录 1 Fine tuning 微调 2 Transfer Learning 迁移学习 3 Knowledge Distillation 知识蒸馏 4 Meta Learning 元学习 这里的相关概念都是基于已有预训练模型 就是模型
  • cmake简洁教程 - 第一篇

    由于cmake内容较多 篇幅较长 为了不让人疲倦 分成了多篇博客 全部博客链接如下 cmake简洁教程 第一篇 YZF Kevin的博客 CSDN博客 cmake简洁教程 第二篇 YZF Kevin的博客 CSDN博客 cmake简洁教程
  • mt19937 随机数

    https blog csdn net real myth article details 53893854 https blog csdn net calmreason article details 72655060 https blo
  • 数字图像处理-python基于opencv代码实现 反转变换、对数变换和幂律(伽马)变换

    本文主要介绍对 数字图像处理 第三章书中示例图片实现 反转变换 对数变换以及伽马变换的代码 若要获取更多数字图像处理 python 深度学习 机器学习 计算机视觉等高清PDF以及 更多有意思的 分享 可搜一搜 微信公共号 分享猿 免费获取资
  • typescript基础之object和Object

    TypeScript 的 object 和 Object 是两种不同的类型 它们的区别和用途如下 object 类型是 TypeScript 2 2 引入的新类型 它表示非原始对象 也就是除了 number string boolean s
  • 实时时钟电路DS1302的原理及应用

    2006 05 11 10 10 39 实时时钟电路DS1302的原理及应用
  • 使用windeployqt.exe打包QT工程,windows系统可执行程序

    前言 因为自己打包qt程序遇到点问题 提示0xc000007b错误 发现是因为打包工具和工程编译工具不对应导致 于是为了记录打包方法 有了此篇文章 记录使用windeployqt exe打包qt工程在windows系统的可执行文件 一 确定
  • adb install 命令参数

    adb install 6个参数描述 t 允许测试包 l 锁定该应用程序 s 把应用程序安装到sd卡上 g 为应用程序授予所有运行时的权限 r 替换已存在的应用程序 也就是说强制安装 d 允许进行将见状 也就是安装的比手机上带的版本低
  • activiti-serviceTask(服务任务)

    Activiti服务任务 serviceTask Activiti服务任务 serviceTask 作者 邓家海 都有一段沉默的时间 等待厚积薄发 应用场景 当客户有这么一个需求 下一个任务我需要自动执行一些操作 并且这个节点不需要任何的人
  • 一文让你深刻理解异步请求池-DNS解析与实现

    一 DNS概念简述 DNS Domain Name Service 域名解析服务 工作在应用层 是互联网的一项服务 它作为将域名和IP地址相互映射的一个分布式数据库 能够使人更方便地访问互联网 DNS监听在TCP和UDP端口53 FQDN
  • SpringMVC系列(十)(处理静态资源)和...

  • 通俗理解泰勒公式

    本博客只用于自身学习 如有错误 虚心求教 在维基百科上的解释 在数学中 泰勒公式 英语 Taylor s Formula 是一个用函数在某点的信息描述其附近取值的公式 这个公式来自于微积分的泰勒定理 Taylor s theorem 泰勒定
  • 计算方法——C语言实现——迭代法求解线性方程组

    最近在上计算方法这门课 要求是用MATLAB做练习题 但是我觉得C语言也很棒棒啊 题目 和直接法不同 迭代法是一种逐次逼近的方法 将复杂问题简单化 求比较大的方程组时一般都不会用直接法 迭代法有好几种 这里使用了Jacobi迭代与Gauss