This is the mail archive of the gsl-discuss@sources.redhat.com mailing list for the GSL project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Parameter vectors declared as const in minimized functions


On Tue, 4 Jan 2005 18:59:58 +0100
Andrej Prsa <andrej.prsa@guest.arnes.si> wrote:

> is being minimized. I never have a fully constrained problem, but at
> least several dimensions may be bounded and that's what I'm after
> here.

It is quite possible that I did not understand your problem, so forgive
me if what I'm going to say will result totally off topic. 

Judging from what you wrote and the example you gave to the mailing
list, it seems that you want to change the value of the function
argument in order to mimic some kind of constraint on the function
domain. This things are dangerous.

As I mentioned before, there is a quite straightforward, and definitely
safer way in which a bounded minimization problem can be transformed in
an unbounded one. It is by means of change of variables. Let me give you
an example. Assume that you want x* solution of

x* = argmin{ f(x) } with x \in  [-1,1] 

Notice that the domain here is a closed interval. Of course this is a
constrained problem. But consider instead the problem

y* = argmin{ f(cos(y) } with y in (-\infty,+\infty)

inspecting the first and second order conditions, you can immediately
see that the extremant y* of this second problem are of two kinds:

1) points y^* such that x^*=arcsin(y^*) is interior to [-1,1] and
is an interior solution of the first problem

2) point y^* such that arcsin(y^*) is on the boundary of the interval of
the first problem, i.e. -1 or 1, and is a boundary solution of the
first problem

You can use an unconstrained optimization algorithm to find out the
set of solutions {y^*}, and then transform back this set to {x^*}.

Now, quite probably what I said above sound trivial to you. Then, let me
conclude by attaching a piece of software that is, if possible,
still more trivial. It is an interface to gsl unbounded optimization
routines to compute constrained optimization on closed, open, bounded
and semi-bounded intervals. It implements different changes of variables
for the different cases. I use it in a package for the maximum
likelihood estimation of the power exponential function (subbotools)
which you can find on my web page (if you want to see an application
of the function). Don't expect anything sophisticated. It's a simple,
minimalistic piece of code. A single function with NAG-like bloated
list of arguments.

I thought that, maybe, someone else could be interested, so I decided to
post it to the mailing list. Forgive me for the size of the resulting
message.


Best,
	G.

-- 
Giulio Bottazzi                 PGP Key ID:BAB0A33F 
/*
  multimin.c  (ver. 0.9.5) -- Interface to GSL multidim. minimization
  Copyright (C) 2002-2003 Giulio Bottazzi

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  (version 2) as published by the Free Software Foundation;
  
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/ 


/*

multimin is an interface to the various GSL minimization
routines. When invoked, all the information necessary to perform the
minimization are passed as formal parameters. This generate a pretty
long, FORTRAN-like, list of parameters. This approach allows, however,
to black-box, as far as possible, the interior functioning of the
routine from the rest of the program.

Let's analyse the calling convention in details:

multimin(size_t n,double *x,double *fun,
	 unsigned *type,double *xmin,double *xmax,
	 void (*f) (const size_t,const double *,void *,double *),
	 void (* df) (const size_t,const double *, void *,double *),
	 void (* fdf) (const size_t,const double *, void *,double *,double *),
	 void *fparams,
	 const struct multimin_params oparams)

where

--------------------------------------------------------------------
n

INPUT: dimension of the problem, number of independent variables of
the function.

--------------------------------------------------------------------
x

INPUT: pointer to an array of n values x[0],...x[n-1] containing the
initial estimate of the minimum point
OUTPUT: contains the final estimation of the minimum position

--------------------------------------------------------------------
type

a pointer to an array of integer type[1],...,type[n-1] describing the
boundary conditions for the different variables. The problem is solved
as an uncostrained one on a suitably trasformed variable y. Possible
values are:

  Interval:                                       Trasformation:
  0 unconstrained                                 x=y
  1 semi-closed right half line [ xmin,+infty )   x=xmin+y^2
  2 semi-closed left  half line ( -infty,xmax ]   x=xmax-y^2
  3 closed interval              [ xmin,xmax ]    x=SS+SD*sin(y)
  4 open right half line        ( xmin,+infty )   x=xmin+exp(y)
  5 open left  half line        ( -infty,xmax )   x=xmax-exp(y)
  6 open interval                ( xmin,xmax )    x=SS+SD*tanh(y)

where SS=.5(xmin+xmax) SD=.5(xmax-xmin)

There are also other UNSUPPORTED trasformations used in various test
  7 open interval                ( xmin,xmax )    x=SS+SD*(1+y/sqrt(1+y^2))
  8 open right half line        ( xmin,+infty )   x=xmin+.5*(y+sqrt(1+y^2))
--------------------------------------------------------------------
xmin 
xmax

pointers to arrays of double containing respectively the lower and
upper boundaries of the different variables. For a given variable,
only the values that are implied by the type of constraints, defined
as in *type, are actually inspected.

--------------------------------------------------------------------
f		 

f calculates the objective function at a specified point x. Its
specification is

void (*f) (const size_t n, const double *x,void *fparams,double *fval)

      n
      INPUT: the number of variables

      x
      INPUT:the point at which the function is required

      fparams
      pointer to a structure containing parameters required by the
      function. If no external parameter are required it can be set to
      NULL.

      fval 
      OUTPUT: the value of the objective function at the current point
      x.

--------------------------------------------------------------------
df		 

df calculates the gradient of the objective function at a specified
point x. Its specification is

void (*df) (const size_t n, const double *x,void *fparams,double *grad)

      n
      INPUT: the number of variables

      x
      INPUT:the point at which the function is required

      fparams
      pointer to a structure containing parameters required by the
      function. If no external parameter are required it can be set to
      NULL.

      grad
      OUTPUT: the values of the gradient of the objective function at
      the current point x are stored in grad[0],...,grad[n-1].

--------------------------------------------------------------------
fdf		 

fdf calculates the value and the gradient of the objective function at
a specified point x. Its specification is

void (*df) (const size_t n, const double *x,void *fparams,double *fval,double *grad)

      n
      INPUT: the number of variables

      x
      INPUT:the point at which the function is required

      fparams
      pointer to a structure containing parameters required by the
      function. If no external parameter are required it can be set to
      NULL.

      fval 
      OUTPUT: the value of the objective function at the current point
      x.

      grad
      OUTPUT: the values of the gradient of the objective function at
      the current point x are stored in grad[0],...,grad[n-1].

--------------------------------------------------------------------
fparams

pointer to a structure containing parameters required by the
function. If no external parameter are required it can be set to NULL.

--------------------------------------------------------------------

oparams

structure of the type "multimin_params" containing the optimization
parameters. The members are

      double step_size
          size of the first trial step 

      double tol
          accuracy of the line minimization

      unsigned maxiter
          maximum number of iterations 

      double epsabs
          accuracy of the minimization

      unsigned method
          method to use. Possible values are:

          0: Fletcher-Reeves conjugate gradient
          1: Polak-Ribiere conjugate gradient
	  2: Vector Broyden-Fletcher-Goldfarb-Shanno method
	  3: Steepest descent algorithm

      unsigned verbosity
          if greater then 0 print info on intermediate steps

*/


#include "common.h"

struct g_params {
  size_t n;
  unsigned *type;
  double *xmin;
  double *xmax;
  void (*f) (const size_t,const double *,void *,double *);
  void (* df) (const size_t,const double *, void *,double *);
  void (* fdf) (const size_t,const double *, void *,double *,double *);
  void *fparams;
};

static double g(const gsl_vector *y,void *gparams){

  struct g_params *p= (struct g_params *) gparams;
  
  size_t i;
  double dtmp1;
  double res=GSL_NAN;/* the function is forced to return a value */
  

  /* dereference usefull stuff */
  const size_t n = p->n;
  const unsigned *type = p->type;
  const double * xmin = p->xmin;
  const double * xmax = p->xmax;

  double *x = (double *) my_alloc(sizeof(double)*n);

  /* compute values of x and of dx/dy */
  for(i=0;i<n;i++){
    switch(type[i]){
    case 0:/* (-inf,+inf) */
      x[i]= GET(y,i);
      break;
    case 1:/* [a,+inf) */
      x[i]= xmin[i]+GET(y,i)*GET(y,i);
      break;
    case 2:/* (-inf,a] */
      x[i]= xmax[i]-GET(y,i)*GET(y,i);
      break;
    case 3:/* [a,b] */
      dtmp1 = sin( GET(y,i) );
      x[i]= .5*(xmin[i]*(1-dtmp1) +xmax[i]*(1+dtmp1));
      break;
    case 4:/* (a,+inf) */
      dtmp1 = exp( GET(y,i) );
      x[i]= xmin[i]+dtmp1;
      break;
    case 5:/* (-inf,a) */
      dtmp1 = -exp( GET(y,i) );
      x[i]= xmax[i]+dtmp1;
      break;
    case 6:/* (a,b) */
      dtmp1 = tanh( GET(y,i) );
      x[i]= .5*(xmin[i]*(1-dtmp1) +xmax[i]*(1+dtmp1));
      break;
    case 7:/* (a,b) second approach */
      dtmp1 = GET(y,i)/sqrt(1.+GET(y,i)*GET(y,i));
      x[i]= .5*(xmin[i]*(1-dtmp1) +xmax[i]*(1+dtmp1));
      break;
    case 8:/* (a,+inf) second approach */
      dtmp1 = sqrt(1.+GET(y,i)*GET(y,i));
      x[i]= xmin[i] + .5*(dtmp1+GET(y,i));
      break;
    }
  }

  p->f(n,x,p->fparams,&res) ;
  free (x);
  return(res);

}

static void dg(const gsl_vector *y,void *gparams,gsl_vector *dg){

  struct g_params *p= (struct g_params *) gparams;
  
  size_t i;
  double dtmp1,dtmp2;
  
  /* dereference usefull stuff */
  const size_t n = p->n;
  const unsigned *type = p->type;
  const double * xmin = p->xmin;
  const double * xmax = p->xmax;

  double *x = (double *) my_alloc(sizeof(double)*n);
  double *dx = (double *) my_alloc(sizeof(double)*n);
  double *df = (double *) my_alloc(sizeof(double)*n);
  
  /* compute values of x and of dx/dy */
  for(i=0;i<n;i++){
    switch(type[i]){
    case 0:/* (-inf,+inf) */
      x[i]= GET(y,i);
      dx[i]= 1;
      break;
    case 1:/* [a,+inf) */
      x[i]= xmin[i]+GET(y,i)*GET(y,i);
      dx[i]= 2.*GET(y,i);
      break;
    case 2:/* (-inf,a] */
      x[i]= xmax[i]-GET(y,i)*GET(y,i);
      dx[i]= -2.*GET(y,i);
      break;
    case 3:/* [a,b] */
      dtmp1 = sin( GET(y,i) );
      x[i]= .5*(xmin[i]*(1-dtmp1) +xmax[i]*(1+dtmp1));
      dx[i]= .5*(xmax[i]-xmin[i])*cos(GET(y,i));
      break;
    case 4:/* (a,+inf) */
      dtmp1 = exp( GET(y,i) );
      x[i]= xmin[i]+dtmp1;
      dx[i]= dtmp1;
      break;
    case 5:/* (-inf,a) */
      dtmp1 = -exp( GET(y,i) );
      x[i]= xmax[i]+dtmp1;
      dx[i]= dtmp1;
      break;
    case 6:/* (a,b) */
      dtmp1 = tanh( GET(y,i) );
      dtmp2 = cosh( GET(y,i) );
      x[i]= .5*(xmin[i]*(1-dtmp1) +xmax[i]*(1+dtmp1));
      dx[i]= .5*(xmax[i]-xmin[i])/(dtmp2*dtmp2);
      break;
    case 7:/* (a,b) second approach */
      dtmp1 = GET(y,i)/sqrt(1.+GET(y,i)*GET(y,i));
      dtmp2 = (1.+GET(y,i)*GET(y,i))*sqrt(1.+GET(y,i)*GET(y,i)) ;
      x[i]= .5*(xmin[i]*(1-dtmp1) +xmax[i]*(1+dtmp1));
      dx[i]= .5*(xmax[i]-xmin[i])/dtmp2;
      break;
    case 8:/* (a,+inf) second approach */
      dtmp1 = GET(y,i);
      dtmp2 = sqrt(1.+dtmp1*dtmp1);
      x[i]= xmin[i] + .5*(dtmp1+dtmp2);
      dx[i]= .5*(dtmp1+dtmp2)/dtmp2;
      break;
    }
  }
  
  p->df(n,x,p->fparams,df);

/*   fprintf(stderr,"#dg: x=( "); */
/*   for(i=0;i<n;i++) */
/*     fprintf(stderr,"%f ",GET(x,i)); */
/*   fprintf(stderr,") dx=( "); */
/*   for(i=0;i<n;i++) */
/*     fprintf(stderr,"%f ",GET(dx,i)); */
/*   fprintf(stderr,") df=( "); */
/*   for(i=0;i<n;i++) */
/*     fprintf(stderr,"%f ",GET(dg,i)); */

  for(i=0;i<n;i++){
    SET(dg,i,df[i]*dx[i]);
  }

/*   fprintf(stderr,") dg=( "); */
/*   for(i=0;i<n;i++) */
/*     fprintf(stderr,"%f ",GET(dg,i)); */
/*   fprintf(stderr,")\n"); */

  free (x);
  free (dx);
  free (df);

}


static void gdg(const gsl_vector *y,void *gparams,double *g,gsl_vector *dg){

  struct g_params *p= (struct g_params *) gparams;
  
  size_t i;
  double dtmp1,dtmp2;


  /* dereference usefull stuff */
  const size_t n = p->n;
  const unsigned *type = p->type;
  const double * xmin = p->xmin;
  const double * xmax = p->xmax;

  double *x = (double *) my_alloc(sizeof(double)*n);
  double *dx = (double *) my_alloc(sizeof(double)*n);
  double *df = (double *) my_alloc(sizeof(double)*n);
  
  /* compute values of x and of dx/dy */
  for(i=0;i<n;i++){
    switch(type[i]){
    case 0:/* (-inf,+inf) */
      x[i]= GET(y,i);
      dx[i]= 1;
      break;
    case 1:/* [a,+inf) */
      x[i]= xmin[i]+GET(y,i)*GET(y,i);
      dx[i]= 2.*GET(y,i);
      break;
    case 2:/* (-inf,a] */
      x[i]= xmax[i]-GET(y,i)*GET(y,i);
      dx[i]= -2.*GET(y,i);
      break;
    case 3:/* [a,b] */
      dtmp1 = sin( GET(y,i) );
      x[i]= .5*(xmin[i]*(1-dtmp1) +xmax[i]*(1+dtmp1));
      dx[i]= .5*(xmax[i]-xmin[i])*cos(GET(y,i));
      break;
    case 4:/* (a,+inf) */
      dtmp1 = exp( GET(y,i) );
      x[i]= xmin[i]+dtmp1;
      dx[i]= dtmp1;
      break;
    case 5:/* (-inf,a) */
      dtmp1 = -exp( GET(y,i) );
      x[i]= xmax[i]+dtmp1;
      dx[i]= dtmp1;
      break;
    case 6:/* (a,b) */
      dtmp1 = tanh( GET(y,i) );
      dtmp2 = cosh( GET(y,i) );
      x[i]= .5*(xmin[i]*(1-dtmp1) +xmax[i]*(1+dtmp1));
      dx[i]= .5*(xmax[i]-xmin[i])/(dtmp2*dtmp2);
      break;
    case 7:/* (a,b) second approach */
      dtmp1 = GET(y,i)/sqrt(1.+GET(y,i)*GET(y,i));
      dtmp2 = (1.+GET(y,i)*GET(y,i))*sqrt(1.+GET(y,i)*GET(y,i)) ;
      x[i]= .5*(xmin[i]*(1-dtmp1) +xmax[i]*(1+dtmp1));
      dx[i]= .5*(xmax[i]-xmin[i])/dtmp2;
      break;
    case 8:/* (a,+inf) second approach */
      dtmp1 = GET(y,i);
      dtmp2 = sqrt(1.+dtmp1*dtmp1);
      x[i]= xmin[i] + .5*(dtmp1+dtmp2);
      dx[i]= .5*(dtmp1+dtmp2)/dtmp2;
      break;
    }
  }

  p->fdf(n,x,p->fparams,g,df);
    
/*   fprintf(stderr,"#gdg: f=%f x=( ",g); */
/*   for(i=0;i<n;i++) */
/*     fprintf(stderr,"%f ",GET(x,i)); */
/*   fprintf(stderr,") dx=( "); */
/*   for(i=0;i<n;i++) */
/*     fprintf(stderr,"%f ",GET(dx,i)); */
/*   fprintf(stderr,") df=( "); */
/*   for(i=0;i<n;i++) */
/*     fprintf(stderr,"%f ",GET(dg,i)); */
/*   fprintf(stderr,")\n"); */

  for(i=0;i<n;i++){
    SET(dg,i,df[i]*dx[i]);
  }
  
  free (x);
  free (dx);
  free (df);
}


/*

n         the dimension of the problem
x         INPUT: initial guess OUTPUT:  minimum point
f         INPUT: ------------- OUTPUT:  minimum value
type      the types of the boundaries
xmin      the minimum values
xmax      the maximum values
f         the structure of a function
fparams   the parameters of the provided function
oparams   parameters of the optimization

*/


void
multimin(size_t n,double *x,double *fun,
	 unsigned *type,double *xmin,double *xmax,
	 void (*f) (const size_t,const double *,void *,double *),
	 void (* df) (const size_t,const double *, void *,double *),
	 void (* fdf) (const size_t,const double *, void *,double *,double *),
	 void *fparams,
	 const struct multimin_params oparams)
{
  unsigned iter=0;
  int status;

  size_t i;
  double dtmp1;

  const gsl_multimin_fdfminimizer_type *T;
  gsl_multimin_fdfminimizer *s;
  

  gsl_vector * y  = gsl_vector_alloc (n);
  gsl_multimin_function_fdf GdG;


  struct g_params gparams;

  /* set the algorithm */
  switch(oparams.method){
  case 0:/* Fletcher-Reeves conjugate gradient */
    T = gsl_multimin_fdfminimizer_conjugate_fr;
    break;
  case 1:/* Polak-Ribiere conjugate gradient */
    T = gsl_multimin_fdfminimizer_conjugate_pr;
    break;
  case 2:/* Vector Broyden-Fletcher-Goldfarb-Shanno method */
    T = gsl_multimin_fdfminimizer_vector_bfgs;
    break;
  case 3:/* Steepest descent algorithm */
    T =gsl_multimin_fdfminimizer_steepest_descent;
    break;
  default:
    fprintf(stderr,"Optimization method not recognized. Try -h\n");
    exit(EXIT_FAILURE);
  };
  s = gsl_multimin_fdfminimizer_alloc(T, n);

  /* --- OUPUT ---------------------------------- */
  if(oparams.verbosity>0){
    fprintf(stderr,"#--- MULTIMIN START [method %s]\n",T->name);
    fprintf(stderr,"#    [step_size=%.3e tol=%.3e maxiter=%u epsabs=%.3e]\n",
	    oparams.step_size,oparams.tol,oparams.maxiter,oparams.epsabs);
  }
  /* -------------------------------------------- */



  /* set the parameters of the new function */
  gparams.n       = n;
  gparams.type    = type;
  gparams.xmin    = xmin;
  gparams.xmax    = xmax;
  gparams.f       = f;
  gparams.df      = df;
  gparams.fdf     = fdf;
  gparams.fparams = fparams;

  /* set the function to solve */
  GdG.f=g;
  GdG.df=dg;
  GdG.fdf=gdg;
  GdG.n=n;
  GdG.params=(void *) &gparams;

  /* compute values of y for initial condition */
  for(i=0;i<n;i++){
    switch(type[i]){
    case 0:/* (-inf,+inf) */
      SET(y,i,x[i]);
      break;
    case 1:/* [a,+inf) */
      SET(y,i,sqrt( x[i]-xmin[i] ));
      break;
    case 2:/* (-inf,a] */
      SET(y,i,sqrt( xmax[i]-x[i] ));
      break;
    case 3:/* [a,b] */
      dtmp1 = (xmax[i]>xmin[i]?
	       (2.*x[i]-xmax[i]-xmin[i])/(xmax[i]-xmin[i]) : 0);
      /*       dtmp1 = (2.*x[i]-xmax[i]-xmin[i])/(xmax[i]-xmin[i]); */
      SET(y,i,asin( dtmp1 ));
      break;
    case 4:/* (a,+inf) */
      SET(y,i,log( x[i]-xmin[i] ));
      break;
    case 5:/* (-inf,a) */
      SET(y,i,log( xmax[i]-x[i] ));
      break;
    case 6:/* (a,b) */
      dtmp1 = (2.*x[i]-xmax[i]-xmin[i])/(xmax[i]-xmin[i]);
      SET(y,i,gsl_atanh ( dtmp1 ));
      break;
    case 7:/* (a,b) second approach */
      dtmp1 = (2.*x[i]-xmax[i]-xmin[i])/(xmax[i]-xmin[i]);
      SET(y,i, dtmp1/sqrt(1-dtmp1*dtmp1));
      break;
    case 8:/* (a,+inf) second approach */
      dtmp1 = x[i]-xmin[i];
      SET(y,i, dtmp1-1./(4.*dtmp1));
      break;
    }
  }

  /* --- OUPUT ---------------------------------- */
  if(oparams.verbosity>1){
    fprintf(stderr,"#    - initial values and boundaries\n");
    for(i=0;i<n;i++){
      switch(type[i]){
      case 0:/* (-inf,+inf) */
	fprintf(stderr,"#    x[%d]=%e (-inf,+inf) -> %e\n",(int) i,x[i],GET(y,i));
	break;
      case 1:/* [a,+inf) */
	fprintf(stderr,"#    x[%d]=%e [%f,+inf) -> %e\n",(int) i,x[i],xmin[i],GET(y,i));
	break;
      case 2:/* (-inf,a] */
	fprintf(stderr,"#    x[%d]=%e (-inf,%f] -> %e\n",(int) i,x[i],xmax[i],GET(y,i));
	break;
      case 3:/* [a,b] */
	fprintf(stderr,"#    x[%d]=%e [%f,%f] -> %e\n",(int) i,x[i],xmin[i],xmax[i],GET(y,i));
	break;
      case 4:/* (a,+inf) */
	fprintf(stderr,"#    x[%d]=%e (%f,+inf) -> %e\n",(int) i,x[i],xmin[i],GET(y,i));
	break;
      case 5:/* (-inf,a) */
	fprintf(stderr,"#    x[%d]=%e (-inf,%f) -> %e\n",(int) i,x[i],xmax[i],GET(y,i));
	break;
      case 6:/* (a,b) */
      case 7:
	fprintf(stderr,"#    x[%d]=%e (%f,%f) -> %e\n",(int) i,x[i],xmin[i],xmax[i],GET(y,i));
	break;
      case 8:/* [a,+inf) */
	fprintf(stderr,"#    x[%d]=%e (%f,+inf) -> %e\n",(int) i,x[i],xmin[i],GET(y,i));
	break;
      }
    }
  }
  /* -------------------------------------------- */
  
  
  /* initialize minimizer */ 
  status=gsl_multimin_fdfminimizer_set(s,&GdG,y,oparams.step_size,oparams.tol);  
  if(status)
    {
      fprintf(stderr,"#ERROR: %s\n",gsl_strerror (status));
      exit(EXIT_FAILURE);
    }

  if(oparams.verbosity>2)
    fprintf(stderr,"#    - start minimization \n");
  do
    {
      iter++;
      status = gsl_multimin_fdfminimizer_iterate (s);

      /* --- OUPUT ---------------------------------- */
      if(oparams.verbosity>2){
	fprintf(stderr,"#    g=%f y=( ",s->f);
	for(i=0;i<n;i++)
	  fprintf(stderr,"%f ",GET(s->x,i));
	fprintf(stderr,") dg=( ");
	for(i=0;i<n;i++)
	  fprintf(stderr,"%f ",GET(s->gradient,i));
	fprintf(stderr,")\n");
      }
      /* -------------------------------------------- */

      if(status){
	fprintf(stderr,"#WARNING: %s\n", gsl_strerror (status));
	break;
      }
      
      status = gsl_multimin_test_gradient (s->gradient,oparams.epsabs);
            
      if(iter>=oparams.maxiter) break;
    }
  while (status == GSL_CONTINUE);


  /* compute values of x */
  for(i=0;i<n;i++){
    switch(type[i]){
    case 0:/* (-inf,+inf) */
      x[i]=GET(s->x,i);
      break;
    case 1:/* [a,+inf) */
      x[i]=xmin[i]+GET(s->x,i)*GET(s->x,i);
      break;
    case 2:/* (-inf,a] */
      x[i]=xmax[i]-GET(s->x,i)*GET(s->x,i);
      break;
    case 3:/* [a,b] */
      dtmp1 = sin( GET(s->x,i) );
      x[i]=.5*(xmin[i]*(1-dtmp1) +xmax[i]*(1+dtmp1));
      break;
    case 4:/* (a,+inf) */
      dtmp1 = exp( GET(s->x,i) );
      x[i]=xmin[i]+dtmp1;
      break;
    case 5:/* (-inf,a) */
      dtmp1 = -exp( GET(s->x,i) );
      x[i]=xmax[i]+dtmp1;
      break;
    case 6:/* (a,b) */
      dtmp1 = tanh( GET(s->x,i) );
      x[i]=.5*(xmin[i]*(1-dtmp1) +xmax[i]*(1+dtmp1));
      break;
    case 7:/* (a,b) second approach */
      dtmp1 = GET(s->x,i) ;
      dtmp1 = dtmp1/sqrt(1.+dtmp1*dtmp1);
      x[i]=.5*(xmin[i]*(1-dtmp1) +xmax[i]*(1+dtmp1));
      break;
    case 8:/* (a,+inf) second approach */
      dtmp1 = sqrt(1.+GET(s->x,i)*GET(s->x,i));
      x[i]= xmin[i] + .5*(dtmp1+GET(s->x,i));
      break;
    }
  }

  *fun=s->f;

  /* --- OUPUT ---------------------------------- */
  if(oparams.verbosity>0){
    fprintf(stderr,"#--- MULTIMIN END --- ");
    fprintf(stderr,"iterations %u\n",iter);
  }
  /* -------------------------------------------- */


  
  gsl_multimin_fdfminimizer_free (s);
  gsl_vector_free (y);
  
}
/*insert GNU extensions*/
#define _GNU_SOURCE
/*in particular, use of NAN extension*/

/* used by <errno.h> */
extern int errno;

/* GSL ----------- */
#include <gsl/gsl_vector.h>
#include <gsl/gsl_multimin.h>
#include <gsl/gsl_errno.h>
/* --------------- */

#define GET(x,i) gsl_vector_get(x,i)
#define SET(x,i,y) gsl_vector_set(x,i,y)

struct multimin_params {
  double step_size;
  double tol;
  unsigned maxiter;
  double epsabs;
  unsigned method;
  unsigned verbosity;
};

void
multimin(size_t,double *,double *,
	 unsigned *,double *,double *,
	 void (*) (const size_t,const double *,void *,double *),
	 void (*) (const size_t,const double *, void *,double *),
	 void (*) (const size_t,const double *, void *,double *,double *),
	 void *,
	 const struct multimin_params);

Attachment: pgp00000.pgp
Description: PGP signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]