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

C 使用gsl multimin在同一范围内计算f和df/dx,c,multidimensional-array,gsl,minimization,C,Multidimensional Array,Gsl,Minimization,gsl库算法如下: 必须为 操作的最小值。您可能还需要提供一个例程 计算函数和第三个例程的梯度 同时计算函数值和渐变 提供的示例定义了如下函数(我省略了特定于问题的详细信息,替换为…): 函数f本身 double my_f (const gsl_vector *v, void *params) { ... return rv; } f,df=(df/dx,df/dy)的梯度 最后,第三个函数同时计算f和df void my_fdf (const gsl_vector *x, void

gsl
库算法如下:

必须为 操作的最小值。您可能还需要提供一个例程 计算函数和第三个例程的梯度 同时计算函数值和渐变

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

函数
f
本身

double
my_f (const gsl_vector *v, void *params)
{
  ...
  return rv;
}
f
df
=(df/dx,df/dy)的梯度

最后,第三个函数同时计算
f
df

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
type
gsl\u multimin\u function\u fdf
的成员,它最终被传递到最小值

有几种情况下,一旦计算出函数值,其导数可能更容易计算,例如:让
f(x,y)=exp(x*g(y))
,其中
g(y)
计算起来可能很昂贵,那么使用
g(y)=log(f)/x来简单地进行
df/dx=g(y)f(x,y)

现在,就我从这个例子中学到的,极小值要求函数及其导数独立定义,而第三个定义看起来像一个虚拟包装器

是否有可能定义这些函数,使函数及其导数实际上可以在同一范围内计算

编辑:

在文件中,关于
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))

根据使用的优化算法,似乎可以交替调用。有人能确认一下吗?回到我原来的问题,这是否意味着库用户必须检查源代码,找出使用什么方法才能利用同时计算函数值及其梯度的可能性?

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

有几种情况下,一旦函数值 计算,其导数可能更容易计算

换句话说,在一个范围内计算值和梯度比单独计算值和梯度更容易。然而,如果极小值只需要梯度,或者如果极小值只需要值,则对两者进行评估将是不必要的昂贵

因此,您应该相信GSL,它知道自己想要什么。当极小化子需要知道某一特定点的值和梯度时,它将调用第三个函数,如果它只需要知道梯度,它将调用第一个或第二个函数

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

#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))