How to minimize a function when variables do not appear directly?

The code is too complicated, so I resume its structure in equivalent way: I choose a start vector x, for example x=[x1 x2 x3 x4] (for my problem it could have more than 1000 elements), and through separate functions I calculate the vectors a,b,c,d. Each of them depends on the previous one, more or less in this way:
a=f(x);
b=f(a,par1,par2,par3);
c=f(b,x,par1,par2,par3);
d=f(c,par1,par2,par3);
The object function (OF) I want to minimize is very simple, something like OF=d1+d2+d3+d4, but how can I find the vector x that minimizes OF if it does not appear in the function?

6 commentaires

Please tell us how d1+d2+d3+d4 are related to the functions you have posted. Why can't you just chain some function handles together?
Your OF would appear to be a vector output. How do you want to minimize a vector? Are you looking to minimize the sum of squares of the entries? Are you looking for a pareto front?
The calculations that are done: are they pure formulas, or do they have conditional logic? If they are formulas then they could be evaluated with symbolic inputs to come up with an overall formula that could be used for minimization.
Each function (a through d) has more than 50 code lines with several "for" cicles, so I think it is impossible to write a direct expression to chain them, such as a polynomial. When I calculate "b", it takes "a" as a vector of numbers calculated in the previous function; the same is for "c" and "d". So I come at the end of my code with a vector d of numbers [d1 d2 d3 d4], whose sum gives me OF (a scalar to answer the question). But all the code, and these final numbers depend on the values of vector x
"for" loops can still be worked symbolically, as long as there are no tests against the value of the variables.
So if the variable x does not appear directly in OF, it is impossible to use fminnunc or similar minimization functions?
You just need to pass the parameters to the function exactly as Walter Roberson and the MATLAB documentation show:

Connectez-vous pour commenter.

 Réponse acceptée

par1 = ...
par2 = ...
par3 = ...
func = @(x) minimize_this(x, par1, par2, par3)
[best_x, fval, exitflag, output] = gamultiobj(func, number_of_variables);
function cost = minimize_this(x, par1, par2, par3);
a=f(x);
b=f(a,par1,par2,par3);
c=f(b,x,par1,par2,par3);
d=f(c,par1,par2,par3);
OF = a + b + c + d;
cost = OF;
end
"So if the variable x does not appear directly in OF, it is impossible to use fminnunc or similar minimization functions?"
Not appearing directly in OF is not the problem. You cannot use fminunc or similar minimization functions because your OF is a vector and it is meaningless to minimize a vector.

Plus de réponses (1)

Pasquale
Pasquale le 4 Nov 2017
Thanks for advice, but the problem is a bit different. I need a,b and c only to evaluate d. To make the problem realistic, a is a displacement vector, b are strains, c stresses, and d stress combination, so they can be calculated only one after the other. When I get d, my OF is the sum of the elements of d vector, so it is scalar. For example OF=d1+d2, or OF=d1+d2+d3+d4+d5...+d1000 (vectors x and d have the same length, this depends on the mesh size).

9 commentaires

par1 = ...
par2 = ...
par3 = ...
func = @(x) minimize_this(x, par1, par2, par3)
x0 = ...
[best_x, fval, exitflag, output] = fminunc(func, x0);
function cost = minimize_this(x, par1, par2, par3);
a=f(x);
b=f(a,par1,par2,par3);
c=f(b,x,par1,par2,par3);
d=f(c,par1,par2,par3);
OF = sum(d)
cost = OF;
end
I am sorry, maybe I did not give good explanation. This example would be perfect if a,b,c,d, were linked to x through polynomial, trigonometric, or similar functions. In my problem x is a vector of numbers, a sort of parameters that I choose at the beginning of the code, and not exactly a variable. It influences the computation of a,b,c,d, but I cannot write them as direct functions of x. So my aim is to find which values should be assigned to x, in order to minimize OF.
You had asked "but how can I find the vector x that minimizes OF" and this code finds that. It tries out different values for entries of x looking for the combination that minimizes the cost, however the cost is calculated. It does not matter whether the calculation is linear. As long as you can take a trial version of x and calculate through to a cost, then the above will do a local minimization.
(If the calculation has discontinuities, it probably will not do well on finding a minima.)
You pass in all the constant values through parameters such as par1 -- you can pass any number of constants that you need. The x parameter gets the current test value whose fitness is to be evaluated. Then it uses the results and possibly numeric gradient estimations to predict where a lower value might be, and it tries that, and so on.
I made a very simple example to try, and it works:
% main code
x=1;
func=@(x)myfunction(x);
x0=5;
[best_x, fval, exitflag, output] = fminunc(func, x0)
% function
function cost=myfunction(x)
A=2*x^2
B=3*x
C=2+x
D=A+B-C
OF=2*D-D
cost=OF
Now, imagine you want to write exactly the same code, but with a structure a bit different, more similar to my real code:
% main code
x=1;
A=funz1(x);
B=funz2(x);
C=funz3(x);
D=funz4(A,B,C);
% function 1
function A=funz1(x)
A=2*x^2
% function 2
function B=funz2(x)
B=3*x
% function 3
function C=funz3(x)
C=2+x
% function 4
function D=funz4(A,B,C)
D=A+B-C
How should I write the function cost, and how write it in the main code? I think this could definitely solve my problem
function cost = minimize_this(x);
a = funz1(x);
b = funz2(x);
c = funz3(x);
d = funz4(a, b, c);
cost = d;
end
with
x0 = ...
[best_x, fval, exitflag, output] = fminunc(@minimize_this, x0);
"how can I find the vector x that minimizes OF if it does not appear in the function?"
This does not make sense: x must appear in the cost function for the minimization to make any sense. The problem is that you seem to think that it is required to evaluate all of those functions for some x value before calling fminunc, but this totally defeats the purpose of functions: they can be passed around without being evaluated with specific values.
Instead of this:
x=1;
A=funz1(x);
B=funz2(x);
C=funz3(x);
D=funz4(A,B,C);
you need to stop thinking that you have to evaluate those functions for some x value before using them in your cost function. All you need is to call those functions inside of your main cost function (of course adding the parameters as Walter Roberson showed):
function OF = cost(x)
A=funz1(x);
B=funz2(x);
C=funz3(x);
D=funz4(A,B,C);
OF=2*D-D;
end
"How should I write the function cost, and how write it in the main code?"
Walter Roberson has already shown you exactly how you should solve this task. Thrice. And now me too. What part of this does not work for you? What are you expecting that this solution does not give you?
I even put all of this into one Mfile and attached it to this comment. It runs. It gives exactly the same output as your "simple example" above.
Add the parameters exactly like Walter Roberson showed you already.
Now it is ok, thank you! It is the first time I have to solve this kind of problems, so I asked to learn.
@Pasquale: you should accept Walter Roberson's answer, because it correctly resolves your question.

Connectez-vous pour commenter.

Catégories

Community Treasure Hunt

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

Start Hunting!

Translated by