chiark / gitweb /
helixish: debugging changes
[moebius3.git] / findcurve.c
1 /*
2  */
3
4 #include <math.h>
5
6 #include <gsl/gsl_errno.h>
7 #include <gsl/gsl_sf.h>
8 #include <gsl/gsl_siman.h>
9 #include <gsl/gsl_randist.h>
10
11 #include "symbolic.c"
12
13 #define X(i) x[i]
14 #define J_END_COL(i) \
15   for (j=0; j<N; 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 double target[N];
26
27 static double cb_Efunc(void *xp) {
28   const double *x = xp;
29   double F[N], e;
30   int i;
31   X_EXTRACT;
32   F_POPULATE;
33   for (i=0, e=0; i<N; i++) {
34     double d = F[i] - target[i];
35     e += d*d;
36   }
37   return e;
38 }
39
40 static void cb_step(const gsl_rng *rng, void *xp, double step_size) {
41   double *x = xp;
42   int i;
43   double step[N];
44   gsl_ran_dir_nd(rng, N,step);
45   for (i=0; i<N; i++)
46     x[i] += step_size * step[i];
47   //printf("\n cb_step %p %.18g [", xp, step_size);
48   //for (i=0; i<N; i++) printf(" %.18g,", step[i]);
49   //printf("]\n");
50 }
51
52 static double cb_metric(void *xp, void *yp) {
53   const double *x=xp, *y=yp;
54   int i;
55   double s;
56   for (i=0, s=0; i<N; i++) {
57     double d = x[i] - y[i];
58     s += d*d;
59   }
60   return sqrt(s);
61 }
62
63 static void printcore(const double *x) {
64   int i;
65   double F[N];
66   X_EXTRACT;
67   F_POPULATE;
68   printf("[");
69   for (i=0; i<6; i++) printf(" %.18g,", x[i]);
70   for (i=0; i<6; i++) printf(" %.18g,", F[i]);
71   printf(" ]\n");
72 }
73
74 static void __attribute__((unused)) cb_print(void *xp) {
75   const double *x = xp;
76   printf("\n");
77   printcore(x);
78 }
79
80 static double scan1double(void) {
81   double v;
82   int r;
83
84   r = scanf("%lf",&v);
85   if (ferror(stdin)) { perror("stdin"); exit(-1); }
86   if (feof(stdin)) exit(0);
87   if (r!=1) { fputs("bad input\n",stderr); exit(-1); }
88   return v;
89 }
90
91 int main(void) {
92   double epsilon;
93   int i;
94
95   double startpoint[N];
96
97   gsl_rng *rng = gsl_rng_alloc(gsl_rng_ranlxd2);
98
99   for (;;) {
100     /* 2N+1 doubles: target, initial guess, epsilon for residual */
101     for (i=0; i<N; i++)
102       target[i] = scan1double();
103     for (i=0; i<N; i++)
104       startpoint[i] = scan1double();
105     epsilon = scan1double();
106
107     gsl_rng_set(rng,0);
108
109     gsl_siman_params_t siman_params = {
110       .k = 1.0,
111       .t_initial = 0.5,
112       .mu_t = 1.001,
113       .t_min = epsilon * 1E-3,
114     };
115
116     gsl_siman_solve(rng,
117                     startpoint,
118                     cb_Efunc, cb_step, cb_metric,
119                     0, // cb_print,
120                     0,0,0, sizeof(startpoint), siman_params);
121
122     printcore(startpoint);
123
124     printf("[]\n");
125     fflush(stdout);
126   }
127 }