/**
* 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
double sum(int n, const double* a) {
double s = 0.0;
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 double* x,
int ly, int ky, const double* y,
int lz, int kz, double* z)
{
if (lx>ly) {
int lt = lx; lx = ly; ly = lt;
int kt = kx; kx = ky; ky = kt;
const double* t = x; x = y; y = t;
}
int imin = kz-kx-ky;
int imax = imin+lz-1;
int i,ilo,ihi,j,jlo,jhi,iz;
double 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.0;
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.0;
sb = 0.0;
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.0;
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.0;
}
///////////////////////////////////////////////////////////////////////////
// FFT
static const int NFAC = 10;
static const int _kfac[] = {16,13,11,9,8,7,5,4,3,2};
static const double P120 = 0.120536680;
static const double P142 = 0.142314838;
static const double P173 = 0.173648178;
static const double P222 = 0.222520934;
static const double P239 = 0.239315664;
static const double P281 = 0.281732557;
static const double P342 = 0.342020143;
static const double P354 = 0.354604887;
static const double P382 = 0.382683432;
static const double P415 = 0.415415013;
static const double P433 = 0.433883739;
static const double P464 = 0.464723172;
static const double P540 = 0.540640817;
static const double P559 = 0.559016994;
static const double P568 = 0.568064747;
static const double P587 = 0.587785252;
static const double P623 = 0.623489802;
static const double P642 = 0.642787610;
static const double P654 = 0.654860734;
static const double P663 = 0.663122658;
static const double P707 = 0.707106781;
static const double P748 = 0.748510748;
static const double P755 = 0.755749574;
static const double P766 = 0.766044443;
static const double P781 = 0.781831482;
static const double P822 = 0.822983866;
static const double P841 = 0.841253533;
static const double P866 = 0.866025404;
static const double P885 = 0.885456026;
static const double P900 = 0.900968868;
static const double P909 = 0.909631995;
static const double P923 = 0.923879533;
static const double P935 = 0.935016243;
static const double P939 = 0.939692621;
static const double P951 = 0.951056516;
static const double P959 = 0.959492974;
static const double P970 = 0.970941817;
static const double P974 = 0.974927912;
static const double P984 = 0.984807753;
static const double P989 = 0.989821442;
static const double P992 = 0.992708874;
static const double PONE = 1.000000000;
void pfa2(double* z, int mu, int m,
int j0, int j1)
{
for (int i=0; i