Файл скалярной целевой функции принимает один вход, скажем 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).
Записать эту функцию как файл, принимающий вектор 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));Сохранить как файл с именем myObjective.m в папку на вашем пути MATLAB ®.
Проверьте правильность оценки функции:
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, можно включить градиенты в целевую функцию. Как правило, решатели являются более надежными и могут быть несколько более быстрыми при включении градиентов. См. раздел Преимущества включения производных инструментов. О включении вторых производных (гессенов) см. в «Включая гессенов».
В следующей таблице показано, какие алгоритмы могут использовать градиенты и гессены.
| Решающее устройство | Алгоритм | Градиент | Мешковина |
|---|---|---|---|
fmincon | active-set | Дополнительный | Нет |
interior-point | Дополнительный | Необязательно (см. Hessian для алгоритма внутренней точки fmincon) | |
sqp | Дополнительный | Нет | |
trust-region-reflective | Необходимый | Необязательно (см. Hessian для алгоритмов fminunc trust-region или fmincon trust-region-reflective) | |
fminunc | quasi-newton | Дополнительный | Нет |
trust-region | Необходимый | Необязательно (см. Hessian для алгоритмов fminunc trust-region или fmincon trust-region-reflective) |
Код записи, возвращающий:
Целевая функция (скаляр) как первый выход
Градиент (вектор) как второй выход
Установите SpecifyObjectiveGradient опция для true использование optimoptions. При необходимости также установите SpecifyConstraintGradient опция для true.
При необходимости проверьте, соответствует ли функция градиента аппроксимации конечных разностей. См. раздел Проверка достоверности градиентов или якобианцев.
Совет
Для большей гибкости пишите условный код. Условный означает, что количество выходов функции может изменяться, как показано в следующем примере. Условный код не имеет ошибок в зависимости от значения SpecifyObjectiveGradient вариант. Безусловный код требует установки соответствующих параметров.
Например, рассмотрим функцию Розенброка
(1 − x1) 2,
который описан и выведен на печать в разделе «Решение ограниченной нелинейной проблемы на основе решателя». Градиент f (x) равен
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)];
endnargout проверяет количество аргументов, указанных вызывающей функцией. См. раздел Поиск аргументов количества функций.
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) функции Розенброка является (см. Как включить градиенты)
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, λ) равен
+∑λh,ihi (x).
g и h - векторные функции, представляющие все ограничения неравенства и равенства соответственно (означающие связанные, линейные и нелинейные ограничения), поэтому задача минимизации состоит в том, чтобы
) = 0.
Дополнительные сведения см. в разделе Теория ограниченной оптимальности. Гессен Лагранжиан -
| +∑λ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≤0 имеет градиент и матрицу второй производной.
[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' вместо 'bfgs'. Если вы можете предоставить свои собственные градиенты, попробуйте 'fin-diff-grads'и установите SpecifyObjectiveGradient и SpecifyConstraintGradient опции для true.
Хотите больше эффективности - предоставьте свои градиенты и гессен. См. разделы Включение гессенцев, fmincon Interior-Point Algorithm with Analytic Hessian и Расчет градиентов и гессенцев с помощью символьных математических Toolbox™.
Причина 'lbfgs' имеет только умеренную эффективность двояко. Имеет относительно дорогие обновления Шермана - Моррисона. И результирующий шаг итерации может быть несколько неточным из-за 'lbfgs' ограниченная память.
Причина 'fin-diff-grads' и HessianMultiplyFcn имеют только умеренную эффективность в том, что они используют подход сопряженного градиента. Они точно оценивают гессен целевой функции, но генерируют не самый точный шаг итерации. Для получения дополнительной информации см. fmincon Interior Point Algorithm и его обсуждение подхода LDL и подхода сопряженного градиента для решения уравнения 38.