#include #define RVEC(A) int A##n, double*A##p #define RMAT(A) int A##r, int A##c, double* A##p #define KRVEC(A) int A##n, const double*A##p #define KRMAT(A) int A##r, int A##c, const double* A##p #define CVEC(A) int A##n, gsl_complex*A##p #define CMAT(A) int A##r, int A##c, gsl_complex* A##p #define KCVEC(A) int A##n, const gsl_complex*A##p #define KCMAT(A) int A##r, int A##c, const gsl_complex* A##p #define FVEC(A) int A##n, float*A##p #define FMAT(A) int A##r, int A##c, float* A##p #define KFVEC(A) int A##n, const float*A##p #define KFMAT(A) int A##r, int A##c, const float* A##p #define QVEC(A) int A##n, gsl_complex_float*A##p #define QMAT(A) int A##r, int A##c, gsl_complex_float* A##p #define KQVEC(A) int A##n, const gsl_complex_float*A##p #define KQMAT(A) int A##r, int A##c, const gsl_complex_float* A##p #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MACRO(B) do {B} while (0) #define ERROR(CODE) MACRO(return CODE;) #define REQUIRES(COND, CODE) MACRO(if(!(COND)) {ERROR(CODE);}) #define OK return 0; #define MIN(A,B) ((A)<(B)?(A):(B)) #define MAX(A,B) ((A)>(B)?(A):(B)) #ifdef DBG #define DEBUGMSG(M) printf("*** calling aux C function: %s\n",M); #else #define DEBUGMSG(M) #endif #define CHECK(RES,CODE) MACRO(if(RES) return CODE;) #ifdef DBG #define DEBUGMAT(MSG,X) printf(MSG" = \n"); gsl_matrix_fprintf(stdout,X,"%f"); printf("\n"); #else #define DEBUGMAT(MSG,X) #endif #ifdef DBG #define DEBUGVEC(MSG,X) printf(MSG" = \n"); gsl_vector_fprintf(stdout,X,"%f"); printf("\n"); #else #define DEBUGVEC(MSG,X) #endif #define DVVIEW(A) gsl_vector_view A = gsl_vector_view_array(A##p,A##n) #define DMVIEW(A) gsl_matrix_view A = gsl_matrix_view_array(A##p,A##r,A##c) #define CVVIEW(A) gsl_vector_complex_view A = gsl_vector_complex_view_array((double*)A##p,A##n) #define CMVIEW(A) gsl_matrix_complex_view A = gsl_matrix_complex_view_array((double*)A##p,A##r,A##c) #define KDVVIEW(A) gsl_vector_const_view A = gsl_vector_const_view_array(A##p,A##n) #define KDMVIEW(A) gsl_matrix_const_view A = gsl_matrix_const_view_array(A##p,A##r,A##c) #define KCVVIEW(A) gsl_vector_complex_const_view A = gsl_vector_complex_const_view_array((double*)A##p,A##n) #define KCMVIEW(A) gsl_matrix_complex_const_view A = gsl_matrix_complex_const_view_array((double*)A##p,A##r,A##c) #define FVVIEW(A) gsl_vector_float_view A = gsl_vector_float_view_array(A##p,A##n) #define FMVIEW(A) gsl_matrix_float_view A = gsl_matrix_float_view_array(A##p,A##r,A##c) #define QVVIEW(A) gsl_vector_complex_float_view A = gsl_vector_float_complex_view_array((float*)A##p,A##n) #define QMVIEW(A) gsl_matrix_complex_float_view A = gsl_matrix_float_complex_view_array((float*)A##p,A##r,A##c) #define KFVVIEW(A) gsl_vector_float_const_view A = gsl_vector_float_const_view_array(A##p,A##n) #define KFMVIEW(A) gsl_matrix_float_const_view A = gsl_matrix_float_const_view_array(A##p,A##r,A##c) #define KQVVIEW(A) gsl_vector_complex_float_const_view A = gsl_vector_complex_float_const_view_array((float*)A##p,A##n) #define KQMVIEW(A) gsl_matrix_complex_float_const_view A = gsl_matrix_complex_float_const_view_array((float*)A##p,A##r,A##c) #define V(a) (&a.vector) #define M(a) (&a.matrix) #define GCVEC(A) int A##n, gsl_complex*A##p #define KGCVEC(A) int A##n, const gsl_complex*A##p #define GQVEC(A) int A##n, gsl_complex_float*A##p #define KGQVEC(A) int A##n, const gsl_complex_float*A##p #define BAD_SIZE 2000 #define BAD_CODE 2001 #define MEM 2002 #define BAD_FILE 2003 void no_abort_on_error() { gsl_set_error_handler_off(); } int sumF(KFVEC(x),FVEC(r)) { DEBUGMSG("sumF"); REQUIRES(rn==1,BAD_SIZE); int i; float res = 0; for (i = 0; i < xn; i++) res += xp[i]; rp[0] = res; OK } int sumR(KRVEC(x),RVEC(r)) { DEBUGMSG("sumR"); REQUIRES(rn==1,BAD_SIZE); int i; double res = 0; for (i = 0; i < xn; i++) res += xp[i]; rp[0] = res; OK } int sumQ(KQVEC(x),QVEC(r)) { DEBUGMSG("sumQ"); REQUIRES(rn==1,BAD_SIZE); int i; gsl_complex_float res; res.dat[0] = 0; res.dat[1] = 0; for (i = 0; i < xn; i++) { res.dat[0] += xp[i].dat[0]; res.dat[1] += xp[i].dat[1]; } rp[0] = res; OK } int sumC(KCVEC(x),CVEC(r)) { DEBUGMSG("sumC"); REQUIRES(rn==1,BAD_SIZE); int i; gsl_complex res; res.dat[0] = 0; res.dat[1] = 0; for (i = 0; i < xn; i++) { res.dat[0] += xp[i].dat[0]; res.dat[1] += xp[i].dat[1]; } rp[0] = res; OK } int prodF(KFVEC(x),FVEC(r)) { DEBUGMSG("prodF"); REQUIRES(rn==1,BAD_SIZE); int i; float res = 1; for (i = 0; i < xn; i++) res *= xp[i]; rp[0] = res; OK } int prodR(KRVEC(x),RVEC(r)) { DEBUGMSG("prodR"); REQUIRES(rn==1,BAD_SIZE); int i; double res = 1; for (i = 0; i < xn; i++) res *= xp[i]; rp[0] = res; OK } int prodQ(KQVEC(x),QVEC(r)) { DEBUGMSG("prodQ"); REQUIRES(rn==1,BAD_SIZE); int i; gsl_complex_float res; float temp; res.dat[0] = 1; res.dat[1] = 0; for (i = 0; i < xn; i++) { temp = res.dat[0] * xp[i].dat[0] - res.dat[1] * xp[i].dat[1]; res.dat[1] = res.dat[0] * xp[i].dat[1] + res.dat[1] * xp[i].dat[0]; res.dat[0] = temp; } rp[0] = res; OK } int prodC(KCVEC(x),CVEC(r)) { DEBUGMSG("prodC"); REQUIRES(rn==1,BAD_SIZE); int i; gsl_complex res; double temp; res.dat[0] = 1; res.dat[1] = 0; for (i = 0; i < xn; i++) { temp = res.dat[0] * xp[i].dat[0] - res.dat[1] * xp[i].dat[1]; res.dat[1] = res.dat[0] * xp[i].dat[1] + res.dat[1] * xp[i].dat[0]; res.dat[0] = temp; } rp[0] = res; OK } int dotF(KFVEC(x), KFVEC(y), FVEC(r)) { DEBUGMSG("dotF"); REQUIRES(xn==yn,BAD_SIZE); REQUIRES(rn==1,BAD_SIZE); DEBUGMSG("dotF"); KFVVIEW(x); KFVVIEW(y); gsl_blas_sdot(V(x),V(y),rp); OK } int dotR(KRVEC(x), KRVEC(y), RVEC(r)) { DEBUGMSG("dotR"); REQUIRES(xn==yn,BAD_SIZE); REQUIRES(rn==1,BAD_SIZE); DEBUGMSG("dotR"); KDVVIEW(x); KDVVIEW(y); gsl_blas_ddot(V(x),V(y),rp); OK } int dotQ(KQVEC(x), KQVEC(y), QVEC(r)) { DEBUGMSG("dotQ"); REQUIRES(xn==yn,BAD_SIZE); REQUIRES(rn==1,BAD_SIZE); DEBUGMSG("dotQ"); KQVVIEW(x); KQVVIEW(y); gsl_blas_cdotu(V(x),V(y),rp); OK } int dotC(KCVEC(x), KCVEC(y), CVEC(r)) { DEBUGMSG("dotC"); REQUIRES(xn==yn,BAD_SIZE); REQUIRES(rn==1,BAD_SIZE); DEBUGMSG("dotC"); KCVVIEW(x); KCVVIEW(y); gsl_blas_zdotu(V(x),V(y),rp); OK } int toScalarR(int code, KRVEC(x), RVEC(r)) { REQUIRES(rn==1,BAD_SIZE); DEBUGMSG("toScalarR"); KDVVIEW(x); double res; switch(code) { case 0: { res = gsl_blas_dnrm2(V(x)); break; } case 1: { res = gsl_blas_dasum(V(x)); break; } case 2: { res = gsl_vector_max_index(V(x)); break; } case 3: { res = gsl_vector_max(V(x)); break; } case 4: { res = gsl_vector_min_index(V(x)); break; } case 5: { res = gsl_vector_min(V(x)); break; } default: ERROR(BAD_CODE); } rp[0] = res; OK } int toScalarF(int code, KFVEC(x), FVEC(r)) { REQUIRES(rn==1,BAD_SIZE); DEBUGMSG("toScalarF"); KFVVIEW(x); float res; switch(code) { case 0: { res = gsl_blas_snrm2(V(x)); break; } case 1: { res = gsl_blas_sasum(V(x)); break; } case 2: { res = gsl_vector_float_max_index(V(x)); break; } case 3: { res = gsl_vector_float_max(V(x)); break; } case 4: { res = gsl_vector_float_min_index(V(x)); break; } case 5: { res = gsl_vector_float_min(V(x)); break; } default: ERROR(BAD_CODE); } rp[0] = res; OK } int toScalarC(int code, KCVEC(x), RVEC(r)) { REQUIRES(rn==1,BAD_SIZE); DEBUGMSG("toScalarC"); KCVVIEW(x); double res; switch(code) { case 0: { res = gsl_blas_dznrm2(V(x)); break; } case 1: { res = gsl_blas_dzasum(V(x)); break; } default: ERROR(BAD_CODE); } rp[0] = res; OK } int toScalarQ(int code, KQVEC(x), FVEC(r)) { REQUIRES(rn==1,BAD_SIZE); DEBUGMSG("toScalarQ"); KQVVIEW(x); float res; switch(code) { case 0: { res = gsl_blas_scnrm2(V(x)); break; } case 1: { res = gsl_blas_scasum(V(x)); break; } default: ERROR(BAD_CODE); } rp[0] = res; OK } inline double sign(double x) { if(x>0) { return +1.0; } else if (x<0) { return -1.0; } else { return 0.0; } } inline float float_sign(float x) { if(x>0) { return +1.0; } else if (x<0) { return -1.0; } else { return 0.0; } } inline gsl_complex complex_abs(gsl_complex z) { gsl_complex r; r.dat[0] = gsl_complex_abs(z); r.dat[1] = 0; return r; } inline gsl_complex complex_signum(gsl_complex z) { gsl_complex r; double mag; if (z.dat[0] == 0 && z.dat[1] == 0) { r.dat[0] = 0; r.dat[1] = 0; } else { mag = gsl_complex_abs(z); r.dat[0] = z.dat[0]/mag; r.dat[1] = z.dat[1]/mag; } return r; } #define OP(C,F) case C: { for(k=0;k1,BAD_SIZE); gsl_poly_complex_workspace * w = gsl_poly_complex_workspace_alloc (an); int res = gsl_poly_complex_solve ((double*)ap, an, w, (double*)zp); CHECK(res,res); gsl_poly_complex_workspace_free (w); OK; } int vector_fscanf(char*filename, RVEC(a)) { DEBUGMSG("gsl_vector_fscanf"); DVVIEW(a); FILE * f = fopen(filename,"r"); CHECK(!f,BAD_FILE); int res = gsl_vector_fscanf(f,V(a)); CHECK(res,res); fclose (f); OK } int vector_fprintf(char*filename, char*fmt, RVEC(a)) { DEBUGMSG("gsl_vector_fprintf"); DVVIEW(a); FILE * f = fopen(filename,"w"); CHECK(!f,BAD_FILE); int res = gsl_vector_fprintf(f,V(a),fmt); CHECK(res,res); fclose (f); OK } int vector_fread(char*filename, RVEC(a)) { DEBUGMSG("gsl_vector_fread"); DVVIEW(a); FILE * f = fopen(filename,"r"); CHECK(!f,BAD_FILE); int res = gsl_vector_fread(f,V(a)); CHECK(res,res); fclose (f); OK } int vector_fwrite(char*filename, RVEC(a)) { DEBUGMSG("gsl_vector_fwrite"); DVVIEW(a); FILE * f = fopen(filename,"w"); CHECK(!f,BAD_FILE); int res = gsl_vector_fwrite(f,V(a)); CHECK(res,res); fclose (f); OK } int matrix_fprintf(char*filename, char*fmt, int ro, RMAT(m)) { DEBUGMSG("matrix_fprintf"); FILE * f = fopen(filename,"w"); CHECK(!f,BAD_FILE); int i,j,sr,sc; if (ro==1) { sr = mc; sc = 1;} else { sr = 1; sc = mr;} #define AT(M,r,c) (M##p[(r)*sr+(c)*sc]) for (i=0; isize,sizeof(double)); int k; for(k=0;ksize;k++) { p[k] = gsl_vector_get(x,k); } double res = f(x->size,p); free(p); return res; } // this version returns info about intermediate steps int minimize(int method, double f(int, double*), double tolsize, int maxit, KRVEC(xi), KRVEC(sz), RMAT(sol)) { REQUIRES(xin==szn && solr == maxit && solc == 3+xin,BAD_SIZE); DEBUGMSG("minimizeList (nmsimplex)"); gsl_multimin_function my_func; // extract function from pars my_func.f = only_f_aux_min; my_func.n = xin; my_func.params = f; size_t iter = 0; int status; double size; const gsl_multimin_fminimizer_type *T; gsl_multimin_fminimizer *s = NULL; // Initial vertex size vector KDVVIEW(sz); // Starting point KDVVIEW(xi); // Minimizer nmsimplex, without derivatives switch(method) { case 0 : {T = gsl_multimin_fminimizer_nmsimplex; break; } #ifdef GSL110 case 1 : {T = gsl_multimin_fminimizer_nmsimplex; break; } #else case 1 : {T = gsl_multimin_fminimizer_nmsimplex2; break; } #endif default: ERROR(BAD_CODE); } s = gsl_multimin_fminimizer_alloc (T, my_func.n); gsl_multimin_fminimizer_set (s, &my_func, V(xi), V(sz)); do { status = gsl_multimin_fminimizer_iterate (s); size = gsl_multimin_fminimizer_size (s); solp[iter*solc+0] = iter+1; solp[iter*solc+1] = s->fval; solp[iter*solc+2] = size; int k; for(k=0;kx,k); } iter++; if (status) break; status = gsl_multimin_test_size (size, tolsize); } while (status == GSL_CONTINUE && iter < maxit); int i,j; for (i=iter; isize,sizeof(double)); int k; for(k=0;ksize;k++) { p[k] = gsl_vector_get(x,k); } double res = fdf->f(x->size,p); free(p); return res; } void df_aux_min(const gsl_vector * x, void * pars, gsl_vector * g) { Tfdf * fdf = ((Tfdf*) pars); double* p = (double*)calloc(x->size,sizeof(double)); double* q = (double*)calloc(g->size,sizeof(double)); int k; for(k=0;ksize;k++) { p[k] = gsl_vector_get(x,k); } fdf->df(x->size,p,g->size,q); for(k=0;ksize;k++) { gsl_vector_set(g,k,q[k]); } free(p); free(q); } void fdf_aux_min(const gsl_vector * x, void * pars, double * f, gsl_vector * g) { *f = f_aux_min(x,pars); df_aux_min(x,pars,g); } int minimizeD(int method, double f(int, double*), int df(int, double*, int, double*), double initstep, double minimpar, double tolgrad, int maxit, KRVEC(xi), RMAT(sol)) { REQUIRES(solr == maxit && solc == 2+xin,BAD_SIZE); DEBUGMSG("minimizeWithDeriv (conjugate_fr)"); gsl_multimin_function_fdf my_func; // extract function from pars my_func.f = f_aux_min; my_func.df = df_aux_min; my_func.fdf = fdf_aux_min; my_func.n = xin; Tfdf stfdf; stfdf.f = f; stfdf.df = df; my_func.params = &stfdf; size_t iter = 0; int status; const gsl_multimin_fdfminimizer_type *T; gsl_multimin_fdfminimizer *s = NULL; // Starting point KDVVIEW(xi); // conjugate gradient fr switch(method) { case 0 : {T = gsl_multimin_fdfminimizer_conjugate_fr; break; } case 1 : {T = gsl_multimin_fdfminimizer_conjugate_pr; break; } case 2 : {T = gsl_multimin_fdfminimizer_vector_bfgs; break; } case 3 : {T = gsl_multimin_fdfminimizer_vector_bfgs2; break; } case 4 : {T = gsl_multimin_fdfminimizer_steepest_descent; break; } default: ERROR(BAD_CODE); } s = gsl_multimin_fdfminimizer_alloc (T, my_func.n); gsl_multimin_fdfminimizer_set (s, &my_func, V(xi), initstep, minimpar); do { status = gsl_multimin_fdfminimizer_iterate (s); solp[iter*solc+0] = iter+1; solp[iter*solc+1] = s->f; int k; for(k=0;kx,k); } iter++; if (status) break; status = gsl_multimin_test_gradient (s->gradient, tolgrad); } while (status == GSL_CONTINUE && iter < maxit); int i,j; for (i=iter; isize,sizeof(double)); double* q = (double*)calloc(y->size,sizeof(double)); int k; for(k=0;ksize;k++) { p[k] = gsl_vector_get(x,k); } f(x->size,p,y->size,q); for(k=0;ksize;k++) { gsl_vector_set(y,k,q[k]); } free(p); free(q); return 0; //hmmm } int multiroot(int method, void f(int, double*, int, double*), double epsabs, int maxit, KRVEC(xi), RMAT(sol)) { REQUIRES(solr == maxit && solc == 1+2*xin,BAD_SIZE); DEBUGMSG("root_only_f"); gsl_multiroot_function my_func; // extract function from pars my_func.f = only_f_aux_multiroot; my_func.n = xin; my_func.params = f; size_t iter = 0; int status; const gsl_multiroot_fsolver_type *T; gsl_multiroot_fsolver *s; // Starting point KDVVIEW(xi); switch(method) { case 0 : {T = gsl_multiroot_fsolver_hybrids;; break; } case 1 : {T = gsl_multiroot_fsolver_hybrid; break; } case 2 : {T = gsl_multiroot_fsolver_dnewton; break; } case 3 : {T = gsl_multiroot_fsolver_broyden; break; } default: ERROR(BAD_CODE); } s = gsl_multiroot_fsolver_alloc (T, my_func.n); gsl_multiroot_fsolver_set (s, &my_func, V(xi)); do { status = gsl_multiroot_fsolver_iterate (s); solp[iter*solc+0] = iter+1; int k; for(k=0;kx,k); } for(k=xin;k<2*xin;k++) { solp[iter*solc+k+1] = gsl_vector_get(s->f,k-xin); } iter++; if (status) /* check if solver is stuck */ break; status = gsl_multiroot_test_residual (s->f, epsabs); } while (status == GSL_CONTINUE && iter < maxit); int i,j; for (i=iter; isize,sizeof(double)); double* q = (double*)calloc(y->size,sizeof(double)); int k; for(k=0;ksize;k++) { p[k] = gsl_vector_get(x,k); } (fjf->f)(x->size,p,y->size,q); for(k=0;ksize;k++) { gsl_vector_set(y,k,q[k]); } free(p); free(q); return 0; } int jf_aux(const gsl_vector * x, void * pars, gsl_matrix * jac) { Tfjf * fjf = ((Tfjf*) pars); double* p = (double*)calloc(x->size,sizeof(double)); double* q = (double*)calloc((jac->size1)*(jac->size2),sizeof(double)); int i,j,k; for(k=0;ksize;k++) { p[k] = gsl_vector_get(x,k); } (fjf->jf)(x->size,p,jac->size1,jac->size2,q); k=0; for(i=0;isize1;i++) { for(j=0;jsize2;j++){ gsl_matrix_set(jac,i,j,q[k++]); } } free(p); free(q); return 0; } int fjf_aux(const gsl_vector * x, void * pars, gsl_vector * f, gsl_matrix * g) { f_aux(x,pars,f); jf_aux(x,pars,g); return 0; } int multirootj(int method, int f(int, double*, int, double*), int jac(int, double*, int, int, double*), double epsabs, int maxit, KRVEC(xi), RMAT(sol)) { REQUIRES(solr == maxit && solc == 1+2*xin,BAD_SIZE); DEBUGMSG("root_fjf"); gsl_multiroot_function_fdf my_func; // extract function from pars my_func.f = f_aux; my_func.df = jf_aux; my_func.fdf = fjf_aux; my_func.n = xin; Tfjf stfjf; stfjf.f = f; stfjf.jf = jac; my_func.params = &stfjf; size_t iter = 0; int status; const gsl_multiroot_fdfsolver_type *T; gsl_multiroot_fdfsolver *s; // Starting point KDVVIEW(xi); switch(method) { case 0 : {T = gsl_multiroot_fdfsolver_hybridsj;; break; } case 1 : {T = gsl_multiroot_fdfsolver_hybridj; break; } case 2 : {T = gsl_multiroot_fdfsolver_newton; break; } case 3 : {T = gsl_multiroot_fdfsolver_gnewton; break; } default: ERROR(BAD_CODE); } s = gsl_multiroot_fdfsolver_alloc (T, my_func.n); gsl_multiroot_fdfsolver_set (s, &my_func, V(xi)); do { status = gsl_multiroot_fdfsolver_iterate (s); solp[iter*solc+0] = iter+1; int k; for(k=0;kx,k); } for(k=xin;k<2*xin;k++) { solp[iter*solc+k+1] = gsl_vector_get(s->f,k-xin); } iter++; if (status) /* check if solver is stuck */ break; status = gsl_multiroot_test_residual (s->f, epsabs); } while (status == GSL_CONTINUE && iter < maxit); int i,j; for (i=iter; if); int k; for(k=0;kx,k); } iter++; if (status) /* check if solver is stuck */ break; status = gsl_multifit_test_delta (s->dx, s->x, epsabs, epsrel); } while (status == GSL_CONTINUE && iter < maxit); int i,j; for (i=iter; iJ, 0.0, M(cov)); gsl_multifit_fdfsolver_free (s); OK } ////////////////////////////////////////////////////// #define RAN(C,F) case C: { for(k=0;k