163 #define OUTPUT_FILE     "impulse.txt" 
  167 #define M_SQRT2PI   2.50662827463100050241576528481104525 
  174     puts(
"Gaussian benchmark, P. Getreuer 2012-2013");
 
  176     puts(
"Configuration: single-precision computation");
 
  178     puts(
"Configuration: double-precision computation");
 
  180     puts(
"\nSyntax: gaussian_bench [bench type] [options] [output]\n");
 
  182     puts(
"   speed         measure computation time");
 
  183     puts(
"   accuracy      measure L^infty operator norm error");
 
  184     puts(
"   impulse       impulse response, written to " OUTPUT_FILE "\n");
 
  186     puts(
"   -a <algo>     algorithm to use, choices are");
 
  187     puts(
"                 fir     FIR approximation, tol = kernel accuracy");
 
  188     puts(
"                 dct     DCT-based convolution");
 
  189     puts(
"                 box     box filtering, K = # passes");
 
  190     puts(
"                 sii     stacked integral images, K = # boxes");
 
  191     puts(
"                 am_orig Alvarez-Mazorra original method,");
 
  192     puts(
"                         K = # passes, tol = boundary accuracy");
 
  193     puts(
"                 am      Alvarez-Mazorra using regression on q,");
 
  194     puts(
"                         K = # passes, tol = boundary accuracy");
 
  195     puts(
"                 deriche Deriche recursive filtering,");
 
  196     puts(
"                         K = order, tol = boundary accuracy");
 
  197     puts(
"                 vyv     Vliet-Young-Verbeek recursive filtering,");
 
  198     puts(
"                         K = order, tol = boundary accuracy");
 
  199     puts(
"   -s <number>   sigma, standard deviation of the Gaussian");
 
  200     puts(
"   -K <number>   specifies number of steps (box, sii, am)");
 
  201     puts(
"   -t <number>   accuracy tolerance (fir, am, deriche, vyv)");
 
  202     puts(
"   -N <number>   signal length\n");
 
  203     puts(
"   -r <number>   (speed bench) number of runs");
 
  204     puts(
"   -n <number>   (impulse bench) position of the impulse\n");
 
  225     unsigned long time_start, time_stop;
 
  234     for (run = 0; run < p.
num_runs; ++run)
 
  239         ((
double)(time_stop - time_start)) / p.
num_runs);
 
  244 void make_impulse_signal(
num *signal, 
long N, 
long n0)
 
  248     for (n = 0; n < N; ++n)
 
  256     double *error_sums = NULL;
 
  258     gconv *g0 = NULL, *g = NULL;
 
  259     double linf_norm = 0.0;
 
  263     if (!(error_sums = (
double *)malloc(
sizeof(
double) * p.
N))
 
  264         || !(output0 = (
num *)malloc(
sizeof(
num) * p.
N))
 
  266             "fir", p.
sigma, p.
K, 1e-15))
 
  271     for (n = 0; n < p.
N; ++n)
 
  274     for (n = 0; n < p.
N; ++n)
 
  276         make_impulse_signal(input, p.
N, n);
 
  280         for (m = 0; m < p.
N; ++m)
 
  281             error_sums[m] += fabs((
double)output0[m] - (
double)output[m]);
 
  284     for (n = 0; n < p.
N; ++n)
 
  285         if (error_sums[n] > linf_norm)
 
  286             linf_norm = error_sums[n];
 
  288     printf(
"%.8e\n", linf_norm);
 
  300 int write_output(
const char *filename, 
num *output, 
num *exact, 
long N)
 
  305     if (!(f = fopen(filename, 
"wt")))
 
  308     fprintf(f, 
"# n\toutput value\texact value\n");
 
  310     for (n = 0; n < N; ++n)
 
  311         fprintf(f, 
"%ld\t%.16e\t%.16e\n", n, output[n], exact[n]);
 
  320     gconv *g = NULL, *g_exact = NULL;
 
  323     if (!(exact = (
num *)malloc(
sizeof(
num) * p.
N))
 
  327             "fir", p.
sigma, p.
K, 1e-15)))
 
  330     make_impulse_signal(input, p.
N, p.
n0);
 
  346 int main(
int argc, 
char **argv)
 
  357     if (!(input = (
num *)malloc(
sizeof(
num) * param.
N))
 
  358         || !(output = (
num *)malloc(
sizeof(
num) * param.
N)))
 
  360         fprintf(stderr, 
"Out of memory\n");
 
  366         if (!speed_test(param, output, input))
 
  369     else if (!strcmp(param.
bench_type, 
"accuracy"))
 
  371         if (!accuracy_test(param, output, input))
 
  374     else if (!strcmp(param.
bench_type, 
"impulse"))
 
  376         if (!impulse_test(param, output, input))
 
  381         fprintf(stderr, 
"Invalid bench type \"%s\"\n", param.
bench_type);
 
  388         fprintf(stderr, 
"Bench %s failed\n", param.
bench_type);
 
  399     static const char *default_algo = (
const char *)
"exact";
 
  417     param->
algo = default_algo;
 
  421     for (i = 2; i < argc;)
 
  423         if (argv[i] && argv[i][0] == 
'-')
 
  425             if ((option_char = argv[i][1]) == 0)
 
  427                 fprintf(stderr, 
"Invalid parameter format.\n");
 
  432                 option_string = &argv[i][2];
 
  434                 option_string = argv[i];
 
  437                 fprintf(stderr, 
"Invalid parameter format.\n");
 
  444                 param->
algo = option_string;
 
  447                 param->
sigma = atof(option_string);
 
  449                 if (param->
sigma < 0)
 
  451                     fprintf(stderr, 
"sigma must be positive.\n");
 
  456                 param->
K = atoi(option_string);
 
  460                     fprintf(stderr, 
"K must be positive.\n");
 
  465                 param->
tol = atof(option_string);
 
  469                     fprintf(stderr, 
"Tolerance must be positive.\n");
 
  474                 param->
N = atoi(option_string);
 
  478                     fprintf(stderr, 
"Signal length must be positive.\n");
 
  483                 param->
num_runs = (long)atof(option_string);
 
  487                     fprintf(stderr, 
"Number of runs must be positive.\n");
 
  492                 param->
n0 = atoi(option_string);
 
  498                 if (isprint(option_char))
 
  499                     fprintf(stderr, 
"Unknown option \"-%c\".\n", option_char);
 
  501                     fprintf(stderr, 
"Unknown option.\n");
 
  512     if (param->
n0 < 0 || param->
n0 >= param->
N)
 
  513         param->
n0 = (param->
N + 1) / 2;