/**
* Benchmark kernels for digital signal processing. The four kernels are
* sinc interpolation, recursive filtering, convolution, and fast Fourier
* transform.
*
* This program is self-contained. It depends on only standard C++ libraries.
* @author Dave Hale, Colorado School of Mines
* @version 2005.10.06
*/
#include
#include
#include
using namespace std;
static const double MAXTIME = 2.0;
/////////////////////////////////////////////////////////////////////////////
// stopwatch
class Stopwatch {
public:
Stopwatch() : running_(false), time_(0.0) {
}
void start() {
if (!running_) {
running_ = true;
start_ = std::clock();
}
}
void stop() {
if (running_) {
time_ = timeSinceStart();
running_ = false;
}
}
void reset() {
stop();
time_ = 0.0;
}
void restart() {
reset();
start();
}
double time() const {
if (running_) {
return time_+timeSinceStart();
} else {
return time_;
}
}
private:
bool running_;
clock_t start_;
double time_;
double timeSinceStart() const {
return ((double)(std::clock()-start_))/CLOCKS_PER_SEC;
}
};
/////////////////////////////////////////////////////////////////////////////
// utilities
float sum(int n, const float* a) {
float s = 0.0f;
for (int i=0; i=0 && kyin<=nxinm) {
for (int isinc=0; isinc=b)?a:b;
}
int min(int a, int b) {
return (a<=b)?a:b;
}
void convolution(
int lx, int kx, const float* x,
int ly, int ky, const float* y,
int lz, int kz, float* z)
{
if (lx>ly) {
int lt = lx; lx = ly; ly = lt;
int kt = kx; kx = ky; ky = kt;
const float* t = x; x = y; y = t;
}
int imin = kz-kx-ky;
int imax = imin+lz-1;
int i,ilo,ihi,j,jlo,jhi,iz;
float sa,sb,xa,xb,ya,yb;
ilo = imin;
ihi = min(-1,imax);
for (i=ilo,iz=i-imin; i<=ihi; ++i,++iz)
z[iz] = 0.0f;
ilo = max(0,imin);
ihi = min(lx-2,imax);
jlo = 0;
jhi = ilo;
for (i=ilo,iz=i-imin; iilo; i-=2,iz-=2,jlo-=2) {
sa = 0.0f;
sb = 0.0f;
yb = y[i-jhi-1];
for (j=jhi; j>jlo; j-=2) {
xa = x[j];
sb += xa*yb;
ya = y[i-j];
sa += xa*ya;
xb = x[j-1];
sb += xb*ya;
yb = y[i-j+1];
sa += xb*yb;
}
xa = x[j];
sb += xa*yb;
if (j==jlo) {
ya = y[i-j];
sa += xa*ya;
xb = x[j-1];
sb += xb*ya;
}
z[iz ] = sa;
z[iz-1] = sb;
}
if (i==ilo) {
jlo = i-ly+1;
jhi = lx-1;
sa = 0.0f;
for (j=jhi; j>=jlo; --j)
sa += x[j]*y[i-j];
z[iz] = sa;
}
ilo = max(lx+ly-1,imin);
ihi = imax;
for (i=ilo,iz=i-imin; i<=ihi; ++i,++iz)
z[iz] = 0.0f;
}
///////////////////////////////////////////////////////////////////////////
// FFT
static const int NFAC = 10;
static const int _kfac[] = {16,13,11,9,8,7,5,4,3,2};
static const float P120 = 0.120536680f;
static const float P142 = 0.142314838f;
static const float P173 = 0.173648178f;
static const float P222 = 0.222520934f;
static const float P239 = 0.239315664f;
static const float P281 = 0.281732557f;
static const float P342 = 0.342020143f;
static const float P354 = 0.354604887f;
static const float P382 = 0.382683432f;
static const float P415 = 0.415415013f;
static const float P433 = 0.433883739f;
static const float P464 = 0.464723172f;
static const float P540 = 0.540640817f;
static const float P559 = 0.559016994f;
static const float P568 = 0.568064747f;
static const float P587 = 0.587785252f;
static const float P623 = 0.623489802f;
static const float P642 = 0.642787610f;
static const float P654 = 0.654860734f;
static const float P663 = 0.663122658f;
static const float P707 = 0.707106781f;
static const float P748 = 0.748510748f;
static const float P755 = 0.755749574f;
static const float P766 = 0.766044443f;
static const float P781 = 0.781831482f;
static const float P822 = 0.822983866f;
static const float P841 = 0.841253533f;
static const float P866 = 0.866025404f;
static const float P885 = 0.885456026f;
static const float P900 = 0.900968868f;
static const float P909 = 0.909631995f;
static const float P923 = 0.923879533f;
static const float P935 = 0.935016243f;
static const float P939 = 0.939692621f;
static const float P951 = 0.951056516f;
static const float P959 = 0.959492974f;
static const float P970 = 0.970941817f;
static const float P974 = 0.974927912f;
static const float P984 = 0.984807753f;
static const float P989 = 0.989821442f;
static const float P992 = 0.992708874f;
static const float PONE = 1.000000000f;
void pfa2(float* z, int mu, int m,
int j0, int j1)
{
for (int i=0; i