Unable to convert expression into double array, in Gamultiobj

Greetings, I need some help with figuring out how to make functions for optimization tools which accept symbolic handles (or so I think). I been trying with many solutions in this community but none seem to fit my problem. Most, if not all revolve around functions with limited symbolic variables that are not dynamic.
My problem is that I have 2 objective linear vectors Z_1 and Z_2 which can have many variables (from 82 to 1k or more), and trying to use the gamultiobj tool, I have the matrices and their vectors, the only thing that I can't figure out is how to make the fit function work. Here is the relevant code:
yy=sym([]); % I start with making the fit function as symbolic as suggested by many other solutions.
yy(:,1)=Z_1*sym('x',[1,size(Z_1,2)])'; % I try to vectorize the fitness function for Z_1 (which I think here is the problem) making the variables 'x1',..., 'xn'
yy(:,2)=Z_2*sym('x',[1,size(Z_1,2)])'; % And Z_2
[x,fval]=gamultiobj(@(x)yy,size(Z_1,2),MatrixInequality,VectorInequality,MatrixEquality,VectorEquality)
I think the problem is the vectorized fit function which may seem easy to fix if you are making only 3 or 8 or so variables (by hand) but if it's very dynamic, how can I make it work?
I attached the Z_1, Z_1 vectors as well as the matrices with their vectors if you need to take a closer look.

 Risposta accettata

Use matlabFunction() to convert yy to a numeric function. Be sure to use the 'vars' option to bundle all of the inputs into a single row vector

4 Commenti

I assume I must write this before yy going inside the function?
yy=matlabFunction(yy,'Vars',sym('x',[1,size(Z_11,2)]));
Now it gives this error:
Input arguments to function include colon operator. To input the colon character, use ':' instead.
EDIT:
I made some changes to the script:
Var=sym('x',[1,size(Z_1,2)]); % Added this for convenience
yy=sym([]);
yy(:,1)=Z_1*sym('x',[1,size(Z_1,2)])';
yy(:,2)=Z_2*sym('x',[1,size(Z_1,2)])';
yy=matlabFunction(yy,'Vars',{Var}) % Added this as suggested but this time adding {Var} This appears to solve the issue partially.
[x,fval]=gamultiobj(@(Var)yy(Var),size(Z_1,2),MatrixInequality,VectorInequality,MatrixEquality,VectorEquality)
% I added @(Var)yy(Var), Var as a handle and as an input. This solved the issue about the colon ':'.
Now the optimization runs without issues, but as I see the function handle yy, I noticed this:
@(in1)[conj(in1(:,1)).*(1.1e1./2.0)+conj(in1(:,2)).*(9.0./2.0)+conj(in1(:,3)).*1.2e2+conj(in1(:,5)).*2.1e2+conj(in1(:,6)).*1.32e3+conj(in1(:,7)).*1.2e3+conj(in1(:,8)).*1.05e3+conj(in1(:,9)).*1.317e3+conj(in1(:,10)).*1.269e3+conj(in1(:,11)).*1.185e3+conj(in1(:,12)).*9.93e2+conj(in1(:,13)).*9.45e2+conj(in1(:,14)).*9.09e2+conj(in1(:,15)).*7.17e2+conj(in1(:,16)).*6.69e2+conj(in1(:,17)).*5.85e2+conj(in1(:,18)).*5.43e2+conj(in1(:,19)).*4.95e2+conj(in1(:,20)).*4.59e2+conj(in1(:,21)).*1.185e3+conj(in1(:,22)).*1.137e3+conj(in1(:,23)).*1.101e3+conj(in1(:,24)).*1.149e3+conj(in1(:,25)).*1.101e3+conj(in1(:,26)).*1.017e3+conj(in1(:,27)).*5.85e2+conj(in1(:,28)).*5.37e2+conj(in1(:,29)).*5.01e2+conj(in1(:,30)).*6.99e2+conj(in1(:,31)).*6.51e2+conj(in1(:,32)).*5.67e2+conj(in1(:,65)).*7.0+conj(in1(:,66)).*5.0,conj(in1(:,33)).*1.0e7+conj(in1(:,34)).*1.5e7+conj(in1(:,67)).*1.0e7+conj(in1(:,68)).*1.5e7]
Even though the variables are named in1, each are considered different variables, it still bothers me that has that 1 in their name "in1". Is that normal or is there something wrong with the script. Because when I run it even though there are no errors, in each interation there doesn't seem to have much change in the values; and the fval in all rows gives the same values. That does seem strange to me, but given the nature of the genetic algorithm I don't know if that is supposed to happen or not.
Var=sym('x',[1,size(Z_1,2)]); % Added this for convenience
Okay, that constructs a vector of symbolic variables.
yy=sym([]);
yy(:,1)=Z_1*sym('x',[1,size(Z_1,2)])';
yy(:,2)=Z_2*sym('x',[1,size(Z_1,2)])';
Those create the same vector of variables, but multiply all of the entries by Z_1 or Z_2. The effect is the same as if you had done
yy = [Z_1 * Var(:), Z_2 * Var(:) ];
Those are algebraic matrix multiplication, with Z_1 and Z_2 being row vectors, and row vector * column vector gives a scalar, so yy will end up being a 1 x 2 vector.
then
yy=matlabFunction(yy,'Vars',{Var})
This creates a function that expects a vector that is 1 x size(Z_1,2) and which returns a 1 x 2 vector.
Your system is linear, so I have to wonder if there are better ways of handling it.
Because it is linear, and most of the Z_1 and Z_2 are 0, most of the time would be spent in finding combinations of the other variables that satisfy boundary conditions, even though those other variables play no other part in finding the optimal value. But likewise, the work is just in finding all those boundary spaces and for each one finding the linear solution for the two entries, so I am not surprised that all of the solutions are the same.
Yes, after playing a bit with the constraints (keeping inequalities, or equalities), everything seems ok. It was just that my problem is too constrained, that's probably why the population converges at an "obvious" local point.
Thanks for the help.
You might want to experiment with increasing your population size using the gamultiobj options.

Accedi per commentare.

Più risposte (0)

Prodotti

Release

R2017b

Community Treasure Hunt

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

Start Hunting!

Translated by