C言語のプログラムで固有値・固有ベクトルを求める方法

このQ&Aのポイント
  • C言語のプログラムで固有値を求める場合、ヤコビ法を使用することが一般的です。
  • ヤコビ法では、与えられた行列を対角行列に変換するための回転角を計算し、行列の対角要素が固有値になるように操作します。
  • ただし、固有ベクトルの計算には注意が必要で、回転角の計算と同時に行列の列ベクトルも変換する必要があります。
回答を見る
  • ベストアンサー

C言語のプログラムで質問です。

C言語のプログラムで質問です。 ヤコビ法で固有値・固有ベクトル絵を求めたいのですが、固有値は上手く出るのですが、 固有ベクトルがめちゃくちゃな値が出ます。何が間違っているのでしょうか教えてください。下のは一応自分で作ってみたプログラムです。 #include <stdio.h> #include <math.h> #define N 4 #define PI 3.14159 void jacobi(double a[N][N], double λ[N], double v[N][N]); int main(void) { int i, j; double a[N][N], λ[N], v[N][N], x; for(i=0;i<N;i++){ printf("\n a[%d][0] a[%d][1] a[%d][2] a[%d][3]=",i,i,i,i); scanf("%lf %lf %lf %lf",&a[i][0],&a[i][1],&a[i][2],&a[i][3]); } jacobi(a, λ, v); for(j=0; j<N; j++){ printf("\n固有値λ[%d]=%lf", j, λ[j]); printf("\n固有ベクトル\n"); for(i=0; i<N; i++){ printf("%lf\n", v[i][j]); } } return 0; } /* ヤコビ法による固有値計算 */ void jacobi(double a[N][N], double λ[N], double v[N][N]) { int i, j, kmax=100, repeat, p, q; double eps, c, s,theta, gmax; double apq, app, aqq, apqmax, apj, aqj, vip, viq; gmax=0.0; for(i=0; i<N; i++){ s=0.0; for(j=i+1; j<N; j++){ s += fabs(a[i][j]); } if(s>gmax) gmax=s; } eps=0.000001*gmax; for(i=0; i<N; i++){ for(j=0; j<N; j++){ v[i][j]=0.0; } v[i][i]=1.0; } for(repeat=1; repeat<kmax; repeat++){ /* 収束判定 */ apqmax = 0.0; for(p=0; p<N; p++){ for(q=0; q<N; q++){ if(p!=q){ apq=fabs(a[p][q]); if(apq>apqmax) apqmax=apq; } } } if(apqmax<eps) break; for(p=0; p<N-1; p++){ for(q=p+1; q<N; q++){ apq=a[p][q]; app=a[p][p]; aqq=a[q][q]; if(fabs(apqmax)<eps) break; /*回転角計算*/ if(fabs(app-aqq)>=1.0e-15){ theta= 0.5*atan(2.0*apq/(app-aqq)); }else{ theta= PI/4.0; } c = cos(theta); s = sin(theta); a[p][p] = app*c*c + 2.0*apq*c*s + aqq*s*s; a[q][q] = app*s*s - 2.0*apq*c*s + aqq*c*c; a[p][q] = 0.0; a[q][p] = 0.0; for(j=0; j<N; j++){ if(j!=p && j!=q){ apj = a[p][j]; aqj = a[q][j]; a[p][j] = apj*c + aqj*s; a[q][j] = -apj*s + aqj*c; a[j][p] = a[p][j]; a[j][q] = a[q][j]; } } /*固有ベクトル*/ for(i=0; i<N; i++){ v[i][p] = v[i][p]*c+v[i][q]*s; v[i][q] = -v[i][p]*s+v[i][q]*c; } } } eps=eps*1.05; } for(i=0; i<N; i++) λ[i] = a[i][i]; }

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

> 何が間違っているのでしょうか /*固有ベクトル*/ for(i=0; i<N; i++){ v[i][p] = v[i][p]*c+v[i][q]*s; v[i][q] = -v[i][p]*s+v[i][q]*c; } forの中の1行目で値を変えた後のv[i][p]を2行目の右辺で使っている

naozerojp
質問者

お礼

直したら上手くいきました。ありがとうございます。

その他の回答 (1)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

なんか何をやっているのかよくわからんプログラムになってるなぁ.... apqmax と eps の比較はなんでこんなに必要なんだろう.

参考URL:
http://hooktail.org/computer/index.php?Jacobi%CB%A1

関連するQ&A

  • C言語のプログラムで質問です。

    C言語のプログラムで質問です。 下のプログラム(最小二乗法の計算)を実行したところ -1.#IND00 というエラーが出てしまいます。 どこを直せばいいのでしょうか、教えてください。 #include <stdio.h> #include <math.h> /* gauss33.c */ #define N 3 main(){ double A[N][N],Aa[N][N]; double b[N],x[N], bb[N], e[N]; int n=N; int i, j, k; double akk, aik, s; double y[N]; double xx,yy; for(i=0;i<n;i++){ /*変数の初期化*/ x[i]=y[i]=0; for(j=0;j<n;j++) A[i][j]=0; } for(i=0;i<5;i++){ /*データ点は5点*/ printf("\n(x,y)="); scanf("%lf,%lf",&xx,&yy); A[0][0]+=xx*xx*xx*xx; /*Σx^4*/ A[0][1]+=xx*xx*xx; /*Σx^3*/ A[0][2]+=xx*xx; /*Σx^2*/ A[0][1]=A[1][0]; A[0][2]=A[1][1]=A[2][0]; A[1][2]+=xx; /*Σx*/ A[1][2]=A[2][1]; A[2][2]=n; y[0]+=xx*xx*yy; /*Σx^2y*/ y[1]+=xx*yy; /*Σxy*/ y[2]+=yy; /*Σy*/ } /* save original coefficients */ for(i=0; i<n; i++){ for(j=0; j<n; j++){ Aa[i][j]=A[i][j]; } bb[i]=b[i]; } /* forward operation */ for(k=0; k<n-1; k++){ akk=1/A[k][k]; for (i=k+1; i<n; i++){ aik=-A[i][k]*akk; for (j=k+1; j<n; j++){ A[i][j]+=aik*A[k][j]; } b[i]+=aik*b[k]; } for(j=k+1; j<n; j++){ A[k][j]*=akk; } b[k]*=akk; } /* backward operation */ x[n-1]=b[n-1]/A[n-1][n-1]; for(k=n-2; k>=0; k--){ s=0.0; for (j=k+1; j<n; j++){ s+=A[k][j]*x[j]; } x[k]=b[k]-s; } /* chek */ for(i=0; i<n; i++){ s=0.0; for(j=0; j<n; j++){ s+=Aa[i][j]*x[j];} e[i]=s-bb[i]; printf("\nx(%d)=%f error=%f\n",i, x[i], e[i]); } }

  • C言語のプログラムで質問です。

    C言語のプログラムで質問です。 これは、2元1次連立方程式の解を求めるプログラムです。 このプログラムを (1)3元1次連立方程式の解を求めるプログラムにする (2)係数行列、定数行列(6、7行目)をキーボードからの入力にする。 ようにしたいのですが、どうすればよいでしょうか。 前半の部分を変えれば良いようなのですが分かりません。教えてください。 #include <stdio.h> #include <math.h> /* gauss22.c */ #define N 2 main(){ double A[N][N]={1.,4.,3.,2.}, Aa[N][N]; /*簡単のため係数行列を予め指定*/ double b[N]={4.,5.}, x[N], bb[N], e[N]; /*簡単のため定数ベクトルを予め指定*/ int n=2; int i, j, k; double akk, aik, s; /* save original coefficients */ for (i=0; i<n; i++){ for (j=0; j<n; j++){ Aa[i][j]=A[i][j]; } bb[i]=b[i]; } /* forward operation */ for (k=0; k<n-1; k++){ akk=1/A[k][k]; for (i=k+1; i<n; i++){ aik=-A[i][k]*akk; for (j=k+1; j<n; j++){ A[i][j]+=aik*A[k][j]; } b[i]+=aik*b[k]; } for (j=k+1; j<n; j++){ A[k][j]*=akk; } b[k]*=akk; } /* backward operation */ x[n-1]=b[n-1]/A[n-1][n-1]; for (k=n-2; k>=0; k--){ s=0.0; for (j=k+1; j<n; j++){ s+=A[k][j]*x[j]; } x[k]=b[k]-s; } /* chek */ for (i=0; i<n; i++){ s=0.0; for (j=0; j<n; j++){ s+=Aa[i][j]*x[j];} e[i]=s-bb[i]; printf("x(%d)=%f error=%f?n",i, x[i], e[i]); } }

  • C言語についての質問です。

    C言語についての質問です。 このプログラムの前半にある A[N][N]={{1,0,0},{0,1,0},{0,0,1}} b[N]={4,5,3} という行列の成分をキーボードから入力するようにする にはどうすればいいでしょうか。 for や scanf や printf を使って、変えてくれないでしょうか。 #include <stdio.h> #include <math.h> /* gauss33.c */ #define N 3 main(){ double A[N][N]={{1,0,0},{0,1,0},{0,0,1}}; double b[N]={4,5,3}; double Aa[N][N]; double x[N], bb[N], e[N]; int n=N; int i, j, k; double akk, aik, s; /* input original coefficients */ /* save original coefficients */ for(i=0; i<n; i++){ for(j=0; j<n; j++){ Aa[i][j]=A[i][j]; } bb[i]=b[i]; } /* forward operation */ for(k=0; k<n-1; k++){ akk=1/A[k][k]; for (i=k+1; i<n; i++){ aik=-A[i][k]*akk; for (j=k+1; j<n; j++){ A[i][j]+=aik*A[k][j]; } b[i]+=aik*b[k]; } for(j=k+1; j<n; j++){ A[k][j]*=akk; } b[k]*=akk; } /* backward operation */ x[n-1]=b[n-1]/A[n-1][n-1]; for(k=n-2; k>=0; k--){ s=0.0; for (j=k+1; j<n; j++){ s+=A[k][j]*x[j]; } x[k]=b[k]-s; } /* chek */ for(i=0; i<n; i++){ s=0.0; for(j=0; j<n; j++){ s+=Aa[i][j]*x[j];} e[i]=s-bb[i]; printf("\nx(%d)=%f error=%f\n",i, x[i], e[i]); } }

  • ガウスの掃き出し法によるC++プログラム

    大学で、ガウスーヨルダンの掃き出し法により連立方程式を解き、係数マトリクスの逆行列と解を表示するプログラムを作れ、という課題が出ました。 4s+t+3u+2v=23 s+4t+3u+3v=30 5s+5t+10u+5v=65 4s+4t+2u+6v=42 という問題です。 まったく素人の状態から4時間ほどやったくらいでこの問題が出たので、解き方が全くわからなかったのですが、いろいろなサイトを巡ってこのようなプログラムを作りました。 #include <stdio.h> #include <float.h> #define N 4 /* 行列の行数および列数 */ double A[N][N] = { { 4.0,1.0,3.0,2.0}, /* 係数行列 A の定義 */ {1.0,4.0,3.0,3.0}, {5.0,5.0,10.0,5.0}, {4.0,4.0,2.0,6.0}}; double b[N] = {23.0,30.0,65.0,42.0}; /* 定数ベクトル b の定義 */ void Gauss_J( int, double*, double* ); void main( void ) { int i; /* カウンタ */ printf( "%d元連立一次方程式\n", N ); for( i = 0; i < N ; i++ ) { printf( "%g s + %g t + %g u + %g v = %g \n", A[i][0], A[i][1], A[i][2],A[i][3], b[i] ); } printf("の解は,\n" ); Gauss_J( N, (double *)A, (double *)b ); /* ガウス・ジョルダン法で解く */ printf( "s = %g \n", b[0] ); printf( "t = %g \n", b[1] ); printf( "u = %g \n", b[2] ); printf( "v = %g \n", b[3] ); } void Gauss_J( int n, double *a, double *b ) { int p, i, j, l ; /* カウンタ */ double pivot, c ; /* ピボット値 */ for ( p = 0 ; p < n ; p++ ) /* 1行目から n行目まで繰り返す */ { pivot = a[ p*n + p ]; /* ピボットを取得する */ for ( i = p ; i < n ; i++ ) /* p行目の p列目から n列目まで */ { a[ p*n + i ] /= pivot; /* 係数行列の p行を pivotで割る */ } b[ p ] /= pivot; /* 定数ベクトルの p行を pivotで割る */ for ( l = 0 ; l < n ; l++ ) /* 1行目から n行目まで */ { if ( l != p ) /* p行を除いて */ { c = a[ l*n + p ]; /* 掃き出す */ for ( j = p ; j < n ; j++ ) { a[ l*n + j ] -= c * a[ p*n + j ]; } b[ l ] -= c * b[ p ]; } } } return ; } これで行列の解は出るようになったのですが、逆行列が表示されてません。 どうすれば表示されるようになるのでしょうか?

  • c言語です。

    c言語です。 実行結果 式 3 X1 + 2 X2 + 1 X3 = &g 2 X1 + 5 X2 + 2 X3 = &g 1 X1 + 4 X2 + 1 X3 = &g 解 X1 = 1 X2 = 2 X3 = 3 を 式 3 X1 + 2 X2 + 1 X3 = 10 2 X1 + 5 X2 + 2 X3 = 18 1 X1 + 4 X2 + 1 X3 = 12 解 X1 = 1 X2 = 2 X3 = 3 に直したいのですが&gの所をどのようにしたら10.18.12になりますか? #include <stdio.h> #include <float.h> #define N 3 double A[N][N] = {{3,2,1}, {2,5,2}, {1,4,1}}; double b[N] = { 10, 18, 12 }; void Gauss_J( int, double*, double* ); void main(void) { int i; printf( "%d式\n", N ); for( i = 0; i < N ; i++ ) { printf( "%g X1 + %g X2 + %g X3 = &g \n", A[i][0], A[i][1], A[i][2], b[i] ); } printf("解\n"); Gauss_J(N, (double *)A, (double *)b ); printf("X1 = %g \n", b[0]); printf("X2 = %g \n", b[1]); printf("X3 = %g \n", b[2]); } void Gauss_J(int n, double *a, double *b) { int p, i, j,I ; double pivot, c ; for ( p = 0 ; p < n ; p++ ) { pivot = a[ p*n + p ]; for ( i = p ; i < n ; i++ ) { a[ p*n + i ] /= pivot; } b[ p ] /= pivot; for ( I = 0 ; I < n ; I++) { if (I != p) { c = a[ I*n + p]; for ( j = p ; j < n; j++ ) { a[ I*n + j] -= c * a[ p*n + j ]; } b[ I ] -= c * b[ p ]; } } } return ; }

  • C言語でのFFTについて

    http://tsuyu.cocolog-nifty.com/blog/2007/03/publi.html に掲載されているVBAのFFTプログラムをC言語に書き換えて 実行しているのですがうまくいきません。 どこが、間違っているか教えてください。 ======以下FFTのサブルーチンソースコード===== void FFT(float Xr[], float Xi[]) { i=0,j=0,k=0,l=0,m=0,n=0,p=0,q=0; n=DN; m = log10(n)/log10(2); Table(c,s); l=n,h=1; for(g=1;g<=m;g++){ l/=2,k=0; for(q=1;q<=h;q++){ p=0; for(i=k;i<=l+k-1;i++){ j=i+l; a=Xr[i]-Xr[j], b=Xi[i]-Xi[j]; Xr[i] = Xr[i] + Xr[j], Xi[i] = Xi[i] + Xi[j]; if(p==0){ Xr[j]=a,Xi[j]=b; }else{ Xr[j] = a * c[p] + b * s[p], Xi[j] = b * c[p] - a * s[p]; } p+=h; } k+=l+l; } h+=h; } j=n/2; for(i=1;i<=n-1;i++){ k=n; if(j<i){ //ビットリバース swap(&Xr[i],&Xr[j]); swap(&Xi[i],&Xi[j]); } k=k/2; while(j>=k){ j=j-k; k /=2; } j = j + k; } }

  • C++についての質問です

    プログラミング初心者です 以下の通りに正方行列の積を求めるプログラムを作成したのですが、うまくいきません。 #include<stdio.h> #define DTM 20 void InputMatrix(double[][DTM], int, char); void PrintMatrix(double[][DTM], int, char); void MatrixMulti(double[][DTM], double[][DTM], double[][DTM], int); int main(void) { double matrixA[DTM][DTM]; double matrixB[DTM][DTM]; double matrixC[DTM][DTM]; int n; printf("正方行列の積を求めるプログラムです\n"); printf("正方行列の次元を入れてください(<=20):"); scanf_s("%d", &n); InputMatrix(matrixA, n, 'A'); InputMatrix(matrixB, n, 'B'); MatrixMulti(matrixA, matrixB, matrixC, n); printf("\n行列 C =A×B\n"); PrintMatrix(matrixC, n, 'C'); return 0; } void InputMatrix(double a[][DTM], int n, char ch) { int i, j; printf("行列 %cの入力\n", ch); for (i = 0; i < n;i++) { for (j = 0;j < n;j++) { printf("%c[%d][%d] =", ch, i + 1, j + 1); scanf_s("%lf", &a[i][j]); } } } void PrintMatrix(double a[][DTM], int n, char ch) { int i, j; printf("行列 %c の出力\n", ch); for (i = 0;i < n;i++) { for (j = 0;j < n;j++) { printf("%5.2f\t", a[i][j]); } printf("\n"); } } void MatrixMulti(double a[][DTM], double b[][DTM], double c[][DTM], int n) { int i, j, k; for (i = 0;i < n;i++) { for (j = 0;j < n;j++) { c[i][j] = 0; for (k = 0;k < n;k++) { c[i][j] =a[i][k] * b[k][j]; } printf("%5.2f\t",c[i][j]); } printf("\n"); } }

  • プログラムの間違いを教えてください。

    VBAのFFTのプログラムをCで書き直しています。 C言語ではうまく動作しません。間違いを教えていただけないでしょうか? よろしくお願いします。 (1)動くVBAのプログラム(参照 http://tsuyu.cocolog-nifty.com/blog/2007/03/publi.html) Option Explicit Public Sub fft() Dim g, h, i, j, k, l, m, n, o, p, q As Integer i = 0 j = 0 k = 0 l = 0 p = 0 h = 0 g = 0 q = 0 'データ数nを指定(2の整数乗である必要あり) n = 1024 m = Log(n) / Log(2) 'xr,xiはデータ数以上、s,cはデータ数の半分以上を指定しておく Dim xr(1024), xi(1024), xd, s(512), c(512), a, b As Single 'データの読み込み 1列目を実数部、2列目を虚数部とする For i = 1 To n xr(i - 1) = Cells(i, 1) xi(i - 1) = Cells(i, 2) Next i 'FFTの計算 a = 0 b = 3.14159265359 * 2 / n For i = 0 To n / 2 s(i) = Sin(a) c(i) = Cos(a) a = a + b Next i l = n h = 1 For g = 1 To m l = l / 2 k = 0 For q = 1 To h p = 0 For i = k To l + k - 1 j = i + l a = xr(i) - xr(j) b = xi(i) - xi(j) xr(i) = xr(i) + xr(j) xi(i) = xi(i) + xi(j) If p = 0 Then xr(j) = a: xi(j) = b Else xr(j) = a * c(p) + b * s(p) xi(j) = b * c(p) - a * s(p) End If p = p + h Next i k = k + l + l Next q h = h + h Next g j = n / 2 For i = 1 To n - 1 k = n If j < i Then xd = xr(i) xr(i) = xr(j) xr(j) = xd xd = xi(i) xi(i) = xi(j) xi(j) = xd End If k = k / 2 Do While j >= k j = j - k k = k / 2 Loop j = j + k Next i 'データの出力 For i = 1 To n '4列目に実数部、5列目に虚数部、6列目に絶対値を表示 Cells(i, 4) = xr(i - 1) Cells(i, 5) = xi(i - 1) Cells(i, 6) = (xr(i - 1) ^ 2 + xi(i - 1) ^ 2) ^ 0.5 Next i End Sub (2)上記のプログラムの書き換えている箇所 For i = 1 To n xr(i - 1) = Cells(i, 1) xi(i - 1) = Cells(i, 2) Next i 'FFTの計算 a = 0 b = 3.14159265359 * 2 / n For i = 0 To n / 2 s(i) = Sin(a) c(i) = Cos(a) a = a + b Next i l = n h = 1 For g = 1 To m l = l / 2 k = 0 For q = 1 To h p = 0 For i = k To l + k - 1 j = i + l a = xr(i) - xr(j) b = xi(i) - xi(j) xr(i) = xr(i) + xr(j) xi(i) = xi(i) + xi(j) If p = 0 Then xr(j) = a: xi(j) = b Else xr(j) = a * c(p) + b * s(p) xi(j) = b * c(p) - a * s(p) End If p = p + h Next i k = k + l + l Next q h = h + h Next g j = n / 2 For i = 1 To n - 1 k = n If j < i Then xd = xr(i) xr(i) = xr(j) xr(j) = xd xd = xi(i) xi(i) = xi(j) xi(j) = xd End If k = k / 2 Do While j >= k j = j - k k = k / 2 Loop j = j + k Next i (3)書き換えたけど変な値が発生するプログラム #include <stdio.h> #include <conio.h> #include <string.h> #include <stdlib.h> #include <math.h> FILE *fp; FILE *fa; char a[100]; double b[1200]; double c[1200]; double d[1200]; double e[1200]; double f[1200]; char str[100]; char *p; double h; long i; long j; long k; long l; int m; long n; long o; int q; double x[25]; long s; double t; double u[1200]; double v[20][1200]; double v2[20][1200]; double v3[20][1200]; double w[25]; double intercept[10]; double slope[10]; double frequency[12]; double dtime; double dtime2; double theta1; double theta2; double co[1200]; double si[1200]; double xd; long l2; long l3; long n3; long h3; long g3; long m3; long k3; long p3; long q3; long i3; long j3; long x3; double y3; double a3; double b3; double c3; double d3; double f3; double w2[25]; x3=0; y3=0; i3=0; j3=0; k3=0; l3=0; p3=0; h3=0; g3=0; q3=0; a3=0; b3=0; c3=0; d3=0; theta1=0; theta2=3.14159265359*2/1024; for(l=0; l<=512; l++){ si[l]=sin(theta1); co[l]=cos(theta1); theta1=theta1+theta2; } n3=1024; m3=10; l3=n3; h3=1; for(g3=1; g3<=m3; g3++){ l3=l3/2; k3=0; for(q3=1; q3<=h3; q3++){ p3=0; for(i3=k3; i3<(l3+k3); i3++){ j3=i3+1; theta1=c[i3]-c[j3]; theta2=d[i3]-d[j3]; if(p3==0){ c[j3]=theta1; d[j3]=theta2; } else{ c[j3]=theta1*co[p3]+theta2*si[p3]; d[j3]=theta2*co[p3]-theta1*si[p3]; } p3=p3+h3; } k3=k3+l3+l3; } h3=h3+h3; } j3=n3/2; for(i3=1; i3<n; i3++){ k3=n3; if(j3<i3){ xd=c[i3]; c[i3]=c[j3]; c[j3]=xd; xd=d[i3]; d[i3]=d[j3]; d[j3]=xd; } k3=k3/2; while(j3>=k3){ j3=j3-k3; k3=k3/2; } j3=j3+k3; } for(i3=0; i3<n3; i3++){ c[i3]=c[i3]/1024; d[i3]=d[i3]/1024; } (1)中の(2)箇所を(3)のように書き換えました。 どうしてもうまく動作しません。 教えていただけないでしょうか? よろしくお願いいたします。

  • C言語について質問です

    C言語について質問です #include <stdio.h> int main(){ int i,j; double a[8][8],p[8][8],x[8]; for(i=0;i<8;i++){ for(j=0;j<8;j++){ a[i][j]=0.0; } } x[8]={0.182289,0.063801,0.125440,0.097210,0.128485,0.080488,0.189581,0.132706}; p[8][8]={{0,25,24,14,19,5,25,10}, {24,0,50,52,15,40,20,11}, {59,18,0,35,37,24,45,12}, {34,3,28,0,22,51,43,3}, {29,31,21,33,0,22,30,15}, {37,7,75,24,38,0,28,31}, {40,8,32,15,16,21,0,21}, {26,28,28,25,24,18,36,0}}; for(i=0;i<8;i++){ for(j=0;j<8;j++){ a[i][j]=1-(x[i]/(x[i]+x[j]))/(p[i][j]/(p[i][j]+p[j][i])); printf("%f\n",a[i][j]); } } } がコンパイル出来ません。コンパイラはvisual stadio2008です。 ご指摘お願いします。

  • C++言語のプログラムをfortranに変換

    const int N = 100; const double q = 10.0, dt = 0.00001, Dm = 30.0, t0 = 2.0, K = 1.0, pi = 3.141592, f = 3.0; double C[N], dC[N]; double dx = q/N; for (int i = 0; i < N; ++i) C[i] = 0; // 初期条件 for (double t = 0; t < t0; t += dt) {  C[0] = 0; // 境界条件1  C[N - 1] = K*sin(2*pi*f*t); // 境界条件2  for (int i = 1; i < N - 1; ++i) dC[i] = (Dm*(C[i + 1] - 2*C[i] + C[i - 1])/(dx*dx))*dt;  for (int i = 1; i < N - 1; ++i) C[i] += dC[i]; } for (int i = 0; i < N; ++i) cout << C[i] << endl; // t = t0 このプログラムをfortranに変換できる方いますか?