使用gsl multimin在同一范围内计算f和df / dx

时间:2014-02-17 14:45:05

标签: c multidimensional-array gsl minimization

gsldocumentation about the multidimensional minimization算法读取:

  

您必须提供n个变量的参数函数   最小化器可以运行。您可能还需要提供一个例行程序   计算函数的梯度和第三个例程   同时计算函数值和梯度。

提供的示例定义了如下函数(我省略了特定于问题的详细信息,替换为...):

函数f本身

double
my_f (const gsl_vector *v, void *params)
{
  ...
  return rv;
}

渐变fdf =(df / dx,df / dy)。

void
my_df (const gsl_vector *v, void *params, gsl_vector *df)
{
  ...
  gsl_vector_set(df, ...);
  gsl_vector_set(df, ...);
}

最后,第三个同时计算fdf的函数

void
my_fdf (const gsl_vector *x, void *params, double *f, gsl_vector *df)
{
  *f = my_f(x, params);
  my_df(x, params, df);
}

这三个是struct类型gsl_multimin_function_fdf的成员,最终传递给最小化器。

有几种情况下,一旦计算出函数值,就可以更容易地计算其导数,例如:设f(x,y) = exp(x * g(y)),其中g(y)的计算成本可能很高,那么它很方便只需df/dx = g(y) f(x,y)使用g(y) = log(f)/x

现在,据我可以从示例中学习,最小化器需要独立定义函数及其派生,而第三个定义看起来像一个虚拟包装器。

是否可以以某种方式定义这些函数,使得函数及其导数实际上可以在同一范围内计算?

编辑:

在文档中,关于fdf,说明了

  

此函数提供f(x)g(x)的单独函数的优化 - 同时计算函数及其导数总是更快。

然而,我不确定如何。通过标题扫描,我发现定义了三个宏,一个用于这三个函数

#define GSL_MULTIMIN_FN_EVAL_F(F,x) (*((F)->f))(x,(F)->params)
#define GSL_MULTIMIN_FN_EVAL_DF(F,x,g) (*((F)->df))(x,(F)->params,(g))
#define GSL_MULTIMIN_FN_EVAL_F_DF(F,x,y,g) (*((F)->fdf))(x,(F)->params,(y),(g))
根据所使用的优化算法,似乎可以替代地调用

。请问有人确认一下吗?回到我原来的问题,这是否暗示库用户必须检查以找出使用什么方法以便利用计算两者的可能性函数值及其梯度在一起?

1 个答案:

答案 0 :(得分:2)

GSL要求三个功能,(a)一个计算,(b),另一个计算梯度,(c)计算一个两者,原因与您所关注的完全相同:

  

有几种情况一旦功能值出现   经计算,其导数可能更容易计算。

换句话说,在一个范围内计算值和梯度比分别计算值和梯度更容易。但是,如果最小化器仅需要梯度,或者如果最小化器仅需要该值,则评估两者将是不必要的昂贵。

因此,您应该信任GSL 它知道它想要什么。当需要知道两个值和特定点的渐变时,最小化器将调用第三个函数,并且如果它只需要知道,则它将调用第一个或第二个函数渐变。

由您决定是否希望第三个函数执行一些利用特定问题的智能计算,或者您是否希望它是一个简单的包装器。