# Generate 3 dimensional random vectors

How can one generate a random vector $$v=[v_1, v_2, v_3]^T$$ satisfying $$\sqrt{v_1v_1^* + v_2 v_2^* + v_3 v_3^*} = 1$$, where $$T$$ and $$*$$ denote the transpose and complex-conjugate, respectively?

• Try lst=Normalize /@ RandomReal[{}, {n, 3}] where instead of n you should put the desired number of vectors. By evaluation lst /. {x_, y_, z_} -> x^2 + y^2 + z^2 you can make sure that they all have a unit length. Jun 23, 2021 at 10:53
• For the complex vectors make the same with RandomComplex and use lst /. {x_, y_, z_} -> x*Conjugate[x] + y*Conjugate[y] + z*Conjugate[z] // Chop for the check. Jun 23, 2021 at 10:58
• Note that there are no "row vectors" or "column vectors" in Mathematica. Vectors are 1-index tensors and cannot be transposed. Jun 23, 2021 at 11:04
• @AlexeiBoulbitch The big question: what does "random object satisfying criterion" mean? I maintain that without additional information, the only reasonable interpretation is that the distribution must be uniform. If any distribution would be acceptable, then I propose assigning probability 1 to the vector {1,0,0} and zero to everything else. You might that that that is not random, but why? It is a valid distribution. Then I would ask you to define what you mean by "random". Jun 23, 2021 at 11:38
• @Szabolcs Maybe you are right. I do not argue against it, the more that I like your solution. Maybe OP, indeed, did not think about such subtleties, as you proposed. Also maybe the OP aim was much simpler than the one you assumed, and a nonuniform set of vectors is OK for him. I propose that we leave the decision for OP. Jun 23, 2021 at 12:13

This is a very simple 1-liner giving a list of n such random vectors

sphericalrandom[n_] := Normalize /@ RandomVariate[NormalDistribution[0, 1], {n, 3}]


Note that these are uniformly distributed on the sphere, since the multivariate normal distribution is invariant under rotation (consider the covariance matrix, R.I.Transpose[R] = I)

We can easily verify that the requirement is met

sphericalrandom[6]
(* {{-0.277119, -0.913442, -0.298042}, {0.784793,
0.124294, -0.607166}, {0.0794014, -0.138744, 0.98714}, {0.477633,
0.578417, -0.661287}, {0.182014, -0.443811,
0.877441}, {-0.967141, -0.236544, 0.0931965}} *)

# . # & /@ %
(* {1., 1., 1., 1., 1., 1.} *)


The question seems to request complex numbers subject to the same criteria. This is very easily done

sphericalrandomcomplex[n_] :=
Normalize /@ (RandomVariate[
NormalDistribution[0, 1], {n, 3, 2}] . {1, I})


Again, the normalisation checks

sphericalrandomcomplex[6]
(* {{0.0291155 + 0.299873 I, 0.118097 + 0.105762 I,
0.872673 + 0.350054 I}, {-0.476609 - 0.271261 I,
0.762756 + 0.326494 I,
0.0928805 - 0.0473263 I}, {0.482045 + 0.36627 I, -0.627184 -
0.11854 I,
0.183277 + 0.438722 I}, {-0.445669 - 0.472578 I, -0.0542457 +
0.260653 I, 0.129732 + 0.700241 I}, {0.398994 + 0.191309 I,
0.147118 - 0.353526 I, -0.455474 - 0.670913 I}, {-0.157891 +
0.0766977 I, 0.66208 + 0.28717 I, -0.261425 + 0.616465 I}} *)

# . Conjugate[#] & /@ %
(* {1. + 0. I, 1. + 0. I, 1. + 0. I, 1. + 0. I, 1. + 0. I,
1. + 0. I} *)

• Thanks. How can we restrict the elements of these vectors to be positive? That is, in my question, if $v_i \ge 0$
– Mike
Jun 25, 2021 at 18:12
• You can simply take the absolute value of each component, using Abs/@v Jun 25, 2021 at 18:17

Generate a single such vector:

Complex @@@ Partition[RandomPoint@Sphere[{0, 0, 0, 0, 0, 0}], 2]


Generate n of them with good performance:

n = 100;

#1 + I #2 & @@ Transpose[
ArrayReshape[RandomPoint[Sphere[{0, 0, 0, 0, 0, 0}], n], {n, 3, 2}],
{2, 3, 1}
]


This method will sample uniformly from the 3-dimensional complex sphere.

At this point, it is appropriate to discuss why one of the suggestions in the comments will not work. The suggestion is the following for reals:

lst=Normalize /@ RandomReal[{}, {n, 3}]


or the same with RandomComplex for complexes.

This will not sample uniformly from the sphere. It sampled from the unit cube, then normalized each element. That leads to a biased distribution, first, because we are restricted to the first octant. This fault is easily fixed by extending to all octants:

lst = Normalize /@ RandomReal[{-1, 1}, {10000, 3}];


However, the sampling is still not uniform, as vectors in the direction of the cube edges will appear more frequently. This is plainly visible in a plot:

Graphics3D[{Opacity[0.5], Point[lst]}]


This can be saved by restricting the sampling to the unit ball before normalizing each vector:

n = 100;
eps = 0.001;
result = Normalize /@ Select[RandomReal[{-1, 1}, {n, 3}], eps < Norm[#] <= 1 &];


eps here is an abirtrary small number that helps avoid numerical imprecision for points very close to the origin. Extension to complexes is possible with RandomComplex[{-1-I, 1+I}, ...].

However, this method does not generate n points, but fewer.

Length[result]
(* 53 *)


One needs to do a bit more work to get precisely n points. This is why I chose to use RandomPoint for my answer.

Update: See @mikado's answer which starts with the normal distribution (which is isotropic) instead of uniform distribution in a cube, and thus avoids the need for the Select above, and makes it easy to generate precisely the desired number of points.