I want to generate a randomly oriented circle in R^n. I have been able to successfully generate points on the surface of an n-sphere. I read that you can intersect it with a plane and get a circle, but I don't know how to do this in Python.
Or is there any other way to generate it in Python?
Thanks!
As a complete python implementation :
You need to use 2 basis vectors for this.
Generate Random unit N-D vector
U
so just create array of N random numbers
ui = <-1,+1>
and then normalize to unit size by dividing them all by the sizesqrt(u0^2+u1^2+...)
Beware TheU
must not be zero !!!Generate N-D vector
V
which is perpendicular toU
In 2D and 3D is this simple as you can just swap
x,y
and negate one in 2D or use cross product in 3D. Unfortunately The cross product is not defined in N-D (at least not to my knowledge) So you need to generate non zero vector for which dot product is zero:So you can create some elements as random and fit the rest (so the sum is zero). To equalize you can use abs higher
vi
whereui
is abs lower... After this normalizeV
to unit size.In the C++ example bellow I used this approach:
v[i]=< -1 , +1 >
such that partial dot product is lovering in magnitude (so just compute sign sou[i]*v[i]
is negative to partial dot product)u[i]
and recomputev[i]
so dot product is zeroV
to unit sizeBeware also
V
must not be zero !!!Circle in N-D
use simple parametric equation:
Where
t = < 0 , 2*Pi >
Here simple C++ example of generating
U,V
:And the result of this for confirmation of approach:
[Edit1] randomness issue
As @RoobieNuby pointed out method above can have randomness issues (the planes will not have uniform distribution) After some testing I confirmed it:
So I tested 3 and 2 basis vectors form and the difference can be visually seen. On the right is the above method in 5D (truncated to 2D view) and on the left is new form obtained like this:
The important stuff here is
void nd_perpendicular(double *a,double *b,double *c);
function which returns perpendicular vector to bothb,c
. To make this robust (In case randomness matters) in N-D You should haven
vectors not just3
.The operation of function is similar to the previous one. The difference is only in that we optimize more that one dot product at once. So you need to choose which dot product to optimize per axis (based on abs coordinate value of the perpendicular vector). So you should rewrite this to optimize
n-1
dot products at once.1st
vector (normal)2nd
vector (1
dot product to optimize)3th
vector (2
dot products to optimize)4th
vector (3
dot products to optimize)n-th
vector (n-1
dot products to optimize)2
(except the first) vectors as basis (you can select them randomly)It looks like just
3
vectors are enough forn>=3
(so you can ignore #4,#5) but to confirm that for sure some sort of statistical analysis would be needed which I am too lazy to do.[Edit2] vector perpendicular to more vectors ...
Have implemented the dot product perpendicular vector computation from the oher answer. And computation of perpendicular vector to multiple vectors:
Too boost robustness It uses 2 different iterative approaches. Here example of usage (
n=5
):The following is assuming that by high dimensional circle you mean the intersection of an N-sphere with an N-hyperplane containing the sphere's centre (i.e. an N-1-sphere in N+1-space).
You can do the following (assuming you are in N+1-space, considering the N sphere):
Since you already know how to generate a random point on the surface of an n-sphere, just generate two such points, call them
P1
andP2
. These will determine the plane in which the circle will lie.I am assuming that both these points are a distance of 1 from the origin, (which will be true if you picked 1 as the radius of your n-sphere). If not, divide each point by its length.
Now we want to make
P2
perpendicular toP1
. This can be done byThen for each point, you can generate a random angle between 0 and 2pi. Convert this angle to a point on the circle by: