exponenta event banner

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

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

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

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

f (x) = 3 * (x - y) 4 + 4 * (x + z) 2/( 1 + x2 + y2 + z2) + cosh (x - 1) + tanh (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

Сведения о включении дополнительных параметров см. в разделе Передача дополнительных параметров. Более сложные примеры файлов функций см. в разделах Минимизация с помощью градиента и гессенского шаблона разреженности или Минимизация с помощью ограничивающих ограничений и Banded Predictioner.

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

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

Например, предположим, что требуется свернуть 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ДополнительныйНеобязательно (см. Hessian для алгоритма внутренней точки fmincon)
sqpДополнительныйНет
trust-region-reflectiveНеобходимыйНеобязательно (см. Hessian для алгоритмов fminunc trust-region или fmincon trust-region-reflective)
fminuncquasi-newtonДополнительныйНет
trust-regionНеобходимыйНеобязательно (см. Hessian для алгоритмов fminunc trust-region или fmincon trust-region-reflective)

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

  1. Код записи, возвращающий:

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

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

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

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

Совет

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

Например, рассмотрим функцию Розенброка

f (x) = 100 (x2 x12) 2 + (1 − x1) 2,

который описан и выведен на печать в разделе «Решение ограниченной нелинейной проблемы на основе решателя». Градиент f (x) равен

∇f (x) = [− 400 (x2 x12) x1 2 (1 x1) 200 (x2 − x12)],

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

При наличии лицензии на символьные математические Toolbox™ можно автоматически вычислять градиенты и гессены, как описано в разделе Расчет градиентов и гессенов с помощью символьных математических Toolbox™.

Включая гессенцев

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

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

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

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

H (x) = [1200x12 400x2 + 2 400x1 400x1200].

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

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,i∇2gi (x) +∑λh,i∇2hi (x).(1)

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

hessian = hessianfcn(x,lambda)

hessian - матрица n-на-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+x22≤1 диска единицы измерения, обратите внимание, что функция ограничения g (x) =x12+x22−1≤0 имеет градиент и матрицу второй производной.

∇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);

Другие примеры использования гессенского алгоритма внутренней точки см. в разделе fmincon Алгоритм внутренней точки с аналитическими гессенскими и вычисляющими градиентами и гессенскими с использованием символьных математических Toolbox™.

Функция умножения Гессена.  Вместо полной гессенской функции, оба fmincon interior-point и trust-region-reflective алгоритмы позволяют подавать гессенскую функцию умножения. Эта функция даёт результат гессеновского-временно-векторного произведения, не вычисляя гессенского напрямую. Это может сэкономить память. 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. HessianMultiplyFcn позволяет передать результат умножения гессена на вектор без вычисления гессена.

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

    W = HessMultFcn(H,v);

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

    Задайте следующие параметры:

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

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

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

Если градиенты не предоставляются, решатели оценивают градиенты с помощью конечных разностей. Если вы предоставляете градиенты, решатель не должен выполнять эту оценку конечных разностей, так что может сэкономить время и быть более точным, хотя оценка конечных разностей может быть быстрее для сложных производных. Кроме того, решатели используют приблизительный гессен, который может быть далек от истинного гессена. Предоставление гессена может дать решение в меньшем количестве итераций. Например, см. конец раздела «Расчет градиентов и гессенов с помощью символьных математических Toolbox™».

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

Выберите «Входное гессенское приближение» для внутренней точки fmincon

fmincon interior-point алгоритм имеет множество вариантов выбора входного гессенского приближения. Дополнительные сведения о синтаксисе см. в разделе Hessian as a Input. Вот варианты, наряду с оценками их относительных характеристик.

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

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

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

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

Связанные темы