Reputation: 63
I have a data matrix X
of size 3065x57 and a column matrix y
of size 3065x1, and I want to compute the argmin
the function sum
defined in the code below.
I tried what is coded below, fminsearch
and so on, but none work.
Another problem is the fact that I have 57 symbolic variables, so MATLAB computations are very slow.
What can be done to speed up computaions?
function [] = argmin(X,y)
w = transpose(sym('w', [1 57]));
sum = 0;
for i=1:3065
sum = sum + log(1+exp(transpose(w)*transpose(X(i,:)))) -...
y(i,1)*transpose(w)*transpose(X(i,:));
end
F = matlabFunction(sum);
argmin = fsolve(F,zeros(1,57))
end
EDIT: I tried the following:
fun = @(w)log(1+exp(transpose([w(1);w(2);w(3);w(4);w(5);w(6);w(7);w(8);w(9);w(10)])*...
[1;1;1;1;1;1;1;1;1;1]))-...
transpose([w(1);w(2);w(3);w(4);w(5);w(6);w(7);w(8);w(9);w(10)])*...
[1;1;1;1;1;1;1;1;1;1]
x0 = [1,1,1,1,1,1,1,1,1,1];
x = fminsearch(fun,x0)
However, I can't do the for
loop.
Upvotes: 1
Views: 850
Reputation: 778
When using things like fminsearch
and fmincon
, you don't have to use an anonymous function in the sense you are using it. You can create your own function and make that into an anonymous function.
Also, your minimization variable does not have to be a symbol. As said in the comments this is very slow and unnecessary for your problem.
Code:
function sum = argmin_fun(x,y,w)
sum = 0;
for ii = 1:3065
sum = sum + log(1 + exp(w'*x(ii,:)')) - y(ii)*w'*x(ii,:)';
end
return
From your script, you can then call
x = randn(3065,57);
y = randn(3065,1);
fun = @(w) argmin_fun(x,y,w);
x0 = ones(57,1);
minimized_vals = fminsearch(fun,x0);
A few notes:
Consider using an options variable so you can set up options parameters such as how well you want it to be optimized, max iterations, as well as other parameters, you can set it up like this.
opts1 = optimset('Display','iter','MaxIter',100);
minimized_vals = fminsearch(fun,x0,opts1);
If you have the optimization toolbox, consider using fmincon
or one of the other optimizers, fminsearch
is good for problems with 1-10 variables but becomes much less accurate for large scale problems. With fmincon
you can also set up boundary constraints for minimum and maximum values. There are workarounds with fminsearch
but they aren't as easy to implement.
In terms of performance, the error function of fminsearch
achieved an error value of 9637.23 while fmincon
achieved an error value of 1945.63 without any constraints added.
[minimized_vals,error_val] = fmincon(fun,x0,[],[]);
Let me know if I missed anything and I'll ammend my answer.
Upvotes: 1
Reputation: 18838
If you want remove the loop, you can use matrix operations:
a = transpose(w)*transpose(X);
a
is a vector with size of 1 x 3065 (as w'
is 1 x 57 and X'
is 57 x 3065).
Now you can do the second operation like the following:
b = transpose(y).*a
So, sum
would be:
totalSum = sum(log(1+exp(a)) - b);
You should consider that as the sum
is a function in Matlab, it would be better change the name of sum
variableto
sum`.
In sum, we can remove the loop and replace the loop with the followings:
a = transpose(w)*transpose(X); % w: 57 x 1, X:3065 x 57
b = b = transpose(y).*a; % y: 3065 x 1, a: 1 x 3065
totalSum = sum(log(1+exp(a)) - b);
It could be so faster than which you write for the first solution.
Upvotes: 1