I need to minimize following function
nDOF, nprocs and T are taken from the first two columns of this table
So I have following vectors in MATLAB
nDOF =
3993
3993
3993
3993
3993
3993
3993
3993
7623
7623
7623
7623
7623
7623
7623
7623
nprocs =
1
2
3
4
6
8
12
24
1
2
3
4
6
8
12
24
vals =
0.6564
0.2569
0.2719
0.1743
0.1305
0.1230
0.1739
0.1147
1.1998
0.5088
0.6419
0.2899
0.2192
0.2033
0.2126
0.1821
And I wanted to minimize the function $F$ with function fmincon like this:
fmincon(@(theta) objFunctionMatAssemble(theta(1), theta(2), theta(3), theta(4), ndofIN, nprocsIN, vals), [0 0 0 0]', [], [], [], [], [0 0 0 0], [+inf +inf +inf +inf] )
Code of objFunctionMatAssemble:
function [t] = objFunctionMatAssemble(alpha, beta, gamma, delta, ndofIN, nprocsIN, vals)
t = 0;
for i=1:length(nprocsIN)
t = t + alpha*ndofIN^beta + gamma*((ndofIN(i)^delta)/nprocsIN(i) - vals(i))^2;
end
end
The problem is, I'm getting following error:
>> fmincon(@(theta) objFunctionMatAssemble(theta(1), theta(2), theta(3), theta(4), ndofIN, nprocsIN, vals), [0 0 0 0]', [], [], [], [], [0 0 0 0], [+inf +inf +inf +inf] )
Error using ^
Inputs must be a scalar and a square matrix.
To compute elementwise POWER, use POWER (.^) instead.
Error in objFunctionMatAssemble (line 4)
t = t + alpha*ndofIN^beta + gamma*((ndofIN(i)^delta)/nprocsIN(i) - vals(i))^2;
Error in @(theta)objFunctionMatAssemble(theta(1),theta(2),theta(3),theta(4),ndofIN,nprocsIN,vals)
Error in fmincon (line 535)
initVals.f = feval(funfcn{3},X,varargin{:});
Caused by:
Failure in initial objective function evaluation. FMINCON cannot continue.
The problem is apparently in my objective function, but I'm not able to write it correctly despite trying several times. I've seen some solution here on SO, but even if my "closure function" takes only one argument and calls the other one, still its format is not correct.
Could you, please, help me with this?
You forgot to index ndofIN
in the loop (you write ndofIN^beta
, which should be ndofIN(i)^beta
).
Now, the operator ^
in MATLAB means matrix power. For scalar/scalar input, this operation is the same as normal exponentiation, but for matrix/scalar inputs, it is not quite the same. In your case, MATLAB tries to exponentiate the vector ndofIN
with beta
-- this is not allowed, since matrix power is only defined for square matrices. That's why you get that error.
Obviously, this is not quite what you intend to do -- you want element wise exponentiation (.^
). Using this, you can simplify and speed up your objective function tremendously -- just write that objective function like this:
function t = objFunctionMatAssemble(alpha, ...
beta, ...
gamma, ...
delta, ...
ndofIN, ...
nprocsIN, ...
vals)
t = alpha * ndofIN.^beta + ...
gamma * (ndofIN.^delta)./nprocsIN - vals;
t = t.' * t;
end
NOTE in your original function there is also a parenthesis inconsistency. That is, your parenthesis make your objective function something else than what you've shown in the question:
% your version
t = t + alpha*ndofIN^beta + gamma*((ndofIN(i)^delta)/nprocsIN(i) - vals(i))^2;
% what's in the image
t = t + (alpha*ndofIN^beta + gamma* (ndofIN(i)^delta)/nprocsIN(i) - vals(i))^2;
NB2: You can also write your objective function like this:
function t = objFunctionMatAssemble2(theta, ...
ndofIN, ...
nprocsIN, ...
TIN)
N = bsxfun(@power, ndofIN, theta([2 4]).');
t = [N(:,1) N(:,2)./nprocsIN] * theta([1 3]) - TIN;
t = t.' * t;
end
so that your objective function does not need so many arguments. But well, that depends on your tastes.