Random vector

I need a random unit vectors in n-dimensional space. Any idea how to build it in C++?
What do you mean by "random unit vector"?
Do you mean a unit vector that has random values?
From my current (very little) understanding, you would probably need to use arrays/vectors.
Also, depending on what you plan to do with your "random unit vector" will influence implementation details.
Sorry, I was not clear. I did not meant vector of C++. I imply the geometric vector (a geometric object that has magnitude and direction). "Unit" means that the magnitude is equal to one. The direction should be random and isotropic (any direction should be equally possible). For example in 2D a random unit vector (x1, x2) can be build like that:
1
2
3
4
5
6
7
8
9
10
11
#include <cmath>
#include <stdlib.h>
...
double   x1, x2, phi, pi;
pi = 4.0*atan(1.0);

phi = rand()/double(RAND_MAX);
phi *= 2.0*pi;

x1 = sin(phi);
x2 = cos(phi);


The question is how to do similar things generally in 3D or in higher dimensional space?
For example, for the three dimensional Cartesian coordinate system:

a. Generate a random direction vector (0,0,0) tp (x,y,z) where x, y, z are random
b. Scale it to the unit vector (0,0,0) tp ( x^ , y^ , z^ )
c. If required, shift the origin to a random location ( x1, y1, z1 )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <random>
#include <ctime>
#include <algorithm>
#include <cmath>
#include <tuple>
#include <iostream>
#include <iomanip>

#define WARM_UP_ENGINE

using vector = std::tuple<double,double,double> ;

const auto x = [] ( vector v ) { return std::get<0>(v) ; } ;
const auto y = [] ( vector v ) { return std::get<1>(v) ; } ;
const auto z = [] ( vector v ) { return std::get<2>(v) ; } ;

double norm( vector v ) { return std::sqrt( x(v)*x(v) + y(v)*y(v) + z(v)*z(v) ) ; }

vector random_vector()
{
    #ifdef WARM_UP_ENGINE // if high quality pseudo-randomness is criticsl

        static int sseq[ std::mt19937::state_size ] ;
        const static bool once = ( std::srand( std::time(nullptr) ),
                                   std::generate( std::begin(sseq), std::end(sseq), std::rand ),
                                   true ) ;
        static std::seed_seq seed_seq( std::begin(sseq), std::end(sseq) ) ;
        static std::mt19937 twister(seed_seq) ;

    #else // no warm up is required, should be adequate for normal use

        static std::mt19937 twister( std::time(0) ) ;

    #endif // WARM_UP_ENGINE

    static std::uniform_real_distribution<double> distr( -1000, 1000 ) ;

    return vector( distr(twister), distr(twister), distr(twister) ) ;
}

vector random_unit_vector()
{
    auto v = random_vector() ;
    constexpr double epsilon = 0.01 ;
    double m = norm(v) ;
    if( m > epsilon ) return vector( x(v)/m, y(v)/m, z(v)/m ) ;
    else return random_unit_vector() ;
}

int main()
{
    std::cout << std::fixed << std::setprecision(3) ;

    for( int i = 0 ; i < 10 ; ++i )
    {
        auto v = random_unit_vector() ;
        std::cout << std::showpos << "(" << x(v) << ',' << y(v) << ',' << z(v)
                  << ")  " ;

        // move the random unit vector to a random location
        static std::mt19937 twister( std::time(0) ) ;
        static std::uniform_real_distribution<double> distr( -10, 10 ) ;

        double x1 = distr(twister), y1 = distr(twister), z1 = distr(twister) ;
        double x2 = x1 + x(v), y2 = y1 + y(v), z2 = z1+z(v) ;

        std::cout << std::showpos << "    (" << x1 << ',' << y1 << ',' << z1 << ')'
                  << " ----> (" << x2 << ',' << y2 << ',' << z2 << ")\n\n" ;
    }
}

http://ideone.com/13p4VJ
Thank you for your reply.
I am sure that such a codes will give you a random but not a isotropic vectors. If you try to plot numbers of such a vectors without shifting (all vectors start at the same point) you will see visually that there will be some preferred directions.
A quick suggestion: try using gaussian distributions along each dimension. A product of N independent gaussians (x1,x2,...) is a gaussian in r =sqrt(x1^2+x2^2+...) times a uniform distribution on the N-dimensional sphere of radius 1.
Thanks a lot! This sounds good. I think each of your ideas, a gaussian distributions along each dimension or a uniform distribution on the N-dimensional unit sphere should be enough for an isotropic distribution.
Topic archived. No new replies allowed.