Objective Function must return a scalar value.

Dear friends,
I am trying to do an optimization for a function using a "fmincon" function. I have got an error and couldn't find the problem.
The following is the error obtained :
Error using fmincon (line 609)
Supplied objective function must return a scalar value.
Error in Topo_3D (line 31)
[x,fval,ef,output,lambda,hessian] = fmincon(objective,x0,A,b,Aeq,beq,lb,ub,nonlincon,options);
A copy of my fmincon function is attached.
I appreciate if somebody help with this issue and how can be solved.
Thank you very much.
RTFQ

 Risposta accettata

f = nf*'u';
That multiplies the column vector nf by the literal character lower-case U. The 'u' will be converted to the character position that is used to encode 'u' which happens to be 117. So the vector nf is multiplied by the scalar 117 which yields a vector. However the first output of the objective function must be a scalar.
Your code happens to ignore the content of the variable you assigned, namely u
Perhaps you want nf*u' if u is a column vector the same length as nf

9 Commenti

Thank you so much Mr Walter!
Hi Mr Walter,
The code should be: f =nf'*u' in order to have the same length as nf.
However, I am getting errors as below;
Error using *
Inner matrix dimensions must agree.
Error in Topo_3D/obj (line 116)
f =nf'*u';
Error in fmincon (line 545)
[initVals.f,initVals.g] = feval(funfcn{3},X,varargin{:});
Error in Topo_3D (line 31)
[x,fval,ef,output,lambda,hessian] = fmincon(objective,x0,A,b,Aeq,beq,lb,ub,nonlincon,options);
Caused by:
Failure in initial objective function evaluation. FMINCON cannot continue.
Hope that Mr Walter can give me some advice on this errors.
Thanks
What is size(nf) and size(u)? Also size(x0)?
The size for nf,u and x0 is;
nf = 1x10
u = 1x2
x0 = 1x25.
Thanks.
Your function obj is the objective function in a call to fmincon(). fmincon() requires that the function returns a scalar as the first output. The first output variable inside obj() is f, so f must be calculated as a scalar.
You have f calculated as a * operation between nf and u. nf is 1x10 and u is 1x2 . The various output sizes possible for * between those variables are:
nf * u -> 1x10 * 1x2 --> error because 10 ~= 1
nf * u' -> 1x10 * 2x1 --> error because 10 ~= 2
nf' * u -> 10x1 * 1x2 --> valid, produces 10x2
nf' * u' -> 10x1 * 2x1 --> error because 1 ~= 2
so the only possibility for an * operation between the two is nf' * u producing a 10x2 output. However, 10x2 is not a scalar.
To repair this, u would have to be either 10x1 or 1x10. But you get u from reading a file, so unless that file is the wrong file, you might simply not be able to perform your computation.
Thank you Mr Walter, based on your advises and help my problem is solved.
However, my graph now is showing a 2D truss. Supposedly it should be a 3D space truss.
Below is my function to plot for the graphs.
Hope that Mr Walter can give me some advice on enhancing it to a 3D graph.
% switch, case execute one of several groups of statements
switch state
case 'init'
hold on
case 'iter'
% Link current point and objective function
% value with history. x must be a row vector.
history.fval = [history.fval; optimValues.fval];
history.x = [history.x; x];
figure(1);
plot(optimValues.iteration,optimValues.fval,'o');
xlabel('Iterations');
ylabel('Objective function');
title('Sequence of Points Computed by fmincon');
truss(x);
% Label points with iteration number and add title.
% Add .15 to x(1) to separate label from plotted 'o'
%text(x(1)+.15,x(2),num2str(optimValues.iteration));
case 'done'
hold off
otherwise
end
end
function plottruss = truss(x)
[node, elem, L] = nodelem(); % Get node and element list
% multiplication factor for area (to be adjusted)
mult = 10^4;
% plot the truss
Nel = size(elem,1);
figure(2);
plot(node(:,1), node(:,2), 'k.')
hold on; axis equal;
for iel = 1:Nel
elnodes = elem(iel, 1:2);
nodexy = node(elnodes, :);
plot(nodexy(:,1), nodexy(:,2), 'LineWidth', (x(iel)*mult))
end
end
end
Thank you very much!
I am having difficulty seeing any third dimension in your program. Possibly
plot3(nodexy(:,1), nodexy(:,2), repmat(x(iel), size(nodexy,1), 1))
Mr Walter,
May I know how do I transform this into a 3D plot for:
I have x,y,z for my nodes. It was imported from Opensees.exe.
function plottruss = truss(x)
[node, elem, L] = nodelem(); % Get node and element list
% multiplication factor for area (to be adjusted)
mult = 10^3;
% plot the truss
Nel = size(elem,1);
figure(2);
plot(node(:,1),node(:,2),'k.')
hold on; axis equal;
for iel = 1:Nel
elnodes = elem(iel, 1:2);
nodexy = node(elnodes, :);
plot3(nodexy(:,1), nodexy(:,2), repmat(x(iel), size(nodexy,1), 1))
end
end
end
Thanks.
As far as I can tell from the code that you posted earlier, there is no z coordinate in the truss file. It is, though, possible that the data exists in the file somewhere but is not read in. I do not have documentation on the file format.

Accedi per commentare.

Più risposte (0)

Community Treasure Hunt

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

Start Hunting!

Translated by