① 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);
}