概要
cscの作法、調べてみた。
練習問題やってみた。
練習問題
dttmfに、fft掛けて、ifft掛けて、グラフ化せよ。
参考にしたページ
写真
サンプルコード
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace app
{
class form1: Form {
public static void FFT(double[] inputRe, double[] inputIm, out double[] outputRe, out double[] outputIm, int bitSize) {
int dataSize = 1 << bitSize;
int[] reverseBitArray = BitScrollArray(dataSize);
outputRe = new double[dataSize];
outputIm = new double[dataSize];
for (int i = 0; i < dataSize; i++)
{
outputRe[i] = inputRe[reverseBitArray[i]];
outputIm[i] = inputIm[reverseBitArray[i]];
}
for (int stage = 1; stage <= bitSize; stage++)
{
int butterflyDistance = 1 << stage;
int numType = butterflyDistance >> 1;
int butterflySize = butterflyDistance >> 1;
double wRe = 1.0;
double wIm = 0.0;
double uRe = System.Math.Cos(System.Math.PI / butterflySize);
double uIm = -System.Math.Sin(System.Math.PI / butterflySize);
for (int type = 0; type < numType; type++)
{
for (int j = type; j < dataSize; j += butterflyDistance)
{
int jp = j + butterflySize;
double tempRe = outputRe[jp] * wRe - outputIm[jp] * wIm;
double tempIm = outputRe[jp] * wIm + outputIm[jp] * wRe;
outputRe[jp] = outputRe[j] - tempRe;
outputIm[jp] = outputIm[j] - tempIm;
outputRe[j] += tempRe;
outputIm[j] += tempIm;
}
double tempWRe = wRe * uRe - wIm * uIm;
double tempWIm = wRe * uIm + wIm * uRe;
wRe = tempWRe;
wIm = tempWIm;
}
}
}
private static int[] BitScrollArray(int arraySize) {
int[] reBitArray = new int[arraySize];
int arraySizeHarf = arraySize >> 1;
reBitArray[0] = 0;
for (int i = 1; i < arraySize; i <<= 1)
{
for (int j = 0; j < i; j++)
{
reBitArray[j + i] = reBitArray[j] + arraySizeHarf;
}
arraySizeHarf >>= 1;
}
return reBitArray;
}
public static void IFFT(double[] inputRe, double[] inputIm, out double[] outputRe, out double[] outputIm, int bitSize) {
int dataSize = 1 << bitSize;
Console.WriteLine(dataSize);
outputRe = new double[dataSize];
outputIm = new double[dataSize];
for (int i = 0; i < dataSize; i++)
{
inputIm[i] = -inputIm[i];
}
FFT(inputRe, inputIm, out outputRe, out outputIm, bitSize);
for (int i = 0; i < dataSize; i++)
{
outputRe[i] /= (double) dataSize;
outputIm[i] /= (double) (-dataSize);
}
}
private double[] data = new double[256];
private double[] data1 = new double[256];
public form1() {
this.Text = "ifft";
this.ClientSize = new Size(400, 600);
Button btn1 = new Button();
btn1.Location = new Point(320, 560);
btn1.Text = "run";
btn1.Click += btn1_Click;
Controls.AddRange(new Control[] {
btn1
});
}
void btn1_Click(object sender, System.EventArgs e) {
const int size = 256;
double[] re = new double[size];
double[] im = new double[size];
double[] re1 = new double[size];
double[] im1 = new double[size];
for (int i = 0; i < size; i++)
{
data[i] = Math.Sin(2 * Math.PI * Math.Cos(2 * 10 * i * Math.PI / 1800) + 2 * 200 * i * Math.PI / 1800);
}
FFT(data, im, out re, out im, 8);
IFFT(re, im, out re1, out im1, 8);
for (int i = 0; i < size; i++)
{
data1[i] = Math.Sqrt(re1[i] * re1[i] + im1[i] * im1[i]) * 2.0;
}
this.Invalidate();
}
protected override void OnPaint(PaintEventArgs e) {
Graphics g = e.Graphics;
Pen pen = new Pen(Color.Blue, 2);
SolidBrush brush = new SolidBrush(Color.Yellow);
float y2 = 150;
float y3 = 350;
for (int i = 0; i < 256; i++)
{
float y0 = (float) (150 + data[i] * 100);
g.DrawLine(pen, 50 + i, y2, 50 + i, y0);
float y1 = (float) (350 + data1[i] * 100);
g.DrawLine(pen, 50 + i, y3, 50 + i, y1);
y2 = y0;
y3 = y1;
}
}
[STAThread]
public static void Main() {
Application.Run(new form1());
}
}
}
以上。