Запись скалярных целевых функций

Файлы функции

Скалярный файл целевой функции принимает один вход, скажем xи возвращает один действительный скалярный выход, скажем f. Область входа x может быть скаляром, вектором или матрицей. Файл функции может вернуть больше выходы (см., Включая градиенты и Гессианы).

Например, предположим, что ваша цель является функцией трех переменных, x, y и z:

f (<reservedrangesplaceholder2>) = 3* (x – y)4 + 4* (x + z)2 / (1 + x2 + y2 + z2) + кош (x - 1) + танх (y + z).

  1. Запишите эту функцию как файл, который принимает вектор xin = [x; y; z] и возвраты f:

    function f = myObjective(xin)
    f = 3*(xin(1)-xin(2))^4 + 4*(xin(1)+xin(3))^2/(1+norm(xin)^2) ...
        + cosh(xin(1)-1) + tanh(xin(2)+xin(3));
  2. Сохраните его как файл с именем myObjective.m в папку на MATLAB® путь.

  3. Проверьте, что функция оценивается правильно:

    myObjective([1;2;3])
    
    ans =
        9.2666

Для получения информации о том, как включить дополнительные параметры, смотрите Передачу дополнительных параметров. Для более сложных примеров файлов функции, см. Минимизацию с градиентом и Гессианом Sparsity Pattern или Минимизацию с ограниченными ограничениями и Banded Preconditioner.

Локальные функции и вложенные функции

Функции могут существовать внутри других файлов как локальные функции или вложенные функции. Использование локальных функций или вложенных функций может снизить количество различных файлов, которые вы сохраняете. Использование вложенных функций также позволяет вам получить доступ к дополнительным параметрам, как показано на Nested Functions.

Например, предположим, что вы хотите минимизировать myObjective.m целевая функция, описанная в Файлы функции, удовлетворяющая ellipseparabola.m ограничение, описанное в разделе Нелинейные ограничения. Вместо записи двух файлов myObjective.m и ellipseparabola.m, запишите один файл, который содержит обе функции как локальные функции:

function [x fval] = callObjConstr(x0,options)
% Using a local function for just one file

if nargin < 2
    options = optimoptions('fmincon','Algorithm','interior-point');
end

[x fval] = fmincon(@myObjective,x0,[],[],[],[],[],[], ...
    @ellipseparabola,options);

function f = myObjective(xin)
f = 3*(xin(1)-xin(2))^4 + 4*(xin(1)+xin(3))^2/(1+sum(xin.^2)) ...
    + cosh(xin(1)-1) + tanh(xin(2)+xin(3));

function [c,ceq] = ellipseparabola(x)
c(1) = (x(1)^2)/9 + (x(2)^2)/4 - 1;
c(2) = x(1)^2 - x(2) - 1;
ceq = [];

Решите ограниченную минимизацию, начиная с точки [1;1;1]:

[x fval] = callObjConstr(ones(3,1))

Local minimum found that satisfies the constraints.

Optimization completed because the objective function is 
non-decreasing in feasible directions, to within the default 
value of the function tolerance, and constraints are satisfied 
to within the default value of the constraint tolerance.

x =
    1.1835
    0.8345
   -1.6439

fval =
    0.5383

Цели анонимных функций

Используйте анонимные функции для записи простых целевых функций. Для получения дополнительной информации об анонимных функциях см. «Что такое анонимные функции?». Функция Розенбрка достаточно проста, чтобы писать как анонимная функция:

anonrosen = @(x)(100*(x(2) - x(1)^2)^2 + (1-x(1))^2);
Проверяйте это anonrosen правильно оценивает в [-1 2]:
anonrosen([-1 2])

ans =
   104
Минимизация anonrosen с fminunc приводит к следующим результатам:
options = optimoptions(@fminunc,'Algorithm','quasi-newton');
[x fval] = fminunc(anonrosen,[-1;2],options)

Local minimum found.

Optimization completed because the size of the gradient
is less than the default value of the function tolerance.

x =
    1.0000
    1.0000

fval =
  1.2266e-10

Включая градиентов и гессиан

Предоставьте производные для решателей

Для fmincon и fminuncможно включать градиенты в целевую функцию. Как правило, решатели более устойчивы и могут быть немного быстрее, когда вы включаете градиенты. Смотрите преимущества включения производных. Чтобы также включить вторые производные (Гессианы), смотрите Включая Гессианы.

Следующая таблица показывает, какие алгоритмы могут использовать градиенты и Гессианы.

РешательАлгоритмГрадиентМешковина
fminconactive-setДополнительныйНет
interior-pointДополнительныйНеобязательно (см. Гессиан для алгоритма fmincon interior-point)
sqpДополнительныйНет
trust-region-reflectiveНеобходимыйНеобязательно (см. Гессиан для fminunc trust-области или fmincon trust- области отражающих алгоритмов)
fminuncquasi-newtonДополнительныйНет
trust-regionНеобходимыйНеобязательно (см. Гессиан для fminunc trust-области или fmincon trust- области отражающих алгоритмов)

Как включить градиенты

  1. Написание кода, который возвращает:

    • Целевая функция (скаляр) как первый выход

    • Градиент (вектор) как второй выход

  2. Установите SpecifyObjectiveGradient опция для true использование optimoptions. При необходимости также установите SpecifyConstraintGradient опция для true.

  3. Опционально проверьте, соответствует ли ваша градиентная функция конечноразностному приближению. См. «Проверка валидности градиентов или якобийцев».

Совет

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

Для примера рассмотрим Розенброк функцию

f(x)=100(x2x12)2+(1x1)2,

который описан и построен на графике в решении ограниченной нелинейной задачи, основанной на решателе. Градиент f (x)

f(x)=[400(x2x12)x12(1x1)200(x2x12)],

rosentwo является обусловленной функцией, которая возвращает все, что требуется решателю:

function [f,g] = rosentwo(x)
% Calculate objective f
f = 100*(x(2) - x(1)^2)^2 + (1-x(1))^2;

if nargout > 1 % gradient required
    g = [-400*(x(2)-x(1)^2)*x(1)-2*(1-x(1));
        200*(x(2)-x(1)^2)];
    
end

nargout проверяет количество аргументов, заданное вызывающей функцией. См. «Определение количества аргументов функции».

fminunc решатель, предназначенный для оптимизации без ограничений, позволяет минимизировать функцию Розенбрка. Сказать fminunc использовать градиент и Гессиан путем установки options:

options = optimoptions(@fminunc,'Algorithm','trust-region',...
    'SpecifyObjectiveGradient',true);

Управляемый fminunc начиная с [-1;2]:

[x fval] = fminunc(@rosentwo,[-1;2],options)
Local minimum found.

Optimization completed because the size of the gradient
is less than the default value of the function tolerance.

x =
    1.0000
    1.0000

fval =
  1.9886e-17

Если у вас есть лицензия Symbolic Math Toolbox™, можно вычислить градиенты и Гессианы автоматически, как описано в разделе Вычислить градиенты и Гессианы Используя Symbolic Math Toolbox™.

Включая Гессиан

Можно включать вторые производные с fmincon 'trust-region-reflective' и 'interior-point' алгоритмы, и с fminunc 'trust-region' алгоритм. Существует несколько способов включить информацию Гессиана, в зависимости от типа информации и от алгоритма.

Необходимо также включать градиенты (set SpecifyObjectiveGradient на true и, если применимо, SpecifyConstraintGradient на true) порядок включения Гессиан.

Гессиан для fminunc доверительная область или fmincon алгоритмы, отражающие доверительную область.  Эти алгоритмы либо не имеют ограничений, либо имеют только связанные или линейные ограничения равенства. Поэтому Гессиан является матрицей вторых производных целевой функции.

Включите матрицу Гессия в качестве третьего выхода целевой функции. Например, Гессиан H (x) функции Розенбрка является (см., Как включить градиенты)

H(x)=[1200x12400x2+2400x1400x1200].

Включите этого Гессиана в цель:

function [f, g, H] = rosenboth(x)
% Calculate objective f
f = 100*(x(2) - x(1)^2)^2 + (1-x(1))^2;

if nargout > 1 % gradient required
    g = [-400*(x(2)-x(1)^2)*x(1)-2*(1-x(1));
        200*(x(2)-x(1)^2)];
    
    if nargout > 2 % Hessian required
        H = [1200*x(1)^2-400*x(2)+2, -400*x(1);
            -400*x(1), 200];  
    end

end

Задайте HessianFcn на 'objective'. Для примера,

options = optimoptions('fminunc','Algorithm','trust-region',...
    'SpecifyObjectiveGradient',true,'HessianFcn','objective');

Гессиан для fmincon алгоритм внутренней точки.  Гессиан является Гессианом Лагранжа, где Лагрангиан L (x, λ)

L(x,λ)=f(x)+λg,igi(x)+λh,ihi(x).

g и h являются векторными функциями, представляющими все ограничения неравенства и равенства соответственно (означающие связанные, линейные и нелинейные ограничения), поэтому задача минимизации

minxf(x) при условии , что g(x)0, h(x)=0.

Для получения дополнительной информации смотрите Ограниченную теорию оптимальности. Гессиан Лагрангиан есть

xx2L(x,λ)=2f(x)+λg,i2gi(x)+λh,i2hi(x).(1)

Чтобы включить Гессиана, запишите функцию с синтаксисом

hessian = hessianfcn(x,lambda)

hessian - n -by n матрица, разреженная или плотная, где n - количество переменных. Если hessian является большим и имеет относительно мало ненулевых значений, экономия времени работы и памяти путем представления hessian как разреженная матрица. lambda является структурой с векторами множителей Лагранжа, сопоставленными с нелинейными ограничениями:

lambda.ineqnonlin
lambda.eqnonlin

fmincon вычисляет структуру lambda и передает его в вашу функцию Гессиана. hessianfcn необходимо вычислить суммы в Уравнении 1. Укажите, что вы поставляете Гессиана, установив следующие опции:

options = optimoptions('fmincon','Algorithm','interior-point',...
    'SpecifyObjectiveGradient',true,'SpecifyConstraintGradient',true,...
    'HessianFcn',@hessianfcn);

Например, чтобы включить Гессиана для функции Розенбрка, ограниченной единичным диском x12+x221, заметьте, что функция ограничения g(x)=x12+x2210 имеет градиент и вторую производную матрицу

g(x)=[2x12x2]Hg(x)=[2002].

Напишите функцию Гессиана как

function Hout = hessianfcn(x,lambda)
% Hessian of objective
H = [1200*x(1)^2-400*x(2)+2, -400*x(1);
            -400*x(1), 200];
% Hessian of nonlinear inequality constraint
Hg = 2*eye(2);
Hout = H + lambda.ineqnonlin*Hg;

Сохраните hessianfcn на пути MATLAB. Чтобы завершить пример, ограничительная функция, включая градиенты,

function [c,ceq,gc,gceq] = unitdisk2(x)
c = x(1)^2 + x(2)^2 - 1;
ceq = [ ];

if nargout > 2
    gc = [2*x(1);2*x(2)];
    gceq = [];
end

Решите проблему, включая градиенты и Гессиан.

fun = @rosenboth;
nonlcon = @unitdisk2;
x0 = [-1;2];
options = optimoptions('fmincon','Algorithm','interior-point',...
    'SpecifyObjectiveGradient',true,'SpecifyConstraintGradient',true,...
    'HessianFcn',@hessianfcn);
[x,fval,exitflag,output] = fmincon(fun,x0,[],[],[],[],[],[],@unitdisk2,options);

Для других примеров, использующих interior-point Hessian, смотрите fmincon Interior-Point Algorithm with Analytic Hessian и Calculate Gradients and Hessians Using Symbolic Math Toolbox™.

Функция умножения Гессиана.  Вместо полной функции Гессиана, оба fmincon interior-point и trust-region-reflective алгоритмы позволяют вам задать функцию умножения Гессиана. Эта функция дает результат векторного продукта Гессиана, не вычисляя непосредственно Гессиана. Это может сохранить память. The SubproblemAlgorithm опция должен быть 'cg' для работы функции умножения Гессиана; это значение trust-region-reflective по умолчанию.

Синтаксисы для двух алгоритмов различаются.

  • Для interior-point алгоритм, синтаксис:

    W = HessMultFcn(x,lambda,v);

    Результат W должен быть продуктом H*v, где H является Гессианом Лагранжа в x (см. Уравнение 1), lambda - множитель Лагранжа (вычисляется fmincon), и v - вектор размера n -by-1. Установите опции следующим образом:

    options = optimoptions('fmincon','Algorithm','interior-point','SpecifyObjectiveGradient',true,... 
        'SpecifyConstraintGradient',true,'SubproblemAlgorithm','cg','HessianMultiplyFcn',@HessMultFcn);

    Поставьте функцию HessMultFcn, который возвращает вектор n -by-1, где n - количество размерностей x. The HessianMultiplyFcn опция позволяет вам передать результат умножения Гессиана на вектор без вычисления Гессиана.

  • The trust-region-reflective алгоритм не включает lambda:

    W = HessMultFcn(H,v);

    Результат W = H*v. fmincon проходит H как значение, возвращенное в третьем выходе целевой функции (см. Гессиан для fminunc trust-области или fmincon trust- области отражающих алгоритмов ).fmincon также проходит v, вектор или матрица с n строками. Количество столбцов в v может варьироваться, поэтому записывайте HessMultFcn для принятия произвольного количества столбцов. H не обязательно быть Гессианом; скорее это может быть все, что позволяет вам вычислять W = H*v.

    Установите опции следующим образом:

    options = optimoptions('fmincon','Algorithm','trust-region-reflective',... 
        'SpecifyObjectiveGradient',true,'HessianMultiplyFcn',@HessMultFcn);

    Для примера, использующего функцию умножения Гессиана с trust-region-reflective алгоритм, см. Минимизация с плотными структурированными Гессианами, линейными равенствами.

Преимущества включения производных

Если вы не предоставляете градиенты, решатели оценивают градиенты через конечные различия. Если вы предоставляете градиенты, ваш решатель не должен выполнять эту конечную оценку различия, поэтому может сэкономить время и быть более точным, хотя оценка конечной разности может быть быстрее для сложных производных. Кроме того, решатели используют приблизительный Гессиан, который может быть далек от истинного Гессиана. Предоставление Гессиана может привести к решению в меньшем количестве итераций. Для примера смотрите конец Вычисления Градиентов и Гессианов Использование Symbolic Math Toolbox™.

Для ограниченных задач, обеспечение градиента имеет другое преимущество. Решатель может достичь точки x таким образом x является допустимым, но, для этого x, конечные различия вокруг x всегда приводят к недопустимой точке. Предположим далее, что целевая функция в недопустимой точке возвращает комплексный выход, Inf, NaN, или ошибка. В этом случае решатель может ошибиться или остановиться преждевременно. Предоставление градиента позволяет решателю продолжить. Чтобы получить это преимущество, вам также может потребоваться включить градиент нелинейной функции ограничения и задать SpecifyConstraintGradient опция для true. См. «Нелинейные ограничения».

Выберите Вход Hessian Приближения для интерьерно-точечных fmincon

fmincon interior-point алгоритм имеет много опций для выбора входа Гессиана приближения. Для получения дополнительной информации о синтаксисе смотрите Гессиан как вход. Вот опции, наряду с оценками их относительных характеристик.

МешковинаОтносительное использование памятиОтносительная эффективность
'bfgs' (по умолчанию)Высокий (для больших задач)Высоко
'lbfgs'От низкого до среднегоУмеренный
'fin-diff-grads'НизкоУмеренный
'HessianMultiplyFcn'Низкий (может зависеть от вашего кода)Умеренный
'HessianFcn'? (зависит от вашего кода)Высокий (зависит от вашего кода)

Используйте 'bfgs' по умолчанию Гессиан, если вы

Причина 'lbfgs' имеет только умеренную эффективность двойной. Имеет относительно дорогие обновления Шермана-Моррисона. И полученный шаг итерации может быть несколько неточным из-за 'lbfgs' ограниченная память.

Причина 'fin-diff-grads' и HessianMultiplyFcn иметь только умеренную эффективность заключается в том, что они используют сопряженный градиентный подход. Они точно оценивают Гессиана целевой функции, но они не генерируют наиболее точный шаг итерации. Для получения дополнительной информации смотрите fmincon Interior Point Algorithm, и его обсуждение подхода LDL и сопряженного градиентного подхода к решению уравнения 38.

Похожие темы