Passing Extra Parameters in Optimization Output

7 visualizaciones (últimos 30 días)
Oyeniyi
Oyeniyi el 8 de Jun. de 2015
Comentada: HiWave el 15 de Sept. de 2020
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

Respuestas (4)

Nicolas Lepage-Saucier
Nicolas Lepage-Saucier el 15 de Dic. de 2017
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 comentarios
Carlos Andrés Candelo Zuluaga
Carlos Andrés Candelo Zuluaga el 2 de Ag. de 2019
Thanks Man. This was useful for me.
HiWave
HiWave el 15 de Sept. de 2020
BIG help...thanks!

Iniciar sesión para comentar.


Walter Roberson
Walter Roberson el 8 de Jun. de 2015
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 el 11 de Oct. de 2017
Editada: Walter Roberson el 11 de Oct. de 2017
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 comentario
Walter Roberson
Walter Roberson el 11 de Oct. de 2017
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.

Iniciar sesión para comentar.


Yaser Khojah
Yaser Khojah el 17 de Mayo de 2018
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.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by