"occasional" division by zero in optim-1.0.4/leasqr.m
Sergei Steshenko
sergstesh at yahoo.com
Fri Jul 10 13:07:31 CDT 2009
Hello,
running my calculations based on optim-1.0.4/leasqr.m I've noticed
occasional "division by zero" message.
Looking into the code I found that division by zero occurs at lines ##
301, 302 in the following piece of code:
281 % CALC VARIANCE COV MATRIX AND CORRELATION MATRIX OF PARAMETERS
282 % re-evaluate the Jacobian at optimal values
283 jac=feval(dFdp,x,f,p,dp,F);
284 msk = dp ~= 0;
285 n = sum(msk); % reduce n to equal number of estimated parameters
286 jac = jac(:, msk); % use only fitted parameters
287
288 %% following section is Ray Muzic's estimate for covariance and correlation
289 %% assuming covariance of data is a diagonal matrix proportional to
290 %% diag(1/wt.^2).
291 %% cov matrix of data est. from Bard Eq. 7-5-13, and Row 1 Table 5.1
292
293 if exist('sparse') % save memory
294 Q=sparse(1:m,1:m,1./wt.^2);
295 Qinv=sparse(1:m,1:m,wt.^2);
296 else
297 Q=diag((0*wt+1)./(wt.^2));
298 Qinv=diag(wt.*wt);
299 end
300 resid=y-f; %un-weighted residuals
301 covr=resid'*Qinv*resid*Q/(m-n); %covariance of residuals
302 Vy=1/(1-n/m)*covr; % Eq. 7-13-22, Bard %covariance of the data
303
304 jtgjinv=inv(jac'*Qinv*jac); %argument of inv may be singular
305 covp=jtgjinv*jac'*Qinv*Vy*Qinv*jac*jtgjinv; % Eq. 7-5-13, Bard %cov of parm est
306 d=sqrt(abs(diag(covp)));
307 corp=covp./(d*d');
308
309 if exist('sparse')
310 covr=spdiags(covr,0);
311 stdresid=resid./sqrt(spdiags(Vy,0));
312 else
313 covr=diag(covr); % convert returned values to compact storage
314 stdresid=resid./sqrt(diag(Vy)); % compute then convert for compact storage
315 end
.
I have verified that division by zero occurs because n == m; in my case
they both were 10, but they can be anything, of course.
Earlier in the code m, n are set this way (line #161)
159 y=y(:); wt=wt(:); pin=pin(:); dp=dp(:); %change all vectors to columns
160 % check data vectors- same length?
161 m=length(y); n=length(pin); p=pin;[m1,m2]=size(x);
162 if m1~=m ,error('input(x)/output(y) data must have same number of rows ') ,end;
.
In English 'm' is number of elements in 'y' vector which is the vector
of observed function values, and 'n' is number of elements in parameters
('p') which are supposed to be approximated by 'leasqr'.
Though I know nothing about covariance matrix (the piece of code where
division by zero occurs) and a little about Levenberg-Marquardt algorithm
implemented by 'leasqr', I do not think there should be a hard requirement
for number of elements in 'y' and 'p' to be different.
I have worked around the problem by changing number of observed points in
my code, so the division by zero does not occur, but I think somebody who
in details understands the algorithm should properly fix 'leasqr'.
Thanks,
Sergei.
More information about the Bug-octave
mailing list