Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
In my previous post, I tried to answer the following question Consider
If I have been able to use Monte Carlo simulations in dimension 2 (on a circle, not on a sphere), I could not get it in dimension 3. Hopefully, my colleague Simon gave me a nice solution (much more efficient than my previous code). Unfortunately, it was in Maple,
clear all taillesim=5000; for N=3:10 nb=0; for k=1:taillesim X=randn(N,1); Y=randn(N,1); Z=randn(N,1); pts=[X Y Z]; for i=1:N pts(i,:)=pts(i,:)/norm(pts(i,:),2); end tol=1e-07; A=-pts; f=[0;0;0]; b=zeros(N,1)-tol; %options=optimset('Display','off'); [x,val,exitflag]=linprog(f,A,b); if(exitflag==1) nb=nb+1; end end probapprox(N-2)=nb/taillesim; end ns=[3:10]; for i=3:10 probhs(i-2)=probh(3,i); end scatter(ns,probhs) hold on plot(ns,probapprox);
The idea is very clever (I did not know how to code it, but as we will see, it is actually simple – or say not too difficult – to code actually). The idea is based on the idea that all the points lie on the same hemisphere if there is some
That is not a big improvement, compared with the previous post, because we have to find such a vector. The idea suggested by Simon is to use some constraint optimization algorithm. We can try to optimize (maximize, or minimize, actually, we do not care) something like
If the set of constraint is empty, then there is no solution, while we can find one (maybe more, but we do not care) if there is such a vector
library(lpSolve) A=rbind(pts,c(1,1,1)) C=c(1,2,3) B=c(rep(1e-10,N),1) slp=lp("min",C,A,c(rep(">=",N),"="),B)
So that I can solve here
and then, we simply have to check for the value of
slp$status
0 means that we found a vector
(yes, it is mentioned in the help of the optimization function that only positive values are considered). So, a simple strategy, since we focus on an orthant here, is to consider all possible orthants. For instance, using
test=FALSE x1=0:(2^3-1)%/%(2^(3-1)) x2=((0:(2^3-1))-(2^2)*x1)%/%(2^(3-2)) x3=((0:(2^3-1))-(2^2)*x1-2*x2) for(u in 1:(2^3)){ pts2=cbind(pts[,1]*(-1)^x1[u], pts[,2]*(-1)^x2[u], pts[,3]*(-1)^x3[u]) A=rbind(pts2,c(1,1,1)) C=c(1,2,3) B=c(rep(1e-10,N),1) slp=lp("min",C,A,c(rep(">=",N),"="),B) if(slp$status==0) test=TRUE} if(test==TRUE) nb0=nb0+1
So here, the code would be something like
taillesim=5000 probaap=rep(NA,10) probath=rep(NA,10) p=function(d,n) .5^(n-1) * sum(choose(n-1,0:(d-1))) for(N in 3:10){ nb0=0 for(k in 1:taillesim){ MZ=matrix(rnorm(n*3),n,3) d=apply(MZ,1,function(z) sqrt(sum(z^2))) X=MZ[,1]/d; Y=MZ[,2]/d; Z=MZ[,3]/d; pts=cbind(X,Y,Z) test=FALSE x1=0:(2^3-1)%/%(2^(3-1)) x2=((0:(2^3-1))-(2^2)*x1)%/%(2^(3-2)) x3=((0:(2^3-1))-(2^2)*x1-2*x2) for(u in 1:(2^3)){ pts2=cbind(pts[,1]*(-1)^x1[u], pts[,2]*(-1)^x2[u], pts[,3]*(-1)^x3[u]) A=rbind(pts2,c(1,1,1)) C=c(1,2,3) B=c(rep(1e-10,N),1) slp=lp("min",C,A,c(rep(">=",N),"="),B) if(slp$status==0) test=TRUE } if(test==TRUE) nb0=nb0+1 } probaap[N]=nb0/taillesim probath[N]=p(3,N) }
and this time, the probability obtained using Monte Carlo simulation is extremely close to the theoretical value.
And the algorithm is extremely fast! So using optimization routines to see if sets defined by linear constraints are empty – or not – is truly a great idea!
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.