二次元空間におけるフーリエサイン変換のプログラミング(C)について
- 二次元のフーリエサイン変換を行うプログラムです。
- 正方形の中心に高い数値を持つ状況を作り、その波数分布を示したいという目標があります。
- 現在のプログラムでは、変換した値が一様に0となってしまう問題が発生しています。
- ベストアンサー
二次元空間におけるフーリエサイン変換のプログラミング(C)について
二次元のフーリエサイン変換を考えています。 正方形の中心にだけ高い数値を持つ状況をつくり、その波数分布を示したい(最終目標は違いますが・・・)のですがうまくいきません。 下記のように書いてみましたが、コンパイルは通っても、変換した値が一様に0となってしまいます。 よろしければ、見てやってください。 #include<stdio.h> #include<math.h> #define max 100 #define pi 3.141592 main() { //変数i,jが位置、ki,kjが波数に当たります int i,j,ki,kj; //Nはデータ点の数 int N=30; double a[max][max]; double A[max][max]; //aの分布をデルタ関数的なものとします。 for(i=0;i<N;i++){ for(j=0;j<N;j++){ a[i][j]=0; }} a[N/2+1][N/2+1]=100; for(ki=0;ki<N;ki++){ for(kj=0;kj<N;kj++){A[ki][kj]=0.0; for(i=0;i<N;i++){ for(j=0;j<N;j++){ A[ki][kj] += (2/N)*(2/N)*a[i][j]*sin((2*pi*ki*i)/N)*sin((2*pi*kj*j)/N); }}}} return(0); }
- kanchan22
- お礼率33% (2/6)
- C・C++・C#
- 回答数1
- ありがとう数1
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
>A[ki][kj] += (2/N)*(2/N)*a[i][j]*sin((2*pi*ki*i)/N)*sin((2*pi*kj*j)/N); の式の右辺の一部は、doubleで計算されない。 「(2/N)*(2/N)」の部分の定数はすべてintであるので、ここはintで計算される。 intでは「2/30」は0である。 従って、上記の式は A[ki][kj] += 0*0*a[i][j]*sin((2*pi*ki*i)/N)*sin((2*pi*kj*j)/N); と等価である。 0に何を掛けても0なので、結局は A[ki][kj] += 0; と等価である。 A[ki][kj] += (2.0/(double)(N))*(2.0/(double)(N))*a[i][j]*sin((2.0*pi*(double)(ki)*(double)(i))/(double)(N))*sin((2.0*pi*(double)(kj)*(double)(j))/(double)(N)); と書かねばならない。 それと「A配列の中身が未初期化」なので for(i=0;i<N;i++){ for(j=0;j<N;j++){ a[i][j]=0; }} を for(i=0;i<N;i++){ for(j=0;j<N;j++){ a[i][j]=0; A[i][j]=0; }} にして、A配列も初期化すること。
関連するQ&A
- 逆離散フーリエ変換
逆フーリエ変換でもとの波形を作りたいです。 http://www.geocities.jp/supermisosan/fourier.html を参考にしました。 ///参考URLの逆フーリエ変換プログラム #include <stdio.h> #include <math.h> #define max 10000 //Nの最大限度数 #define pi 3.1415926535 //円周率 int main() { int i,k,n,N; double Ref,Imf; double ReF[max+1],ImF[max+1]; FILE *fourier; FILE *inversef; //逆フーリエ変換したいデータをあらかじめfourier.dataに保存しておく fourier=fopen("fourier.data","r"); inversef=fopen("inversef.data","w"); //データの読み込み。 for(N=0;N<max;N++) { if(fscanf(fourier,"%d %lf %lf",&i,&ReF[N],&ImF[N]) == EOF) { N--; break; } } //フーリエ逆変換 for(k=0;k<N;k++) { Ref=Imf=0.0; for(n=0;n<N;n++) { Ref+=(ReF[n]*cos(2*pi*k*n/N)-ImF[n]*sin(2*pi*k*n/N))/N; Imf+=(ReF[n]*sin(2*pi*k*n/N)+ReF[n]*sin(2*pi*k*n/N))/N; } fprintf(inversef,"%d %f %f\n",k,Ref,Imf); } fclose(fourier); fclose(inversef); return 0; } ////// Refが実数部分の値で、Imfが虚数部分の値になるのですが、 どうしたら元の波形データが得られるのかがわかりません。 教えて頂けたら幸いです。
- 締切済み
- C・C++・C#
- 一次元のフーリエ変換(FFT)
フーリェ変換について勉強しているものです。このページ(http://www.kurims.kyoto-u.ac.jp/~ooura/fftman/ftmndl.html)で配布している、fft.tgz (71 KB)というファイルのdfst()という関数を使おうと思っているんですが、その関数の返り値(返り配列と言った方が正しい?)の詳しい意味がよくわからないのです。 以下はこの関数のマニュアル(readme.txt)の一部です。 dfst()の大まかな処理内容を示しています。 --------------------------------------------------------- 以下の変換は : S[k] = sum_j=1^n-1 a[j]*sin(pi*j*k/n), 0<k<n このように分割される : S[2*k] = sum_j=1^n/2-1 (a[j]-a[n-j])*sin(pi*j*k/(n/2)), ◎ S[2*k+1] = sum'_j=1^n/2 (a[j]+a[n-j])*sin(pi*j*(k+1/2)/(n/2)) 注意:sum_■^▲はΣを表しており、■から▲までの部分和となっています。 nは要素数です。 ------------------------------------------------------ この◎の配列はどのような意味を持つのでしょうか?
- 締切済み
- C・C++・C#
- FFTをc言語でプログラミング
助けてください↓c言語でFFTをプログラミングしているのですがバグが発見できずに困り果て居ます。 プログラミングは以下の通りです。画像はカラーではなく、グレースケールのMANDRILLに対して行っています。 for(n=0;n<M;n++){ for(i=0;i<N;i++){ for(j=0;j<N;j++){ Imbatx[n][i][j]=0; } } } //行FFT //まずはソート for(i=0;i<N;i++){ int x=1; for(j=0;j<N;j++){ if(j<N/2){ //左半分 if(j%2!=0) //jが奇数 batx[0][i][j]=imagein[i][j+N/2-1]; if(j%2==0) //jが偶数 batx[0][i][j]=imagein[i][j]; } if(N/2<=j && j<N){ //右半分 if(j%2!=0) //jが奇数 batx[0][i][j]=imagein[i][x+N/2-1]; if(j%2==0) //jが偶数 batx[0][i][j]=imagein[i][x]; x++; } } } for(i=0;i<N;i++){ for(n=1;n<M+1;n++){ k=0; for(j=0;j<N;j++){ mul=(int)pow(2.0,(double)n); if(j%mul < mul/2){ //偶数列 batx[n][i][j] = batx[n-1][i][j]+cos(2*PI*k/mul)*batx[n-1][i][j+mul/2]- sin(2*PI*k/mul)*Imbatx[n-1][i][j+mul/2]; Imbatx[n][i][j]=Imbatx[n-1][i][j]+sin(2*PI*k/mul)*batx[n-1][i][j+mul/2]+ cos(2*PI*k/mul)*Imbatx[n-1][i][j+mul/2]; k++; } else{ //奇数列 batx[n][i][j] = cos(2*PI*k/mul)*batx[n-1][i][j] + batx[n-1][i][j-mul/2]- sin(2*PI*k/mul)*Imbatx[n-1][i][j]; Imbatx[n][i][j]=Imbatx[n-1][i][j-mul/2]+sin(2*PI*k/mul)*batx[n-1][i][j]+cos(2*PI*k/mul)*Imbatx[n-1][i][j]; k++; } Re_countx[i][j] = batx[M][i][j]; Im_countx[i][j] = Imbatx[M][i][j]; } } } for(i=0;i<N;i++){ for(j=0;j<N;j++){ FFT[i][j]=pow(pow(Re_countx[i][j],2)+pow(Im_countx[i][j],2),0.5); FFT[i][j]=log10(FFT[i][j]); if(FFT[i][j]>max) max=FFT[i][j]; imageout[i][j]=(unsigned char)255*FFT[i][j]/max; } } 結果的に出力される画像は以下の画像になります。 ごらんのように縞模様が出てしまいます。 分かる方どうかお願いいたします。
- 締切済み
- C・C++・C#
- C言語 プログラミング 行列演算
下記のプログラムのおかしい点と解決法を教えてください。 コンパイルは通りますがうまく動きません。。 #include<stdio.h> #define MAX 500 int main(void){ int matrA[MAX][MAX],matrB[MAX][MAX],matrC[MAX][MAX],l,m,n,i,j,k; printf("lとmを入力してください:"); scanf("%d",&l); scanf("%d",&m); printf("行列Aを入力してください"); for(i=0;i<l;i++){ printf(">"); for(j=0;l<m;j++){ scanf("%d",&matrA[i][j]); } printf("\n"); } printf("nを入力してください(m = %d):",m); scanf("%d",&n); printf("行列Bを入力してください"); for(i=0;i<m;i++){ printf(">"); for(j=0;j<n;j++){ scanf("%d",&matrB[i][j]); } printf("\n"); } printf("C=\n"); for(i=0;i<l;i++){ for(j=0;j<n;j++){ for(k=0;k<m;k++){ matrC[i][j]+=matrA[i][k]*matrB[k][j]; } printf("%d",matrC[i][j]); } printf("\n"); } }
- ベストアンサー
- C・C++・C#
- Visual C++でのプログラミング
学校でプログラミングの課題が出たので自分のパソコンに Microsoft Visual C++ 2010 Express をインストールして作ってみました。 それが以下のプログラムです。 これは任意の値nを入力してa[n]までの配列をつくり それを降順に並び替えるものです。 #include <stdio.h> #define N 10000 int main(){ int a[N],i,j,max,min,n,temp; n=0; printf("n="); scanf("%d",n); if(N<n){ return 0; } else if(n<=0){ return 0; } else if(n<=N){ for(i=0;i<=n;i++){ printf("a[%d]",i); scanf("%d\n",&a[i]); } max=min=a[0]; for(i=1;i<n;i++){ if(max<a[i]){ max=a[i]; } else if(min>a[i]){ min=a[i]; } } printf("a[i]のソート結果\n"); for(i=0;i<n;i++);{ for(j=i+1;j<n;j++){ if(a[i]<a[j]){ temp=a[i]; a[i]=a[j]; a[j]=temp; } } } for(i=0;i<n;i++){ printf("a[i]=%d\n",a[i]); } printf("Max=%d\n",max); printf("Min=%d\n",min); } } これをVisual C++でデバックすると 『test.exeの0x0fcbe42e(msvcr100d.dll)にハンドルされていない例外が発生しました:0C0000005: 場所 0x00000000 に書き込み中のアクセス違反が発生しました。』 と表示されて実行できません。 今日インストールしたばかりなのでどこでエラーが起きているのかわかりません。 これはプログラミングとVisual C++のどっちが原因なのでしょうか? もしお分かりになるならば、具体的な解決方法や プログラムの訂正点などを教えていただきたいです。
- ベストアンサー
- C・C++・C#
- プログラミングCの質問です
現在10×10の市松模様を表示させるというプログラムを作成しています。 #define文、IF文、for文の使用、printfを使って■と□を表示させることが条件です。 間違っているところの指摘をお願いします。 #include <stdio.h> #define N 10 int main(void) { for( i=1 ; i<=N ; ++i ) { for( j=1 ; j<=N ; ++j ) } if( (i+j) % 2 ){ printf("■"); }else printf("□"); } printf("\n"); i++; } return 0; }
- 締切済み
- C・C++・C#
- 離散フーリエ変換(DFT)のプログラム
タイトルの通りのレポートを出されたのですが、その問題に似たサンプルソースすら何をいっているのかわからない状態です。ひとまず、サンプルソースが何をいっているのか理解したいので、いくつか教えてください。 ソースです。質問はその後に書かせてもらいました。 #include<stdio.h> #include<math.h> #define N 10 #define F 0.1 #define PI 3.14151692 #define SQR(x) ((x)*(x)) void func() { int n; FILE *fp; fp=fopen("temporal.data","w"); for(n=0;n<N;n++) fprintf(fp,"%lf\n",cos(2.0*PI*F*(double)n)); fclose(fp); } void get_data(double x[]) { int n; FILE *fp; fp=fopen("temporal.data","r"); for(n=0;n<N;n++) fscanf(fp,"%lf",&x[n]); fclose(fp); } void dft(double x[],double X_r[],double X_i[]) { int k,n; for(k=0;k<N;k++){ X_r[k]=X_i[k]=0.0; for(n=0;n<N;n++){ X_r[k]+=x[n]*cos(2.0*PI*(double)n*(double)k/(double)N); X_i[k]-=x[n]*sin(2.0*PI*(double)n*(double)k/(double)N); } } for(k=0;k<N;k++) printf("X[%d]=%lf+j%lf\n",k,X_r[k],X_i[k]); } void amplitude(double X_r[],double X_i[]) { int k; FILE *fp; double amp; fp=fopen("amp.data","w"); for(k=0;k<N;k++){ amp=sqrt(SQR(X_r[k])+SQR(X_i[k])); fprintf(fp,"%lf\n",amp); } fclose(fp); } main() { double x[N],X_r[N],X_i[N]; func(); get_data(x); dft(x,X_r,X_i); amplitude(X_r,X_i); } 文字数の制限があるみたいなので、質問を別にさせてもらいます。
- 締切済み
- C・C++・C#
- C言語のプログラミングで質問です
C言語のプログラミングで質問です. 時間を測ろうと下記のようなプログラムをしてみましたが計測時間がoTime, nTime共に0.000になってしまいます.(winmm.libはリンクさせてます) おかしいところはどこでしょうか? #include<stdio.h> #include<time.h> #include<windows.h> #include<mmsystem.h> #include<stdlib.h> #define N 2048 #define M 32 int main(int argc, char* argv[]) { int i, j, k, l; float target = 0; float* a; float* b; float c; DWORD nTime, oTime; a = (float*)malloc(sizeof(float)*N); b = (float*)malloc(sizeof(float)*N); c = 0; for(i = 0; i < N; i++) { a[i] = 1000; b[i] = 0; } oTime = timeGetTime(); for(i = 0; i < M; i++) { for(j = 1; j < N/M; j += j) { for(k = 0; k < N/M; k++) { if(k % 2 == 0) { a[k+i*N/M] += a[k+j+i*N/M]; } } } b[i] = a[i*N/M]; printf("%f\n", a[i*N/M]); } for(i = 0; i < M; i++) { target += b[i]; } c = target; nTime = timeGetTime(); printf("%f\n%f\n%f", c, oTime, nTime); getch(); return 0; }
- ベストアンサー
- C・C++・C#
- シェルソート(Cプログラミング)
シェル・ソート 基本挿入法により、データを昇順にソートする。 というプログラムを実行したいと思ったのですが、エラーがでてしまいコンパイルできません。 書いたプログラムは以下の通りです。 #include<stdio.h> #include<math.h> #define N 100 int main (void) { int a[N],i,j,t; for (i=0;i<N;i++) a[i]=rand(); for (i=1;i<N;i++){ for (j=j-1;j>=0;j--){ if (a[j]>a[j+1]){ t=a[j]; a[j]=a[j+1]; a[j+1]=t; } else break; } } for (i=0;i<N;i++) printf("%8d",a[i]); } エラーメッセージは以下のようにでました。 警告 W8065 sample.c 10: プロトタイプ宣言のない関数 'rand' の呼び出し(関数 main ) 警告 W8070 sample.c 22: 関数は値を返すべき(関数 main ) どうすれば出来るのでしょうか、お答えよろしくお願いします。
- ベストアンサー
- C・C++・C#
- 離散フーリエ変換について
10 REM dft 20 N=8 30 DIM A(N),B(N),X(N) 40 FOR I=0 TO N-1 50 READ X(1) 60 NEXT I 70 P=6.283/N 80 FOR K=0 TO N-1 90 A(K)=0:B(K)=0 100 FOR J=0 TO N-1 110 A(K) =A(K)+X(j)*COS(P*J*K) 120 B(K) =B(K)-X(J)*SIN(P*J*K) 130 NEXT J 140 NEXT K 150 FOR I=0 TO N-1 160 Y=SQL(A(I)^2+B(I)^2) 170 LPRINT I;:LPRINT USING "###,###";A(I),B(I),Y 180 NEXT I 190 DATA 1,1,1,1,0,0,0,0 このDFTプログラムをC言語に直したいのですがよく分かりません; お願いします@@;
- 締切済み
- C・C++・C#
お礼
すばやいご回答本当にありがとうございました。 以前数学関数の中にint型を入力しても大丈夫だった気がしたのですが…。やり直したらうまくいきました。 丁寧に添削くださり、感謝しております。ありがとうございました。