chiark / gitweb /
simplex wip: use gsl_vector_get for X, for abandonment
[moebius3.git] / findcurve.c
1 /*
2  */
3
4 #include <math.h>
5 #include <string.h>
6
7 #include <gsl/gsl_errno.h>
8 #include <gsl/gsl_sf.h>
9 #include <gsl/gsl_siman.h>
10 #include <gsl/gsl_randist.h>
11
12 #include "symbolic.c"
13
14 #define J_END_COL(i) \
15   for (j=0; j<PN; j++) gsl_matrix_set(J,i,j,J_COL[j]);
16
17 static inline _Bool IS_SMALL(double v) {
18   return v < 1E6;
19 }
20
21 static inline double sinc(double x) {
22   return gsl_sf_sinc(x / M_PI);
23 }
24
25 static int NP;
26 static double *INPUT; /* dyanmic array, on main's stack */
27 static double PREP[NPREP];
28
29 #define X(xi) gsl_vector_get(xg, (xi))
30
31 static void printcore(gsl_vector *xg) {
32   int i, j;
33   DECLARE_F_G;
34   CALCULATE_F_G;
35   printf("[");
36   for (i=0; i<NP; i++)
37     for (j=0; j<3; j++)
38       printf(" %25.18g,", POINT(i,j));
39   printf(" ]\n");
40 }
41
42 static void prepare(double X[] /* startpoint */) {
43   /* fills in PREP and startpoint */
44   PREPARE;
45 }
46
47 //#define DEBUG
48
49 static double cb_f(const gsl_vector *xg, void *params) {
50   int P;
51   DECLARE_F_G;
52   CALCULATE_F_G;
53
54 #ifdef DEBUG
55   int i,j;
56   printf(" Efunc\n");
57   for (j=0; j<3; j++) {
58     for (P=0; P<NP; P++)
59       printf(" %7.4f", POINT(P)[j]);
60     printf("\n");
61   }
62   printf("             ");
63 #endif
64
65   CALCULATE_COST;
66   return cost;
67 }
68
69 static void cb_step(const gsl_rng *rng, void *xp, double step_size) {
70   double *x = xp;
71   int i;
72   double step[NX];
73   gsl_ran_dir_nd(rng, NX, step);
74   for (i=0; i<NX; i++)
75     x[i] += step_size * step[i];
76   //printf("\n cb_step %p %10.7f [", xp, step_size);
77   //for (i=0; i<N; i++) printf(" %10.7f,", step[i]);
78   //printf("]\n");
79 }
80
81 static double cb_metric(void *xp, void *yp) {
82   const double *x=xp, *y=yp;
83   int i;
84   double s;
85   for (i=0, s=0; i<NX; i++) {
86     double d = x[i] - y[i];
87     s += d*d;
88   }
89   return sqrt(s);
90 }
91
92 static void __attribute__((unused)) cb_print(void *xp) {
93   const double *x = xp;
94   printf("\n");
95   printcore(x);
96 }
97
98 static double scan1double(void) {
99   double v;
100   int r;
101
102   r = scanf("%lf",&v);
103   if (ferror(stdin)) { perror("stdin"); exit(-1); }
104   if (feof(stdin)) exit(0);
105   if (r!=1) { fputs("bad input\n",stderr); exit(-1); }
106   return v;
107 }
108
109 int main(int argc, const char *const *argv) {
110   double epsilon;
111   int i;
112
113   NP = atoi(argv[1]);
114   epsilon = atof(argv[2]);
115
116   gsl_rng *rng = gsl_rng_alloc(gsl_rng_ranlxd2);
117
118   double input[NINPUT]; INPUT = input;
119   double startpoint[NX];
120
121   for (;;) {
122     /* NINPUT + 1 doubles: startpoint, epsilon for residual */
123     for (i=0; i<NINPUT; i++)
124       INPUT[i] = scan1double();
125
126     gsl_rng_set(rng,0);
127
128     gsl_siman_params_t siman_params = {
129       .k = 1.0,
130       .t_initial = 0.5,
131       .mu_t = 1.001,
132       .t_min = epsilon * 1E-3,
133       .iters_fixed_T = 100,
134       .n_tries = 10,
135       .step_size = 0.05,
136     };
137
138     prepare(startpoint);
139
140     gsl_siman_solve(rng,
141                     startpoint,
142                     cb_Efunc, cb_step, cb_metric,
143                     0, // cb_print,
144                     0,0,0, sizeof(startpoint), siman_params);
145
146     printcore(startpoint);
147
148     printf("[]\n");
149     fflush(stdout);
150   }
151 }