fminconВ этом примере показано, как сгенерировать код для fmincon решатель оптимизации. Генерация кода требует лицензии MATLAB® Coder™. Для получения дополнительной информации требований генерации кода, смотрите Генерацию кода в fmincon Фоне.
Пример использует следующую простую целевую функцию. Чтобы использовать эту целевую функцию в вашем собственном тестировании, скопируйте код в файл с именем rosenbrockwithgrad.m. Сохраните файл на своем пути MATLAB.
function [f,g] = rosenbrockwithgrad(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
Сгенерировать код с помощью rosenbrockwithgrad целевая функция, создайте файл с именем test_rosen.m содержа этот код:
function [x,fval] = test_rosen opts = optimoptions('fmincon','Algorithm','sqp'); [x fval] = fmincon(@rosenbrockwithgrad,[-1,1],[],[],[],[],[-3,-3],[3,3],[],opts)
Сгенерируйте код для test_rosen файл.
codegen -config:mex test_rosen
Через какое-то время, codegen создает файл MEX под названием test_rosen_mex.mexw64 (расширение файла будет варьироваться, в зависимости от вашей системы). Можно запустить получившийся код С путем ввода test_rosen_mex. Результаты следующие или подобны:
x =
1.0000 1.0000
fval =
1.3346e-11
ans =
1.0000 1.0000После некоторых предложений в Генерации кода Оптимизации для Приложений реального времени, набор настройка сгенерированного кода, чтобы иметь меньше проверок и использовать выделение статического ЗУ.
cfg = coder.config('mex'); cfg.IntegrityChecks = false; cfg.SaturateOnIntegerOverflow = false; cfg.DynamicMemoryAllocation = 'Off';
Сожмите границы на проблеме от [-3,3] к [-2,2]. Кроме того, установите более свободную погрешность оптимальности, чем 1e-6 по умолчанию.
function [x,fval] = test_rosen2 opts = optimoptions('fmincon','Algorithm','sqp',... 'OptimalityTolerance',1e-5); [x fval eflag output] = fmincon(@rosenbrockwithgrad,[-1,1],[],[],[],[],... [-2,-2],[2,2],[],opts)
Сгенерируйте код для test_rosen2 файл.
codegen -config cfg test_rosen2
Запустите получившийся код.
test_rosen2_mex
x =
1.0000 1.0000
fval =
2.0057e-11
eflag =
2
output =
struct with fields:
iterations: 40
funcCount: 155
algorithm: 'sqp'
constrviolation: 0
stepsize: 5.9344e-08
lssteplength: 1
ans =
1.0000 1.0000Это решение почти так же хорошо как предыдущее решение с fval выведите вокруг 2e-11 по сравнению с предыдущим 1e-11.
Попытайтесь ограничить количество позволенных итераций к половине из взятых в предыдущем расчете.
function [x,fval] = test_rosen3 options = optimoptions('fmincon','Algorithm','sqp',... 'MaxIterations',20); [x fval eflag output] = fmincon(@rosenbrockwithgrad,[-1,1],[],[],[],[],... [-2,-2],[2,2],[],options)
Запустите test_rosen3 в MATLAB.
test_rosen3
x =
0.2852 0.0716
fval =
0.5204
eflag =
0
output =
struct with fields:
iterations: 20
funcCount: 91
algorithm: 'sqp'
message: '↵Solver stopped prematurely.↵↵fmincon stopped because it exceeded the iteration limit,↵options.MaxIterations = 2.000000e+01.↵↵'
constrviolation: 0
stepsize: 0.0225
lssteplength: 1
firstorderopt: 1.9504
ans =
0.2852 0.0716С этим серьезным пределом итерации, fmincon не достигает хорошего решения. Компромисс между точностью и скоростью может затруднить, чтобы справиться.
Чтобы сохранить вычисления функции и возможно увеличить точность, используйте встроенные производные примера путем установки SpecifyObjectiveGradient опция к true.
function [x,fval] = test_rosen4 options = optimoptions('fmincon','Algorithm','sqp',... 'SpecifyObjectiveGradient',true); [x fval eflag output] = fmincon(@rosenbrockwithgrad,[-1,1],[],[],[],[],... [-2,-2],[2,2],[],options)
Сгенерируйте код для test_rosen4 использование той же настройки как в test_rosen2.
codegen -config cfg test_rosen4
Запустите получившийся код.
test_rosen4_mex
x =
1.0000 1.0000
fval =
3.3610e-20
eflag =
2
output =
struct with fields:
iterations: 40
funcCount: 113
algorithm: 'sqp'
constrviolation: 0
stepsize: 9.6356e-08
lssteplength: 1
ans =
1.0000 1.0000По сравнению с test_rosen2, количество итераций является тем же самым в 40, но количество вычислений функции ниже в 113 вместо 155. Результат имеет лучшее (более низкое) значение целевой функции 3e-20 по сравнению с 2e-11.
fmincon | optimoptions | codegen (MATLAB Coder)