微分方程差分三对角矩阵解法C语言程序
微分方程数值解追赶法

微分方程数值解追赶法追赶法,也称为三对角矩阵算法,是一种用于求解线性微分方程的数值方法。
这种方法主要基于矩阵分解和迭代的思想,能够有效地解决微分方程的数值求解问题。
在微分方程的数值解法中,追赶法通常用于求解形如 (y' = f(x, y)) 的常微分方程。
其基本思想是将微分方程转化为差分方程,然后通过迭代的方式逐步逼近微分方程的解。
具体来说,追赶法的步骤如下:矩阵分解:首先,将微分方程 (y' = f(x, y)) 转化为差分方程的形式。
然后,将差分方程中的系数矩阵进行分解,将其分解为一个下三角矩阵 (L)、一个对角矩阵 (D) 和一个上三角矩阵 (U)。
这样,差分方程可以转化为(D^{-1}Lx = D^{-1}b) 的形式。
迭代求解:接下来,使用迭代法求解 (D^{-1}Lx = D^{-1}b)。
通常,可以选择Gauss-Seidel迭代法或者SOR(Successive Over-Relaxation)迭代法等。
在每次迭代中,先求解下三角矩阵 (L) 的部分,然后求解对角矩阵(D) 的部分,最后求解上三角矩阵 (U) 的部分。
通过不断迭代,逐步逼近差分方程的解。
收敛性判断:在迭代求解的过程中,需要判断迭代的解是否收敛。
通常,可以通过比较相邻两次迭代的解的差值来判断是否收敛。
当差值小于某个预设的阈值时,认为迭代收敛。
解的输出:当迭代收敛后,可以得到微分方程的数值解。
此时,可以将解输出到控制台或者保存到文件中。
追赶法的优点在于其算法简单、易于实现,并且对于大规模的微分方程求解问题具有较高的计算效率和精度。
然而,追赶法也存在一些局限性,例如对于某些特殊类型的微分方程可能不适用,需要进行特殊处理。
三对角方程组的并行解法

本算法中设有 p 台并行机,把 A 分裂为 p p 块三对角形式,其中每一主对角块是 k k 的三对角阵,即 n pk 因此每一台处理机主要处理一个k 阶的三对角块,其分解形式为:
A0 BT 0 A
其中:
B0 A1
B1 BT p 3
Ap 2 BT p2
p 1 m 2 p 1 m 1
则
0 0 00 0 0 0 1 10 A
0 1
0 m 2 0 m 2 0 m b0 1
b m2
p2
0
b m 1
p2
0
b0 b1 bm2 b m 1
0 0 0
0
b0 b1
p 2 p 2
b0
b1
b m2
d 0p 1 d1p 1
p 1 dm 2
b
p 2 m 1 p 2
b m 1
p2 b m 1 p 1 d m 1
三对角方程组的并行算法设所要求解的对称正定三对角线方程组成为ax称正定三对角矩阵且非奇异具体形式为n2n2xn2yn2n2n1xn1yn1本算法中设有台并行机把分裂为块三对角形式其中每一主对角块是的三对角阵即npk因此每一台处理机主要处理一个k阶的三对角块其分解形式a0b0m2m2bim2m1m2m2m2m1m1p2b0b1bm2bm1则此时l1alt有如下形式
T T T T
x1 xmp 1 ] 中的 x j 均可直接得到,
,
yj dj
(三) 数值结果分析
编写用追赶法解三对角线性方程组的程序,并解下列方程组

计算方法与实习上机实验(二)实验名称:编写用追赶法解三对角线性方程组的程序,并解下列方程组:(1)⎪⎪⎩⎪⎪⎨⎧-=+-=-+--=-+-=-12,112,122,524343232121x x x x x x x x x x (2)Ax=b,其中A 10×10=⎥⎥⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎢⎢⎣⎡-----41141.........14114114, b 10×1=⎥⎥⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎢⎢⎣⎡--1515...15-15-27- 程序代码:#include<iostream>using namespace std;#include<iomanip>int main(){float a[100],b[100],c[100],x[100];int i,k,N;while(1){int ability=1; //ability 用于判断可不可以执行追赶法的操作cout<<"输入三对角矩阵的维度:"<<endl;cin>>N;cout<<"输入三对角的数据:"<<endl;cin>>b[0]>>c[0]>>x[0];for(i=1;i<N-1;i++) //输入各组数据{cin>>a[i]>>b[i]>>c[i]>>x[i];}cin>>a[N-1]>>b[N-1]>>x[N-1];for(k=0;k<N-1;k++){if(b[k]==0) {cout<<"不可用追赶法解此题!"<<endl;//当对角线上的元素全部为零的时候不可以用追赶法.ability=0;break;}else{ a[k+1]=a[k+1]/b[k];b[k+1]=b[k+1]-a[k+1]*c[k];x[k+1]=x[k+1]-a[k+1]*x[k];//这个过程执行的是消元过程(即追赶法的追):对应于书上的βi=bi-lic(i-1),yi=di-liy(i-1)}}if(ability){x[N-1]=x[N-1]/b[N-1]; //回代法的第一项for(i=N-2;i>=0;i--) //下标从大到小变化,是赶的过程{x[i]=(x[i]-c[i]*x[i+1])/b[i];}cout<<"此方程的解为:"<<endl;for(i=0;i<N;i++){cout<<setiosflags(ios::showpoint);cout<<"x["<<i+1<<"]="<<setiosflags(ios::fixed)<<setprecision(1)<<x[i]<<endl; //保留一位有效数字}}}return 0;}运行结果:。
三对角线性方程组的求解

一、概述三对角线性方程组的求解是许多科学和工程计算中最重要也是最基本的问题之一。
在核物理、流体力学、油藏工程、石油地震数据处理及数值天气预报等许多领域的大规模科学工程和数值处理中都会遇到三对角系统的求解问题。
很多三对角线性方程组的算法可以直接推广到求解块三对角及带状线性方程组。
由于在理论和实际应用上的重要性,近20年来三对角方程组的并行算法研究十分活跃。
大规模科学计算需要高性能的并行计算机。
随着软硬件技术的发展,高性能的并行计算机日新月异。
现今,SMP可构成每秒几十亿次运算的系统,PVP和COW可构成每秒几百亿次运算的系统,而MPP和DSM可构成每秒万亿次运算或更高的系统。
高性能并行计算机只是给大型科学计算提供了计算工具。
如何发挥并行计算机的潜在性能和对三对角系统进行有效求解,其关键在于抓住并行计算的特点进行并行算法的研究和程序的设计与实现。
另外,对处理机个数较多的并行计算系统,在设计并行算法时必须解决算法的可扩展性,并对可扩展性进行研究和分析。
二、问题的提出设三对角线性方程组为AX=Y(1)式中:A∈Rn×n非奇异,αij=0,。
X=(x1,x2,…xn) T Y=(y1,y2,…yn)T。
此系统在许多算法中被提出,因此研究其高性能并行算法是很有理论和实际意义的。
三、并行求解三对角系统的直接解法关于三对角线性方程组的直接求解已经有大量并行算法,其中Wang的分裂法是最早针对实际硬件环境,基于分治策略提出的并行算法。
它不仅通信结构简单,容易推广到一般带状线性方程组的并行求解,而且为相继出现的许多其它并行算法提供了可行的局部分解策略。
近20年来求解三对角方程组的并行算法都是基于分治策略,即通过将三对角方程组分解成P个小规模问题,求解这P个小规模问题,再将这些解结合起来得到原三对角方程组的解。
一般求解三对角方程组的分治方法的计算过程可分为3个阶段:一是消去,每台处理机对子系统消元;二是求解缩减系统(需要通信);三是回代,将缩减系统的解回代到每个子系统,求出最终结果。
三对角法求微分方程组

三对角法求微分方程组摘要:1.引言2.三对角法的基本原理3.三对角法求解微分方程组的步骤4.举例说明5.结论正文:1.引言微分方程组在数学和物理学等领域有着广泛的应用,如何有效地求解微分方程组一直是学者们关注的焦点。
近年来,数值计算方法在求解微分方程组方面取得了显著进展。
其中,三对角法作为一种常用的数值计算方法,得到了广泛的应用。
本文将对三对角法求解微分方程组的原理和步骤进行详细介绍。
2.三对角法的基本原理三对角法是一种基于矩阵的三对角分解方法,其基本思想是将求解微分方程组的问题转化为求解一组三对角线性方程组。
具体来说,对于一个n 阶微分方程组,首先将其转化为n 个一阶微分方程,然后通过三对角分解,将这些一阶微分方程转化为一组三对角线性方程组。
最后,通过求解这组三对角线性方程组,得到原微分方程组的解。
3.三对角法求解微分方程组的步骤求解微分方程组的三对角法主要包括以下三个步骤:(1) 构造三对角矩阵。
根据微分方程组的系数矩阵,构造一个三对角矩阵。
具体来说,对于一个n 阶微分方程组,构造一个n×n 的三对角矩阵,其中对角线以下的元素为原方程组系数矩阵的元素,对角线以上的元素为原方程组系数矩阵的转置矩阵的元素。
(2) 求解三对角线性方程组。
通过三对角分解,将原微分方程组转化为一组三对角线性方程组。
然后,利用迭代法(如牛顿法、梯度下降法等)求解这组三对角线性方程组,得到一组近似解。
(3) 得到微分方程组的解。
根据三对角线性方程组的解,可以通过反向替换得到原微分方程组的解。
4.举例说明假设有一个二阶微分方程组:y"(x) = 3x^2 - 2y(x)y"(x) = x^3 - xy(x)采用三对角法求解该微分方程组,首先构造一个三对角矩阵:```[ 3x^2 - 2y(x), 0 ][ 0, x^3 - xy(x) ]```然后,通过三对角分解,将该矩阵分解为两个对角矩阵的乘积:```[ 1, 0, 0 ][ 0, 1, 0 ][ 0, 0, 1 ]```将分解后的矩阵代入原矩阵,得到一组三对角线性方程组:```u"(x) = au(x)v"(x) = bv(x)w"(x) = cw(x)```其中,u(x) = y(x),v(x) = xy(x),w(x) = x^2y(x),a = 3,b = 1,c = 1。
使用C语言解常微分方程 C ODE

解常微分方程姓名:Vincent年级:2010,学号:1033****,组号:5(小组),4(大组) 1. 数值方法:我们的实验目标是解常微分方程,其中包括几类问题。
一阶常微分初值问题,高阶常微分初值问题,常微分方程组初值问题,二阶常微分方程边值问题,二阶线性常微分方程边值问题。
对待上面的几类问题,我们分别使用不同的方法。
初值问题使用 龙格-库塔 来处理 边值问题 用打靶法来处理 线性边值问题 有限差分法初值问题我们分别使用二阶 龙格-库塔 方法 4阶 龙格-库塔 方法来处理一阶常微分方程。
理论如下:对于这样一个方程'()(,)y t f t y =当h 很小时,我们用泰勒展开,12111111(,)(,)(,)k k k k i i k k j j i ij k hf t y k hf t h y k k hf a b a b t h y h k -===++=++∑当我们选择正确的参数 a[i][j],b[i][j]之后,就可以近似认为这就是泰勒展开。
对于二阶,我们有:()01()()y t h y t h Af Bf+=++其中 010(,)(,)P f f t y f f t y h Qhf ==++经过前人的计算机经验,我们有,选择 A=1/2,B=1/2,则 P=1,Q=1,于是又如下形式,这也使休恩方法的表达式。
所以我们称其为 龙格(库塔)休恩方法()()()(,)(,(,))2hy t h y t f t y f t h y hf t y +=++++对于4阶龙格方法,我们有类似的想法, 我们使用前人经验的出的系数,有如下公式112341213243(22),6(,),(,),22(,),22(,).n n n n n n n n n n h y y k k k k k f t y h h k f t y k h h k f t y k k f t h y hk +⎧=++++⎪⎪=⎪⎪⎪=++⎨⎪⎪=++⎪⎪=++⎪⎩对于高阶微分方程及微分方程组我们用4阶龙格-库塔方法来解对于一个如下的微分方程组'111'1(,,,),(,,,).n nn n y f t y y y f t y y ⎧=⎪⎨⎪=⎩ 101,00,0(),()n n y t y y t y=⎧⎪⎨⎪=⎩ 我们可以认为是一个一阶向量微分方程,所以可以用龙格-库塔方法的向量形式解。
最新三对角线性方程组的解法知识讲解

Jacobi迭代法
1.迭代过程: 对于Ax b ,设A可逆,且对于aii0,i1,2, ,n 令D为A的对角元素部分,则 A(AD )D, 继而对于方程组有 D x(D A )xb,所以有 解 ,令 xD 1(D A )xD 1b B JD 1(D A )D 1(LU ) 为迭代矩阵,fJ D1b。则Jacobi迭代法的迭 代格式为: 。 x(k1) Bjx(k) fJ
二、实验内容
考虑线性方程组:
A xb , A R n n,b R n
其中A为三对角矩阵,编制程序求解该方程组
三、实验要求
(1)考虑不同的数值解法,对方程组进行编程,编写其通用代码; (2)对不同的程序代码用实例进行验证,取矩阵:
2 1 0 0 0 1
1
2
1
0
0
0
A 0 1 2 1 0 ,b 1
0
0 1 2 1
0
0 0 0 1 2 0
x 方程初值 :
(0,0,0,0,0,0)T
0
。
(3)比较不同方法对求解三对角线性方程组的优异性。
四、实验过程
解法
追赶法
Jacobi迭代法
Gauss迭代法
SOR迭代法
(一)追赶法
• 编程思想:
矩阵的三对角线性方程组是由矩阵的直接三角分解法来推到的 来的,求解பைடு நூலகம்价于解两个三角形方程组:
B w(D w) 1 L (1 (w )D w)U
其中 x(k1) Bwx(k)fw 迭代法
且 fw wb 。当w=1时,SOR法就是Gauss
• SOR方法是Gauss迭代法的一种修正,主要思想是:设已知 x (k )
(1)Ly f ,求y;(2)Ux y ,求x
使用C语言解常微分方程 C ODE

解常微分方程姓名:Vincent年级:2010,学号:1033****,组号:5(小组),4(大组)1. 数值方法:我们的实验目标是解常微分方程,其中包括几类问题。
一阶常微分初值问题,高阶常微分初值问题,常微分方程组初值问题,二阶常微分方程边值问题,二阶线性常微分方程边值问题。
对待上面的几类问题,我们分别使用不同的方法。
∙ 初值问题使用 龙格-库塔 来处理 ∙ 边值问题用打靶法来处理 ∙ 线性边值问题有限差分法初值问题我们分别使用∙ 二阶 龙格-库塔 方法 ∙ 4阶 龙格-库塔 方法 来处理一阶常微分方程。
理论如下:对于这样一个方程'()(,)y t f t y =当h 很小时,我们用泰勒展开,12111111(,)(,)(,)k k k k i i k k j j i ij k hf t y k hf t h y k k hf a b a b t h y h k -===++=++∑当我们选择正确的参数 a[i][j],b[i][j]之后,就可以近似认为这就是泰勒展开。
对于二阶,我们有:()01()()y t h y t h Af Bf+=++其中010(,)(,)P f f t y f f t y h Qhf ==++经过前人的计算机经验,我们有,选择 A=1/2,B=1/2,则 P=1,Q=1,于是又如下形式,这也使休恩方法的表达式。
所以我们称其为 龙格(库塔)休恩方法()()()(,)(,(,))2hy t h y t f t y f t h y hf t y +=++++对于4阶龙格方法,我们有类似的想法, 我们使用前人经验的出的系数,有如下公式112341213243(22),6(,),(,),22(,),22(,).n n n n n n n n n n h y y k k k k k f t y h h k f t y k h h k f t y k k f t h y hk +⎧=++++⎪⎪=⎪⎪⎪=++⎨⎪⎪=++⎪⎪=++⎪⎩对于高阶微分方程及微分方程组 我们用∙ 4阶龙格-库塔方法来解对于一个如下的微分方程组'111'1(,,,),(,,,).n nn n y f t y y y f t y y ⎧=⎪⎨⎪=⎩ 101,00,0(),()n n y t y y t y=⎧⎪⎨⎪=⎩ 我们可以认为是一个一阶向量微分方程,所以可以用龙格-库塔方法的向量形式解。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include<stdio.h>
#include<math.h>
#define N 1000
//三对角方程组Thomas算法,计算两点边值问题
//-u"(x)+u(x)=exp(x)(sin(x)-cos(x),0<=x<=pi
//u(00=0, u(pi)=0.
void ThomasMethodsf(double a[],double b[],double c[],double d[],int n);
//Thomas算法函数
void Errorf(double x[],double d[],double e[],double *maxe_h,int n);
//计算结点处数值解的误差的绝对值和数值解的最大误差函数
void prtf(double a[],double b[],double c[],double d[],int n);
//打印三对角方程组系数矩阵函数
double fi(double xi);//微分方程右端项
//double qi(double xi);//微分方程u(x)系数
double ui(double xi);//微分方程精确解u(x)
void res(double d[],double e[],double maxe_h,int n);//输出结果到Result.txt文档
void main()
{
double a[N];//系数矩阵左下非零元素集合,顺序从左到右,从上到下
double b[N];//系数矩阵对角线元素集合,顺序同上
double c[N];//系数矩阵右上非零元素集合,顺序同上
double d[N];//方程组常数项集合
double x[N];//网格节点集合
double e[N];//误差
double maxe_h=0;//最大误差
double *p_1,*p_2,*p_3;//*p_1指向数组d[N],*p_2指向数组e[N],*p_3指向maxe_h double h;//网格步长
int m;//求解区间等分度
int n;//系数矩阵阶数
int i;
printf("请输入求解区间等分度:\nm=");
scanf("%d",&m);
h=3.1415926/m;
n=m-1;
for(i=1;i<m;i++)//系数矩阵和常数项赋值
{
x[i]=i*h;
a[i]=-1;
b[i]=2+h*h;
c[i]=-1;
d[i]=h*h*fi(x[i]);
}
p_1=d;
ThomasMethodsf(a,b,c,p_1,n);
p_2=e;
p_3=&maxe_h;
Errorf(x,d,p_2,p_3,n);
res(d,e,maxe_h,n);
printf("Reslut:\n");
for(i=(n+1)/5;i<=n;i=i+(n+1)/5)
printf("u%d=%f\n",i,d[i]);
printf("\n");
return;
}
double fi(double xi)
{
double fx;
fx=exp(xi)*(sin(xi)-2*cos(xi));
return fx;
}
/*double qi(double xi)
{
}*/
double ui(double xi)
{
double ux;
ux=exp(xi)*sin(xi);
return ux;
}
void ThomasMethodsf(double a[],double b[],double c[],double d[],int n) {
int j;
double p;
// prtf(a,b,c,d,n);
if(fabs(b[1])<1e-15)//判断系数矩阵是否为奇异矩阵函数
{
printf("Error: Matrix A is sigular.");
return;
}
c[1]=c[1]/b[1];//追
d[1]=d[1]/b[1];
for(j=2;j<n;j++)
{
p=b[j]-a[j]*c[j-1];
if(fabs(b[j])<1e-15)//判断系数矩阵是否为奇异矩阵函数
{
printf("Error: Matrix A is sigular.");
return;
}
c[j]=c[j]/p;
d[j]=(d[j]-a[j]*d[j-1])/p;
}
p=b[n]-a[n]*c[n-1];//赶
if(fabs(b[n])<1e-15)//判断系数矩阵是否为奇异矩阵函数
{
printf("Error: Matrix A is sigular.");
return;
}
d[n]=(d[n]-a[n]*d[n-1])/p;
for(j=n-1;j>=1;j--)
d[j]=d[j]-c[j]*d[j+1];
}
void res(double d[],double e[],double maxe_h,int n)
{
FILE *fp;
int j;
if((fp=fopen("Result.txt","a"))==NULL)//打开文件
{
printf("Connot open this file.");
return;
}
fprintf(fp,"m=%d时的数值解:\n",n+1);
for(j=1;j<=n;j=j++)
{
fprintf(fp,"u%d=%f ",j,d[j]);//写入文件
}
fprintf(fp,"\n对应数值解的误差的绝对值:\n");
for(j=1;j<=n;j=j++)
{
fprintf(fp,"%10.3e ",e[j]);//写入文件
}
fprintf(fp,"\n数值解的最大误差:%10.3e\n\n",maxe_h);
fclose(fp);//关闭文件
}
void Errorf(double x[],double d[],double e[],double *maxe_h,int n) {
int i;
for(i=1;i<=n;i++)
{
e[i]=fabs(ui(x[i])-d[i]);
if(e[i]>*maxe_h)
*maxe_h=e[i];
}
}
void prtf(double a[],double b[],double c[],double d[],int n)
{
int i,j;
printf("Coefficient Matrix:\n");
printf("%f %f \n",b[1],c[1]);
printf("%f %f %f\n",a[2],b[2],c[2]);
for(j=3;j<n;j++)
{
for(i=2;i<j;i++)
printf(" ");
printf("%f %f %f\n",a[j],b[j],c[j]);
}
for(i=2;i<n;i++)
printf(" ");
printf("%f %f\n",a[n],b[n]);
printf("Constant:\n");
for(j=1;j<=n;j++) printf("%f ",d[j]);
printf("\n");
}。