jacobi迭代法c語言
A. 急需一個運用雅可比迭代法求線性方程組的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";
}
B. 雅克比迭代法求解線性方程組的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語言,關於雅可比法求矩陣的特徵值和特徵向量的迭代次數
如果把所有非對角元掃描一遍作為一次迭代,那麼幾步迭代後就能收斂,換句話說需要O(n^2)步旋轉才能收斂,因為Jacobi演算法具有漸進二次收斂性。
Jacobi演算法一般比較慢,但是如果慢的過分一般來講是你的代碼有問題,你可以把非對角元的平方和輸出出來觀察一下收斂速度。
D. Jacobi迭代法和Gauss-Seidel迭代法有什麼區別
迭代公式有點差別,計算精度也不相同。
E. 雅克比迭代法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
F. 用C語言編譯雅可比迭代法,程序總是無法運行,為什麼
在c語言中數組說明的一般形
式為:
類型說明符
數組名
[常量表達式],……;
其中,類型說明符是任一種基本數據類型或構造數據類型。
數組名是用戶定義的數組標識符。
方括弧中的常量表達式表示數據元素的個數,也稱為數組的長度。例如:
int
a[10];
說明整型數組a,有10個元素。
float
b[10],c[20];
說明實型數組b,有10個元素,實型數組c,有20個元素。
char
ch[20];
說明字元數組ch,有20個元素。
對於數組類型說明應注意以下幾點:
1.數組的類型實際上是指數組元素的取值類型。對於同一個數組,其所有元素的數據類型都是相同的。
2.數組名的書寫規則應符合標識符的書寫規定。
3.數組名不能與其它變數名相同,例如:
void
main()
{
int
a;
float
a[10];
……
}
是錯誤的。
4.方括弧中常量表達式表示數組元素的個數,如a[5]表示數組a有5個元素。但是其下標從0開始計算。因此5個元素分別為a[0],a[1],a[2],a[3],a[4]。
5.不能在方括弧中用變數來表示元素的個數,
但是可以是符號常數或常量表達式。例如:
#define
fd
5
void
main()
{
int
a[3+2],b[7+fd];
……
}
是合法的。但是下述說明方式是錯誤的。
void
main()
{
int
n=5;
int
a[n];
……
}
明白了吧你所定義的數組的個數n是變數,而規定中必須是常量的,另外這一行少了"*"號
else
y[i]=(b[i]-a[i][j]x[i])/a[i][i];
應該為else
y[i]=(b[i]-a[i][j]*x[i])/a[i][i];
G. 雅可比迭代法的工作原理
雅克比迭代法就是眾多迭代法中比較早且較簡單的一種,其命名也是為紀念普魯士著名數學家雅可比。雅克比迭代法的計算公式簡單,每迭代一次只需計算一次矩陣和向量的乘法,且計算過程中原始矩陣A始終不變,比較容易並行計算。
概念
考慮線性方程組Ax =b時,一般當A為低階稠密矩陣時,用主元消去法解此方程組是有效方法。但是,對於由工程技術中產生的大型稀疏矩陣方程組(A的階數很高,但零元素較多,例如求某些偏微分方程數值解所產生的線性方程組),利用迭代法求解此方程組就是合適的,在計算機內存和運算兩方面,迭代法通常都可利用A中有大量零元素的特點。雅克比迭代法就是眾多迭代法中比較早且較簡單的一種,其命名也是為紀念普魯士著名數學家雅可比。
折疊編輯本段迭代過程
迭代過程
首先將方程組中的系數矩陣A分解成三部分,即:A = L+D+U,如圖1所示,其中D為對角陣,L為下三角矩陣,U為上三角矩陣。
之後確定迭代格式,X^(k+1) =B*X^(k) +f,(這里^表示的是上標,括弧內數字即迭代次數),如圖2所示,其中B稱為迭代矩陣,雅克比迭代法中一般記為J。(k = 0,1,......)
再選取初始迭代向量X^(0),開始逐次迭代。
折疊編輯本段收斂性
設Ax= b,其中A=D+L+U為非奇異矩陣,且對角陣D也非奇異,則當迭代矩陣J的譜半徑ρ(J)<1時,雅克比迭代法收斂。
折疊編輯本段優缺點
雅克比迭代法的優點明顯,計算公式簡單,每迭代一次只需計算一次矩陣和向量的乘法,且計算過程中原始矩陣A始終不變,比較容易並行計算。然而這種迭代方式收斂速度較慢,而且占據的存儲空間較大,所以工程中一般不直接用雅克比迭代法,而用其改進方法。
折疊編輯本段程序實現示例
#include<stdio.h>
#include<math.h>
#include <stdlib.h>
main(){
float e=0.001,z,m,a[3][3]={5,2,1,-1,4,2,2,-3,10},b[3]={-12,20,3},x[3]={0,0,0},y[3];
int n=3,j,i,k=1;
while(1) {
for(i=0;i<3;i++) {
for(j=0;j<3;j++)
m=m+a[i][j]*x[j];
m=m-x[i]*a[i][i];
y[i]=(b[i]-m)/a[i][i];
m=0;
}
i=0;
while(i<3) {
z=fabs(x[i]-y[i]);
if(z>e)
break;
i++;
}
if(i!=3) {
for(i=0;i<3;i++)
x[i]=y[i];
k++;
}
else if(i==3)
break;
}
printf("%f %f %f ",y[0],y[1],y[2]);
}
H. 求雅可比迭代法解方程組的C\C++程序
/************************************
下面程序是解下面這個方程:(可以改變方程系,程序即可解不同的方程)
方程:
5x1+2x2+x3=8
2x1+8x2-3x3=21
x1-3x2-6x3=1
用VC6.0編譯,保存代碼時,以.C為後綴名
************************************/
#include<malloc.h>
#include<stdio.h>
#include<conio.h>
#include<math.h>
#define EPS 1e-6/*允許誤差*/
#define MAX 100/*迭代次數的最大值*/
float *Jacobi(float a[3][4],int n);
main()
{
int i;
float a[3][4]={5,2,1,8,2,8,-3,21,1,-3,-6,1};/*方程的系數*/
float *x;
x=(float *)malloc(3*sizeof(float));/*動態申請內存,用於保存方程的解*/
x=Jacobi(a,3);/*調用雅可比函數*/
for(i=0;i<3;i++)/*輸出方程的解*/
{
printf("x[%d]=%f\t",i,x[i]);
}
printf("\n");
getch();
}
float *Jacobi(float a[3][4],int n)
{
float *x,*y;
float epsilon,s;
int i,j,k=0;
x=(float *)malloc(n*sizeof(float));
y=(float *)malloc(n*sizeof(float));
for(i=0;i<n;i++)
x[i]=0;
while(1)
{
epsilon=0;/*容允誤差*/
k++;/*迭代次數計數*/
for(i=0;i<n;i++)
{
s=0;
for(j=0;j<n;j++)
{
if(j==i)
{
continue;
}
s+=a[i][j]*x[j];
}
y[i]=(a[i][n]-s)/a[i][i];/*計算"x^(k+1)"*/
epsilon+=(float)fabs(y[i]-x[i]);
}
if(epsilon<EPS)
{
printf("迭代次數為:%d\n",k);
return x;/*返回方程的解*/
}
if(k>=MAX)
{
printf("方程不收斂\n");
return y;
}
for(i=0;i<n;i++)
{
x[i]=y[i];
}
}
}
I. 網上找的用C語言實現的雅克比迭代法,顯示一個錯誤哪裡有錯
主函數和各個函數都沒有返回值,可以把函數類型改為void就沒有事了 。如主函數寫成:
void main()
其他的函數名前的float寫成void