#include #include #include #include #define Nmax 32768 struct Complex{ /* 構造体宣言 */ double Real; double Imag; }; struct Complex C_DOUBLE(double a,double b); struct Complex C_PLUS(struct Complex z1,struct Complex z2); struct Complex C_MINUS(struct Complex z1,struct Complex z2); struct Complex C_TIMES(struct Complex z1,struct Complex z2); struct Complex C_DIVIDED(struct Complex z1,struct Complex z2); double D_ABS(struct Complex z); struct Complex C_CONJ(struct Complex z); struct Complex C_SQRT(struct Complex z); struct Complex C_EXP(struct Complex z); struct Complex C_COS(struct Complex z); struct Complex C_SIN(struct Complex z); struct Complex C_COSH(struct Complex z); struct Complex C_SINH(struct Complex z); void main_part(char fnameR[],char fnameW[]); void CFFT(int n,struct Complex x[Nmax],int ind); /*-------------------------------------------------------------------*/ int main(int argc,char *argv[]) { char fnameR[50]; /*入力ファイル名*/ char fnameW[50]; /*出力ファイル名*/ strcpy(fnameR,argv[1]); strcpy(fnameW,argv[2]); main_part(fnameR,fnameW); printf("リターンキーを押してください"); getchar(); return 0; } /*---------------------------------------------------------------------------*/ void main_part(char fnameR[],char fnameW[]) { int i; double dt; int ndata; int nn; FILE *fin,*fout; char dat[256]; char sv[20]; double ck; double data[Nmax]; struct Complex x[Nmax]; struct Complex y[Nmax]; /*データ読み込み*/ fin=fopen(fnameR,"r"); fgets(dat,sizeof dat,fin); fgets(dat,sizeof dat,fin);strtok(dat,",");dt=atof(strtok(NULL,",")); fgets(dat,sizeof dat,fin);strtok(dat,",");ndata=atoi(strtok(NULL,",")); nn = 2; do{ nn = nn * 2; }while( nn < ndata * 1); for(i=1;i<=nn;i++){ data[i-1]=0.0; x[i-1]=C_DOUBLE(0.0,0.0); } for(i=1;i<=ndata;i++){ fgets(dat,sizeof dat,fin);data[i-1]=atof(strtok(dat,",")); x[i-1]=C_DOUBLE(data[i-1],0.0); } fclose(fin); /*フーリエ変換・逆変換*/ CFFT(nn,x,-1); /* フーリエ変換 */ for(i=1;i<=nn;i++){ x[i-1]=C_DIVIDED(x[i-1],C_DOUBLE((double)nn,0)); /* 出力値をデータ数で除す */ y[i-1]=x[i-1]; } CFFT(nn,y,+1); /* フーリエ逆変換 */ /*データ書き出し*/ fout=fopen(fnameW,"w"); fputs("m:番号\n",fout); fputs("data:波形時刻歴数値\n",fout); fputs("k:番号\n",fout); fputs("Re(Ck):複素フーリエ係数実数部\n",fout); fputs("Im(Ck):複素フーリエ係数虚数部\n",fout); fputs("abs(Ck):複素フーリエ係数絶対値\n",fout); fputs("Re(xm):フーリエ逆変換実数部\n",fout); fputs("Im(xm):フーリエ逆変換虚数部\n",fout); fputs("m,data,k,Re(Ck),Im(Ck),abs(Ck),Re(xm),Im(xm)\n",fout); for(i=1;i<=nn;i++){ sprintf(sv,"%d",i-1) ;strcpy(dat,sv); sprintf(sv,"%e",data[i-1]) ;strcat(dat,",");strcat(dat,sv); sprintf(sv,"%d",i-1) ;strcat(dat,",");strcat(dat,sv); sprintf(sv,"%e",x[i-1].Real) ;strcat(dat,",");strcat(dat,sv); sprintf(sv,"%e",x[i-1].Imag) ;strcat(dat,",");strcat(dat,sv); sprintf(sv,"%e",D_ABS(x[i-1]));strcat(dat,",");strcat(dat,sv); sprintf(sv,"%e",y[i-1].Real) ;strcat(dat,",");strcat(dat,sv); sprintf(sv,"%e",y[i-1].Imag) ;strcat(dat,",");strcat(dat,sv); strcat(dat,"\n"); fputs(dat,fout); } fclose(fout); } /*-------------------------------------------------------------------*/ void CFFT(int n,struct Complex x[Nmax],int ind) { /************************************************************/ /* 複素数計算による高速フーリエ変換 */ /************************************************************/ /* n:データ数(2の累乗) */ /* x[]:入出力データ(複素数) */ /* ind:-1=フーリエ変換,+1=フーリエ逆変換 */ struct Complex temp,theta; int i,j,k,m,kmax,istep; double pi=M_PI; j=1; for(i=1;i<=n;i++){ if(i=2); j=j+m; } kmax=1; do{ istep=kmax*2; for(k=1;k<=kmax;k++){ theta=C_DOUBLE(0.0,pi*(double)(ind*(k-1))/(double)kmax); for(i=k;i<=n;i=i+istep){ j=i+kmax; temp=C_TIMES(x[j-1],C_EXP(theta)); x[j-1]=C_MINUS(x[i-1],temp); x[i-1]=C_PLUS(x[i-1],temp); } } kmax=istep; }while(kmax