Optimization: Reuse calculations from objective function in nonlinear constraints function

조회 수: 2 (최근 30일)
Hello,
Is it possible to reuse calculations from one function in the other to save computational effort?
Example:
function SSE = objfunc(inputs)
% some calculations that output model results + some other things
SSE = sum(residuals.^2)
end
function [c, ceq] = nonlinconstraint(inputs)
% same calculations as the objective function
building c and ceq vectors
end
Now, I know I could make a third function that wraps the calculations I mention and call that function both in objfunc and nonlinconstraint but that would imply in doing (the same) expensive calculations twice. Is there a way to reuse the calculations from one function into another or calculate it only once and pass the results to them? Other some other workflow that saves time?
If I use parallel computing toolbox I doubt it would reuse these common calculations, although it would probably make the code faster.
I am talking in the context of optimization, like multistart, globalsearch, fmincon, etc. that take up those functions to try to find global/local optimum.
I could potentially write a single function that outputs SSE,c,ceq but then I do not know how I would pass it to the aforementioned algorithms.

채택된 답변

Torsten
Torsten 2022년 8월 15일
  댓글 수: 13
Torsten
Torsten 2022년 8월 16일
You get the control vector
u = [u1,u2,u3,...,uN]
passed from "fmincon", I guess, because it is usually made up of variables to be adapted/optimized. With this control vector, one usually forms a function handle
fun_u = @(t)interp1(tspan,u,t,'spline') (or something else instead of spline)
passes this function handle to the ode-integrator (more precisely: to the function where you define the ode system) and evaluates it at the places where the control variable needs to be inserted as
u = fun_u(t).
Note that the (length of u) might be the (length of tspan - 1) ; this has somhow to be handled in the definition of fun_u.
Gustavo Lunardon
Gustavo Lunardon 2022년 8월 16일
Thanks for the explanation! Passing a handle looks better than passing a vector as I was thinking. Looks more neat.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Bruno Luong
Bruno Luong 2022년 8월 15일
You can use this design pattern
function preciousvalue = expensivereuse(inputs)
persistent lastresult
if ~isempty(lastresult) && isequal(input, lastresult.inputs)
preciousvalue = lastresult.preciousvalue;
else
preciousvalue = computepreciousvalue(inputs); % this is the function that computes the expensive part
lastresult = struct('inputs', inputs, 'preciousvalue', preciousvalue);
end
end
function SSE = objfunc(inputs)
preciousvalue = expensivereuse(inputs);
% some specific calculations that output model results + some other things
% from preciousvalue
SSE = sum(residuals.^2)
end
function [c, ceq] = nonlinconstraint(inputs)
preciousvalue = expensivereuse(inputs);
% some specific calculations
from preciousvalue
building c and ceq vectors
end
  댓글 수: 1
Gustavo Lunardon
Gustavo Lunardon 2022년 8월 15일
That is an interesting approach. It uses some lines I was not familiar with, like the persistent and from. I will keep that in mind. Thanks for the suggestion! It opens some paths to do other things I was looking for as well.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Global or Multiple Starting Point Search에 대해 자세히 알아보기

제품


릴리스

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by