[R] quasi-random sequences
baptiste Auguié
ba208 at exeter.ac.uk
Sun Apr 27 13:46:16 CEST 2008
Hi again,
I've had a go at Prof Ripley's suggestion (Strauss process, code
below). It works great for my limited purpose (qualitative drawing,
really), I can just add a few mild concerns,
- ideally the hard core would not be a fixed number, but a
distribution of sizes (ellipses).
- I could not quite understand the link between the window size,
intensity, and number of elements returned. Is there a simple
relation I've missed?
- in general, I just have no clue how rStrauss works, I guess Prof
Ripley's first reference cited in ?Strauss would be useful for that
matter as I could not find anything with google but a C code looking
a bit alike some genetic algorithm (death and birth of objects).
Am I on the right track in thinking that the idea is not so
dissimilar with the following approach:
1) create a first random distribution (Poisson, apparently)
2) give birth and death to new objects
3) carry on with this evolution until the sample distribution
respects the given intensity and interaction parameters (e.g, for
hard core, no overlap is permitted within the radius)
This looks a bit like the idea of an "electrostatic problem",
1) start with an initial configuration
2) define the total potential energy as a cost function to be
minimized, sum of a boundary (repulsive term), and short distance
repulsion
3) optimize the positions with respect to this objective function
I tried unsuccessfully this second approach (see below), but I'm sort
of concerned about the handling of all these parameters by optim().
rStrauss works beautifully anyway !
Thanks again,
baptiste
##############
# Code
##############
library(spatstat) # Strauss process
## ellipse function obtained from R mailing list ##
## could use library(car) as an alternative
ellipse <- function(x,y,width,height,theta, npoints=100,plot=F)
{
# x = x coordinate of center
# y = y coordinate of center
# width = length of major axis
# height = length of minor axis
# theta = rotation
# npoints = number of points to send to polygon
# plot = if TRUE, add to current device
# = if FALSE, return list of components
a <- width/2
b <- height/2
theta<-theta*pi/180
xcoord <- seq(-a,a,length=npoints)
ycoord.neg <- sqrt(b^2*(1-(xcoord)^2/a^2))
ycoord.pos <- -sqrt(b^2*(1-(xcoord)^2/a^2))
xx <- c(xcoord,xcoord[npoints:1])
yy <- c(ycoord.neg,ycoord.pos)
x.theta <- xx*cos(2*pi-theta)+yy*sin(2*pi-theta)+x
y.theta <- yy*cos(2*pi-theta)-xx*sin(2*pi-theta)+y
if(plot)
invisible(polygon(x.theta,y.theta,col="black"))
else
invisible(list(coords=data.frame(x=x.theta,y=y.theta),
center=c(x,y),
theta=theta))
}
getEllipse<-function(dataf,plot=TRUE){
ellipse(dataf[1],dataf[2],dataf[3],dataf[4],dataf[5],plot=plot)
}
N <- 200 # initial number (loosely related to the actual number of
elements)
##############################################
## positions from Strauss hard core process ##
##############################################
positions <- rStrauss(beta = 0.1, gamma = 0, R = 2, W= square(N/2))
# beta: intensity
# gamma: interaction. 0 : hard core (no overlap), 1: complete
randomness
# R: radius of interaction (size of the core)
# W: window
N2<-length(positions$x)# number of elements
rand.angles <- rnorm(N2,sd=45,mean=45) # ellipse angles
rand.a <- rnorm(N2,sd=0.4,mean=1) # ellipse semi-axes
rand.b <- rnorm(N2,sd=0.4,mean=1) #
par(bty="n")
plot(cbind(positions$x,positions$y) ,cex = rand.a,axes=F,
xlab="",ylab="",t="n") # just circles: type="p"
ell.pos<-cbind(positions$x,positions$y,rand.a,rand.b,rand.angles)
apply(ell.pos,1,getEllipse) -> b.quiet # draw ellipses
##############################################
##############################################
##############################################
## optimizing an "electrostatic potential" problem (not working)
##############################################
N <-200
p0 <- matrix(rnorm(2*N),ncol=2) # random starting point
# boundary repulsion potential #
x <- seq(-1.2,1.2,l=N)
delta <- 0.1
# 1D example #
y <- -1*( 1 - exp(-abs(x)/delta) - exp(abs(x)/delta))
#plot(x,y,t="l")
# 2D example
xy <- expand.grid(x = x, y=x)
z.x <- -1*( 1 - exp(-abs(xy[,1])/delta) - exp(abs(xy[,1])/delta))
z.y <- -1*( 1 - exp(-abs(xy[,2])/delta) - exp(abs(xy[,2])/delta))
z <- matrix(z.x+z.y, ncol=length(x))
#image(x=x,y=x,z=z)
boundary <- function(xy = p0[1,]){
z.x <- -1*( 1 - exp(-abs(xy[1])/delta) - exp(abs(xy[1])/delta))
z.y <- -1*( 1 - exp(-abs(xy[2])/delta) - exp(abs(xy[2])/delta))
z.x + z.y
}
dist.2d <- function(x = c(1, 0 ),y = c(0,1) , w = 0.1){
(drop((x - y) %*% (x - y)) + w^2 )^(-3/2)
}
obj <- function(p = p0){
bound <- sum(apply(p,1,boundary)) # boundary term
rel.positions <- expand.grid(x=p,y=p) # all relative positions
bound + sum(apply(rel.positions,1,dist.2d)) # cost
}
optim(p0,obj) # fails miserably, but this does not sound right anyway
_____________________________
Baptiste Auguié
Physics Department
University of Exeter
Stocker Road,
Exeter, Devon,
EX4 4QL, UK
Phone: +44 1392 264187
http://newton.ex.ac.uk/research/emag
http://projects.ex.ac.uk/atto
More information about the R-help
mailing list