Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I'd like to create a list of triplets $(x,y,z)$ which satisfy the following properties: $$0<x<1/2 \\ 0<y<1/2-x \\ -1<z<-2(x+y)$$ Basically I would like to uniformly generate random points inside a pyramid which is what these inequalities represent. I'm not sure how to place these restrictions on the RandomReal command or how to tell Mathematica to exclude points that do not satisfy these conditions. Any help?

Thank you.

share|improve this question
    
Related: (13038), (32501), (33652) –  Mr.Wizard Aug 15 at 1:23
    
@Mr.Wizard It seems pretty close to a duplicate of 33652 -- see my answer. –  Michael E2 Aug 15 at 3:12

3 Answers 3

up vote 5 down vote accepted

The following seems to work:

Cases[RandomReal[{-1, 1}, {1500000, 3}], {x_, y_, z_} /; 
  0 < x < 0.5 && 0 < y < 0.5 - x && -1 < z < -2 (x + y)]

OR

Select[RandomReal[{-1, 1}, {1500000, 3}], 
 0 < #[[1]] < 0.5 && 0 < #[[2]] < 0.5 - #[[1]] && -1 < #[[3]] < -2 (#[[1]] + #[[2]]) &]

Here is what it looks like:

Mathematica graphics

share|improve this answer
    
I believe that generation and filtering is a fine approach when the selection percentage is relatively high as is the case here. +1 –  Mr.Wizard Aug 15 at 1:13
    
@Mr.Wizard Thanks. I thought about a different approach but this seems to do the job in this case. –  RunnyKine Aug 15 at 1:16
    
See links above for advanced methods for this class of problem. –  Mr.Wizard Aug 15 at 1:26
    
@Mr.Wizard. Thanks, I actually voted in 2 out of the 3 links you provided. Just forgot about those. –  RunnyKine Aug 15 at 1:42
2  
@Mr.Wizard I think it should be pointed out that about 0.5% of the points will be selected. RunnyKine, it would more efficient to use separate RandomReal calls for each coordinate, transpose, and select. The expected yield would be 1/6 or about 17%. –  Michael E2 Aug 15 at 3:30

Ray Koopman's answer to Uniformly distributed n-dimensional probability vectors applied to a simplex with given vertices leads to the following way to get (exactly) n uniformly distributed random points in the simplex (and do it quickly):

pts = #.vertices/Total[#, {2}] &@ Log @ RandomReal[1, {n, 4}];

Here are 2000 points in the OP's simplex:

vertices = Append[
  {x, y, z} /. 
     Last@Maximize[{#, 
         0 < x < 1/2 && 0 < y < 1/2 (1 - 2 x) && -1 < z < -2 x - 2 y} /. 
        Less -> LessEqual, {x, y, z}] & /@ {x, y, -z},
  {0, 0, 0}
  ]
(* {{1/2, 0, -1}, {0, 1/2, -1}, {0, 0, -1}, {0, 0, 0}} *)

pts = #.vertices/Total[#, {2}] &@ Log @ RandomReal[1, {2000, 4}];

Graphics3D[Point[pts], Axes -> True, 
 PlotRange -> {{0, 1/2}, {0, 1/2}, {-1, 0}}]

Mathematica graphics

share|improve this answer
    
I think this is a good extension of the linked question rather than a duplicate. +1 –  Mr.Wizard Aug 15 at 3:47

The easiest way is to define the vertices sequentially.

x=RandomReal[{0,1/2},1000]
y=RandomReal[{0,1/2-x},1000]
z=RandomReal[{-1,-2(x+y)},1000]
share|improve this answer
    
I'm sorry but this is not a uniform distribution. –  Silvia Aug 16 at 18:14

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.