Search All of the Math Forum:
Views expressed in these public forums are not endorsed by
Drexel University or The Math Forum.
|
|
|
|
Re: fminunc for function with two parameter inputs
Posted:
Feb 11, 2013 1:09 PM
|
|
On 2/7/2013 1:46 PM, Sebastian wrote: > Alan_Weiss <aweiss@mathworks.com> wrote in message > <kdjsks$q8s$1@newscl01ah.mathworks.com>... >> On 1/21/2013 10:15 AM, Sebastian wrote: >> > Dear all, >> > >> > I am looking for a way to minimize a function with two inputs: >> > >> > function ll=loglik(coef,coef2) >> > >> > p = zeros(NCS,NCLASS); >> > for i = 1:NCLASS; >> > v = VARS*coef(:,i); >> > for n = 1:NCS >> > vv = v(IDCASE==n,1); >> > vy = v(IDCASE==n & IDDEP==1,1); >> > vv = vv-repmat(vy,size(vv,1),1); >> > p(n,i) = 1/sum(exp(vv)); >> > end; >> > end; >> > >> > zg = RISK'*coef2; >> > h = zeros(NCLASS,NCS); >> > for i = 1:NCS; >> > for n = 1:NCLASS; >> > v = exp(zg(i,n)); >> > vv = sum(exp(zg(i,1:end))); >> > h(n,i) = v/vv; >> > end; >> > end; >> > h = max(h,0.00000001); >> > >> > % FUNCTION TO BE MINIMIZED >> > ll=-sum(log(diag(p*h))); >> > >> > >> > The problem is, that the inputs do not have the same dimensions. >> > >> > Example: >> > B = [0 0 0; 0 0 0; 0 0 0]; >> > G = 0; >> > >> > where B are the initial values for coef and G the ones of coef2 >> > I tried: >> > >> [paramhat,fval,exitflag,output,grad,hessian]=fminunc(@loglik,[B',G],options) >> > >> > Error (obviously): >> > CAT arguments dimensions are not consistent. >> > >> > >> [paramhat,fval,exitflag,output,grad,hessian]=fminunc(@(B)loglik(B',G),options,@(G)loglik(B',G)) >> > >> > Error: >> > FMINUNC only accepts inputs of data type double. >> > >> > What is the correct way of solving this? >> > >> > Best Regards >> > Sebastian >> >> You have two problems: fminunc wants all the variables it controls to >> be in one vector or array, and it also wants the initial point to be >> a single vector or array. If you want fminunc to change the values of >> both coef and coef2, well, you have to get those values into one >> vector or array. >> >> If coef2 is a constant, then you can follow the prescriptions in >> http://www.mathworks.com/help/optim/ug/passing-extra-parameters.html#bskkr4z >> >> For example, you could write >> fun = @(coef)loglik(coef,coef2) >> and just pass the initial value of coef as x0. >> >> But if, as I suspect, both coef and coef2 are variable, then you need >> to think of >> x = [coef(:);coef2(:)] >> In other words, make a single vector out of all the entries in coef >> and coef2. >> You can then take >> function u = loglik2(x) >> N = 15; % instead of 15 put in the number of elements of coef >> coef = x(1:N); >> coef = reshape(coef,mm,nn); % put in the correct values for mm and nn >> coef2 = x(N+1:end); >> % reshape coef2 if necessary >> u = loglik(coef,coef2) >> >> Do the same trick for x0. >> x0 = [B'(:);G(:)]; >> >> Then call fminunc: >> [paramhat,fval,exitflag,output,grad,hessian]=fminunc(@loglik2,x0,options) >> >> >> Alan Weiss >> MATLAB mathematical toolbox documentation > > Dear Alan, > I programmed this now and I have a problem: > My goal is to calculate a latent class logit > (http://www.stephanehess.me.uk/papers/Hess_Ben-Akiva_Gopinath_Walker_May_2011.pdf) > However, my programme does not vary the parameters properly. > > Programme: > the function loglik is minimized by using > [paramhat,fval,exitflag,output,grad,hessian]=fminunc(@loglik,B,options); > > B contains both coefficients and has size > ((NVARS+NRISK) x NCLASS) > where the partition (1:NVARS,NCLASS) contains the first set of parameters > and (NVARS+1,NCLASS) the last set of parameters > the last parameter is constrained to be zero > > so the function becomes: > > function ll=loglik(coef,coef2) > p = zeros(NCS,NCLASS); > for i = 1:NCLASS; > v = VARS*coef(:,i); > for n = 1:NCS > vv = v(IDCASE==n,1); > vy = v(IDCASE==n & IDDEP==1,1); > vv = vv-repmat(vy,size(vv,1),1); > p(n,i) = 1/sum(exp(vv)); > end; > end; > > zg = RISK'*coef2*R; %R is the matrix restricting the last coef to 0 > h = zeros(NCLASS,NCS); > for i = 1:NCS; > for n = 1:NCLASS; > v = exp(zg(i,n)); > vv = sum(exp(zg(i,1:end))); > h(n,i) = v/vv; > end; > end; > h = max(h,0.00000001); > > % FUNCTION TO BE MINIMIZED > ll=-sum(log(diag(p*h))); > > the problem is, that the coef2 always splits the sample in a way, that > I wind up with all classes being equally likely (RISK is so far only a > constant). Furthermore, my hessian always has as many rows and columns > being NaN as NCLASS. > What might be the problem? > > Best Greetings > Sebastian
I am not completely sure what is going on here. If you have a coefficient that is supposed to be fixed at 0, then you should reformulate the problem removing this coefficient. For example, if you wanted to minimize over [x(1), x(2), x(3)], and x(2) is restricted to be 0, then you should rewrite the problem to just have x(1) and x(3), and set x(2) = 0 in any formula using all the x.
If you don't want to do that, then use fmincon, and enter the restriction on the variable as a linear constraint or as two bounds that are equal. You can use equal bounds in the interior-point algorithm.
I am puzzled by your statement that you obtain NaN results. This sounds to me like some sort of error, either in programming, problem formulation, or use of fminunc with a constraint. Perhaps the problem reformulation I suggested, removing any fixed variables, will eliminate this problem.
I do not have any knowledge about why the "classes being equally likely" is a problem--if you have formulated your problem correctly, fminunc is just trying to minimize your cost, and it doesn't care about anything else.
Good luck,
Alan Weiss MATLAB mathematical toolbox documentation
|
|
|
|