В документации по алгоритмам многомерной минимизации gsl
библиотеки говорится:
Вы должны предоставить параметрическую функцию n переменных, с которой будут работать минимизаторы. Вам также может потребоваться предоставить подпрограмму, которая вычисляет градиент функции, и третью подпрограмму, которая вычисляет как значение функции, так и градиент вместе.
В приведенном примере такие функции определяются следующим образом (я пропустил детали конкретной проблемы, заменены на ...
):
Сама функция f
double
my_f (const gsl_vector *v, void *params)
{
...
return rv;
}
Градиент f
, df
= (df / dx, df / dy).
void
my_df (const gsl_vector *v, void *params, gsl_vector *df)
{
...
gsl_vector_set(df, ...);
gsl_vector_set(df, ...);
}
И, наконец, третья функция для одновременного вычисления 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
типа 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))
которые, кажется, называются альтернативно, в зависимости от используемого алгоритма оптимизации. Не мог бы кто-нибудь подтвердить это, пожалуйста? Возвращаясь к моему первоначальному вопросу, означает ли это, что пользователь библиотеки должен проверить источник, чтобы узнать, какой метод использовать, чтобы воспользоваться возможностью вычисления обоих значение функции и ее градиент вместе?