# Random reals according to conditions

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.

• Related: (13038), (32501), (33652) Commented Aug 15, 2014 at 1:23
• @Mr.Wizard It seems pretty close to a duplicate of 33652 -- see my answer. Commented Aug 15, 2014 at 3:12

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:

• I believe that generation and filtering is a fine approach when the selection percentage is relatively high as is the case here. +1 Commented Aug 15, 2014 at 1:13
• @Mr.Wizard Thanks. I thought about a different approach but this seems to do the job in this case. Commented Aug 15, 2014 at 1:16
• See links above for advanced methods for this class of problem. Commented Aug 15, 2014 at 1:26
• @Mr.Wizard. Thanks, I actually voted in 2 out of the 3 links you provided. Just forgot about those. Commented Aug 15, 2014 at 1:42
• @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%. Commented Aug 15, 2014 at 3:30

Ray Koopman's answer to Uniformly distributed n-dimensional probability vectors over a simplex 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}}]


• I think this is a good extension of the linked question rather than a duplicate. +1 Commented Aug 15, 2014 at 3:47

You can use RandomPoint with ImplicitRegion:

RandomPoint[
ImplicitRegion[0<x<1/2 && 0<y<1/2 && -1<z<-2(x+y), {x,y,z}],
10
]


{{0.0644104, 0.289938, -0.812196}, {0.162676, 0.0447583, -0.805135}, {0.29663, 0.0801703, -0.955995}, {0.0845065, 0.0982267, -0.542481}, {0.00591773, 0.0586124, -0.222642}, {0.395283, 0.0611798, -0.965819}, {0.281329, 0.0247549, -0.985743}, {0.0997621, 0.156397, -0.969405}, {0.136775, 0.176456, -0.934246}, {0.165527, 0.234188, -0.836819}}

Or, if you know the corners of the tetrahedron, you could use:

RandomPoint[
Tetrahedron[{{0,0,-1},{0,1/2,-1},{1/2,0,-1},{0,0,0}}],
10
]


{{0.103469, 0.00460676, -0.804016}, {0.155514, 0.266517, -0.934628}, {0.0258173, 0.0425049, -0.344449}, {0.161183, 0.0999294, -0.639421}, {0.124769, 0.194545, -0.914526}, {0.223348, 0.08202, -0.620869}, {0.0379937, 0.0701453, -0.401479}, {0.0608969, 0.0313861, -0.458453}, {0.00207286, 0.136834, -0.477351}, {0.246812, 0.0634065, -0.89431}}