chiark / gitweb /
helixish: attempt at the whole thing
[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   //printf("\n cb_Efunc %p %10.7f [", xp, e);
38   //for (i=0; i<N; i++) printf(" %10.7f,", x[i]);
39   //printf("]\n");
40   return e;
41 }
42
43 static void cb_step(const gsl_rng *rng, void *xp, double step_size) {
44   double *x = xp;
45   int i;
46   double step[N];
47   gsl_ran_dir_nd(rng, N,step);
48   for (i=0; i<N; i++)
49     x[i] += step_size * step[i];
50   //printf("\n cb_step %p %10.7f [", xp, step_size);
51   //for (i=0; i<N; i++) printf(" %10.7f,", step[i]);
52   //printf("]\n");
53 }
54
55 static double cb_metric(void *xp, void *yp) {
56   const double *x=xp, *y=yp;
57   int i;
58   double s;
59   for (i=0, s=0; i<N; i++) {
60     double d = x[i] - y[i];
61     s += d*d;
62   }
63   return sqrt(s);
64 }
65
66 static void printcore(const double *x) {
67   int i;
68   double F[N];
69   X_EXTRACT;
70   F_POPULATE;
71   printf("[");
72   for (i=0; i<6; i++) printf(" %.18g,", x[i]);
73   for (i=0; i<6; i++) printf(" %.18g,", F[i]);
74   printf(" ]\n");
75 }
76
77 static void __attribute__((unused)) cb_print(void *xp) {
78   const double *x = xp;
79   printf("\n");
80   printcore(x);
81 }
82
83 static double scan1double(void) {
84   double v;
85   int r;
86
87   r = scanf("%lf",&v);
88   if (ferror(stdin)) { perror("stdin"); exit(-1); }
89   if (feof(stdin)) exit(0);
90   if (r!=1) { fputs("bad input\n",stderr); exit(-1); }
91   return v;
92 }
93
94 int main(void) {
95   double epsilon;
96   int i;
97
98   double startpoint[N];
99
100   gsl_rng *rng = gsl_rng_alloc(gsl_rng_ranlxd2);
101
102   for (;;) {
103     /* 2N+1 doubles: target, initial guess, epsilon for residual */
104     for (i=0; i<N; i++)
105       target[i] = scan1double();
106     for (i=0; i<N; i++)
107       startpoint[i] = scan1double();
108     epsilon = scan1double();
109
110     gsl_rng_set(rng,0);
111
112     gsl_siman_params_t siman_params = {
113       .k = 1.0,
114       .t_initial = 0.5,
115       .mu_t = 1.001,
116       .t_min = epsilon * 1E-3,
117       .iters_fixed_T = 100,
118       .n_tries = 10,
119       .step_size = 0.05,
120     };
121
122     gsl_siman_solve(rng,
123                     startpoint,
124                     cb_Efunc, cb_step, cb_metric,
125                     0, //cb_print,
126                     0,0,0, sizeof(startpoint), siman_params);
127
128     printcore(startpoint);
129
130     printf("[]\n");
131     fflush(stdout);
132   }
133 }