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