diff options
author | Alberto Ruiz <aruiz@um.es> | 2009-06-04 09:01:56 +0000 |
---|---|---|
committer | Alberto Ruiz <aruiz@um.es> | 2009-06-04 09:01:56 +0000 |
commit | 6e0dd472ef8c570ec1924ac641e5872db30ac142 (patch) | |
tree | 64963c6af75cdbc02336de82b51136964f36dc73 /lib/Numeric/GSL/gsl-aux.c | |
parent | f49ac4def26b38d3d084375007715156be347412 (diff) |
added some root finding algorithms
Diffstat (limited to 'lib/Numeric/GSL/gsl-aux.c')
-rw-r--r-- | lib/Numeric/GSL/gsl-aux.c | 101 |
1 files changed, 91 insertions, 10 deletions
diff --git a/lib/Numeric/GSL/gsl-aux.c b/lib/Numeric/GSL/gsl-aux.c index 3802574..80c23fc 100644 --- a/lib/Numeric/GSL/gsl-aux.c +++ b/lib/Numeric/GSL/gsl-aux.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <gsl/gsl_deriv.h> | 7 | #include <gsl/gsl_deriv.h> |
8 | #include <gsl/gsl_poly.h> | 8 | #include <gsl/gsl_poly.h> |
9 | #include <gsl/gsl_multimin.h> | 9 | #include <gsl/gsl_multimin.h> |
10 | #include <gsl/gsl_multiroots.h> | ||
10 | #include <gsl/gsl_complex.h> | 11 | #include <gsl/gsl_complex.h> |
11 | #include <gsl/gsl_complex_math.h> | 12 | #include <gsl/gsl_complex_math.h> |
12 | #include <string.h> | 13 | #include <string.h> |
@@ -288,6 +289,22 @@ int fft(int code, KCVEC(X), CVEC(R)) { | |||
288 | } | 289 | } |
289 | 290 | ||
290 | 291 | ||
292 | int deriv(int code, double f(double, void*), double x, double h, double * result, double * abserr) | ||
293 | { | ||
294 | gsl_function F; | ||
295 | F.function = f; | ||
296 | F.params = 0; | ||
297 | |||
298 | if(code==0) return gsl_deriv_central (&F, x, h, result, abserr); | ||
299 | |||
300 | if(code==1) return gsl_deriv_forward (&F, x, h, result, abserr); | ||
301 | |||
302 | if(code==2) return gsl_deriv_backward (&F, x, h, result, abserr); | ||
303 | |||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | |||
291 | int integrate_qng(double f(double, void*), double a, double b, double prec, | 308 | int integrate_qng(double f(double, void*), double a, double b, double prec, |
292 | double *result, double*error) { | 309 | double *result, double*error) { |
293 | DEBUGMSG("integrate_qng"); | 310 | DEBUGMSG("integrate_qng"); |
@@ -440,7 +457,7 @@ void fdf_aux_min(const gsl_vector * x, void * pars, double * f, gsl_vector * g) | |||
440 | df_aux_min(x,pars,g); | 457 | df_aux_min(x,pars,g); |
441 | } | 458 | } |
442 | 459 | ||
443 | // conjugate gradient | 460 | |
444 | int minimizeWithDeriv(int method, double f(int, double*), void df(int, double*, double*), | 461 | int minimizeWithDeriv(int method, double f(int, double*), void df(int, double*, double*), |
445 | double initstep, double minimpar, double tolgrad, int maxit, | 462 | double initstep, double minimpar, double tolgrad, int maxit, |
446 | KRVEC(xi), RMAT(sol)) { | 463 | KRVEC(xi), RMAT(sol)) { |
@@ -492,18 +509,82 @@ int minimizeWithDeriv(int method, double f(int, double*), void df(int, double*, | |||
492 | OK | 509 | OK |
493 | } | 510 | } |
494 | 511 | ||
512 | //--------------------------------------------------------------- | ||
495 | 513 | ||
496 | int deriv(int code, double f(double, void*), double x, double h, double * result, double * abserr) | 514 | typedef void TrawfunV(int, double*, double*); |
497 | { | ||
498 | gsl_function F; | ||
499 | F.function = f; | ||
500 | F.params = 0; | ||
501 | 515 | ||
502 | if(code==0) return gsl_deriv_central (&F, x, h, result, abserr); | 516 | int only_f_aux_root(const gsl_vector*x, void *pars, gsl_vector*y) { |
517 | TrawfunV * f = (TrawfunV*) pars; | ||
518 | double* p = (double*)calloc(x->size,sizeof(double)); | ||
519 | double* q = (double*)calloc(x->size,sizeof(double)); | ||
520 | int k; | ||
521 | for(k=0;k<x->size;k++) { | ||
522 | p[k] = gsl_vector_get(x,k); | ||
523 | } | ||
524 | f(x->size,p,q); | ||
525 | for(k=0;k<y->size;k++) { | ||
526 | gsl_vector_set(y,k,q[k]); | ||
527 | } | ||
528 | free(p); | ||
529 | free(q); | ||
530 | return 0; //hmmm | ||
531 | } | ||
503 | 532 | ||
504 | if(code==1) return gsl_deriv_forward (&F, x, h, result, abserr); | 533 | int root(int method, void f(int, double*, int, double*), |
534 | double epsabs, int maxit, | ||
535 | KRVEC(xi), RMAT(sol)) { | ||
536 | REQUIRES(solr == maxit && solc == 1+2*xin,BAD_SIZE); | ||
537 | DEBUGMSG("root_only_f"); | ||
538 | gsl_multiroot_function my_func; | ||
539 | // extract function from pars | ||
540 | my_func.f = only_f_aux_root; | ||
541 | my_func.n = xin; | ||
542 | my_func.params = f; | ||
543 | size_t iter = 0; | ||
544 | int status; | ||
545 | const gsl_multiroot_fsolver_type *T; | ||
546 | gsl_multiroot_fsolver *s; | ||
547 | // Starting point | ||
548 | KDVVIEW(xi); | ||
549 | switch(method) { | ||
550 | case 0 : {T = gsl_multiroot_fsolver_hybrids;; break; } | ||
551 | case 1 : {T = gsl_multiroot_fsolver_hybrid; break; } | ||
552 | case 2 : {T = gsl_multiroot_fsolver_dnewton; break; } | ||
553 | case 3 : {T = gsl_multiroot_fsolver_broyden; break; } | ||
554 | default: ERROR(BAD_CODE); | ||
555 | } | ||
556 | s = gsl_multiroot_fsolver_alloc (T, my_func.n); | ||
557 | gsl_multiroot_fsolver_set (s, &my_func, V(xi)); | ||
505 | 558 | ||
506 | if(code==2) return gsl_deriv_backward (&F, x, h, result, abserr); | 559 | do { |
560 | status = gsl_multiroot_fsolver_iterate (s); | ||
507 | 561 | ||
508 | return 0; | 562 | solp[iter*solc+0] = iter; |
563 | |||
564 | int k; | ||
565 | for(k=0;k<xin;k++) { | ||
566 | solp[iter*solc+k+1] = gsl_vector_get(s->x,k); | ||
567 | } | ||
568 | for(k=xin;k<2*xin;k++) { | ||
569 | solp[iter*solc+k+1] = gsl_vector_get(s->f,k-xin); | ||
570 | } | ||
571 | |||
572 | iter++; | ||
573 | if (status) /* check if solver is stuck */ | ||
574 | break; | ||
575 | |||
576 | status = | ||
577 | gsl_multiroot_test_residual (s->f, epsabs); | ||
578 | } | ||
579 | while (status == GSL_CONTINUE && iter < maxit); | ||
580 | |||
581 | int i,j; | ||
582 | for (i=iter; i<solr; i++) { | ||
583 | solp[i*solc+0] = iter; | ||
584 | for(j=1;j<solc;j++) { | ||
585 | solp[i*solc+j]=0.; | ||
586 | } | ||
587 | } | ||
588 | gsl_multiroot_fsolver_free(s); | ||
589 | OK | ||
509 | } | 590 | } |