10回目 課題 ヒント
//153R000000-10-1.cpp #include <stdio.h> #include <math.h> #include "153R000000-10-complex.h" #include "153R000000-10-wave.h" #include "153R000000-10-dft.h" int main(){ const int n = 100; double x1[n] = {0}, x2[n] = {0}, x11[n] = {0}, x21[n] = {0}; Complex dx1[n], dx2[n]; FILE *fp; //配列の初期化 //配列に各波形の値を代入 //dftの計算 //スペクトルの計算 for(int i = 0; i < n; i++){ x11[i] = Cabs(dx1[i]) * Cabs(dx1[i]); x21[i] = Cabs(dx2[i]) * Cabs(dx2[i]); } //ファイル出力 fclose(fp); printf("ファイル出力完了!\n"); return 0; } |
メイン関数のソースファイル 必要なヘッダファイルをインクルード |
//153R000000-10-complex.cpp #include <stdio.h> #include <math.h> #include "153R000000-10-complex.h" /* ファイル名は各自で変更 */ Complex ToComplex(double x, double y){ // 実数x,yから複素数を作り,戻り値として返す関数 Complex z; z.re = x; z.im = y; return z; } |
複素数の実装ファイル |
//153R000000-10-complex.h #ifndef COMPLEX_H #define COMPLEX_H struct Complex { double re; double im; }; Complex ToComplex(double x, double y); /* 実数2つから複素数を生成 */ void Cdisp(Complex z); /* 複素数を画面に表示 */ Complex Cinp(void); /* キーボードから実部,虚部を入力して複素数を返す */ Complex Cadd(Complex a, Complex b); /* 複素数 a, b の和を返す */ Complex Csub(Complex a, Complex b); /* 差 */ Complex Cmul(Complex a, Complex b); /* 積 */ Complex Cdiv(Complex a, Complex b); /* 商 */ Complex Conj(Complex z); /* 共役な複素数を返す */ double Cabs(Complex z); /* 絶対値 */ double Carg(Complex z); /* 偏角 */ Complex Cexp(Complex z); /* 指数関数 */ #endif |
複素数のヘッダファイル 関数を宣言 |
//153R000000-10-dft.cpp #include <stdio.h> #include <math.h> #include "153R000000-10-complex.h" void dft(const double in[], Complex out[], const int N){ // // 離散フーリエ変換(DFT) // 元データは実数,変換後は複素数 // // in : 元データ.これは変更しない.実数の配列. // out : 計算結果.こちらは複素数. // N : データ個数.inもoutも同じデータ数でなければならない // Complex tmp; /* 出力用の配列を初期化 */ /*for(int f=0; f<N; f++) { // 以下のループで 1個のF[omega]を計算する. double omega = 2 * M_PI * f; /* 積分の中身の計算 */ // Sigmaの計算 } for(int i = 0; i < N; i++){ out[i].re /= N; out[i].im /= N; } } |
DFTの実装ファイル |
//153R000000-10-dft.h #ifndef DFT_H #define DFT_H void dft(const double in[], Complex out[], const int N); #endif |
DFTのヘッダファイル |
//153R000000-10-wave.cpp #include <stdio.h> #include <math.h> #include "153R000000-10-wave.h" void clear_array(double x[], int n){ for(int i = 0; i < n; i++){ x[i] = 0; } } void square_wave(double x[], int n){ int freq = 10; //任意の半周波数をここで設定 for(int i = 0; i < n; i++){ if((i/freq)%2 == 0) x[i] = -1; //iを任意の半周期で割った解の整数の位が2の倍数なら-1を代入,それ以外で1を代入 else x[i] = 1; } } void sin_waves(double x[], int n, double f1, double f2, double f3){ for(int i = 0; i < n; i++){ x[i] = (2.0 * sin(2*M_PI*i/n * f1) //M_PIはmath.hに定義される円周率の定数 + 0.5 * cos(2*M_PI*i/n * f2) + 0.25 * sin(2*M_PI*i/n * f3)); } } |
波形生成の実装ファイル |
//153R000000-10-wave.h #ifndef WAVE_H #define WAVE_H void clear_array(double x[], int n); // 要素数 n の配列 x に,すべて 0 を代入する(初期化). void square_wave(double x[], int n); // 要素数 n の配列 x に,任意の周波数(例えば 5 )の矩形波を書き込む.振幅は任意,例えば -1 から 1 など. void sin_waves(double x[], int n, double f1, double f2, double f3); // 配列に周波数 f1, f2, f3,計3個の正弦波または余弦波の和を入れる. #endif |
波形生成のヘッダファイル |
#include <stdio.h> #include <stdlib.h> #include <math.h> #include "153R000000-10-wave2.h" void noise(double x[], int n){ //ランダムノイズの波形 for(int i = 0; i < n; i++){ x[i] = rand(); } } void sin_wave(double x[], int n){ //正弦波のみの波形 double f = 10; for(int i = 0; i < n; i++){ x[i] = sin(2*M_PI*i/n*f); } } void sinnoise(double x[], int n){ //正弦波にノイズを加えた波形 double f = 10; for(int i = 0; i < n; i++){ x[i] = sin(2*M_PI*i/n*f) + (double)rand()/RAND_MAX; } } void impulse(double x[], int n){ //インパルス波形 x[0] = 1; for(int i = 1; i < n; i++){ x[i] = 0; } } void pulse(double x[], int n){ //周期freqのパルス int freq = 10; for(int i = 0; i < n; i++){ if(i%freq == 0) x[i] = 1.0; else x[i] = 0; } } void step(double x[], int n){ //ステップ関数 for(int i = 0; i < n; i++){ if(i < n/2) x[i] = 0; else x[i] = 1; } } void saw(double x[], int n){ //周期freqの三角波(鋸波) int freq = 10; double max = 1.0; for(int i = 0; i < n; i++){ x[i] = max/(freq - 1) * (i%freq); } } void polynomial(double x[], int n){ //6次関数で極値をとるのはx=1,2,3,4,5のとき double j = 0; for(int i = 0; i < n; i++){ j = i * 0.1; x[i] = 1.0/6*pow(j,6) - 3*pow(j,5) + 85.0/4*pow(j,4) - 75*pow(j,3) + 137*pow(j,2) - 120*j + 31; } } void display_array(double x[], int n){ //数列を表示する関数(課題には含まれない)で、作った関数で波形がうまくできているか確認するためのもの for(int i = 0; i < n; i++){ printf("%f\n", x[i]); } } |
|
//153R000000-10-wave2.h #ifndef WAVE2_H #define WAVE2_H void noise(double x[], int n); void sin_wave(double x[], int n); void sinnoise(double x[], int n); void impulse(double x[], int n); void pulse(double x[], int n); void step(double x[], int n); void saw(double x[], int n); void polynomial(double x[], int n); void display_array(double x[], int n); #endif |