#daarem codes from daarem package version 0.4.1
#modified to show some information at each iteration
daarem <- function(par, fixptfn, objfn, ..., control=list(),showiter,showerroriter) {
control.default <- list(maxiter=2000, order=5, tol=1.e-08, mon.tol=0.01,
cycl.mon.tol=0.0, kappa=40, alpha=1.3)
# control.default <- list(maxiter=2000, order=5, tol=1.e-08, mon.tol=0.01,
# cycl.mon.tol=0.0, kappa=25, alpha=1.2)
namc <- names(control)
if (!all(namc %in% names(control.default))) {
stop("unknown names in control: ", namc[!(namc %in% names(control.default))])
}
control <- modifyList(control.default, control)
maxiter <- control$maxiter
tol <- control$tol
mon.tol <- control$mon.tol ## monotonicity tolerance
cycl.mon.tol <- control$cycl.mon.tol
a1 <- control$alpha
kappa <- control$kappa
num.params <- length(par)
order.default <- ifelse(num.params>20,10,floor(num.params/2))
nlag <- min(control$order, order.default)
#nlag <- min(control$order, ceiling(num.params/2))
#if(!missing(objfn)) {
ans <- daarem_base_objfn(par, fixptfn, objfn, maxiter, tol, mon.tol,
cycl.mon.tol, a1, kappa, num.params, nlag,
showiter, showerroriter, ...)
return(ans)
}
#
daarem_base_objfn <- function(par, fixptfn, objfn, maxiter, tol, mon.tol,
cycl.mon.tol, a1, kappa, num.params, nlag,
showiter, showerroriter, ...) {
#num.params <- length(par)
#nlag <- min(control$order, ceiling(num.params/2))
Fdiff <- Xdiff <- matrix(0.0, nrow=num.params, ncol=nlag)
obj_funvals <- rep(NA, maxiter + 2)
xold <- par
xnew <- fixptfn(xold, ...)
obj_funvals[1] <- objfn(xold, ...)
obj_funvals[2] <- objfn(xnew, ...)
likchg <- obj_funvals[2] - obj_funvals[1]
obj.evals <- 2
fold <- xnew - xold
k <- 0
count <- 0
shrink.count <- 0
shrink.target <- 1/(1 + a1^kappa)
lambda.ridge <- 100000
r.penalty <- 0
conv <- FALSE
ss.resids <- 10
ell.star <- obj_funvals[2]
while(k < maxiter) {
k <- k+1
count <- count + 1
fnew <- fixptfn(xnew, ...) - xnew
#ss.resids <- sqrt(crossprod(fnew))
# if (k > 2){
# at<- (obj_funvals[k+1]-obj_funvals[k])/(obj_funvals[k]-obj_funvals[k-1])
# ss.resids <- abs((obj_funvals[k+1]-obj_funvals[k])/(1-at))
# } #mudando para outro criterio
if (k>1) ss.resids <- abs((obj_funvals[k+1]-obj_funvals[k])/obj_funvals[k])
if (is.nan(ss.resids)) ss.resids=10
#
if (showiter&&!showerroriter) cat("Iteration ",k,"\r")#," of ",maxiter,"\r")
if (showerroriter) cat("Iteration ",k," of ",maxiter," - criterium =",ss.resids,
" - loglik =",obj_funvals[k+1],"\r")
#
if(ss.resids < tol) { #& count==nlag
conv <- TRUE
break
}
Fdiff[,count] <- fnew - fold
Xdiff[,count] <- xnew - xold
np <- count
if(np==1) {
Ftmp <- matrix(Fdiff[,1], nrow=num.params, ncol=np)
Xtmp <- matrix(Xdiff[,1], nrow=num.params, ncol=np) ## is this matrix function needed?
} else {
Ftmp <- Fdiff[,1:np]
Xtmp <- Xdiff[,1:np]
}
tmp <- La.svd(Ftmp)
dvec <- tmp$d
dvec.sq <- dvec*dvec
uy <- crossprod(tmp$u, fnew)
uy.sq <- uy*uy
### Still need to compute Ftf
Ftf <- sqrt(sum(uy.sq*dvec.sq))
tmp_lam <- DampingFind(uy.sq, dvec, a1, kappa, shrink.count, Ftf, lambda.start=lambda.ridge, r.start=r.penalty)
lambda.ridge <- tmp_lam$lambda
r.penalty <- tmp_lam$rr
dd <- (dvec*uy)/(dvec.sq + lambda.ridge)
gamma_vec <- crossprod(tmp$vt, dd)
xbar <- xnew - drop(Xtmp%*%gamma_vec)
fbar <- fnew - drop(Ftmp%*%gamma_vec)
x.propose <- xbar + fbar
new.objective.val <- try(objfn(x.propose, ...), silent=TRUE)
obj.evals <- obj.evals + 1
if(class(new.objective.val)[1] != "try-error" && !is.na(obj_funvals[k+1]) &&
!is.nan(new.objective.val)) {
if(new.objective.val >= obj_funvals[k+1] - mon.tol) { ## just change this line in daarem_base_noobjfn
## Increase delta
obj_funvals[k+2] <- new.objective.val
fold <- fnew
xold <- xnew
xnew <- x.propose
shrink.count <- shrink.count + 1
} else {
## Keep delta the same
fold <- fnew
xold <- xnew
xnew <- fold + xold
obj_funvals[k+2] <- objfn(xnew, ...)
obj.evals <- obj.evals + 1
}
} else {
## Keep delta the same
fold <- fnew
xold <- xnew
xnew <- fold + xold
obj_funvals[k+2] <- objfn(xnew, ...)
obj.evals <- obj.evals + 1
count <- 0
}
if(count==nlag) {
count <- 0
## restart count
## make comparison here l.star vs. obj_funvals[k+2]
if(obj_funvals[k+2] < ell.star - cycl.mon.tol) {
## Decrease delta
shrink.count <- max(shrink.count - nlag, -2*kappa)
}
ell.star <- obj_funvals[k+2]
}
shrink.target <- 1/(1 + a1^(kappa - shrink.count))
}
if (showiter||showerroriter) cat("\n")
obj_funvals <- obj_funvals[!is.na(obj_funvals)]
value.obj <- objfn(xnew, ...)
# if(k >= maxiter) {
# conv <- FALSE
# }
return(list(par=c(xnew), fpevals = k, value.objfn=value.obj, objfevals=obj.evals,
criterio=as.numeric(ss.resids), convergence=conv, objfn.track=obj_funvals[-1]))
}
#
fpiter <- function(par, fixptfn, objfn=NULL, control=list( ), showiter, showerroriter, ...){
control.default <- list(tol=1.e-07, maxiter=5000)
namc <- names(control)
if (!all(namc %in% names(control.default))){
stop("unknown names in control: ", namc[!(namc %in% names(control.default))])
}
ctrl <- modifyList(control.default, control)
tol <- ctrl$tol
maxiter <- ctrl$maxiter
iter <- 1
#resid <- rep(NA,1)
objeval <- 0
conv <- FALSE
obj_funvals <- rep(NA, maxiter)
res <- 10
while (iter <= maxiter) {
#print(par)
p.new <- fixptfn(par, ...)
#p.new <- fixptfn(par, y=y,x=x,z=z,time=time,ind=ind,distr=distr,pAR=pAR,lb=lb,lu=lu)
par <- p.new
obj_funvals[iter] <- objfn(par, ...)
#obj_funvals[iter] <- objfn(par, y=y,x=x,z=z,time=time,ind=ind,distr=distr,pAR=pAR,lb=lb,lu=lu)
# if (iter > 3){
# at<- (obj_funvals[iter]-obj_funvals[iter-1])/(obj_funvals[iter]-obj_funvals[iter-2])
# res <- abs((obj_funvals[iter]-obj_funvals[iter-1])/(1-at))
# } #mudar para abs((llji-llj1)/llj1) ?
if (iter>2) res <- abs((obj_funvals[iter]-obj_funvals[iter-1])/obj_funvals[iter-1])
if (is.nan(res)) res=10
#res <- sqrt(crossprod(p.new - par))
if (showiter&&!showerroriter) cat("Iteration ",iter,"\r")#," of ",maxiter,"\r")
#if (showerroriter) cat("Iteration ",iter," of ",maxiter," - criterium =",res,"\r")
if (showerroriter) cat("Iteration ",iter," of ",maxiter," - criterium =",res,
" - loglik =",obj_funvals[iter],"\r")
if ( res < tol) {conv <- TRUE; break}
iter <- iter+1
}
if (showiter||showerroriter) cat("\n")
loglik.best <- obj_funvals[iter-1]#objfn(par, ...)
obj_funvals <- obj_funvals[!is.na(obj_funvals)]
return(list(par=par, value.objfn=loglik.best, fpevals=iter-1, criterio=as.numeric(res),
convergence=conv,objfn.track=obj_funvals))
}
#
DampingFind <- function(uy.sq, dvec, aa, kappa, sk, Ftf, lambda.start=NULL,
r.start=NULL, maxit=10) {
## uy.sq is a vector whose jth component (U^t*y)^2
## d.sq is a vector whose jth component is d_j^2.
## (aa, kappa, sk) - parameters in determining delta_k
## Ftf <- F_{k}^T f_{k}
##
## Output: value of penalty term such that (approximately)
## . || beta.ridge ||^2/||beta.ols||^2 = delta_{k}^{2}, with 0 < target < 1.
if(is.null(lambda.start) | is.na(lambda.start)) {
lambda.start <- 100
}
if(is.null(r.start) | is.na(r.start)) {
r.start <- 0
}
if(sum(dvec==0.0) > 0) {
ind <- dvec > 0
dvec <- dvec[ind]
uy.sq <- uy.sq[ind]
## what about if dvec has length 1?
}
pow <- kappa - sk
target <- exp(-0.5*log1p(aa^pow)) ### This is sqrt(delta_k)
#d.sq <- pmax(dvec*dvec, 1e-7) ## in case the least-squares problem is very poorly conditioned
d.sq <- dvec*dvec
betahat.ls <- uy.sq/d.sq
betahat.ls.norm <- sqrt(sum(betahat.ls))
vk <- target*betahat.ls.norm
if(vk == 0) {
## the norm of the betas is zero, so the value of lambda shouldn't matter
return(list(lambda=lambda.start, rr=r.start))
}
### Initialize lambda and lower and upper bounds
lambda <- lambda.start - r.start/vk
LL <- (betahat.ls.norm*(betahat.ls.norm - vk))/sum(uy.sq/(d.sq*d.sq))
UU <- Ftf/vk
## Compute lstop and ustop
pow.low <- pow + 0.5
pow.up <- pow - 0.5
l.stop <- exp(-0.5*log1p(aa^pow.low))
u.stop <- exp(-0.5*log1p(aa^pow.up))
### Start iterations
for(k in 1:maxit) {
### Check if lambda is inside lower and upper bounds
if(lambda <= LL | lambda >= UU) {
lambda <- max(.0001*UU, sqrt(LL*UU))
}
### Evaluate ||s(lambda)|| and \phi(lambda)/phi'(lambda)
d.lambda <- (dvec/(d.sq + lambda))^2
d.prime <- d.lambda/(d.sq + lambda)
s.norm <- sqrt(sum(uy.sq*d.lambda))
phi.val <- s.norm - vk
phi.der <- (-1)*sum(uy.sq*d.prime)/s.norm
phi.ratio <- phi.val/phi.der
d.u <- (dvec/(d.sq + LL))^2
s.up <- sqrt(sum(uy.sq*d.u))
### Initial Lower bound is not correct
### Check convergence
if(s.norm <= u.stop*betahat.ls.norm & s.norm >= l.stop*betahat.ls.norm) {
break
}
### If not converged, update lower and upper bounds
UU <- ifelse(phi.val >= 0, UU, lambda)
LL <- max(LL, lambda - phi.ratio)
### Now update lambda
lambda <- lambda - (s.norm*phi.ratio)/vk
bb <- (s.norm*phi.ratio)/vk
}
ans <- list(lambda=lambda, rr=s.norm*phi.ratio)
return(ans)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.