① jacobi迭代法是什么
jacobi迭代法是求全积分的一种方法,把拉格朗阶查皮特方法推广到求n个自变量一阶非线性方程的全积分的方法称为雅可比方法。
雅克比迭代法的计算公式简单,每迭代一次只需计算一次矩阵和向量的乘法,且计算过程中原始矩阵A始终不变,比较容易并行计算。
具体解释
考虑线性方程组Ax=b时,一般当A为低阶稠密矩阵时,用主元消去法解此方程组是有效方法。但是,对于由工程技术中产生的大型稀疏矩阵方程组(A的阶数很高,但零元素较多,例如求某些偏微分方程数值解所产生的线性方程组)。
利用迭代法求解此方程组就是合适的,在计算机内存和运算两方面,迭代法通常都可利用A中有大量零元素的特点。雅克比迭代法就是众多迭代法中比较早且较简单的一种,其命名也是为纪念普鲁士着名数学家雅可比。
② 求雅可比迭代法的程序流程图及3×3结构的C程序
#include<stdio.h>
#include<math.h>
main()
{
int n,M,i,j;
printf("请输入希望迭代的次数");
scanf("%d",&M);
printf("请输入方程阶数");
scanf("%d",&n);
float p,y[n],x[n],a[n][n],b[n];
printf("请输入误差限");
scanf("%f",&p);
printf("请输入系数行列式");
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%f",&a[i][j]);
printf("请输入常数项向量");
for(i=0;i<n;i++)
scanf("%f",&b[i]);
printf("请输入初始向量");
for(i=0;i<n;i++)
scanf("%f",&x[i]);
for(k=1;k<=M;k++)
{
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
if(j==i) continue;
else y[i]=(b[i]-a[i][j]x[i])/a[i][i];
}
for(i=0;i<n;i++)
if(fabs(x[i]-y[i])<p)
for(i=0;i<n;i++)
{
printf("x%d=%f",i+1,y[i]);break;
}
else for(i=0;i<n;i++)
x[i]=y[i];
}
if(k>M) printf("没有得到在误差范围内的根");
}
③ 求雅可比迭代法解方程组的C\C++程序
#include<iostream>
#include<math.h>
#include<iomanip>
using namespace std;
#define kk 50 //定义最大方程元数
int n,i,c,j,ll,hh,gg,mm;
double A[kk][kk],x[kk][kk],b[kk],y[kk],a[kk],z[kk],m,nn,d,e=1,w,fff ;
void main()
{
cout<<" **********************************************************************"<<endl;
cout<<" ***本程序可以用雅可比迭代法,塞德尔迭代法,逐次超松弛法求解线性方程组***"<<endl;
cout<<" ***************************制作人:李小龙*****************************"<<endl;
cout<<" ***********************说明:方程最多个数为50**************************"<<endl;
cout<<" **********************************************************************"<<endl;
//*********************************数据的输入********************************
/*bb:*/cout<<"输入的方程元数"<<endl;
cin>>n;
cout<<"请输入方程系数矩阵:"<<endl;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
cin>>A[i][j];
cout<<"请输入右边向量:"<<endl;
for(i=0;i<n;i++)
cin>>b[i];
cout<<"输入你想要的迭代精度(建议1e-5以上)!"<<endl;
cin>>fff;
cout<<"输入最大迭代次数(建议300次以上)!"<<endl;
cin>>mm;
////*******************************判断是否对角占优*************************
// for(i=0;i<n;i++)
// {
// for(j=0;j<n;j++)
// {
// nn=0;
// if(i==j)
// {
// d=fabs(A[i][i]);
// }
// else
// nn=nn+fabs(A[i][j]);
// }
// if(nn>d)
// {
// cout<<"该方程不对角占优,迭代不收敛"<<endl;
// cout<<"是否继续?是(0),否(1)"<<endl;
// cin>>hh;
// if(hh!=1)
// goto bb;
// else exit(1);
// }
// }
//********************************计算出迭代矩阵*************************
for(i=0;i<n;i++)
{
b[i]=b[i]/A[i][i];
for(j=0;j<n;j++)
{
if(i==j)
{
x[i][i]=0;
}
else
{
x[i][j]=-A[i][j]/A[i][i];
}
}
}
//*******************************输出迭代矩阵*****************************
cout<<"计算出迭代矩阵为:"<<endl;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
cout<<x[i][j]<<" ";
cout<<b[i]<<" ";
cout<<endl;
}
//****************************迭代方法的选择*****************************
cout<<"请你选择迭代方法!"<<endl;
cout<<endl;
cout<<endl;
cout<<"选用雅可比迭代法,请输入(1)!"<<endl;
cout<<endl;
cout<<endl;
cout<<"选用塞德尔迭代法,请输入(2)!"<<endl;
cout<<endl;
cout<<endl;
cout<<"选用逐次超松弛法,请输入(3)!"<<endl;
cout<<endl;
cout<<endl;
cin>>ll;
//*****************************赋迭代初值***********************************
cout<<"输入迭代初值"<<endl;
for(i=0;i<n;i++)
cin>>y[i];
int f=1;
switch(ll)
{
case 1:goto cc;
break;
case 2:goto aa;
break;
case 3:goto dd;
}
//***************************雅可比迭代法************************************
cc:cout<<" ";
for(i=1;i<n+1;i++)
cout<<"X["<<i<<"]"<<" ";
cout<<"精度";
cout<<endl;
cout<<"迭代初值为: ";
cout<<setiosflags(ios::fixed);
for(i=0;i<n;i++)
cout<<y[i]<<" ";
cout<<endl;
while(e>fff)
{
for(i=0;i<n;i++)
z[i]=y[i];
for(i=0;i<n;i++)
{
nn=0;
for(j=0;j<n;j++)
{
if(i!=j)
nn=nn+x[i][j]*z[j];
y[i]=nn+b[i];
}
e=fabs(z[0]-y[0]);
if(fabs(z[i]-y[i])>e)
e=fabs(z[i]-y[i]);
if(i==0)
{
cout<<setiosflags(ios::fixed);
cout<<"第"<<setw(3)<<setprecision(3)<<f++<<"次迭代"<<" ";
}
cout<<setiosflags(ios::fixed);
cout<<setw(8)<<setprecision(8)<<y[i]<<" ";
}
cout<<e;
cout<<endl;
if(f>mm)
{
cout<<"迭代次数大于"<<mm<<"次"<<endl;
cout<<"认为方程发散,迭代不收敛"<<endl;
exit(1);
}
}
cout<<endl;
cout<<endl;
cout<<"方程迭代了"<<f-1<<"次,达到你所要求的精度"<<fff<<endl;
cout<<"最后结果为:"<<endl;
cout<<endl;
for(i=0;i<n;i++)
{
cout<<"X"<<"["<<i+1<<"]"<<"="<<y[i];
cout<<endl;
}
exit(1);
//***********************************塞德尔迭代法********************************
aa:cout<<" ";
for(i=1;i<n+1;i++)
cout<<"X["<<i<<"]"<<" ";
cout<<"精度";
cout<<endl;
cout<<"迭代初值为: ";
cout<<setiosflags(ios::fixed);
for(i=0;i<n;i++)
cout<<y[i]<<" ";
cout<<endl;
while(e>fff)
{
for(i=0;i<n;i++)
{
z[i]=y[i];
nn=0;
for(j=0;j<n;j++)
{
nn=nn+x[i][j]*y[j];
y[i]=nn+b[i];
}
e=fabs(z[0]-y[0]);
if(fabs(z[i]-y[i])>e)
e=fabs(z[i]-y[i]);
if(i==0)
{
cout<<setiosflags(ios::fixed);
cout<<"第"<<setw(3)<<setprecision(3)<<f++<<"次迭代"<<" ";
}
cout<<setiosflags(ios::fixed);
cout<<setw(8)<<setprecision(8)<<y[i]<<" ";
}
cout<<e;
cout<<endl;
if(f>mm)
{
cout<<"迭代次数大于"<<mm<<"次"<<endl;
cout<<"认为方程发散,迭代不收敛"<<endl;
exit(1);
}
}
cout<<endl;
cout<<endl;
cout<<"方程迭代了"<<f-1<<"次,达到你所要求的精度"<<fff<<endl;
cout<<"最后结果为:"<<endl;
cout<<endl;
for(i=0;i<n;i++)
{
cout<<"X"<<"["<<i+1<<"]"<<"="<<y[i];
cout<<endl;
}
exit(1);
//***********************************逐次超松弛法********************************
dd: cout<<"输入加速因子W(0<W<2):"<<endl;
cin>>w;
/*if((w>2)||(w<0))
{
cout<<"输入错误!加速因子W(0<W<2):"<<endl;
cout<<"请重新输入:"<<endl;
cin>>w;
}*/
//不知道为什么写成这样大于2能判断,而小于0就不能判断老?????
if(w>=2)//还有w>=2,w<=0输入0或2时也不能判断!!
{
cout<<"输入错误!加速因子W(0<W<2):"<<endl;
cout<<"请重新输入:"<<endl;
cin>>w;
}
if(w<=0)
{
cout<<"输入错误!加速因子W(0<W<2):"<<endl;
cout<<"请重新输入:"<<endl;
cin>>w;
}
cout<<" ";
for(i=1;i<n+1;i++)
cout<<"X["<<i<<"]"<<" ";
cout<<"精度";
cout<<endl;
cout<<"迭代初值为: ";
cout<<setiosflags(ios::fixed);
for(i=0;i<n;i++)
cout<<y[i]<<" ";
cout<<endl;
while(e>fff)
{
for(i=0;i<n;i++)
{
z[i]=y[i];
nn=0;
for(j=0;j<n;j++)
{
nn=nn+x[i][j]*y[j];
y[i]=(1-w)*z[i]+w*(nn+b[i]);
}
e=fabs(z[0]-y[0]);
if(fabs(z[i]-y[i])>e)
e=fabs(z[i]-y[i]);
if(i==0)
{
cout<<setiosflags(ios::fixed);
cout<<"第"<<setw(3)<<setprecision(3)<<f++<<"次迭代"<<" ";
}
cout<<setiosflags(ios::fixed);
cout<<setw(8)<<setprecision(8)<<y[i]<<" ";
}
cout<<e;
cout<<endl;
if(f>mm)
{
cout<<"迭代次数大于"<<mm<<"次"<<endl;
cout<<"认为方程发散,迭代不收敛"<<endl;
exit(1);
}
}
cout<<endl;
cout<<endl;
cout<<"方程迭代了"<<f-1<<"次,达到你所要求的精度"<<fff<<endl;
cout<<"最后结果为:"<<endl;
cout<<endl;
for(i=0;i<n;i++)
{
cout<<"X"<<"["<<i+1<<"]"<<"="<<y[i];
cout<<endl;
}
exit(1);
}
④ 什么是雅克比迭代法
雅可比迭代法可求解线性方程组,也可用于求实对称矩阵的特征值。关于特征值求解举一例。
上面《Jacobⅰ迭代法》仅迭代一次就得到准确解。但该矩阵用 《QR迭代法》迭代多次为啥得近似答案?因为对称矩阵更适合用Jacobⅰ迭代法,迭代次数少且答案准确。
⑤ c语言,关于雅可比法求矩阵的特征值和特征向量的迭代次数
如果把所有非对角元扫描一遍作为一次迭代,那么几步迭代后就能收敛,换句话说需要O(n^2)步旋转才能收敛,因为Jacobi算法具有渐进二次收敛性。
Jacobi算法一般比较慢,但是如果慢的过分一般来讲是你的代码有问题,你可以把非对角元的平方和输出出来观察一下收敛速度。
⑥ 雅克比迭代法求解线性方程组的C语言程序
void Solve ( double dCoef [] , double dY [] , unsigned int iOrder , double dErr)
{//用Jacobi迭代法解方程组, dCoef[]系数阵, Y[]向量, iOrder给出方程阶数, dErr给出精度
double res [Max]; //方程解
double res2[Max]; //保存上一阶方程解
if ( Max < iOrder )
{
printf ("最多支持%d阶方程组.", Max);
return;
}
for ( unsigned int i = 0 ; i < iOrder ; res2 [i++] = 0.0 ); //初始解向量 (0,0...)
while ( true )
{
bool bStopIterative = true;
for (unsigned int i = 0 ; i < iOrder ; ++i)
{
double dSum2 = 0;
for (unsigned int j = 0 ; j < iOrder ; j++)
{//求第二项
if ( j == i ) continue;
dSum2 += dCoef [i * iOrder + j] * res2 [j];
}
res[i] = 1/dCoef[i * iOrder + i] * ( dY[i] - dSum2 );
if ( abs ( res2[i] - res [i] ) > dErr )
bStopIterative = false;
}
if ( bStopIterative )
break;
for (unsigned int i = 0 ; i < iOrder ; i++ )
res2[ i ] = res[ i ];
}
//输出结果
for (unsigned int i = 0 ; i < iOrder ; i++)
printf ("x%d = %lf\n", i+1 , res[i]);
}
int main(int argc, char* argv[])
{
double a[] =
{
8,-3,2,
4,11,-1,
2,1,4
};
double b[3] =
{
20,33,12
};
Solve ( a , b , 15 , 1e-10);
getchar();
return 0;
}
⑦ 急需一个运用雅可比迭代法求线性方程组的C/C++程序!
我有高斯赛德尔的,你拿过去改一改可用吧?
#include <iostream>
#include <time.h>
#include <math.h>
#include <cstdlib>
#include <fstream>
using std::cin;
using std::cout;
using std::endl;
using std::ofstream;
#define MAX 10000 // it can be changed when it is needed
double a[MAX][MAX], b[MAX], result[MAX], x[MAX], tmp[MAX], eps, temp;
int n, i, j, k;
ofstream ouc("GSresult.txt");
clock_t start, finished;
bool molus() {
for (i = 0; i < n; i++) {
for (tmp[i] = -b[i], j = 0; j < n; j++) tmp[i] += a[i][j] * x[j];
tmp[i] = fabs(tmp[i]);
}
for (i = 1; i < n; i++) if (tmp[0] < tmp[i]) tmp[0] = tmp[i];
return tmp[0] > eps;
}
int main() {
while (cin >> n >> eps) {
// the input term
srand(time(0));
for(i = 0; i < n; i++)
result[i] = (double)(rand() % 10000) / 100.0;
for(i = 0; i < n; i++) {
for(b[i] = 0, j = 0; j < n;j++) {
if (j == i) while (fabs(a[i][j]) < 1000) a[i][j] = (double) (rand() % 10000);
else {
k = (rand() % 2 == 0) ? 1 : (-1);
a[i][j] = k * (double) (rand() % 10000) / 1000.0;
}
b[i] += a[i][j] * result[j];
}
x[i] = 1.1;
}
// algorithms term
start = clock(); // clock started
k = 0;
while (molus()) {
for (i = 0; i < n; i++) {
for (temp = 0, j = 0; j < i; j++) temp += a[i][j] * x[j];
for (j = i + 1; j < n; j++) temp += a[i][j] * x[j];
x[i] = (b[i] - temp) / a[i][i];
}
k++;
}
// final version
for (i = 0, temp = 0; i < n; i++) temp += (x[i] - result[i]) * (x[i] - result[i]);
temp = sqrt(temp / n);
finished = clock(); // clock end
ouc << "When n is " << n << "; eps is " << eps << "; then the result {X} is\n\t";
for (i = 0; i < n; i++) ouc << x[i] << " ";
ouc << "\nTime is: " << finished - start << "; Precision is: " << temp << "; Iteration times are " << k << "\n\n";
}
cout << "Thank you!\n";
}
⑧ 雅克比迭代法c语言程序,急!
double
a[N][N]={
0,0,0,0,
0.78,-0.02,-0.12,-0.14,
-0.02,0.86,-0.04,0.06,
-0.12,-0.04,0.72,-0.08,
-0.14,0.06,-0.08,0.74},
你定义的N为4,4*4=16,但你初始化有20个值,建议改成4*5,或5*5
⑨ 用雅可比迭代法求解一个三阶矩阵的算法的C语言源代码
求什么3阶矩阵啊? 是求方程吧
高斯法我有,别的就没有了,你网上找找吧
double *Gauss(int n,double a[],double b[]) //数组a、b对应于线性方程组AX=B中的向量A、B
{
int i,j,k,*js,is;
double max,t;
js=malloc(n*sizeof(int)); // 开辟用于记录列交换位置的动态空间
for(k=0;k <n-1;k++)
{
max=0.0;
for(i=k;i <n;i++) // 全选主元
for(j=k;j <n;j++)
{
t=fabs(a[i*n+j]);
if(t> max)
{
max=t;
js[k]=j;
is=i;
}
}
if(max+1.0==1.0) // 如果系数矩阵奇异,就返回相关信息并退出
{
free(js);
printf( "\nHas not exclusive result or has not result!\n ");
}
else
{
if(js[k]!=k) // 列交换
for(i=0;i <n;i++)
{
t=a[i*n+k];
a[i*n+k]=a[i*n+js[k]];
a[i*n+js[k]]=t;
}
if(is!=k)
{
for(j=k;j <n;j++) //行交换
{
t=a[k*n+j];
a[k*n+j]=a[is*n+j];
a[is*n+j]=t;
}
t=b[k];
b[k]=b[is];
b[is]=t;
}
}
max=a[k*n+k];
for(j=k+1;j <n;j++) // 归一化
a[k*n+j]/=max;
b[k]/=max;
for(i=k+1;i <n;i++) // 消元
{
for(j=k+1;j <n;j++)
a[i*n+j]-=a[i*n+k]*a[k*n+j];
b[i]-=a[i*n+k]*b[k];
}
}
max=a[(n-1)*n+(n-1)];
if(fabs(max)+1.0==1.0) //如果系数矩阵奇异,就返回相关信息并退出
{
free(js);
printf( "\nHas not exclusive result or has not result!\n ");
}
b[n-1]/=max; //以下为回代,而这一步计算向量的最后一个分量
for(k=n-2;k>=0;k--)
{
t=0.0;
for(j=k+1;j<n;j++) t+=a[k*n+j]*b[j];
b[k]-=t; //这时数组b用来记录解向量,而不是原来的常数向量
}
js[n-1]=n-1; //最后一步的系数矩阵的右下角(n-k+1)阶子阵只有一个元素a[n-1][n-1],绝对值最大的当然是这个元素了
for(k=n-1;k>=0;k--)
if(js[k]!=k)
{
t=b[k];
b[k]=b[js[k]];
b[js[k]]=t;
}
free(js);
return(b);
}