TransWikia.com

Generate 3 dimensional random vectors

Mathematica Asked on August 2, 2021

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?

2 Answers

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} *)

Correct answer by mikado on August 2, 2021

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]}]

enter image description here

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.

Answered by Szabolcs on August 2, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP