Вычислить f и df / dx в одной области с помощью gsl multimin

В документации по алгоритмам многомерной минимизации 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))

которые, кажется, называются альтернативно, в зависимости от используемого алгоритма оптимизации. Не мог бы кто-нибудь подтвердить это, пожалуйста? Возвращаясь к моему первоначальному вопросу, означает ли это, что пользователь библиотеки должен проверить источник, чтобы узнать, какой метод использовать, чтобы воспользоваться возможностью вычисления обоих значение функции и ее градиент вместе?


person Marshall    schedule 17.02.2014    source источник


Ответы (1)


GSL запрашивает три функции: (а) одну, которая вычисляет значение, (б), другую, которая вычисляет градиент, и (в), которая вычисляет оба по той же причине, что и вас беспокоит:

Есть несколько случаев, когда после вычисления значения функции легче вычислить ее производную.

Другими словами, может быть проще рассчитать и значение, и градиент в одной области, чем вычислять значение и градиент по отдельности. Однако оценка обоих будет излишне затратной, если минимизатору нужен только градиент или если минимизатору нужно только значение.

Следовательно, вы должны доверять GSL в том, что он знает, чего хочет. Минимизатор будет вызывать третью функцию всякий раз, когда ему нужно знать и значение, и градиент в определенной точке, и что он будет вызывать первую или вторую функцию, если ему нужно знать только либо значение или градиента.

Вам решать, хотите ли вы, чтобы третья функция выполняла некоторые умные вычисления, использующие конкретную проблему, или вы хотите, чтобы она была простой оболочкой.

person s.bandara    schedule 17.02.2014