dftc語言
❶ 基於FFT的演算法優化 要c語言完整程序(利用旋轉因子的性質),有的請留言,答謝!!!(有核心代碼,望指教
實現(C描述)
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
//#include "complex.h"
// --------------------------------------------------------------------------
#define N 8 //64
#define M 3 //6 //2^m=N
#define PI 3.1415926
// --------------------------------------------------------------------------
float twiddle[N/2] = {1.0, 0.707, 0.0, -0.707};
float x_r[N] = {1, 1, 1, 1, 0, 0, 0, 0};
float x_i[N]; //N=8
/*
float twiddle[N/2] = {1, 0.9951, 0.9808, 0.9570, 0.9239, 0.8820, 0.8317, 0.7733,
0.7075, 0.6349, 0.5561, 0.4721, 0.3835, 0.2912, 0.1961, 0.0991,
0.0000,-0.0991,-0.1961,-0.2912,-0.3835,-0.4721,-0.5561,-0.6349,
-0.7075,-0.7733, 0.8317,-0.8820,-0.9239,-0.9570,-0.9808,-0.9951}; //N=64
float x_r[N]={1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,};
float x_i[N];
*/
FILE *fp;
// ----------------------------------- func -----------------------------------
/**
* 初始化輸出虛部
*/
static void fft_init( void )
{
int i;
for(i=0; i<N; i++) x_i[i] = 0.0;
}
/**
* 反轉演算法.將時域信號重新排序.
* 這個演算法有改進的空間
*/
static void bitrev( void )
{
int p=1, q, i;
int bit_rev[ N ]; //
float xx_r[ N ]; //
bit_rev[ 0 ] = 0;
while( p < N )
{
for(q=0; q<p; q++)
{
bit_rev[ q ] = bit_rev[ q ] * 2;
bit_rev[ q + p ] = bit_rev[ q ] + 1;
}
p *= 2;
}
for(i=0; i<N; i++) xx_r[ i ] = x_r[ i ];
for(i=0; i<N; i++) x_r[i] = xx_r[ bit_rev[i] ];
}
/* ------------ add by sshc625 ------------ */
static void bitrev2( void )
{
return ;
}
/* */
void display( void )
{
printf("\n\n");
int i;
for(i=0; i<N; i++)
printf("%f\t%f\n", x_r[i], x_i[i]);
}
/**
*
*/
void fft1( void )
{ fp = fopen("log1.txt", "a+");
int L, i, b, j, p, k, tx1, tx2;
float TR, TI, temp; // 臨時變數
float tw1, tw2;
/* 深M. 對層進行循環. L為當前層, 總層數為M. */
for(L=1; L<=M; L++)
{
fprintf(fp,"----------Layer=%d----------\n", L);
/* b的意義非常重大,b表示當前層的顆粒具有的輸入樣本點數 */
b = 1;
i = L - 1;
while(i > 0)
{
b *= 2;
i--;
}
// -------------- 是否外層對顆粒循環, 內層對樣本點循環邏輯性更強一些呢! --------------
/*
* outter對參與DFT的樣本點進行循環
* L=1, 循環了1次(4個顆粒, 每個顆粒2個樣本點)
* L=2, 循環了2次(2個顆粒, 每個顆粒4個樣本點)
* L=3, 循環了4次(1個顆粒, 每個顆粒8個樣本點)
*/
for(j=0; j<b; j++)
{
/* 求旋轉因子tw1 */
p = 1;
i = M - L; // M是為總層數, L為當前層.
while(i > 0)
{
p = p*2;
i--;
}
p = p * j;
tx1 = p % N;
tx2 = tx1 + 3*N/4;
tx2 = tx2 % N;
// tw1是cos部分, 實部; tw2是sin部分, 虛數部分.
tw1 = ( tx1>=N/2)? -twiddle[tx1-N/2] : twiddle[ tx1 ];
tw2 = ( tx2>=N/2)? -twiddle[tx2-(N/2)] : twiddle[tx2];
/*
* inner對顆粒進行循環
* L=1, 循環了4次(4個顆粒, 每個顆粒2個輸入)
* L=2, 循環了2次(2個顆粒, 每個顆粒4個輸入)
* L=3, 循環了1次(1個顆粒, 每個顆粒8個輸入)
*/
for(k=j; k<N; k=k+2*b)
{
TR = x_r[k]; // TR就是A, x_r[k+b]就是B.
TI = x_i[k];
temp = x_r[k+b];
/*
* 如果復習一下 (a+j*b)(c+j*d)兩個復數相乘後的實部虛部分別是什麼
* 就能理解為什麼會如下運算了, 只有在L=1時候輸入才是實數, 之後層的
* 輸入都是復數, 為了讓所有的層的輸入都是復數, 我們只好讓L=1時候的
* 輸入虛部為0
* x_i[k+b]*tw2是兩個虛數相乘
*/
fprintf(fp, "tw1=%f, tw2=%f\n", tw1, tw2);
x_r[k] = TR + x_r[k+b]*tw1 + x_i[k+b]*tw2;
x_i[k] = TI - x_r[k+b]*tw2 + x_i[k+b]*tw1;
x_r[k+b] = TR - x_r[k+b]*tw1 - x_i[k+b]*tw2;
x_i[k+b] = TI + temp*tw2 - x_i[k+b]*tw1;
fprintf(fp, "k=%d, x_r[k]=%f, x_i[k]=%f\n", k, x_r[k], x_i[k]);
fprintf(fp, "k=%d, x_r[k]=%f, x_i[k]=%f\n", k+b, x_r[k+b], x_i[k+b]);
} //
} //
} //
}
/**
* ------------ add by sshc625 ------------
* 該實現的流程為
* for( Layer )
* for( Granule )
* for( Sample )
*
*
*
*
*/
void fft2( void )
{ fp = fopen("log2.txt", "a+");
int cur_layer, gr_num, i, k, p;
float tmp_real, tmp_imag, temp; // 臨時變數, 記錄實部
float tw1, tw2;// 旋轉因子,tw1為旋轉因子的實部cos部分, tw2為旋轉因子的虛部sin部分.
int step; // 步進
int sample_num; // 顆粒的樣本總數(各層不同, 因為各層顆粒的輸入不同)
/* 對層循環 */
for(cur_layer=1; cur_layer<=M; cur_layer++)
{
/* 求當前層擁有多少個顆粒(gr_num) */
gr_num = 1;
i = M - cur_layer;
while(i > 0)
{
i--;
gr_num *= 2;
}
/* 每個顆粒的輸入樣本數N' */
sample_num = (int)pow(2, cur_layer);
/* 步進. 步進是N'/2 */
step = sample_num/2;
/* */
k = 0;
/* 對顆粒進行循環 */
for(i=0; i<gr_num; i++)
{
/*
* 對樣本點進行循環, 注意上限和步進
*/
for(p=0; p<sample_num/2; p++)
{
// 旋轉因子, 需要優化...
tw1 = cos(2*PI*p/pow(2, cur_layer));
tw2 = -sin(2*PI*p/pow(2, cur_layer));
tmp_real = x_r[k+p];
tmp_imag = x_i[k+p];
temp = x_r[k+p+step];
/*(tw1+jtw2)(x_r[k]+jx_i[k])
*
* real : tw1*x_r[k] - tw2*x_i[k]
* imag : tw1*x_i[k] + tw2*x_r[k]
* 我想不抽象出一個
* typedef struct {
* double real; // 實部
* double imag; // 虛部
* } complex; 以及針對complex的操作
* 來簡化復數運算是否是因為效率上的考慮!
*/
/* 蝶形演算法 */
x_r[k+p] = tmp_real + ( tw1*x_r[k+p+step] - tw2*x_i[k+p+step] );
x_i[k+p] = tmp_imag + ( tw2*x_r[k+p+step] + tw1*x_i[k+p+step] );
/* X[k] = A(k)+WB(k)
* X[k+N/2] = A(k)-WB(k) 的性質可以優化這里*/
// 旋轉因子, 需要優化...
tw1 = cos(2*PI*(p+step)/pow(2, cur_layer));
tw2 = -sin(2*PI*(p+step)/pow(2, cur_layer));
x_r[k+p+step] = tmp_real + ( tw1*temp - tw2*x_i[k+p+step] );
x_i[k+p+step] = tmp_imag + ( tw2*temp + tw1*x_i[k+p+step] );
printf("k=%d, x_r[k]=%f, x_i[k]=%f\n", k+p, x_r[k+p], x_i[k+p]);
printf("k=%d, x_r[k]=%f, x_i[k]=%f\n", k+p+step, x_r[k+p+step], x_i[k+p+step]);
}
/* 開跳!:) */
k += 2*step;
}
}
}
/*
* 後記:
* 究竟是顆粒在外層循環還是樣本輸入在外層, 好象也差不多, 復雜度完全一樣.
* 但以我資質愚鈍花費了不少時間才弄明白這數十行代碼.
* 從中我發現一個於我非常有幫助的教訓, 很久以前我寫過一部分演算法, 其中絕大多數都是遞歸.
* 將數據量減少, 減少再減少, 用歸納的方式來找出數據量加大代碼的規律
* 比如FFT
* 1. 先寫死LayerI的代碼; 然後再把LayerI的輸出作為LayerII的輸入, 又寫死代碼; ......
* 大約3層就可以統計出規律來. 這和遞歸也是一樣, 先寫死一兩層, 自然就出來了!
* 2. 有的功能可以寫偽代碼, 不急於求出結果, 降低復雜性, 把邏輯結果定出來後再添加.
* 比如旋轉因子就可以寫死, 就寫1.0. 流程出來後再寫旋轉因子.
* 寥寥數語, 我可真是流了不少汗! Happy!
*/
void dft( void )
{
int i, n, k, tx1, tx2;
float tw1,tw2;
float xx_r[N],xx_i[N];
/*
* clear any data in Real and Imaginary result arrays prior to DFT
*/
for(k=0; k<=N-1; k++)
xx_r[k] = xx_i[k] = x_i[k] = 0.0;
// caculate the DFT
for(k=0; k<=(N-1); k++)
{
for(n=0; n<=(N-1); n++)
{
tx1 = (n*k);
tx2 = tx1+(3*N)/4;
tx1 = tx1%(N);
tx2 = tx2%(N);
if(tx1 >= (N/2))
tw1 = -twiddle[tx1-(N/2)];
else
tw1 = twiddle[tx1];
if(tx2 >= (N/2))
tw2 = -twiddle[tx2-(N/2)];
else
tw2 = twiddle[tx2];
xx_r[k] = xx_r[k]+x_r[n]*tw1;
xx_i[k] = xx_i[k]+x_r[n]*tw2;
}
xx_i[k] = -xx_i[k];
}
// display
for(i=0; i<N; i++)
printf("%f\t%f\n", xx_r[i], xx_i[i]);
}
// ---------------------------------------------------------------------------
int main( void )
{
fft_init( );
bitrev( );
// bitrev2( );
//fft1( );
fft2( );
display( );
system( "pause" );
// dft();
return 1;
}
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/sshcx/archive/2007/06/14/1651616.aspx
❷ C語言 基本問題
1.typedef能通過已有類型定義新的類型。它的語法形式和變數聲明一致(區別僅在於顯式前置typedef關鍵字和語義),聲明後的類型可以用來直接聲明該類型的變數。
typedef struct{
char dm[5];
int sl;
}PRO;
PRO sell[200];
PRO cell;
這里聲明了類型struct {
char dm[5];
int sl;
}(注意,以上整個字元段才表示一個類型,最後沒有分號)。
為了方便聲明變數起見,用了typedef把上面的類型聲明簡化為PRO。
如果不用typedef,也可以這樣:
struct{
char dm[5];
int sl;
}sell[200],cell;(注意結尾的變數名稱和分號,包含了sell[200],cell這些變數名,整段字元是一個完整的聲明),但明顯比用PRO聲明得復雜了許多,而且除非把類型聲明完整地再照抄一編否則不能用它聲明其它變數,可見typedef的優勢。
用結構體類型名稱也可以做到這一點:
struct PRO
{
char dm[5];
int sl;
}sell[200];
struct PRO cell;
不過需要注意struct不可省略,在這里struct PRO是一個類型,而PRO不是(在C++中則可以省略,編譯器默認會在編譯過程中自動加上struct處理)。雖然看起來差不多,不過在C語言中對於頻繁用到(struct PRO*)強制轉換之類的場合,用typedef可以少寫許多「struct」,更簡潔一些。
2.cell=sell[i];可行,原因如下:
1).運算符「=」在此處有定義(C語言內置運算符「=」可以對同類型的結構體變數間直接賦值);
2).左邊是一個左值(而不是常量或者編譯期臨時變數);
3).左右類型相同,都是PRO(對於基本類型編譯器可以進行隱式強制轉換,類型不同也沒關系,最多編譯警告;但對於諸如兩個不同類型的結構體或指針之類編譯器就不知道怎麼處理了,需要顯式強制轉換才有可能通過編譯)。
如果覺得比較難理解,可以先把類型代換為基本類型。就像
int a=0,b[3]={1};
a=b[0];
一樣,它是可行的。原因是數組本身的語義特性——數組中每個元素的類型被定義為它的基類型。
至於LZ說的
PRO cell[10];
cell[0]=sell[i];
也是可行的,原因同上,通過LZ的聲明可以看到cell[0]和sell[i]的類型相同,左邊是變數。
但這樣聲明後cell=sell[i]是非法的,因為cell是PRO*型地址常量,而sell[i]是PRO型變數。
關鍵在於,這里聲明不同。賦值的合法性需要關注兩端標識符的類型,因此需要明確聲明的具體細節。
----
[原創回答團]
❸ 二階濾波器用C語言怎麼寫
這個可比你想像的復雜多了,s是個復變數,1/(s+1)極點在-1,要想用C語言寫,必須理解清楚下面幾個問題:
1、輸入必須是個有限序列,比如(x+yi),x和y分別是兩個長度為N的數組
2、要過濾的頻率,必須是個整型值,或者是個整型區間
3、輸出結果同樣是兩個長度為N的數組(p+qi)
4、整個程序需要使用最基本的復數運算,這一點C語言本身不提供,必須手工寫復函數運算庫
5、實現的時候具體演算法還需要編,這里才是你問題的核心。
我可以送你一段FFT的程序,自己琢磨吧,和MATLAB的概念差別很大:
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include "complex.h"
extern "C" {
// Discrete Fourier Transform (Basic Version, Without Any Enhancement)
// return - Without Special Meaning, constantly, zero
int DFT (long count, CComplex * input, CComplex * output)
{
assert(count);
assert(input);
assert(output);
CComplex F, X, T, W; int n, i;
long N = abs(count); long Inversing = count < 0? 1: -1;
for(n = 0; n < N ; n++){ // compute from line 0 to N-1
F = CComplex(0.0f, 0.0f); // clear a line
for(i = 0; i < N; i++) {
T = input[i];
W = HarmonicPI2(Inversing * n * i, N);
X = T * W;
F += X; // fininshing a line
}//next i
// save data to outpus
memcpy(output + n, &F, sizeof(F));
}//next n
return 0;
}//end DFT
int fft (long count, CComplex * input, CComplex * output)
{
assert(count);
assert(input);
assert(output);
int N = abs(count); long Inversing = count < 0? -1: 1;
if (N % 2 || N < 5) return DFT(count, input, output);
long N2 = N / 2;
CComplex * iEven = new CComplex[N2]; memset(iEven, 0, sizeof(CComplex) * N2);
CComplex * oEven = new CComplex[N2]; memset(oEven, 0, sizeof(CComplex) * N2);
CComplex * iOdd = new CComplex[N2]; memset(iOdd , 0, sizeof(CComplex) * N2);
CComplex * oOdd = new CComplex[N2]; memset(oOdd , 0, sizeof(CComplex) * N2);
int i = 0; CComplex W;
for(i = 0; i < N2; i++) {
iEven[i] = input[i * 2];
iOdd [i] = input[i * 2 + 1];
}//next i
fft(N2 * Inversing, iEven, oEven);
fft(N2 * Inversing, iOdd, oOdd );
for(i = 0; i < N2; i++) {
W = HarmonicPI2(Inversing * (- i), N);
output[i] = oEven[i] + W * oOdd[i];
output[i + N2] = oEven[i] - W * oOdd[i];
}//next i
return 0;
}//end FFT
void __stdcall FFT(
long N, // Serial Length, N > 0 for DFT, N < 0 for iDFT - inversed Discrete Fourier Transform
double * inputReal, double * inputImaginary, // inputs
double * AmplitudeFrequences, double * PhaseFrequences) // outputs
{
if (N == 0) return;
if (!inputReal && !inputImaginary) return;
short n = abs(N);
CComplex * input = new CComplex[n]; memset(input, 0, sizeof(CComplex) * n);
CComplex * output= new CComplex[n]; memset(output,0, sizeof(CComplex) * n);
double rl = 0.0f, im = 0.0f; int i = 0;
for (i = 0; i < n; i++) {
rl = 0.0f; im = 0.0f;
if (inputReal) rl = inputReal[i];
if (inputImaginary) im = inputImaginary[i];
input[i] = CComplex(rl, im);
}//next i
int f = fft(N, input, output);
double factor = n;
//factor = sqrt(factor);
if (N > 0)
factor = 1.0f;
else
factor = 1.0f / factor;
//end if
for (i = 0; i < n; i++) {
if (AmplitudeFrequences) AmplitudeFrequences[i] = output[i].getReal() * factor;
if (PhaseFrequences) PhaseFrequences[i] = output[i].getImaginary() * factor;
}//next i
delete [] output;
delete [] input;
return ;
}//end FFT
int __cdecl main(int argc, char * argv[])
{
fprintf(stderr, "%s usage:\n", argv[0]);
fprintf(stderr, "Public Declare Sub FFT Lib \"wfft.exe\" \
(ByVal N As Long, ByRef inputReal As Double, ByRef inputImaginary As Double, \
ByRef freqAmplitude As Double, ByRef freqPhase As Double)");
return 0;
}//end main
};//end extern "C"
❹ 求FFT的c語言程序
快速傅里葉變換 要用C++ 才行吧 你可以用MATLAB來實現更方便點啊
此FFT 是用VC6.0編寫,由FFT.CPP;STDAFX.H和STDAFX.CPP三個文件組成,編譯成功。程序可以用文件輸入和輸出為文件。文件格式為TXT文件。測試結果如下:
輸入文件:8.TXT 或手動輸入
8 //N
1
2
3
4
5
6
7
8
輸出結果為:或保存為TXT文件。(8OUT.TXT)
8
(36,0)
(-4,9.65685)
(-4,4)
(-4,1.65685)
(-4,0)
(-4,-1.65685)
(-4,-4)
(-4,-9.65685)
下面為FFT.CPP文件:
// FFT.cpp : 定義控制台應用程序的入口點。
#include "stdafx.h"
#include <iostream>
#include <complex>
#include <bitset>
#include <vector>
#include <conio.h>
#include <string>
#include <fstream>
using namespace std;
bool inputData(unsigned long &, vector<complex<double> >&); //手工輸入數據
void FFT(unsigned long &, vector<complex<double> >&); //FFT變換
void display(unsigned long &, vector<complex<double> >&); //顯示結果
bool readDataFromFile(unsigned long &, vector<complex<double> >&); //從文件中讀取數據
bool saveResultToFile(unsigned long &, vector<complex<double> >&); //保存結果至文件中
const double PI = 3.1415926;
int _tmain(int argc, _TCHAR* argv[])
{
vector<complex<double> > vecList; //有限長序列
unsigned long ulN = 0; //N
char chChoose = ' '; //功能選擇
//功能循環
while(chChoose != 'Q' && chChoose != 'q')
{
//顯示選擇項
cout << "\nPlease chose a function" << endl;
cout << "\t1.Input data manually, press 'M':" << endl;
cout << "\t2.Read data from file, press 'F':" << endl;
cout << "\t3.Quit, press 'Q'" << endl;
cout << "Please chose:";
//輸入選擇
chChoose = getch();
//判斷
switch(chChoose)
{
case 'm': //手工輸入數據
case 'M':
if(inputData(ulN, vecList))
{
FFT(ulN, vecList);
display(ulN, vecList);
saveResultToFile(ulN, vecList);
}
break;
case 'f': //從文檔讀取數據
case 'F':
if(readDataFromFile(ulN, vecList))
{
FFT(ulN, vecList);
display(ulN, vecList);
saveResultToFile(ulN, vecList);
}
break;
}
}
return 0;
}
bool Is2Power(unsigned long ul) //判斷是否是2的整數次冪
{
if(ul < 2)
return false;
while( ul > 1 )
{
if( ul % 2 )
return false;
ul /= 2;
}
return true;
}
bool inputData(unsigned long & ulN, vector<complex<double> >& vecList)
{
//題目
cout<< "\n\n\n==============================Input Data===============================" << endl;
//輸入N
cout<< "\nInput N:";
cin>>ulN;
if(!Is2Power(ulN)) //驗證N的有效性
{
cout<< "N is invalid (N must like 2, 4, 8, .....), please retry." << endl;
return false;
}
//輸入各元素
vecList.clear(); //清空原有序列
complex<double> c;
for(unsigned long i = 0; i < ulN; i++)
{
cout << "Input x(" << i << "):";
cin >> c;
vecList.push_back(c);
}
return true;
}
bool readDataFromFile(unsigned long & ulN, vector<complex<double> >& vecList) //從文件中讀取數據
{
//題目
cout<< "\n\n\n===============Read Data From File==============" << endl;
//輸入文件名
string strfilename;
cout << "Input filename:" ;
cin >> strfilename;
//打開文件
cout << "open file " << strfilename << "......." <<endl;
ifstream loadfile;
loadfile.open(strfilename.c_str());
if(!loadfile)
{
cout << "\tfailed" << endl;
return false;
}
else
{
cout << "\tsucceed" << endl;
}
vecList.clear();
//讀取N
loadfile >> ulN;
if(!loadfile)
{
cout << "can't get N" << endl;
return false;
}
else
{
cout << "N = " << ulN << endl;
}
//讀取元素
complex<double> c;
for(unsigned long i = 0; i < ulN; i++)
{
loadfile >> c;
if(!loadfile)
{
cout << "can't get enough infomation" << endl;
return false;
}
else
cout << "x(" << i << ") = " << c << endl;
vecList.push_back(c);
}
//關閉文件
loadfile.close();
return true;
}
bool saveResultToFile(unsigned long & ulN, vector<complex<double> >& vecList) //保存結果至文件中
{
//詢問是否需要將結果保存至文件
char chChoose = ' ';
cout << "Do you want to save the result to file? (y/n):";
chChoose = _getch();
if(chChoose != 'y' && chChoose != 'Y')
{
return true;
}
//輸入文件名
string strfilename;
cout << "\nInput file name:" ;
cin >> strfilename;
cout << "Save result to file " << strfilename << "......" << endl;
//打開文件
ofstream savefile(strfilename.c_str());
if(!savefile)
{
cout << "can't open file" << endl;
return false;
}
//寫入N
savefile << ulN << endl;
//寫入元素
for(vector<complex<double> >::iterator i = vecList.begin(); i < vecList.end(); i++)
{
savefile << *i << endl;
}
//寫入完畢
cout << "save succeed." << endl;
//關閉文件
savefile.close();
return true;
}
void FFT(unsigned long & ulN, vector<complex<double> >& vecList)
{
//得到冪數
unsigned long ulPower = 0; //冪數
unsigned long ulN1 = ulN - 1;
while(ulN1 > 0)
{
ulPower++;
ulN1 /= 2;
}
//反序
bitset<sizeof(unsigned long) * 8> bsIndex; //二進制容器
unsigned long ulIndex; //反轉後的序號
unsigned long ulK;
for(unsigned long p = 0; p < ulN; p++)
{
ulIndex = 0;
ulK = 1;
bsIndex = bitset<sizeof(unsigned long) * 8>(p);
for(unsigned long j = 0; j < ulPower; j++)
{
ulIndex += bsIndex.test(ulPower - j - 1) ? ulK : 0;
ulK *= 2;
}
if(ulIndex > p)
{
complex<double> c = vecList[p];
vecList[p] = vecList[ulIndex];
vecList[ulIndex] = c;
}
}
//計算旋轉因子
vector<complex<double> > vecW;
for(unsigned long i = 0; i < ulN / 2; i++)
{
vecW.push_back(complex<double>(cos(2 * i * PI / ulN) , -1 * sin(2 * i * PI / ulN)));
}
for(unsigned long m = 0; m < ulN / 2; m++)
{
cout<< "\nvW[" << m << "]=" << vecW[m];
}
//計算FFT
unsigned long ulGroupLength = 1; //段的長度
unsigned long ulHalfLength = 0; //段長度的一半
unsigned long ulGroupCount = 0; //段的數量
complex<double> cw; //WH(x)
complex<double> c1; //G(x) + WH(x)
complex<double> c2; //G(x) - WH(x)
for(unsigned long b = 0; b < ulPower; b++)
{
ulHalfLength = ulGroupLength;
ulGroupLength *= 2;
for(unsigned long j = 0; j < ulN; j += ulGroupLength)
{
for(unsigned long k = 0; k < ulHalfLength; k++)
{
cw = vecW[k * ulN / ulGroupLength] * vecList[j + k + ulHalfLength];
c1 = vecList[j + k] + cw;
c2 = vecList[j + k] - cw;
vecList[j + k] = c1;
vecList[j + k + ulHalfLength] = c2;
}
}
}
}
void display(unsigned long & ulN, vector<complex<double> >& vecList)
{
cout << "\n\n===========================Display The Result=========================" << endl;
for(unsigned long d = 0; d < ulN;d++)
{
cout << "X(" << d << ")\t\t\t = " << vecList[d] << endl;
}
}
下面為STDAFX.H文件:
// stdafx.h : 標准系統包含文件的包含文件,
// 或是常用但不常更改的項目特定的包含文件
#pragma once
#include <iostream>
#include <tchar.h>
// TODO: 在此處引用程序要求的附加頭文件
下面為STDAFX.CPP文件:
// stdafx.cpp : 只包括標准包含文件的源文件
// FFT.pch 將成為預編譯頭
// stdafx.obj 將包含預編譯類型信息
#include "stdafx.h"
// TODO: 在 STDAFX.H 中
//引用任何所需的附加頭文件,而不是在此文件中引用
❺ 請給我一份用C語言編輯的用於計算DFT的程序
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
//#define MyE 2.7182818284590452354
//#define GET_ARRAY_LEN(array,len){len = (sizeof(array) / sizeof(array[0]));}
int main()
{
void fft();
int len,i; //len=N
printf("Input the size of the array: ");//設定數組大小
if (scanf("%d",&len)==EOF)
return 0;
double arr[len];
printf("Input the arry elements:\n");
for (i=0;i<len;i++)
{
printf("[%d]: (for example: 5<Enter>)",i);
scanf("%lf",&arr[i]);
}
// int len;//自定義長度
// GET_ARRAY_LEN(a,len);
// printf("%d\n",len);
printf("Result is :\n");
fft(arr,len);
return 0;
}
void fft(double a[],int lang)
{
int N;
int n,k;
N=lang;
double sumsin=0,sumcos=0;
for (k=0;k<N;k++)
{
for (n=0;n<N;n++)
{
sumcos=sumcos+cos(n*k*8*atan(1)/N)*a[n]; //8*atan(1)=2π
//printf("n=%d,sumcos=%.1lf",n,sumcos);
//printf("\n");
sumsin=sumsin+(-1)*sin(n*k*8*atan(1)/N)*a[n];
//printf("n=%d,sumcos=%.1lf",n,sumsin);
//printf("\n");
}
printf("x[%d]= %.1lf + %.1lfj",k,sumcos,sumsin);
sumcos=0;
sumsin=0;
printf("\n");
}
}
【請尊重我的勞動成果,若滿意,請及時採納~~謝謝!!】
❻ 如何根據基於dft的對數幅度譜估計某幀濁音的基音周期
如何根據基於dft的對數幅度譜估計某幀濁音的基音周期
2?運算符豐富。共有34種。C把括弧、賦值、逗號等都作為運算符處理。從而使C的運算類型極為豐富,可以實現其他高級語言難以實現的運算。
3?數據結構類型豐富。
4?具有結構化的控制語句。
5?語法限制不太嚴格,程序設計自由度大。
6?C語言允許直接訪問物理地址,能進行位(bit)操作,能實現匯編語言的大部分功能,可以直接對硬體進行操作。因此有人把它稱為中級語言。
7?生成目標代碼質量高,程序執行效率高。
8?與匯編語言相比,用C語言寫的程序可移植性好。
但是,C語言對程序員要求也高,程序員用C寫程序會感到限制少、靈活性大,功能強,但較其他高級語言在學習上要困難一些。
1.5 面向對象的程序設計語言
❼ C語言計算基波幅值和功率因數,高人指點!
很高深啊