*/
#include <math.h>
+#include <string.h>
+#include <assert.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_sf.h>
#include <gsl/gsl_siman.h>
#include <gsl/gsl_randist.h>
+#include <gsl/gsl_multimin.h>
#include "symbolic.c"
-#define X(i) x[i]
#define J_END_COL(i) \
- for (j=0; j<N; j++) gsl_matrix_set(J,i,j,J_COL[j]);
+ for (j=0; j<PN; j++) gsl_matrix_set(J,i,j,J_COL[j]);
static inline _Bool IS_SMALL(double v) {
return v < 1E6;
return gsl_sf_sinc(x / M_PI);
}
-static double target[N];
+static int NP;
+static double *INPUT; /* dyanmic array, on main's stack */
+static double PREP[NPREP];
+
+#define GET_X(xg) \
+ double X[NX]; \
+ ({ int get_x_i; \
+ for (get_x_i=0; get_x_i<NX; get_x_i++) \
+ X[get_x_i] = gsl_vector_get(xg, get_x_i); \
+ })
+
+static void printcore(const double *X) {
+ int i, j;
+ DECLARE_F_G;
+ CALCULATE_F_G;
+ printf("[");
+ for (i=0; i<NP; i++)
+ for (j=0; j<3; j++)
+ printf(" %25.18g,", POINT(i)[j]);
+ printf(" ]\n");
+}
-static double cb_Efunc(void *xp) {
- const double *x = xp;
- double F[N], e;
- int i;
- X_EXTRACT;
- F_POPULATE;
- for (i=0, e=0; i<N; i++) {
- double d = F[i] - target[i];
- e += d*d;
+static void prepare(double X[] /* startpoint */) {
+ /* fills in PREP and startpoint */
+ PREPARE;
+}
+
+//#define DEBUG
+
+static double cb_f(const gsl_vector *xg, void *params) {
+ int P;
+
+ GET_X(xg);
+
+ DECLARE_F_G;
+ CALCULATE_F_G;
+
+#ifdef DEBUG
+ int i,j;
+ printf(" Efunc\n");
+ for (j=0; j<3; j++) {
+ for (P=0; P<NP; P++)
+ printf(" %7.4f", POINT(P)[j]);
+ printf("\n");
}
- //printf("\n cb_Efunc %p %10.7f [", xp, e);
- //for (i=0; i<N; i++) printf(" %10.7f,", x[i]);
- //printf("]\n");
- return e;
+ printf(" ");
+#endif
+
+ CALCULATE_COST;
+ return cost;
}
-static void cb_step(const gsl_rng *rng, void *xp, double step_size) {
+static void __attribute__((unused)) cb_step(const gsl_rng *rng, void *xp, double step_size) {
double *x = xp;
int i;
- double step[N];
- gsl_ran_dir_nd(rng, N,step);
- for (i=0; i<N; i++)
+ double step[NX];
+ gsl_ran_dir_nd(rng, NX, step);
+ for (i=0; i<NX; i++)
x[i] += step_size * step[i];
//printf("\n cb_step %p %10.7f [", xp, step_size);
//for (i=0; i<N; i++) printf(" %10.7f,", step[i]);
//printf("]\n");
}
-static double cb_metric(void *xp, void *yp) {
+static double __attribute__((unused)) cb_metric(void *xp, void *yp) {
const double *x=xp, *y=yp;
int i;
double s;
- for (i=0, s=0; i<N; i++) {
+ for (i=0, s=0; i<NX; i++) {
double d = x[i] - y[i];
s += d*d;
}
return sqrt(s);
}
-static void printcore(const double *x) {
- int i;
- double F[N];
- X_EXTRACT;
- F_POPULATE;
- printf("[");
- for (i=0; i<6; i++) printf(" %.18g,", x[i]);
- for (i=0; i<6; i++) printf(" %.18g,", F[i]);
- printf(" ]\n");
-}
-
-static void __attribute__((unused)) cb_print(void *xp) {
- const double *x = xp;
+static void __attribute__((unused)) cb_print(gsl_vector *xp) {
+ GET_X(xp);
printf("\n");
- printcore(x);
+ printcore(X);
}
static double scan1double(void) {
return v;
}
-int main(void) {
+int main(int argc, const char *const *argv) {
double epsilon;
- int i;
+ int i, r;
+
+ NP = atoi(argv[1]);
+ epsilon = atof(argv[2]);
+
+ double startpoint_X[NX];
+ double input[NINPUT]; INPUT = input;
+
+ gsl_multimin_function func = {
+ .f = cb_f,
+ .n = NX,
+ .params = 0,
+ };
- double startpoint[N];
+ gsl_vector *current_gx = gsl_vector_alloc(NX);
+ gsl_vector *step_size = gsl_vector_alloc(NX);
+ gsl_vector_set_all(step_size, 0.01);
- gsl_rng *rng = gsl_rng_alloc(gsl_rng_ranlxd2);
+ gsl_multimin_fminimizer *minimiser =
+ gsl_multimin_fminimizer_alloc(gsl_multimin_fminimizer_nmsimplex2rand, NX);
for (;;) {
- /* 2N+1 doubles: target, initial guess, epsilon for residual */
- for (i=0; i<N; i++)
- target[i] = scan1double();
- for (i=0; i<N; i++)
- startpoint[i] = scan1double();
- epsilon = scan1double();
-
- gsl_rng_set(rng,0);
-
- gsl_siman_params_t siman_params = {
- .k = 1.0,
- .t_initial = 0.5,
- .mu_t = 1.001,
- .t_min = epsilon * 1E-3,
- .iters_fixed_T = 100,
- .n_tries = 10,
- .step_size = 0.05,
- };
-
- gsl_siman_solve(rng,
- startpoint,
- cb_Efunc, cb_step, cb_metric,
- cb_print,
- 0,0,0, sizeof(startpoint), siman_params);
-
- printcore(startpoint);
+ /* NINPUT + 1 doubles: startpoint, epsilon for residual */
+ for (i=0; i<NINPUT; i++)
+ INPUT[i] = scan1double();
+
+ prepare(startpoint_X);
+ for (i=0; i<NX; i++)
+ gsl_vector_set(current_gx, i, startpoint_X[i]);
+
+ r = gsl_multimin_fminimizer_set(minimiser, &func, current_gx, step_size);
+ assert(!r);
+
+ for (;;) {
+ r = gsl_multimin_fminimizer_iterate(minimiser);
+ assert(!r);
+
+ //cb_print(current_gx);
+
+ double size = gsl_multimin_fminimizer_size(minimiser);
+ //printf(" size=%10.7f\n", size);
+
+ if (size < epsilon) break;
+ }
+
+ cb_print(current_gx);
printf("[]\n");
fflush(stdout);