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?
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]}]
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
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP