2012-02-18 9 views
0

Runge Kuttaメソッドを使ってLorenzシステムを計算しようとしていますが、私のコードにエラーがある場所が見つかりません。私はそれを実行すると、システムは静的なポイントに行き、私は蝶(ロレンツアトラクター)を取得する必要があります。私はそれがルンゲクッタメソッドのセクションの 'for'loopsにあるものだと思う。ここに私のコードは、Windows上で私の編集者が持っていたようで、私はLinux上で(より簡易な方法で)再びコードを書き、それがOK走る事前にRunge Kutta in C for Lorenz equation

#include<stdio.h> 
#include<stdlib.h> 
#include<math.h> 
double f(int,double,double []); 
double s,r,b; 
FILE *output; 
int main() 
{ 
    output=fopen("lorenzdata.dat","w"); 
    int j,N=3; 
    double x[2],dt,y[2],K1[2],K2[2],K3[2],K4[2],ti,t,i; 
    printf("\n Introduce parameters s, r and b sepparated by a space:"); 
    scanf("%lf %lf %lf",&s,&r,&b); 
    printf("\n Introduce initial conditions t0,x0,y0 and z0:"); 
    scanf("%lf %lf %lf %lf",&ti,&x[0],&x[1],&x[2]); 
    printf("\n Introduce time step:"); 
    scanf("%lf",&dt); 
    printf("\n Specify time to compute in the equations:"); 
    scanf("%lf",&t); 
/* Loop para Runge Kutta 4 */ 
    do 
    { 
     /* printf("%9.4f %9.4f %9.4f %9.4f \n",ti,x[0],x[1],x[2]); */ 
     i++; 
     for(j=0;j<N;j++) 
     { 
      K1[j] = f(j,ti,x); 
     } 
     for(j=0;j<N;j++) 
     { 
      y[j] = x[j]+(K1[j]/2)*dt; 
     } 
     for(j=0;j<N;j++) 
     { 
      K2[j] = f(j,ti+dt/2,y); 
     } 
     for(j=0;j<N;j++) 
     { 
      y[j] = x[j]+(K2[j]/2)*dt; 
     } 
     for(j=0;j<N;j++) 
     { 
      K3[j] = f(j,ti+dt/2,y); 
     } 
     for(j=0;j<N;j++) 
     { 
      y[j] = x[j]+(K3[j])*dt; 
     } 
     for(j=0;j<N;j++) 
     { 
      K4[j] = f(j,ti+dt,y); 
     } 
     for(j=0;j<N;j++) 
     { 
      x[j] += dt*((K1[j]/6)+(K2[j]/3)+(K3[j]/3)+(K4[j]/6)); 
     } 
     ti +=dt; 
     fprintf(output,"%9.4f %9.4f %9.4f \n",x[0],x[1],x[2]); 
    }while(i*dt <= t); 
    fclose(output); 
    return 0; 
} 
/* Definimos la funcion */ 
double f(int m,double h,double x[]) 
{ 
    if(m==0) 
    { 
     return s*(x[1]-x[0]); 
    } 
    else if(m==1) 
    { 
     return x[0]*(r-x[2])-x[1]; 
    } 
    else if(m==2) 
    { 
     return x[0]*x[1]-b*x[2]; 
    } 
} 

おかげ

EDIT

ですコードをコンパイルしたときに無限大の値を多く投げた何か(多分エンコーディング)。なぜか分からず、それに気付くまでに多くの時間がかかりました。 あなたの助けをありがとう

+0

関数fに入力するdouble hのポイントは何ですか?それは使用されていないようです。それは必要ですか? –

+0

mm nop、diff方程式が明示的にtに依存する場合には、より一般化されたコードを作成するためにhをそこに置きます。 –

答えて

2

行が間違っています。

それは

for(j=0;j<N;j++) 
{ 
    K1[j] = f(j,ti,x[j],y[j]); 
    L1[y] = g(j,ti,x[j],y[j]); 
} 
for(j=0;j<N;j++) 
{ 
    K2[j] = f(j,ti+dt/2,x+k1[j]/2,y+L1[j]/2); 
    L2[j] = g(j,ti+dt/2,x+k1[j]/2,y+L1[j]/2); 
} 
for(j=0;j<N;j++) 
{ 
    K3[j] = f(j,ti+dt/2,x+K2[j]/2,y+L2[j]/2); 
    L3[j] = g(j,ti+dt/2,x+K2[j]/2,y+L2[j]/2); 
} 
for(j=0;j<N;j++) 
{ 
    K4[j] = f(j,ti+dt,x+K3[j],y+L3[j]); 
    L4[j] = g(j,ti+dt,x+K3[j],y+L3[j]); 
} 
for(j=0;j<N;j++) 
{ 
    x[j] += dt*((K1[j]/6)+(K2[j]/3)+(K3[j]/3)+(K4[j]/6)); 
    y[j] += dt*((L1[j]/6)+(L2[j]/3)+(L3[j]/3)+(L4[j]/6)); 
} 

ルンゲクッタはこのように動作します、のようになります。

あなたは方程式系を持っています。

DX/DT = F(T、X、Y) DY/DT = G(T、X、Y)

関数の各引数については、ルンゲ・クッタのサブステップを必要とします( k1、k2など)。 したがって、各サブステップ「k」に対して、「サブステップ」の更新されたxとyの値が必要です。第2サブステップx + k1/2およびy + l1/2の例として、

+0

Mmm ...しかし、私は関数fのj要素を考慮している。コードの最後に表示されている場合、fには3つのコンポーネントがあります。 x(x [0]、x [1]、x [2])にx、y、zがあると考えると、x [j]あなたが言うようにコードを書くと、 'for'サイクルはそこにあるべきではないと私は思う。 –

+0

それはあなたがそれを書いた方法を非常に混乱させるが、今何をしているのかを見る。問題は、dtを2倍していることです。 'x [j] + = dt *((K1 [j]/dt;)]行目で' y [j] = x [j] +(K3 [j] 6)+(K2 [j]/3)+(K3 [j]/3)+(K4 [j]/6)); 'dtで乗算する必要はありません。 – user1139069

+0

私はy [j]がf()内で評価されなければならない '更新された' x []なので、これを行う必要があると思います –

1

他の問題を無視して、変数 'i'はどこに初期化されていますか?

for(j=0;j<N;j++) 
{ 
    y[j] = x[j]+(K1[j]/2)*dt; 
} 

ように見える

+0

これはコンパイルしないでください。 'double'は' ++ '演算子を持っていません –

+0

@SethCarnegie私は(少なくとも)それをサポートする2つのコンパイラを持っています。しかし、それは少し奇妙です... – justin

+0

ああ、私は気づいていないが、とにかく、コードはまだ私に間違った出力を与える –

0

、私はあなたがそれを除いて何も悪いことだとは思わないN = 3は、X、Y、およびKsの配分が

X [3]なければならないことを意味し、Y [3]、K1 [3] .. k2 [2]、K3 [2]、K4 [2]、ti、t、i; の代わりにdouble x [2]、dt、y [2]、K1 [2]