chiark / gitweb /
findcurve handling: fflush stdout
[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 }
48
49 static double cb_metric(void *xp, void *yp) {
50   const double *x=xp, *y=yp;
51   int i;
52   double s;
53   for (i=0, s=0; i<N; i++) {
54     double d = x[i] - y[i];
55     s += d*d;
56   }
57   return sqrt(s);
58 }
59
60 static void cb_print(void *xp) {
61   const double *x = xp;
62   double F[N];
63   int i;
64   X_EXTRACT;
65   F_POPULATE;
66   printf("\n[");
67   for (i=0; i<6; i++) printf(" %.18g,", x[i]);
68   for (i=0; i<6; i++) printf(" %.18g,", F[i]);
69   printf(" ]\n");
70 }
71
72 static double scan1double(void) {
73   double v;
74   int r;
75
76   r = scanf("%lf",&v);
77   if (ferror(stdin)) { perror("stdin"); exit(-1); }
78   if (feof(stdin)) exit(0);
79   if (r!=1) { fputs("bad input\n",stderr); exit(-1); }
80   return v;
81 }
82
83 int main(void) {
84   double epsilon;
85   int i;
86
87   double startpoint[N];
88
89   gsl_rng *rng = gsl_rng_alloc(gsl_rng_ranlxd2);
90
91   for (;;) {
92     /* 2N+1 doubles: target, initial guess, epsilon for residual */
93     for (i=0; i<N; i++)
94       target[i] = scan1double();
95     for (i=0; i<N; i++)
96       startpoint[i] = scan1double();
97     epsilon = scan1double();
98
99     gsl_rng_set(rng,0);
100
101     gsl_siman_params_t siman_params = {
102       .k = 1.0,
103       .t_initial = 0.5,
104       .mu_t = 1.001,
105       .t_min = epsilon * 1E-3,
106     };
107
108     gsl_siman_solve(rng,
109                     startpoint,
110                     cb_Efunc, cb_step, cb_metric,
111                     0, // cb_print,
112                     0,0,0, sizeof(startpoint), siman_params);
113
114     cb_print(startpoint);
115
116     printf("[]\n");
117     fflush(stdout);
118   }
119 }