计算方法实验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);
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

短视频矩阵系统源头技术开发--每一次技术迭代

短视频矩阵系统源头开发3年的我们&#xff0c;肯定是需求不断的迭代更新的&#xff0c;目前我们已经迭代了3年之久&#xff0c;写技术文章已经写了短视频矩阵系统&#xff0c;写了3年了&#xff0c;开发了3年了 短视频矩阵获客系统是一种基于短视频平台的获客游戏。短视频矩阵系…

基因在各个细胞系表达情况

从CCLE下载数据得到基因在每个细胞系中的 现在从DepMap: The Cancer Dependency Map Project at Broad Institute 需要先选择Custom Downloads 就可以下载数据进行处理了&#xff1a; rm(list ls()) library(tidyverse) library(ggpubr) rt <- data.table::fread("…

基于SpringBoot校园外卖服务系统设计与实现

点赞收藏关注 → 私信领取本源代码、数据库一、项目概述 项目名称&#xff1a;基于SpringBoot校园外卖服务系统设计与实现 项目架构&#xff1a;B/S架构 开发语言&#xff1a;Java语言 主要技术&#xff1a;SpringBootMybatisMySQL 运行环境&#xff1a;Windows7以上、JDK…

QT----给程序添加上任务栏托盘图标和退出

让我们的程序拥有任务栏托盘图标&#xff0c;实现程序后台运行&#xff0c;退出等功能 1、关闭程序保持后台 重写关闭事件,忽略点击窗口关闭 void MainWindow::closeEvent(QCloseEvent *event) {// 隐藏窗口&#xff0c;而不是真正关闭setVisible(false);// 忽略关闭事件&am…

【蓝牙协议栈】【BLE】低功耗蓝牙配对绑定过程分析(超详细)

1. 精讲蓝牙协议栈&#xff08;Bluetooth Stack&#xff09;&#xff1a;SPP/A2DP/AVRCP/HFP/PBAP/IAP2/HID/MAP/OPP/PAN/GATTC/GATTS/HOGP等协议理论 2. 欢迎大家关注和订阅&#xff0c;【蓝牙协议栈】和【Android Bluetooth Stack】专栏会持续更新中.....敬请期待&#xff01…

Java双指针算法

参考&#xff1a; 【Java版本】常用代码模板1——基础算法 模板题参考实现 - AcWing 【Java版本】常用代码模板2——数据结构 模板题参考实现 - AcWing 题目一&#xff1a; 输入&#xff1a;abc def ghi 输出&#xff1a;abc def ghi 题解&#xff1a; public class …

☆【前后缀】【双指针】Leetcode 42. 接雨水

【前后缀】【双指针】Leetcode 42. 接雨水 解法1 前后缀分解解法2 双指针 ---------------&#x1f388;&#x1f388;42. 接雨水 题目链接&#x1f388;&#x1f388;------------------- 解法1 前后缀分解 维护一个前缀&#xff08;左侧最高&#xff09;后缀&#xff08;右侧…

基于python+vue高校门诊管理系统flask-django-php-nodejs

课题主要采用python开发语言、django框架和MySQL数据库开发技术以及基于Eclipse的编辑器。系统主要包括用户、用户充值、医生、挂号信息、检查开药、药品信息、药品入库、取药出库等功能&#xff0c;从而实现智能化的管理方式&#xff0c;提高工作效率。 语言&#xff1a;Pytho…

全流程基于GIS、python机器学习技术的地质灾害风险评价与信息化建库教程

原文链接&#xff1a;全流程基于GIS、python机器学习技术的地质灾害风险评价与信息化建库https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247598798&idx6&sn29597597dc134060576998b3302467f8&chksmfa820329cdf58a3fa73c04ac20a28fab7c7ee8fb15d0f8ac50…

python处理Excel的方法之xlrd

python处理Excel常用到的模块是xlrd。使用xlrd可以非常方便的处理Excel文档&#xff0c;下面介绍一下基本用法 打开文件 import xlrd data xlrd.open_workbook("c:\\skills.xls") 获取一个工作表 table data.sheet_by_name(uskills) #也可以 table data.sheet_by_…

测试CAN功能是否使能成功

一. 简介 上一篇文章学习了在 kernel内核源码如何使能 Linux 内核自带的 FlexCAN 驱动。通过配置kernel来实现。文章如下&#xff1a; 本文验证&#xff0c;开发板加载新生成的 zImage内核镜像文件&#xff0c;确定 CAN驱动是否已经成功使能。 二. 测试CAN驱动是否使能成功…

Go --- 编程知识点及其注意事项

new与make 二者都是用于内存分配&#xff0c;当声明的变量是引用类型时&#xff0c;不能给该变量赋值&#xff0c;因为没有分配空间。 我们可以用new和make对其进行内存分配。 首先说说new new函数定义 func new(Type) *Type传入一个类型&#xff0c;返回一个指向分配好该…

Nacos部署(一)Linux部署Nacos2.3.x单机环境

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; Nacos部署&#xff08;一&#xff09;Linux部署Nacos2.3.x单机环境 ⏱️…

鸿蒙开发学习【地图位置服务组件】

简介 移动终端设备已经深入人们日常生活的方方面面&#xff0c;如查看所在城市的天气、新闻轶事、出行打车、旅行导航、运动记录。这些习以为常的活动&#xff0c;都离不开定位用户终端设备的位置。 当用户处于这些丰富的使用场景中时&#xff0c;系统的位置定位能力可以提供…

深度解析:Elasticsearch写入请求处理流程

版本 Elasticsearch 8.x 原文链接&#xff1a;https://mp.weixin.qq.com/s/hZ_ZOLFUoRuWyqp47hqCgQ 今天来看下 Elasticsearch 中的写入流程。 不想看过程可以直接跳转文章末尾查看总结部分。最后附上个人理解的一个图。 从我们发出写入请求&#xff0c;到 Elasticsearch 接收请…

应急响应实战笔记03权限维持篇(7)

第7篇&#xff1a;常见WebShell管理工具 攻击者在入侵网站时&#xff0c;通常要通过各种方式写入Webshell&#xff0c;从而获得服务器的控制权限&#xff0c;比如执行系统命令、读取配置文件、窃取用户数据&#xff0c;篡改网站页面等操作。 本文介绍十款常用的Webshell管理工…

图论基础|深度优先dfs、广度优先bfs

dfs 与 bfs 区别 提到深度优先搜索&#xff08;dfs&#xff09;&#xff0c;就不得不说和广度优先搜索&#xff08;bfs&#xff09;有什么区别 先来了解dfs的过程&#xff0c;很多录友可能对dfs&#xff08;深度优先搜索&#xff09;&#xff0c;bfs&#xff08;广度优先搜索…

K8S之DaemonSet控制器

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

【嵌入式】Docker镜像构建指南:引领应用部署的革新之路

&#x1f9d1; 作者简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟。提供嵌入式方向的学习指导、简历面…

绘制韦恩图

主要源于跟着Cell学作图 | 12.韦恩图(Vennerable包)-CSDN博客&#xff0c;增加了相关数据转换的处理。 韦恩图与upset差异 upset图&#xff1a;多个集合交集可视_upset图r语言代码自定义交集顺序-CSDN博客 rm(list ls()) #构建模型数据 group1 <- rep(c("1",…