4
$\begingroup$

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?

$\endgroup$
9
  • $\begingroup$ 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. $\endgroup$ Jun 23, 2021 at 10:53
  • $\begingroup$ 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. $\endgroup$ Jun 23, 2021 at 10:58
  • $\begingroup$ Note that there are no "row vectors" or "column vectors" in Mathematica. Vectors are 1-index tensors and cannot be transposed. $\endgroup$
    – Szabolcs
    Jun 23, 2021 at 11:04
  • 1
    $\begingroup$ @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". $\endgroup$
    – Szabolcs
    Jun 23, 2021 at 11:38
  • 1
    $\begingroup$ @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. $\endgroup$ Jun 23, 2021 at 12:13

2 Answers 2

4
$\begingroup$

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} *)
$\endgroup$
2
  • $\begingroup$ Thanks. How can we restrict the elements of these vectors to be positive? That is, in my question, if $v_i \ge 0$ $\endgroup$
    – Mike
    Jun 25, 2021 at 18:12
  • $\begingroup$ You can simply take the absolute value of each component, using Abs/@v $\endgroup$
    – mikado
    Jun 25, 2021 at 18:17
7
$\begingroup$

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.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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