Date: Feb 11, 2013 1:09 PM
Author: Alan Weiss
Subject: Re: fminunc for function with two parameter inputs

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