chiark / gitweb /
curveopt: try simple, but no good
[moebius3.git] / findcurve.c
index 695277887b3ce6e2c70b6f9cda5533cdb101c111..ca3cd8fd4ae76c2ab12ddcd5cdccc7b4e0d1cb6a 100644 (file)
@@ -2,16 +2,19 @@
  */
 
 #include <math.h>
+#include <string.h>
+#include <assert.h>
 
 #include <gsl/gsl_errno.h>
 #include <gsl/gsl_sf.h>
-#include <gsl/gsl_multiroots.h>
+#include <gsl/gsl_siman.h>
+#include <gsl/gsl_randist.h>
+#include <gsl/gsl_multimin.h>
 
 #include "symbolic.c"
 
-#define X(i) gsl_vector_get(x,i)
 #define J_END_COL(i) \
-  for (j=0; j<N; j++) gsl_matrix_set(J,i,j,J_COL[j]);
+  for (j=0; j<PN; j++) gsl_matrix_set(J,i,j,J_COL[j]);
 
 static inline _Bool IS_SMALL(double v) {
   return v < 1E6;
@@ -21,30 +24,85 @@ static inline double sinc(double x) {
   return gsl_sf_sinc(x / M_PI);
 }
 
-static int cb_f(const gsl_vector *x, void *params, gsl_vector *f) {
-  double *target = params;
-  double F[6];
+static int NP;
+static double *INPUT; /* dyanmic array, on main's stack */
+static double PREP[NPREP];
 
+#define GET_X(xg)                                      \
+  double X[NX];                                                \
+  ({ int get_x_i;                                      \
+     for (get_x_i=0; get_x_i<NX; get_x_i++)            \
+       X[get_x_i] = gsl_vector_get(xg, get_x_i);       \
+  })
+
+static void printcore(const double *X) {
+  int i, j;
+  DECLARE_F_G;
+  CALCULATE_F_G;
+  printf("[");
+  for (i=0; i<NP; i++)
+    for (j=0; j<3; j++)
+      printf(" %25.18g,", POINT(i)[j]);
+  printf(" ]\n");
+}
+
+static void prepare(double X[] /* startpoint */) {
+  /* fills in PREP and startpoint */
+  PREPARE;
+}
+
+//#define DEBUG
+
+static double cb_f(const gsl_vector *xg, void *params) {
+  int P;
+
+  GET_X(xg);
+
+  DECLARE_F_G;
+  CALCULATE_F_G;
+
+#ifdef DEBUG
+  int i,j;
+  printf(" Efunc\n");
+  for (j=0; j<3; j++) {
+    for (P=0; P<NP; P++)
+      printf(" %7.4f", POINT(P)[j]);
+    printf("\n");
+  }
+  printf("             ");
+#endif
+
+  CALCULATE_COST;
+  return cost;
+}
+
+static void __attribute__((unused))  cb_step(const gsl_rng *rng, void *xp, double step_size) {
+  double *x = xp;
   int i;
-  X_EXTRACT;
-  F_POPULATE;
-  for (i=0; i<N; i++) gsl_vector_set(f,i, F[i] - target[i]);
-  return 0;
+  double step[NX];
+  gsl_ran_dir_nd(rng, NX, step);
+  for (i=0; i<NX; i++)
+    x[i] += step_size * step[i];
+  //printf("\n cb_step %p %10.7f [", xp, step_size);
+  //for (i=0; i<N; i++) printf(" %10.7f,", step[i]);
+  //printf("]\n");
 }
 
-static int cb_df(const gsl_vector *x, void *params, gsl_matrix *J) {
-  double J_COL[N];
-  int j;
-  X_EXTRACT;
-  J_POPULATE;
-  return 0;
+static double __attribute__((unused))  cb_metric(void *xp, void *yp) {
+  const double *x=xp, *y=yp;
+  int i;
+  double s;
+  for (i=0, s=0; i<NX; i++) {
+    double d = x[i] - y[i];
+    s += d*d;
+  }
+  return sqrt(s);
 }
 
-static int cb_fdf(const gsl_vector *x, void *params,
-                 gsl_vector *f, gsl_matrix *J) {
-  cb_f(x,params,f);
-  cb_df(x,params,J);
-  return 0;
+static void __attribute__((unused)) cb_print(gsl_vector *xp) {
+  GET_X(xp);
+  printf("\n");
+  printcore(X);
 }
 
 static double scan1double(void) {
@@ -58,61 +116,56 @@ static double scan1double(void) {
   return v;
 }
 
-int main(void) {
-  double target[N], epsilon;
-  int i, j;
+int main(int argc, const char *const *argv) {
+  double epsilon;
+  int i, r;
+
+  NP = atoi(argv[1]);
+  epsilon = atof(argv[2]);
 
-  gsl_multiroot_function_fdf function;
-  function.f = cb_f;
-  function.df = cb_df;
-  function.fdf = cb_fdf;
-  function.n = N;
-  function.params = target;
+  double startpoint_X[NX];
+  double input[NINPUT]; INPUT = input;
 
-  gsl_vector *startpoint = gsl_vector_alloc(N);
+  gsl_multimin_function func = {
+    .f = cb_f,
+    .n = NX,
+    .params = 0,
+  };
 
-  gsl_multiroot_fdfsolver *solver
-    = gsl_multiroot_fdfsolver_alloc(gsl_multiroot_fdfsolver_hybridsj, N);
+  gsl_vector *current_gx = gsl_vector_alloc(NX);
+  gsl_vector *step_size = gsl_vector_alloc(NX);
+  gsl_vector_set_all(step_size, 0.01);
+
+  gsl_multimin_fminimizer *minimiser =
+    gsl_multimin_fminimizer_alloc(gsl_multimin_fminimizer_nmsimplex2rand, NX);
 
   for (;;) {
-    /* 2N+1 doubles: target, initial guess, epsilon for residual */
-    for (i=0; i<N; i++)
-      target[i] = scan1double();
-    for (i=0; i<N; i++)
-      gsl_vector_set(startpoint,i,scan1double());
-    epsilon = scan1double();
+    /* NINPUT + 1 doubles: startpoint, epsilon for residual */
+    for (i=0; i<NINPUT; i++)
+      INPUT[i] = scan1double();
+
+    prepare(startpoint_X);
+    for (i=0; i<NX; i++)
+      gsl_vector_set(current_gx, i, startpoint_X[i]);
 
-    gsl_multiroot_fdfsolver_set(solver, &function, startpoint);
+    r = gsl_multimin_fminimizer_set(minimiser, &func, current_gx, step_size);
+    assert(!r);
 
-    int r;
     for (;;) {
-      r = gsl_multiroot_fdfsolver_iterate(solver);
-      if (r) break;
-
-      printf("[");
-      for (i=0; i<6; i++) printf(" %.18g,", gsl_vector_get(solver->x, i));
-      for (i=0; i<6; i++) printf(" %.18g,",
-                                target[i] + gsl_vector_get(solver->f, i));
-      printf(" ]\n");
-
-      r = gsl_multiroot_test_residual(solver->f, epsilon);
-      if (r != GSL_CONTINUE) break;
-    }
-
-    if (r) {
-      gsl_matrix *j_dump = gsl_matrix_alloc(N,N);
-      cb_df(solver->x, target, j_dump);
-      fprintf(stderr,"// FC J %35s %35s", "d(Q)/", "d(dQ)/\n");
-      for (i=0; i<6; i++) {
-       fprintf(stderr,"// FC J d./d%-6s ", PARAM_NAMES[i]);
-       for (j=0; j<6; j++)
-         fprintf(stderr," %10.5f,", gsl_matrix_get(j_dump, i, j));
-       fprintf(stderr,"\n");
-      }
-      fprintf(stderr,"ERROR %s\n",gsl_strerror(r));
-      exit(-1);
-    }
+      r = gsl_multimin_fminimizer_iterate(minimiser);
+      assert(!r);
+
+      //cb_print(current_gx);
+
+      double size = gsl_multimin_fminimizer_size(minimiser);
+      //printf(" size=%10.7f\n", size);
+
+      if (size < epsilon) break;
+    }      
+
+    cb_print(current_gx);
 
     printf("[]\n");
+    fflush(stdout);
   }
 }