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