Passing Extra Parameters in Optimization Output

조회 수: 7 (최근 30일)
Oyeniyi
Oyeniyi 2015년 6월 8일
댓글: HiWave 2020년 9월 15일
Is there a way to pass out extra calculated values (including the objective) from the objective function file while using the optimizers (e.g. fmincon, fminunc). For example in the code below, 'y' is the objective function to be minimized but I want the function to also return 'z' when the optimizer is called.
function [y z] = func(x,a,b,c)
y = (a - b*x(1)^2 + x(1)^4/3)*x(1)^2 + x(1)*x(2) + ...
(-c + c*x(2)^2)*x(2)^2;
z = x(2)*x(1)^2 + b*x(2)^5;
end

답변 (4개)

Nicolas Lepage-Saucier
Nicolas Lepage-Saucier 2017년 12월 15일
It is better to avoid using global variables. A better way is to use extra input instead of extra output.
Step 1: Create a handle class (using a piece of code seen many places on forums)
Create a .m file named hObj.m and save it in your working directory:
classdef hObj < handle
properties
o=[];
end
methods
function obj=hObj(receivedObject)
obj.o=receivedObject;
end
end
end
Step 2: In your main file, create the handles that will receive your desired output, for instance:
y = hObj([]);
z = hObj([]);
Step 3: Add y_out and z_out as extra input of your optimization function and store their values in y_out.o and z_out.o:
function y = func(x,a,b,c,y_out,z_out)
y = (a - b*x(1)^2 + x(1)^4/3)*x(1)^2 + x(1)*x(2) + ...
(-c + c*x(2)^2)*x(2)^2;
y_out.o = y;
z_out.o = x(2)*x(1)^2 + b*x(2)^5;
end
(note the .o that gives you access to the objects that y_out and z_out are pointing to).
Step 4: Add y and z to the input when calling the optimizer. For instance:
[x,fval] = fminunc(@(x)func(x,a,b,c,y,z),x0)
The whole code of the main file may look like this (note that prior to Matlab 2017, you may need to save your function func in a separate file, I'm not sure).
y = hObj([]);
z = hObj([]);
a = 4; b = 2.1; c = 4; % Assign parameter values
x0 = [0.5,0.5];
[x,fval] = fminunc(@(x)func(x,a,b,c,y,z),x0)
y.o
z.o
function y = func(x,a,b,c,y_out,z_out)
y = (a - b*x(1)^2 + x(1)^4/3)*x(1)^2 + x(1)*x(2) + ...
(-c + c*x(2)^2)*x(2)^2;
y_out.o = y;
z_out.o = x(2)*x(1)^2 + b*x(2)^5;
end
  댓글 수: 2
Carlos Andrés Candelo Zuluaga
Carlos Andrés Candelo Zuluaga 2019년 8월 2일
Thanks Man. This was useful for me.
HiWave
HiWave 2020년 9월 15일
BIG help...thanks!

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


Walter Roberson
Walter Roberson 2015년 6월 8일
No.
If I recall properly some error messages I have seen posted, the minimizers will check and will complain if you return extra outputs not configured by GradObj (second output) or Hessian (third output).
You could consider using an Output Function or Plot Function if what you wanted to do was display or plot current points or statistics.
However, if you want to output something computed along the way that, such as your z, then neither Output Functions nor Plot Functions are suitable, not directly.
You must already know how to parameterize objective functions, as otherwise you would not be receiving anything other than x for your objective function, no a, b, c. You can likewise parameterize Output Functions or Plot functions, and do the computation of z there and display or plot it.
If you want the values stored, then you will need to have your routine save the values somewhere, along with the current x. For example you could use nested routines to define your objective function, including shared variables that your objective function writes to. You can also do the same thing with global variables.
variable_to_save_to(end+1,:) = [z; x]; %scalar or column vector z
or
variable_to_save_to{end+1} = {x, z}; %any other kind of z

Yvan Denis
Yvan Denis 2017년 10월 11일
편집: Walter Roberson 2017년 10월 11일
Juste for those who find that post in the futur: I know it's usually a bad idea but global variables could do the trick here.
global z
function [y z] = func(x,a,b,c)
y = (a - b*x(1)^2 + x(1)^4/3)*x(1)^2 + x(1)*x(2) + ...
(-c + c*x(2)^2)*x(2)^2;
global z
z = [z x(2)*x(1)^2 + b*x(2)^5];
end
z store all the value obtained at each iteration.
  댓글 수: 1
Walter Roberson
Walter Roberson 2017년 10월 11일
You have a conflict there, between z as the output variable, and z as the global variable. In current releases, MATLAB will refuse to execute that code.
Also, as I indicated above, the optimizers check the number of output arguments and will complain if you return extra outputs beyond what might be required by using the GradObj or Hessian options.

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


Yaser Khojah
Yaser Khojah 2018년 5월 17일
I tried it but it shows the z value at the minimum point of y. Is there a way to show the value of z at all values of y; not only the minimum one.

카테고리

Help CenterFile Exchange에서 Solver-Based Nonlinear Optimization에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by