csminit <- function(fcn,x0,f0,g0,badg,H0,...){ ### retcodes: 0, normal step. 5, largest step still improves too fast. ### 4,2 back and forth adjustment of stepsize didn't finish. 3, smallest ### stepsize still improves too slow. 6, no improvement found. 1, zero ### gradient. ###--------------------- ### Fixed 7/17/93 to use inverse-hessian instead of hessian itself in bfgs ### update. ### ### Fixed 7/19/93 to flip eigenvalues of H to get better performance when ### it's not psd. ### ## ANGLE <- .0005 ANGLE <- 1e-7 THETA <- .3 #(0 1e12 ## disp('Bad, small gradient problem.') ## dx = dx*FCHANGE/dxnorm; ## end ##else ## Gauss-Newton step; ##---------- Start of 7/19/93 mod --------------- ##[v d] = eig(H0); ##toc ##d=max(1e-10,abs(diag(d))); ##d=abs(diag(d)); ##dx = -(v.*(ones(size(v,1),1)*d'))*(v'*g); dx <- -H0 %*% g dxnorm <- sqrt(sum(dx^2)) if (dxnorm > 1e12){ cat("Near-singular H problem.\n") dx <- dx*FCHANGE/dxnorm } dfhat <- crossprod(dx,g0) if(!badg){ ## test for alignment of dx with gradient and fix if necessary a <- -dfhat/(gnorm*dxnorm) if(a 0) && (f0-f > -(1-THETA)*dfhat*lambda) )) if( shrinkSignal && ( (lambda>lambdaPeak) || (lambda<0) )){ if ((lambda>0) && ((!shrink || (lambda/factor <= lambdaPeak)))){ shrink <- 1 factor <- factor^.6 while(lambda/factor <= lambdaPeak){ factor <- factor^.6 } if( abs(factor-1)lambdaPeak) ){ lambdaMax <- lambda } lambda <- lambda/factor if( abs(lambda) < MINLAMB ){ if( (lambda > 0) & (f0 <= fhat) ){ ## try going against gradient, which may be inaccurate lambda <- -lambda*factor^6 }else{ if( lambda < 0 ){ retcode <- 6 }else{ retcode <- 3 } done <- 1 } } }else{ if( (growSignal && lambda>0) || (shrinkSignal && ((lambda <= lambdaPeak) && (lambda>0))) ) { if( shrink ){ shrink <- 0 factor <- factor^.6 if( abs(factor-1)0) ) { fPeak <- f lambdaPeak <- lambda if( lambdaMax<=lambdaPeak ) { lambdaMax <- lambdaPeak*factor*factor } } lambda <- lambda*factor if( abs(lambda) > 1e20 ) { retcode <- 5 done <-1 } } else { done <- 1 if( factor < 1.2 ){ retcode <- 7 } else { retcode <- 0 } } } } } cat(sprintf("Norm of dx %10.5g\n", dxnorm)) return(list(fhat=fhat,xhat=xhat,fcount=fcount,retcode=retcode)) }