Re: [R] sampling from the unoform distrubuton over a convex hull

2007-03-25 Thread Ted Harding
On 24-Mar-07 19:26:21, Ted Harding wrote:
> On 24-Mar-07 14:00:44, Ted Harding wrote:
>> [...]
> [...]
> Well, I've written some rather crude code to implement the
> above. Even allowing for possible "editorial" improvements,
> the more I look at it the more I think there may be a better
> way! (Of doing it directly, I mean, raher than a rejection
> method).
> 
> Still, it seems to work (and quite slickly) ...
> 
> 
And now I've done what I should have donein the first place:
the code for rdiric() in VGAM is "stand-alone" and can simply
be copied, so:

## library(VGAM) gives the following code for function rdiric()
rdiric<-function(n, shape, dimension = NULL) 
{
dimension = if (!is.numeric(dimension)) length(shape)
shape = rep(shape, len = dimension)
ans = if (is.R()) 
rgamma(n * dimension, rep(shape, rep(n, dimension)))
else rgamma(n * dimension, rep(shape, each = n))
dim(ans) = c(n, dimension)
ans = ans/apply(ans, 1, sum)
ans
}

## Make some random points, get their CH and centroid, and draw them
X<-cbind(rnorm(10),rnorm(10))
plot(X[,1],X[,2],pch="+",col="green")
H<-chull(X)
C<-colMeans(X[H,])
points(C[1],C[2],pch="+",col="red")
## Draw the CH and the triangulation
H<-c(H,H[1])   ## To close the contour
K<-length(H)-1 ## No of triangles
lines(X[H,1],X[H,2],col="blue")
for(i in (1:K)){lines(c(X[H[i],1],C[1]),c(X[H[i],2],C[2]),col="red")}
  
## Set up the sampling by triangles
As<-numeric(K)
Ns<-numeric(K)
 
## Get the areas of the triangles
for(i in (1:(K))){
  V1<-X[H[i],]
  V2<-X[H[i+1],]
  V3<-C
  As[i]<-abs(det(rbind(V1-V3,V2-V3)))
}
 
## As illustration, 1000 points over the CH
N<-1000
 
## How many points to go in eavh triangle
Cuts<-cumsum(As)/sum(As)
R<-runif(N)
Ns[1]<-sum(R<=Cuts[1])
for(i in (2:K)){Ns[i]<-sum(R<=Cuts[i])-sum(R<=Cuts[i-1])}
## Uniform distribution over each triangle
for(i in (1:(K))){
  V1<-X[H[i],]
  V2<-X[H[i+1],]
  V3<-C
  ## The Dirichlet sample:
  T<-rbind(X[H[i],],X[H[i+1],],C)
  D<-rdiric(Ns[i],c(1,1,1))
  Z<-D%*%T
  points(Z[,1],Z[,2],pch="+",col="blue")
}

Ted. 


E-Mail: (Ted Harding) <[EMAIL PROTECTED]>
Fax-to-email: +44 (0)870 094 0861
Date: 25-Mar-07   Time: 11:26:58
-- XFMail --

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.


Re: [R] sampling from the unoform distrubuton over a convex hull

2007-03-24 Thread Ted Harding
On 24-Mar-07 14:00:44, Ted Harding wrote:
> [...]
> Another possible approach (again in two dimensions) could be based
> on the following.
> 
> First, if A, B, C are the vertices of a triangle, let (w1,w2,w3)
> be sampled from the 3-variate Dirichlet distribution with index
> ("shape") parameters (1,1,1). Then the weighted sum
> 
>w1*A + w2*B + w3*C
> 
> is uniformly distributed over the triangle.[1] (This does not
> generalise to planar convex hulls with more than three vertices).
> 
> Next, triangulate the convex hull (e.g. joining each vertex to the
> centroid of the convex hull, getting K triangles, say), and calculate
> the area of each triangle. Then, to sample N points, partition N at
> random into K parts with probabilities proportional to the areas.
> For instance, by cutting
> 
> sort(runif(N))
> 
> at the breakpoints given by
> 
> cumsum(A)/sum(A)
> 
> where A is a vector of areas
> 
> Then, for each component Nj of Ns, sample Nj points uniformly
> over triangle j using the Dirichlet method above.

Well, I've written some rather crude code to implement the
above. Even allowing for possible "editorial" improvements,
the more I look at it the more I think there may be a better
way! (Of doing it directly, I mean, raher than a rejection
method).

Still, it seems to work (and quite slickly) ...


## Needed for rdiric() to sample from Dirichlet
## Better to write one's own rdiric() for this application!
library(VGAM)

## Make some random points, get their CH and centroid, and draw them
X<-cbind(rnorm(10),rnorm(10))
plot(X[,1],X[,2],pch="+",col="green")
H<-chull(X)
C<-colMeans(X[H,])
points(C[1],C[2],pch="+",col="red")
## Draw the CH and the triangulation
H<-c(H,H[1])   ## To close the contour
K<-length(H)-1 ## No of triangles
lines(X[H,1],X[H,2],col="blue")
for(i in (1:K)){lines(c(X[H[i],1],C[1]),c(X[H[i],2],C[2]),col="red")}

 
## Set up the sampling by triangles
As<-numeric(K)
Ns<-numeric(K)

## Get the areas of the triangles
for(i in (1:(K))){
  V1<-X[H[i],]
  V2<-X[H[i+1],]
  V3<-C
  As[i]<-abs(det(rbind(V1-V3,V2-V3)))
}

## As illustration, 1000 points over the CH
N<-2000

## How many points to go in eavh triangle
Cuts<-cumsum(As)/sum(As)
R<-runif(N)
Ns[1]<-sum(R<=Cuts[1])
for(i in (2:K)){Ns[i]<-sum(R<=Cuts[i])-sum(R<=Cuts[i-1])}

## Uniform distribution over each triangle
for(i in (1:(K))){
  V1<-X[H[i],]
  V2<-X[H[i+1],]
  V3<-C
  ## The Dirichlet sample:
  T<-rbind(X[H[i],],X[H[i+1],],C)
  D<-rdiric(Ns[i],c(1,1,1))
  Z<-D%*%T
  points(Z[,1],Z[,2],pch="+",col="blue")
}


Any advance on the above??

Best wishes,
Ted.



E-Mail: (Ted Harding) <[EMAIL PROTECTED]>
Fax-to-email: +44 (0)870 094 0861
Date: 24-Mar-07   Time: 19:26:18
-- XFMail --

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.


Re: [R] sampling from the unoform distrubuton over a convex hull

2007-03-24 Thread Alberto Vieira Ferreira Monteiro
Duncan Murdoch wrote:
>
> Suggestion:  Find a rectangular region containing the hull, and sample
> uniformly there.  Accept points that don't expand the hull of the
> original points.
>
This is a feasible solution only in lower dimensions; the area of the
convex hull can become exponentially small relative to its external
rectangle. For example, if the convex hull is approximately spherical,
the relation of the (hyper)volumes are (time to summon Wikipedia)...
http://en.wikipedia.org/wiki/Hypersphere#Hyperspherical_volume
...

Volume.ratio <- pi^(n/2) * 2^(-n) / gamma(n/2 + 1)

Even for n = 5 this would be 0.16

The hypervolume of a _hyperpyramidal_ convex hull would be even
worse, as it would be 1/n! (= 1/gamma(n+1)) of the hypervolume of the
hypercube.

Alberto Monteiro

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.


Re: [R] sampling from the unoform distrubuton over a convex hull

2007-03-24 Thread Ted Harding
On 24-Mar-07 05:43:06, Ranjan Maitra wrote:
> Dear list,
> 
> Does anyone have a suggestion (or better still) code for sampling from
> the uniform distribution over the convex hull of a set of points?
> 
> Many thanks and best wishes,
> Ranjan

I was curious if anyone would come up with some ready-made efficient
code for this problem -- it cannot be the first time it has been
addressed! But if Duncan Murdoch doesn't, that reduces the probability
that such code is already available in R!

Duncan's suggestion of a rejection method for uniform points in an
enclosing rectangle will probably be efficient, provided the convex
hull occupies a good proportion of the rectangle. So I would suggest
for this method that a preliminary transformation be made, rotating
onto principal axes of the convex hull. This would avoid the situation
where the convex hull is a narrow cigar-shape at 45 degrees. At the
end, transform back to the original coordinates.

Another possible approach (again in two dimensions) could be based
on the following.

First, if A, B, C are the vertices of a triangle, let (w1,w2,w3)
be sampled from the 3-variate Dirichlet distribution with index
("shape") parameters (1,1,1). Then the weighted sum

   w1*A + w2*B + w3*C

is uniformly distributed over the triangle.[1] (This does not
generalise to planar convex hulls with more than three vertices).

Next, triangulate the convex hull (e.g. joining each vertex to the
centroid of the convex hull, getting K triangles, say), and calculate
the area of each triangle. Then, to sample N points, partition N at
random into K parts with probabilities proportional to the areas.
For instance, by cutting

sort(runif(N))

at the breakpoints given by

cumsum(A)/sum(A)

where A is a vector of areas

Then, for each component Nj of Ns, sample Nj points uniformly
over triangle j using the Dirichlet method above.

[1] This can be seen geometrically: (w1,w2,w3) is uniformly
distributed over the triangle T1 with vertices (1,0,0), (0,1,0)
and (0,0,1). Given any other triangle T2, by rotating T1 in
space and projecting orthogonally onto the plane containing T2,
you can match 2 (and therefore all 3) of the angles of T1 with
the angles of T2. Then dilate the projection of T1 until it
is congruent with T2. Since equal areas project orthogonally
onto equal areas, a uniform distribution on T1 projects into
a uniform on the projection of T1, therefore on T2.


PS I could envisage the above approach being generalised
to more than 2 dimensions. In 3 dimensions, for instance,
since the Dirchlet(1,1,1,1) is uniform on the simplex with
vertices (1,0,0,0), (0,1,0,0), (0,0,1,0), (0,0,0,1) we
similarly have that for a general simplex with vertices
A,B,C,D the point w1*A + w2*B + w3*C + w4*D is uniformly
distributed in the simplex.

But this requires "simplectification" of the convex hull,
(e.g. joining the vertices of its outer faces to its centroid)
so it gets more complicated, so no doubt Duncan's proposal
wins on simplicity, if not on efficiency (since the more
dimensions, the greater the proportion of points rejected).

Ted.


E-Mail: (Ted Harding) <[EMAIL PROTECTED]>
Fax-to-email: +44 (0)870 094 0861
Date: 24-Mar-07   Time: 14:00:40
-- XFMail --

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.


Re: [R] sampling from the unoform distrubuton over a convex hull

2007-03-24 Thread Liaw, Andy
The convhulln() function in the "geometry" package provides an R interface to 
qhull for computing n-dimensional convex hull.
 
Andy



From: [EMAIL PROTECTED] on behalf of Duncan Murdoch
Sent: Sat 3/24/2007 7:52 AM
To: Ranjan Maitra
Cc: r-help@stat.math.ethz.ch
Subject: Re: [R] sampling from the unoform distrubuton over a convex hull 
[Broadcast]



On 3/24/2007 1:43 AM, Ranjan Maitra wrote:
> Dear list,
>
> Does anyone have a suggestion (or better still) code for sampling from the 
> uniform distribution over the convex hull of a set of points?

Are you talking about two dimensional points, or higher dimensions?  The
suggestion below works for any dimension, but the actual code is
2-dimensional. I don't know if there's an equivalent of chull available
for higher dimensions.

Suggestion:  Find a rectangular region containing the hull, and sample
uniformly there.  Accept points that don't expand the hull of the
original points.

For example:

rhull <- function(n,x) {
   boundary <- x[chull(x),]

   xlim <- range(boundary[,1])
   ylim <- range(boundary[,2])

   boundary <- rbind(c(NA,NA), boundary)  # add space for new test point

   result <- matrix(NA, n, 2)

   for (i in 1:n) {
 repeat {
   boundary[1,1] <- runif(1, xlim[1], xlim[2])
   boundary[1,2] <- runif(1, ylim[1], ylim[2])
   if ( !(1 %in% chull(boundary)) ) {
  result[i,] <- boundary[1,]
 break
   }
 }
   }

   result
}

x <- matrix(rnorm(20), ncol=2)
plot(x, cex=2, col="red")
sample <- rhull(1000, x)
points(sample)

Duncan Murdoch

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.





--
Notice:  This e-mail message, together with any attachments,...{{dropped}}

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.


Re: [R] sampling from the unoform distrubuton over a convex hull

2007-03-24 Thread Duncan Murdoch
On 3/24/2007 1:43 AM, Ranjan Maitra wrote:
> Dear list,
> 
> Does anyone have a suggestion (or better still) code for sampling from the 
> uniform distribution over the convex hull of a set of points?

Are you talking about two dimensional points, or higher dimensions?  The 
suggestion below works for any dimension, but the actual code is 
2-dimensional. I don't know if there's an equivalent of chull available 
for higher dimensions.

Suggestion:  Find a rectangular region containing the hull, and sample 
uniformly there.  Accept points that don't expand the hull of the 
original points.

For example:

rhull <- function(n,x) {
   boundary <- x[chull(x),]

   xlim <- range(boundary[,1])
   ylim <- range(boundary[,2])

   boundary <- rbind(c(NA,NA), boundary)  # add space for new test point

   result <- matrix(NA, n, 2)

   for (i in 1:n) {
 repeat {
   boundary[1,1] <- runif(1, xlim[1], xlim[2])
   boundary[1,2] <- runif(1, ylim[1], ylim[2])
   if ( !(1 %in% chull(boundary)) ) {
  result[i,] <- boundary[1,]
 break
   }
 }
   }

   result
}

x <- matrix(rnorm(20), ncol=2)
plot(x, cex=2, col="red")
sample <- rhull(1000, x)
points(sample)

Duncan Murdoch

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.


[R] sampling from the unoform distrubuton over a convex hull

2007-03-23 Thread Ranjan Maitra
Dear list,

Does anyone have a suggestion (or better still) code for sampling from the 
uniform distribution over the convex hull of a set of points?

Many thanks and best wishes,
Ranjan

__
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.