diff src/fftw-3.3.3/support/addchain.c @ 10:37bf6b4a2645

Add FFTW3
author Chris Cannam
date Wed, 20 Mar 2013 15:35:50 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/fftw-3.3.3/support/addchain.c	Wed Mar 20 15:35:50 2013 +0000
@@ -0,0 +1,171 @@
+/* addition-chain optimizer */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static int verbose;
+static int mulcost = 18;
+static int ldcost = 2;
+static int sqcost = 10;
+static int reflcost = 8;
+#define INFTY 100000
+
+static int *answer;
+static int best_so_far;
+
+static void print_answer(int n, int t)
+{
+     int i;
+     printf("| (%d, %d) -> [", n, t);
+     for (i = 0; i < t; ++i)
+	  printf("%d;", answer[i]);
+     printf("] (* %d *)\n", best_so_far);
+}
+
+#define DO(i, j, k, cst)			\
+if (k < n) {					\
+     int c = A[i] + A[j] + cst;			\
+     if (c < A[k]) {				\
+	  A[k] = c;				\
+	  changed = 1;				\
+     }						\
+}
+
+#define DO3(i, j, l, k, cst)			\
+if (k < n) {					\
+     int c = A[i] + A[j] + A[l] + cst;		\
+     if (c < A[k]) {				\
+	  A[k] = c;				\
+	  changed = 1;				\
+     }						\
+}
+
+static int optimize(int n, int *A)
+{
+     int i, j, k, changed, cst, cstmax;
+
+     do {
+	  changed = 0;
+	  for (i = 0; i < n; ++i) {
+	       k = i + i;
+	       DO(i, i, k, sqcost);
+	  }
+
+	  for (i = 0; i < n; ++i) {
+	       for (j = 0; j <= i; ++j) {
+		    k = i + j;
+		    DO(i, j, k, mulcost);
+		    k = i - j;
+		    DO(i, j, k, mulcost);
+
+		    k = i + j;
+		    DO3(i, j, i - j, k, reflcost);
+	       }
+	  }
+
+     } while (changed);
+
+     cst = cstmax = 0;
+     for (i = 0; i < n; ++i) {
+	  cst += A[i];
+	  if (A[i] > cstmax) cstmax = A[i];
+     }
+/*     return cstmax; */
+     return cst;
+}
+
+static void search(int n, int t, int *A, int *B, int depth)
+{
+     if (depth == 0) {
+	  int i, tc;
+	  for (i = 0; i < n; ++i)
+	       A[i] = INFTY;
+	  A[0] = 0;		/* always free */
+	  for (i = 1; i <= t; ++i)
+	       A[B[-i]] = ldcost;
+
+	  tc = optimize(n, A);
+	  if (tc < best_so_far) {
+	       best_so_far = tc;
+	       for (i = 1; i <= t; ++i)
+		    answer[t - i] = B[-i];
+	       if (verbose)
+		    print_answer(n, t);
+	  }
+     } else {
+	  for (B[0] = B[-1] + 1; B[0] < n; ++B[0])
+	       search(n, t, A, B + 1, depth - 1);
+     }
+}
+
+static void doit(int n, int t)
+{
+     int *A;
+     int *B;
+
+     A = malloc(n * sizeof(int));
+     B = malloc((t + 1) * sizeof(int));
+     answer = malloc(t * sizeof(int));
+
+     B[0] = 0;
+     best_so_far = INFTY;
+     search(n, t, A, B + 1, t);
+
+     print_answer(n, t);
+
+     free(A); free(B); free(answer);
+}
+
+int main(int argc, char *argv[])
+{
+     int n = 32;
+     int t = 3;
+     int all;
+     int ch;
+
+     verbose = 0;
+     all = 0;
+     while ((ch = getopt(argc, argv, "n:t:m:l:r:s:va")) != -1) {
+	  switch (ch) {
+	  case 'n':
+	       n = atoi(optarg);
+	       break;
+	  case 't':
+	       t = atoi(optarg);
+	       break;
+	  case 'm':
+	       mulcost = atoi(optarg);
+	       break;
+	  case 'l':
+	       ldcost = atoi(optarg);
+	       break;
+	  case 's':
+	       sqcost = atoi(optarg);
+	       break;
+	  case 'r':
+	       reflcost = atoi(optarg);
+	       break;
+	  case 'v':
+	       ++verbose;
+	       break;
+	  case 'a':
+	       ++all;
+	       break;
+	  case '?':
+	       fprintf(stderr, "use the source\n");
+	       exit(1);
+	  }
+     }
+
+     if (all) {
+	  for (n = 4; n <= 64; n *= 2) {
+	       int n1 = n - 1; if (n1 > 7) n1 = 7;
+	       for (t = 1; t <= n1; ++t)
+		    doit(n, t);
+	  }
+     } else {
+	  doit(n, t);
+     }
+
+     return 0;
+}