Улучшение точности и производительности в оптимизации

Этот пример демонстрирует, что Symbolic Math Toolbox помогает минимизировать ошибки при решении нелинейной системы уравнений.

Этот пример использует следующую поддержку Symbolic Math Toolbox:

  • Вычисление аналитического градиента с помощью gradient

  • Вычисление аналитического якобиана с помощью jacobian

  • Преобразование символьных результатов в числовые функции с помощью matlabFunction

  • Аналитическая визуализация с fplot

Цель состоит в том, чтобы найти минимум Функции Розенброка или так называемую "банановую" функцию.

f(x)=i=1n/2100(x2i-x2i-12)2+(1-x2i-1)2

Используйте fplot создать быструю визуализацию Функции Розенброка двух переменных

syms x y
a=1;    b=100;
f(x,y)=(a-x)^2+b*(y-x^2)^2
f(x, y) = x-12+100y-x22(x - 1) ^2 + 100* (y - x^2) ^2
fsurf(f,[-2 2 -1 3])
view([-45 50])
colormap jet
caxis([0,1000])
colorbar

Мотивация

“Нелинейные уравнения с Аналитическим якобиевским” примером в Optimization Toolbox решают ту же задачу при помощи fsolve функция. Рабочий процесс, показанный в том примере, имеет два потенциальных источника ошибок. Вы должны были бы

  1. Переведите уравнения для Функции Розенброка и якобиана от математической формы в тексте к цифровому коду.

  2. Явным образом вычислите якобиан. Для сложных уравнений эта задача подвержена ошибкам.

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

Перепишите функцию Розенброка как систему нелинейных уравнений

Во-первых, преобразуйте Функцию Розенброка f к системе нелинейных уравнений F, где F градиент f .

clear
n = 64;
x = sym('x',[n,1]);
f = sum(100*(x(2:2:n)-x(1:2:n).^2).^2 + (1-x(1:2:n)).^2);
F = gradient(f,x);

Покажите первые 10 уравнений:

F(1:10)
ans = 

(2x1-400x1x2-x12-2200x2-200x122x3-400x3x4-x32-2200x4-200x322x5-400x5x6-x52-2200x6-200x522x7-400x7x8-x72-2200x8-200x722x9-400x9x10-x92-2200x10-200x92)[2*x1 - 400*x1* (x2 - x1^2) - 2; 200*x2 - 200*x1^2; 2*x3 - 400*x3* (x4 - x3^2) - 2; 200*x4 - 200*x3^2; 2*x5 - 400*x5* (x6 - x5^2) - 2; 200*x6 - 200*x5^2; 2*x7 - 400*x7* (x8 - x7^2) - 2; 200*x8 - 200*x7^2; 2*x9 - 400*x9* (x10 - x9^2) - 2; 200*x10 - 200*x9^2]

Чтобы совпадать с промежуточными результатами, показанными в примере Optimization Toolbox, используйте ту же форму F.

F(1:2:n) = simplify(F(1:2:n) + 2*x(1:2:n).*F(2:2:n));
F(1:2:n) = -F(1:2:n)/2;
F(2:2:n) = F(2:2:n)/20;

Теперь системы уравнений идентичны:

F(1:10)
ans = 

(1-x110x2-10x121-x310x4-10x321-x510x6-10x521-x710x8-10x721-x910x10-10x92)[1 - x1; 10*x2 - 10*x1^2; 1 - x3; 10*x4 - 10*x3^2; 1 - x5; 10*x6 - 10*x5^2; 1 - x7; 10*x8 - 10*x7^2; 1 - x9; 10*x10 - 10*x9^2]

Вычислите якобиан матрицы, представляющей систему уравнений

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

JF = jacobian(F,x);

Покажите первые 10 строк и столбцов якобиевской матрицы.

JF(1:10,1:10)
ans = 

(-1000000000-20x1100000000000-1000000000-20x3100000000000-1000000000-20x5100000000000-1000000000-20x7100000000000-1000000000-20x910)[-sym (1), sym (0), sym (0), sym (0), sym (0), sym (0), sym (0), sym (0), sym (0), sym (0);-20*x1, sym (10), sym (0), sym (0), sym (0), sym (0), sym (0), sym (0), sym (0), sym (0); sym (0), sym (0),-sym (1), sym (0), sym (0), sym (0), sym (0), sym (0), sym (0), sym (0); sym (0), sym (0),-20*x3, sym (10), sym (0), sym (0), sym (0), sym (0), sym (0), sym (0); sym (0), sym (0), sym (0), sym (0),-sym (1), sym (0), sym (0), sym (0), sym (0), sym (0); sym (0), sym (0), sym (0), sym (0),-20*x5, sym (10), sym (0), sym (0), sym (0), sym (0); sym (0), sym (0), sym (0), sym (0), sym (0), sym (0),-sym (1), sym (0), sym (0), sym (0); sym (0), sym (0), sym (0), sym (0), sym (0), sym (0),-20*x7, sym (10), sym (0), sym (0); sym (0), sym (0), sym (0), sym (0), sym (0), sym (0), sym (0), sym (0),-sym (1), sym (0); sym (0), sym (0), sym (0), sym (0), sym (0), sym (0), sym (0), sym (0),-20*x9, sym (10)]

Большинство элементов якобиевского матричного JF нули. Тем не менее, когда вы преобразуете эту матрицу в функцию MATLAB, результатом является плотная числовая матрица. Часто, операции на разреженных матрицах более эффективны, чем те же операции на плотных матрицах.

Поэтому, чтобы создать эффективный код, преобразуйте только ненулевые элементы JF к символьному вектору прежде, чем вызвать matlabFunction. is и js представляйте шаблон разреженности JF.

[is,js] = find(JF);
JF = JF(JF~=0);

Преобразуйте Систему уравнений и якобиан к функции MATLAB

Система уравнений F, представление Функции Розенброка, символьная матрица, которая состоит из символьных выражений. Смочь решить его с fsolve функция, преобразуйте эту систему в функцию MATLAB. На этом шаге удобно преобразовать оба F и его якобиан, JF, к одной основанной на файле функции MATLAB, FJFfun. В принципе это позволяет F и JF к переменным повторного использования. В качестве альтернативы можно преобразовать их в отдельные функции MATLAB.

matlabFunction([F;JF],'var',x,'file','FJFfun');

FJFfun принимает переменные как список, но fsolve ожидает вектор переменных. Функциональный genericObj преобразует вектор в список. Анонимная функция bananaObj задан, чтобы зафиксировать значения аргументов для genericObj. Отметьте использование шаблона разреженности в функциональном genericObj. Далее обратите внимание что этот подход использования FJFfun и genericObj вместе не связывается к конкретному выражению, представленному F и может быть использован как есть для любого F.

bananaobj = @(y) genericObj(y,@FJFfun,is,js)
bananaobj = function_handle with value:
    @(y)genericObj(y,@FJFfun,is,js)

Используйте fsolve, чтобы Численно Решить Систему Нелинейных уравнений

Используйте fsolve для системы уравнений, преобразованной в функцию MATLAB. Используйте начальную точку x (i) = –1.9 для нечетных индексов и x (i) = 2 для ровных индексов. Установите 'Display' to'iter' видеть прогресс решателя. Установите 'Jacobian' к 'on' использовать якобиан задало in bananaobj.

x0(1:n,1) = -1.9;
x0(2:2:n,1) = 2;
options = optimoptions(@fsolve,'Display','iter','Jacobian','on');
[sol1,Fsol,exitflag,output,JAC] = fsolve(bananaobj,x0,options);
                                         Norm of      First-order   Trust-region
 Iteration  Func-count     f(x)          step         optimality    radius
     0          1         8563.84                           615               1
     1          2         3093.71              1            329               1
     2          3         225.104            2.5           34.8             2.5
     3          4          212.48           6.25           34.1            6.25
     4          5          212.48           6.25           34.1            6.25
     5          6          212.48         1.5625           34.1            1.56
     6          7         116.793       0.390625           5.79           0.391
     7          8         109.947       0.390625          0.753           0.391
     8          9         99.4696       0.976563            1.2           0.977
     9         10         83.6416        2.44141           7.13            2.44
    10         11         77.7663        2.44141           9.94            2.44
    11         12         77.7663        2.44141           9.94            2.44
    12         13          43.013       0.610352           1.38            0.61
    13         14         36.4334       0.610352           1.58            0.61
    14         15         34.1448        1.52588           6.71            1.53
    15         16         18.0108        1.52588           4.91            1.53
    16         17         8.48336        1.52588           3.74            1.53
    17         18         3.74566        1.52588           3.58            1.53
    18         19         1.46166        1.52588           3.32            1.53
    19         20         0.29997        1.24265           1.94            1.53
    20         21               0      0.0547695              0            1.53

Equation solved.

fsolve completed because the vector of function values is near zero
as measured by the value of the function tolerance, and
the problem appears regular as measured by the gradient.

Используйте vpasolve, чтобы Численно Решить Систему Нелинейных уравнений

Система нелинейных уравнений, F, может быть альтернативно решен с vpasolve функция, которая является числовым решателем, доступным в Symbolic Math Toolbox. Основное отличие between vpasolve и fsolve тот fsolve использование арифметика с двойной точностью, чтобы решить уравнения, тогда как vpasolve арифметика переменной точности использования и поэтому, позволяет вам управлять точностью расчетов.

sol2 = vpasolve(F);

Если вы присваиваете решение системы уравнений к одной переменной, sol2, затем vpasolve возвращает решения в форме массива структур. Можно получить доступ к каждому решению (каждое поле массива структур):

sol2.x1
ans = 1.0vpa ('1.0')

Также можно преобразовать sol2 к символьному вектору, и затем получают доступ к области значений решений. Например, отобразите 5-е к 25-м решениям:

for k=(1:64)
  sol2_array(k) = sol2.(char(x(k)));
end
sol2_array(5:25)
ans = (1.01.01.01.01.01.01.01.01.01.01.01.01.01.01.01.01.01.01.01.01.0)[vpa ('1.0'), vpa ('1.0'), vpa ('1.0'), vpa ('1.0'), vpa ('1.0'), vpa ('1.0'), vpa ('1.0'), vpa ('1.0'), vpa ('1.0'), vpa ('1.0'), vpa ('1.0'), vpa ('1.0'), vpa ('1.0'), vpa ('1.0'), vpa ('1.0'), vpa ('1.0'), vpa ('1.0'), vpa ('1.0'), vpa ('1.0'), vpa ('1.0'), vpa ('1.0')]

Функции помощника

function [F,J] = genericObj(x,FJFfun,is,js)
% genericObj takes as input, vector x, Function and Jacobian evaluation 
% function handle FJFfun, and sparsity pattern is,js and returns as output,
% the numeric values of the Function and Jacobian: F and Jfunction 
% FJs(1:length(x)) is the numeric vector for the Function
% FJs(length(x)+1:end) is the numeric vector for the non-zero entries of the Jacobian

xcell = num2cell(x);
FJs = FJFfun(xcell{:});
F = FJs(1:length(x));
J = sparse(is,js,FJs(length(x)+1:end));

end

Copyright © 2016 MathWorks, Inc.

Для просмотра документации необходимо авторизоваться на сайте