计算方法实验2:列主元消元法和Gauss-Seidel迭代法解线性方程组

Task

在这里插入图片描述
即已知 y 0 = 0 , y 100 = 1 y_0=0,y_{100}=1 y0=0,y100=1,解线性方程组 A y = b \mathbf{A}\mathbf{y} = \mathbf{b} Ay=b,其中

A 99 × 99 = [ − ( 2 ϵ + h ) ϵ + h 0 ⋯ 0 ϵ − ( 2 ϵ + h ) ϵ + h ⋯ 0 0 ϵ − ( 2 ϵ + h ) ⋯ 0 ⋮ ⋮ ⋱ ⋱ ⋮ 0 0 ⋯ ϵ − ( 2 ϵ + h ) ] \mathbf{A_{99\times99}}= \begin{bmatrix} -(2\epsilon + h) & \epsilon + h & 0 & \cdots & 0 \\ \epsilon & -(2\epsilon + h) & \epsilon + h & \cdots & 0 \\ 0 & \epsilon & -(2\epsilon + h) & \cdots & 0 \\ \vdots & \vdots & \ddots & \ddots & \vdots \\ 0 & 0 & \cdots& \epsilon& -(2\epsilon + h) \\ \end{bmatrix} A99×99= (2ϵ+h)ϵ00ϵ+h(2ϵ+h)ϵ00ϵ+h(2ϵ+h)ϵ000(2ϵ+h)

y = [ y 1 y 2 y 3 ⋮ y 99 ] b = [ a h 2 a h 2 ⋮ a h 2 a h 2 − ϵ − h ] \begin{align*} \mathbf{y} = \begin{bmatrix} y_1 \\ y_2 \\ y_3 \\ \vdots \\ y_{99} \\ \end{bmatrix} \quad & \quad \mathbf{b}= \begin{bmatrix} ah^2 \\ ah^2 \\ \vdots \\ ah^2 \\ ah^2-\epsilon-h \end{bmatrix} \end{align*} y= y1y2y3y99 b= ah2ah2ah2ah2ϵh
在这里插入图片描述

Algorithm1:列主元消元法

Code

#include<iostream>
#include<cmath>
#include <iomanip>
using namespace std;long double a = 1.0 / 2, n = 100, h = 1.0 / n;//注意a=1/2会把a赋为0而不是0.5
long double x[99], A[99][99], b[99];// 交换两个数组的元素
void swap(long double* x, long double* y)
{for(int i = 0; i <= n - 1; i++){long double temp = x[i];x[i] = y[i];y[i] = temp;}return ;
}long double* Column_Elimination(long double (*A)[99])
{long double* x = new long double[99]();long double (*matrix)[100] = new long double[99][100];//增广矩阵fill_n(&matrix[0][0], 99*100, 0);for(int i = 0; i < n - 1; i++)for(int j = 0; j < n - 1; j++)matrix[i][j] = A[i][j];for(int i = 0; i < n - 1; i++)matrix[i][99] = b[i];for(int col = 0; col < n - 1; col++)//找到列主元{long double maxnum = abs(matrix[col][col]);int maxrow = col;for(int row = col + 1; row < n - 1; row++){if(abs(matrix[row][col]) > maxnum){maxnum = abs(matrix[row][col]);maxrow = row;}}swap(matrix[col], matrix[maxrow]);for(int row = col + 1; row < n - 1; row++){long double res = matrix[row][col] / matrix[col][col];for(int loc = col; loc <= n - 1; loc++)matrix[row][loc] -= matrix[col][loc] * res; }}for(int row = n - 2; row >= 0; row--)//回代{for(int col = row + 1; col < n - 1; col++){matrix[row][99] -= matrix[col][99] * matrix[row][col] / matrix[col][col];matrix[row][col] = 0;}matrix[row][99] /= matrix[row][row];matrix[row][row] = 1;}for(int i = 0; i < n - 1; i++)x[i] = matrix[i][99];return x;
}long double* PreciseSol(long double* x , long double epsilon)
{long double* y = new long double[99];for(int i = 0; i < n - 1; i++)y[i] = (1 - a) * (1 - exp(-x[i] / epsilon)) / (1 - exp(-1 / epsilon)) + a * x[i];return y;
}void Calculate(long double epsilon)
{for(int i = 0; i < n - 1; i++)b[i] = a * h * h;b[98] -= epsilon + h;long double* Presol = PreciseSol(x , epsilon);for(int i = 0; i < n - 1; i++){A[i][i + 1] = epsilon + h;A[i + 1][i] = epsilon;}for(int i = 0; i < n - 1; i++)A[i][i] = -(2 * epsilon + h);long double* Column = Column_Elimination(A);long double errorColumn = 0;for(int i = 0; i < n - 1; i++){errorColumn += abs(Column[i] - Presol[i]) / 99;//cout << Column[i] << " " << Seidel[i] << " " << Presol[i] << endl;}cout << "epsilon=" << epsilon << "时,列主元消元法的相对误差为"  << errorColumn << endl;delete[] Presol;
}int main()
{for(int i = 0; i < n; i++)x[i] = (i + 1) * h;Calculate(1);Calculate(0.1);Calculate(0.01);Calculate(0.0001);
}

Algorithm2:Gauss-Seidel迭代法

X ( k + 1 ) = − ( D + L ) − 1 U X ( k ) + ( D + L ) − 1 b \mathbf{X^{(k+1)}}=-(\mathbf{D}+\mathbf{L})^{-1}\mathbf{U}\mathbf{X^{(k)}}+(\mathbf{D}+\mathbf{L})^{-1}\mathbf{b} X(k+1)=(D+L)1UX(k)+(D+L)1b

S = − ( D + L ) − 1 U = [ 0 ϵ + h 2 ϵ + h 0 ⋯ 0 0 ϵ ( ϵ + h ) ( 2 ϵ + h ) 2 ϵ + h 2 ϵ + h ⋯ 0 0 ϵ 2 ( ϵ + h ) ( 2 ϵ + h ) 3 ϵ ( ϵ + h ) ( 2 ϵ + h ) 2 ⋱ 0 ⋮ ⋮ ⋮ ⋱ ⋮ 0 ϵ n − 1 ( ϵ + h ) ( 2 ϵ + h ) n 0 ⋯ ϵ ( ϵ + h ) ( 2 ϵ + h ) 2 ] \begin{align*} \mathbf{S} &= -(\mathbf{D}+\mathbf{L})^{-1}\mathbf{U} \\ &= \begin{bmatrix} 0 & \frac{\epsilon + h}{2\epsilon + h} & 0 & \cdots & 0 \\ 0 & \frac{\epsilon(\epsilon + h)}{(2\epsilon + h)^2} & \frac{\epsilon + h}{2\epsilon + h}& \cdots & 0 \\ 0 & \frac{\epsilon^2(\epsilon + h)}{(2\epsilon + h)^3} & \frac{\epsilon(\epsilon + h)}{(2\epsilon + h)^2} & \ddots & 0 \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ 0 & \frac{\epsilon^{n-1}(\epsilon + h)}{(2\epsilon + h)^n} & 0 & \cdots & \frac{\epsilon(\epsilon + h)}{(2\epsilon + h)^2} \\ \end{bmatrix} \end{align*} S=(D+L)1U= 00002ϵ+hϵ+h(2ϵ+h)2ϵ(ϵ+h)(2ϵ+h)3ϵ2(ϵ+h)(2ϵ+h)nϵn1(ϵ+h)02ϵ+hϵ+h(2ϵ+h)2ϵ(ϵ+h)0000(2ϵ+h)2ϵ(ϵ+h)
I n v = ( D + L ) − 1 = [ − 1 2 ϵ + h 0 0 ⋯ 0 − ϵ ( 2 ϵ + h ) 2 − 1 2 ϵ + h 0 ⋯ 0 − ϵ 2 ( 2 ϵ + h ) 3 − ϵ ( 2 ϵ + h ) 2 − 1 2 ϵ + h ⋯ 0 ⋮ ⋮ ⋮ ⋱ ⋮ − ϵ n − 1 ( 2 ϵ + h ) n − ϵ n − 2 ( 2 ϵ + h ) n − 1 ⋯ − ϵ ( 2 ϵ + h ) 2 − 1 2 ϵ + h ] \begin{align*} \mathbf{Inv} &= (\mathbf{D}+\mathbf{L})^{-1} \\ &= \begin{bmatrix} -\frac{1}{2\epsilon + h} & 0 & 0 & \cdots & 0 \\ -\frac{\epsilon}{(2\epsilon + h)^2} & -\frac{1}{2\epsilon + h} & 0 & \cdots & 0 \\ -\frac{\epsilon^2}{(2\epsilon + h)^3} & -\frac{\epsilon}{(2\epsilon + h)^2} & -\frac{1}{2\epsilon + h} & \cdots & 0 \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ -\frac{\epsilon^{n-1}}{(2\epsilon + h)^n} & -\frac{\epsilon^{n-2}}{(2\epsilon + h)^{n-1}} & \cdots & -\frac{\epsilon}{(2\epsilon + h)^2} & -\frac{1}{2\epsilon + h} \\ \end{bmatrix} \end{align*} Inv=(D+L)1= 2ϵ+h1(2ϵ+h)2ϵ(2ϵ+h)3ϵ2(2ϵ+h)nϵn102ϵ+h1(2ϵ+h)2ϵ(2ϵ+h)n1ϵn2002ϵ+h1(2ϵ+h)2ϵ0002ϵ+h1
∥ X ( k + 1 ) − X ( k ) ∥ ∞ ≤ 1 0 − 6 \|\mathbf{X^{(k+1)}}-\mathbf{X^{(k)}}\|_{\infty}\leq10^{-6} X(k+1)X(k)106时结束迭代。

Code

#include<iostream>
#include<cmath>
#include <iomanip>
using namespace std;long double a = 1.0 / 2, n = 100, h = 1.0 / n;
long double x[99], A[99][99], b[99];// 矩阵和向量的乘法,用于求Gauss-Seidel迭代的f向量
long double* Multiplie(long double (*Inv)[99], long double* x)
{long double* res = new long double[99]();for(int i = 0; i < n - 1; i++){for(int j = 0; j < n - 1; j++)res[i] += Inv[i][j] * x[j];}return res;
}// 计算两个向量的差向量的无穷范数
long double Norm(long double* x1, long double* x2)
{long double norm = 0;for(int i = 0; i < n - 1; i++)if(abs(x1[i] - x2[i]) > norm)norm = abs(x1[i] - x2[i]);return norm;
}// Gauss-Seidel迭代法求解线性方程组
long double* Gauss_Seidel(long double (*S)[99], long double (*Inv)[99])
{long double* x1 = new long double[99]();long double tempx[99];for(int i = 0; i < n - 1; i++)tempx[i] = x[i];long double *temp1 = Multiplie(S, tempx);long double *temp2 = Multiplie(Inv, b);for(int i = 0; i < n - 1; i++)    x1[i] = temp1[i] + temp2[i];while(Norm(tempx, x1) > 1e-6){for(int i = 0; i < n - 1; i++) tempx[i] = x1[i];long double *temp1 = Multiplie(S, tempx);long double *temp2 = Multiplie(Inv, b);for(int i = 0; i < n - 1; i++)    x1[i] = temp1[i] + temp2[i];}return x1;
}// 计算精确解
long double* PreciseSol(long double* x , long double epsilon)
{long double* y = new long double[99];for(int i = 0; i < n - 1; i++)y[i] = (1 - a) * (1 - exp(-x[i] / epsilon)) / (1 - exp(-1 / epsilon)) + a * x[i];return y;
}// 计算误差并输出
void Calculate(long double epsilon)
{for(int i = 0; i < n - 1; i++)b[i] = a * h * h;b[98] -= epsilon + h;long double* Presol = PreciseSol(x , epsilon);long double S[99][99], Inv[99][99];fill(&S[0][0], &S[0][0] + sizeof(S) / sizeof(S[0][0]), 0);fill(&Inv[0][0], &Inv[0][0] + sizeof(Inv) / sizeof(Inv[0][0]), 0);long double init1 = (epsilon + h) / (2 * epsilon + h);long double temp = epsilon / (2 * epsilon + h);for(int i = 0; i < n - 1; i++)//初始化S=-(D+L)^(-1)U{for(int j = i , k = 1; j < n -1 && k < n - 1; j++, k++){S[j][k] = init1;}init1 *= temp; }long double init2 = -1 / (2 * epsilon + h);for(int i = 0; i < n - 1; i++)//初始化(D+L)^(-1){for(int j = i, k = 0; j < n - 1 && k < n - 1; j++ , k++){Inv[j][k] = init2;}init2 *= temp; }long double* Seidel = Gauss_Seidel(S, Inv);long double errorSeidel = 0;for(int i = 0; i < n - 1; i++)errorSeidel += abs(Seidel[i] - Presol[i]) / 99;cout << "epsilon=" << epsilon << "时,Gauss_Seidel迭代法的相对误差为"  << errorSeidel << endl;delete[] Presol;
}int main()
{for(int i = 0; i < n - 1; i++)x[i] = (i + 1) * h;Calculate(1);Calculate(0.1);Calculate(0.01);Calculate(0.0001);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/767024.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++命名空间和内联函数

目录 命名空间 内联函数 概述 特性&#xff1a; 命名空间 在C/C中&#xff0c;变量&#xff0c;函数和和类这些名称都存在于全局作用域中&#xff0c;可能会导致很多冲突&#xff0c;使用命名空间的目的是对标识符的名称进行本地化&#xff0c;避免命名冲突或名字污染&…

C语言函数和数组

目录 一.数组 一.一维数组&#xff1a; 1.一维数组的创建: 2.一维数组的初始化&#xff1a; 3.一维数组的使用 4.一维数组在内存中的存储&#xff1a; 二.二维数组&#xff1a; 三.数组越界&#xff1a; 四.数组作为函数参数&#xff1a; 二.函数 一.函数是什么&…

vue3对openlayers使用(加高德,天地图图层)

OpenLayers认识 WebGIS四大框架&#xff1a; Leaflet、OpenLayers、Mapbox、Cesium OpenLayers 是一个强大的开源 JavaScript 地图库&#xff0c;专注于提供可嵌入网页的交互式地图体验。作为一款地理信息系统&#xff08;GIS&#xff09;的前端开发工具&#xff0c;OpenLaye…

关于php foreach函数和变量覆盖

foreach函数是PHP中用于遍历数组或对象的函数&#xff08;且仅用于数组的遍历&#xff09;。它允许循环遍历数组中的每个元素&#xff0c;并对每个元素执行相同的操作。foreach语句的基本语法如下&#xff1a; foreach ($array as $value) {//执行的操作 }在这个语法中&#x…

C++ Thread 源码 观后 自我感悟 整理

Thread的主要数据成员为_Thr 里面存储的是线程句柄和线程ID 先看看赋值运算符的移动构造 最开始判断线程的ID是否不为0 _STD就是使用std的域 如果线程ID不为0&#xff0c;那么就抛出异常 这里_New_val使用了完美转发&#xff0c;交换_Val和_New_val的值 _Thr _STD exchange(_…

回归预测 | Matlab基于SAO-LSTM雪消融算法优化长短期记忆神经网络的数据多输入单输出回归预测

回归预测 | Matlab基于SAO-LSTM雪消融算法优化长短期记忆神经网络的数据多输入单输出回归预测 目录 回归预测 | Matlab基于SAO-LSTM雪消融算法优化长短期记忆神经网络的数据多输入单输出回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab基于SAO-LSTM雪消融…

【Linux】进程的进一步认识

目录 进程的创建 fork函数初步认识 fork函数的返回值 写时拷贝 操作系统怎么知道什么时候要写时拷贝的呢&#xff1f; fork的常规用法 fork调用失败的原因 进程终止 进程的退出场景 进程常见退出方法 正常终止&#xff08;可以通过 echo $? 查看进程退出码&#xff…

Spring Boot从入门到实战

课程介绍 本课程从SpringBoot的最基础的安装、配置开始到SpringBoot的日志管理、Web业务开发、数据存储、数据缓存&#xff0c;安全控制及相关企业级应用&#xff0c;全程案例贯穿&#xff0c;案例每一步的都会讲解实现思路&#xff0c;全程手敲代码实现。让你不仅能够掌Sprin…

【Linux操作系统】:进程控制

目录 一、程序地址空间 1.C/C中的程序地址空间 2.进程地址空间 进程地址空间概念 什么是地址空间&#xff1f;什么是区域划分&#xff1f; 为啥要有地址空间&#xff1f; 地址空间的补充 二、进程创建 1.fork函数 2.写时拷贝 3.fork常规用法 4.fork调用失败的原因 …

Linux 常用命令 1

Tips&#xff1a;终端热键ctrl shift 放大终端窗口的字体 ctrl - 缩小终端窗口的字体 注意区分大小写 查阅命令帮助信息&#xff1a; 1&#xff09;--help command –help(两个减号) 显示command命令的帮助信息 2&#xff09;man man command 查阅command命令的使…

MyEclipse打开文件跳转到notepad打开问题

问题描述 windows系统打开README.md文件&#xff0c;每次都需要右键选择notepad打开&#xff0c;感觉很麻烦&#xff0c;然后就把README.md文件打开方式默认选择了notepad&#xff0c;这样每次双击就能打开&#xff0c;感觉很方便。 然后某天使用MyEclipse时&#xff0c;双击RE…

matlab实现神经网络检测手写数字

一、要求 1.计算sigmoid函数的梯度&#xff1b; 2&#xff0e;随机初始化网络权重&#xff1b; 3.编写网络的代价函数。 二、算法介绍 神经网络结构&#xff1a; 不正则化的神经网络的代价函数&#xff1a; 正则化&#xff1a; S型函数求导&#xff1a; 反向传播算法&…

【Linux】Linux工具学习之git

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《C》 《Linux》 《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 文章目录 前言一、账号注册1.1 GitHub与Gitee 二、构建仓库三、安装git 四、配置git五、克…

详解库和程序运行过程

我最近开了几个专栏&#xff0c;诚信互三&#xff01; > |||《算法专栏》&#xff1a;&#xff1a;刷题教程来自网站《代码随想录》。||| > |||《C专栏》&#xff1a;&#xff1a;记录我学习C的经历&#xff0c;看完你一定会有收获。||| > |||《Linux专栏》&#xff1…

lvgl 窗口 windows lv_port_win_visual_studio 版本 已解决

不知道的东西&#xff0c;不知道lvgl窗口。一切从未知开始 lv_port_win_visual_studio 主分支 对应的分支 v7版本更新git submodule update --init --recursive同步 lvgl代码随后打开 visualSudio 打开.sln 文件 编译 release模式 允许 一切正常代码部分

考研数学基础差,跟宋浩?

宋浩老师的课程我大一的时候听过&#xff0c;是我大一高数的救命恩人&#xff01; 不过&#xff0c;考研的针对性很强&#xff0c;基础差听宋浩老师的课程不如直接听汤家凤老师的课程&#xff0c;因为汤家凤老师的课程是专门为考研数学设计的&#xff0c;针对性很强。 汤家凤老…

K8S之DaemonSet控制器

DaemonSet控制器 概念、原理解读、应用场景概述工作原理典型的应用场景介绍DaemonSet 与 Deployment 的区别 解读资源清单文件实践案例 概念、原理解读、应用场景 概述 DaemonSet控制器能够确保K8S集群所有的节点都分别运行一个相同的pod副本&#xff1b; 当集群中增加node节…

Django之Celery篇(一)

一、介绍 Celery是由Python开发、简单、灵活、可靠的分布式任务队列,是一个处理异步任务的框架,其本质是生产者消费者模型,生产者发送任务到消息队列,消费者负责处理任务。 Celery侧重于实时操作,但对调度支持也很好,其每天可以处理数以百万计的任务。特点: 简单:熟悉…

监控系统Prometheus--入门

文章目录 Prometheus特点易于管理监控服务的内部运行状态强大的数据模型强大的查询语言PromQL高效可扩展易于集成可视化开放性 Prometheus架构Prometheus 生态圈组件架构理解 Prometheus的安装安装Prometheus Server上传安装包解压安装包修改配置文件 prometheus.yml 安装Pushg…

Halcon 3D 平面拟合(区域采样、Z值过滤、平面拟合、平面移动)

Halcon 3D 平面拟合(区域采样、Z值过滤、平面拟合、平面移动) 链接:https://pan.baidu.com/s/1UfFyZ6y-EFq9jy0T_DTJGA 提取码:ewdi * 1.读取图片 ****************