[Pomp-commits] r421 - pkg/R
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Tue Nov 23 21:33:48 CET 2010
Author: kingaa
Date: 2010-11-23 21:33:44 +0100 (Tue, 23 Nov 2010)
New Revision: 421
Added:
pkg/R/sannbox.R
Log:
- add a simulated annealing algorithm with box constraints
Added: pkg/R/sannbox.R
===================================================================
--- pkg/R/sannbox.R (rev 0)
+++ pkg/R/sannbox.R 2010-11-23 20:33:44 UTC (rev 421)
@@ -0,0 +1,108 @@
+######################
+## Simulated annealing minimizer with box constraints
+##
+## By default, the annealing schedule is
+## temp / log(((k-1) %/% tmax)*tmax + exp(1)), where
+## the parameters of this schedule can be changed via
+## the 'control' argument, and k ranges from 0 to 'maxit'
+##
+## modified from code originally written by
+## Daniel Reuman, Imperial College London
+
+sannbox <- function (par, fn, control = list(), ...) {
+
+ npar <- length(par)
+ neval <- 0
+
+ control.default <- list(
+ maxit=10000,
+ temp=1,
+ tmax=10,
+ sched=NULL,
+ candidate.dist=NULL,
+ parscale=1,
+ lower=-Inf,
+ upper=Inf,
+ trace=0
+ )
+ control.default[names(control)] <- control
+ control <- control.default
+
+ if (is.null(control$sched)) # default cooling schedule
+ control$sched <- function (k) control$temp/log(((k-1)%/%control$tmax)*control$tmax+exp(1))
+
+ if (is.function(control$sched))
+ temps <- sapply(seq.int(from=1,to=control$maxit,by=1),control$sched)
+ else if (is.numeric(control$sched))
+ temps <- control$sched
+
+ if (is.null(control$candidate.dist))
+ candidate.dist <- function (temp) rnorm(n=npar,mean=0,sd=control$parscale*temp)
+
+ if (length(control$lower)<npar)
+ control$lower <- rep(control$lower,npar)
+ if (length(control$upper)<npar)
+ control$upper <- rep(control$upper,npar)
+
+ ## initialization for the algorithm
+ laststep <- 0
+ thetabest <- thetacurrent <- par
+ ybest <- ycurrent <- fn(thetacurrent,...)
+ neval <- 1
+
+ if (control$trace>0)
+ cat("initial evaluation: ",ycurrent,"\n")
+ if (control$trace>2)
+ cat("initial parameters: ",thetacurrent,"\n")
+
+ ## main loop
+ for (k in seq_len(control$maxit)) {
+ ## get a candidate thetacand
+ thetacand <- thetacurrent+candidate.dist(temps[k])
+ ## enforce box constraints
+ thetacand <- ifelse(
+ thetacand<control$lower,
+ control$lower,
+ thetacand
+ )
+ thetacand <- ifelse(
+ thetacand>control$upper,
+ control$upper,
+ thetacand
+ )
+ ycand <- fn(thetacand,...)
+ neval <- neval+1
+
+ ## see if you have a new best.params
+ if (ycand<ybest) {
+ ybest <- ycand
+ thetabest <- thetacand
+ }
+
+ accept <- runif(1)<exp((ycurrent-ycand)/temps[k])
+ if (accept) { # simulated annealing step
+ thetacurrent <- thetacand
+ ycurrent <- ycand
+ }
+
+ if (control$trace>1)
+ cat("iter ",k," val=",ycurrent,", accept=",accept,"\n")
+ if (control$trace>3)
+ cat("proposed params: ",thetacand,"\n")
+ if (control$trace>2)
+ cat("current params: ",thetacurrent,"\n")
+
+ }
+
+ if (control$trace>0)
+ cat("best val=",ybest,"\n")
+
+ list(
+ counts=c(neval,NA),
+ convergence=0,
+ final.params=thetacurrent,
+ final.value=ycurrent,
+ par=thetabest,
+ value=ybest
+ )
+}
More information about the pomp-commits
mailing list