#######################################################################
# #
# Mode Forest S-plus Functions #
# #
# Save as text, then source into S-plus #
# #
# Copyright 1996, Michael C. Minnotte #
# #
# For assistance, or to report bugs, please contact: #
# #
# minnotte@math.usu.edu #
# #
# Last updated, September 17, 1998 #
# #
# For more information about mode forests, see: #
# #
# Minnotte, M.C., Marchette, D.J., and Wegman, E.J., (1998), "The #
# bumpy road to the mode forest," Journal of Computational and #
# Graphical Statistics, 7, 239-251. #
# #
# Functions include: #
# #
# forest - main mode forest routine. Handles all versions with #
# appropriate options set #
# onetree - shortcut to crude single mode tree #
# resamp.forest - shortcut to resampled mode forest #
# subsamp.forest - shortcut to random subset mode forest #
# nnjit.forest - shorcut to nearest neighbor mode forest #
# ransamp.forest - shortcut to random subset mode forest (random size)#
# forestplot - mode forest plotting function using image, called #
# from forest if doplot = T #
# forestplot.poly - mode forest plotting function using polygons; not #
# recommended if forestplot works #
# forestps - postscript device with shading levels set #
# normkde - normal kernel density estimate #
# nicerange - range of data increased by pct (default 10%) each side #
# #
#######################################################################
normkde<-function(dat,xlist,h)
{# normal kernel density estimate
# dat - data
# xlist - points of evaluation
# h - bandwidth (smoothing parameter; standard deviation of normal kernel)
m<-length(xlist)
fhat<-rep(0,m)
n<-length(dat)
if(m fhat[1:(nx-2)] &
fhat[3:nx] < fhat[2:(nx-1)]]
count[i,modes]<-count[i,modes]+1
}
else if (nwhat==2) # count bumps
{bumps<-(2:(nx-1))[fhat[2:(nx-1)] - fhat[1:(nx-2)] >
fhat[3:nx] - fhat[2:(nx-1)]]
count[i,bumps]<-count[i,bumps]+1
}
else # density
{count[i,]<-count[i,]+fhat*hcent[i]
}
}
if (doplot & update) forestplot(list(count=count,x=xrange,h=hrange))
}
if (nsamp > 0)
{if (jit == "nn")
{jitlist<-c((3*dat[1]-dat[2])/2,(dat[-1]+dat[-n])/2,(3*dat[n]-dat[n-1])/2)
}
for (k in 1:nsamp)
{if (rsampsize) sampsize<-rbinom(1,n,1/2)
resamp<-sample(n,sampsize,replace=replace)
if (jit=="nn")
{smooth<-runif(sampsize,jitlist[resamp],jitlist[resamp+1])
}
else if (jit > 0)
{smooth<-runif(sampsize,dat[resamp]-jit,dat[resamp]+jit)
}
else
{smooth<-dat[resamp]
}
for (i in 1:nh)
{if (docat) cat("Sample ",k,"; h ",i,"\n")
fhat<-normkde(smooth, xcent, hcent[i])
if (nwhat==1) # count modes
{modes<-(2:(nx-1))[fhat[2:(nx-1)] > fhat[1:(nx-2)] &
fhat[3:nx] < fhat[2:(nx-1)]]
count[i,modes]<-count[i,modes]+1
}
else if (nwhat==2) # count bumps
{bumps<-(2:(nx-1))[fhat[2:(nx-1)] - fhat[1:(nx-2)] >
fhat[3:nx] - fhat[2:(nx-1)]]
count[i,bumps]<-count[i,bumps]+1
}
else # density
{count[i,]<-count[i,]+fhat*hcent[i]
}
}
if (doplot & update & orig == F & k==1)
{forestplot(list(count=count,x=xrange,h=hrange))
}
else if (doplot & update)
{forestplot(list(count=count,x=xrange,h=hrange),add=T)
}
}
}
if (doplot & !update) forestplot(list(count=count,x=xrange,h=hrange))
return(count=count,x=xrange,h=hrange,n=n,nsamp=nsamp,
sampsize=sampsize,replace=replace,what=what,orig=orig,jit=jit)
}
##########################################################################
onetree<-function(dat, xr=nicerange(dat), hr=c(diff(nicerange(dat))/4,
diff(nicerange(dat))/400), nx=200, nh=50, xlabel="x",docat=T,
doplot=T,what="mode")
{# shortcut to generate a single mode tree
# parameters are as in forest, with different defaults
forest(dat, xr=xr, hr=hr, nx=nx, nh=nh, nsamp=0, xlabel=xlabel,docat=docat,
doplot=doplot,what=what)}
################################################################################
resamp.forest<-function(dat, xr=nicerange(dat), hr=c(diff(nicerange(dat))/4,
diff(nicerange(dat))/400), nx=200, nh=50, nsamp=49, xlabel="x",docat=T,
doplot=T,update=F,orig=T,what="bump")
{# shortcut to generate a resampled mode forest
# parameters are as in forest, with different defaults
forest(dat, xr=xr, hr=hr, nx=nx, nh=nh, nsamp=nsamp, xlabel=xlabel,docat=docat,
doplot=doplot,update=update,orig=orig,what=what)}
################################################################################
subsamp.forest<-function(dat, xr=nicerange(dat), hr=c(diff(nicerange(dat))/4,
diff(nicerange(dat))/400), nx=200, nh=50, nsamp=49, xlabel="x",docat=T,
doplot=T,update=F,sampsize=round(sqrt(length(dat))),replace=F,orig=F,
what="bump")
{# shortcut to generate a random subset mode forest
# parameters are as in forest, with different defaults
forest(dat, xr=xr, hr=hr, nx=nx, nh=nh, nsamp=nsamp, xlabel=xlabel,docat=docat,
doplot=doplot,update=update,sampsize=sampsize,replace=replace,orig=orig,
what=what,jit=0)}
################################################################################
nnjit.forest<-function(dat, xr=nicerange(dat), hr=c(diff(nicerange(dat))/4,
diff(nicerange(dat))/400), nx=200, nh=50, nsamp=49, xlabel="x",docat=T,
doplot=T,update=F,sampsize=length(dat),replace=F,orig=T,what="bump",
jit="nn")
{# shortcut to generate a nearest-neighbor jittered mode forest
# parameters are as in forest, with different defaults
forest(dat, xr=xr, hr=hr, nx=nx, nh=nh, nsamp=nsamp, xlabel=xlabel,docat=docat,
doplot=doplot,update=update,sampsize=sampsize,replace=replace,orig=orig,
what=what,jit=jit)}
################################################################################
ransamp.forest<-function(dat, xr=nicerange(dat), hr=c(diff(nicerange(dat))/4,
diff(nicerange(dat))/400), nx=200, nh=50, nsamp=49, xlabel="x",docat=T,
doplot=T,update=F,sampsize=round(sqrt(length(dat))),replace=F,orig=F,
what="bump")
{# shortcut to generate a random sample size mode forest
# parameters are as in forest, with different defaults
forest(dat, xr=xr, hr=hr, nx=nx, nh=nh, nsamp=nsamp, xlabel=xlabel,docat=docat,
doplot=doplot,update=update,sampsize=sampsize,replace=replace,orig=orig,
what=what,jit=0,rsampsize=T)}
################################################################################