generator
Generates points uniformly on a hyperSphere
main.c
1 /*
2  * This file is part of the Hyper-Sphere Uniform Point Generator.
3  *
4  * Hyper-Sphere Uniform Point Generator by Luis M. S. Russo and
5  * Alexandre P. Francisco / KDBIO / INESC-ID is licensed under a Creative
6  * Commons Attribution 3.0 Unported License. Permissions beyond the
7  * scope of this license may be available at qhv@kdbio.inesc-id.pt
8  *
9  * Any published media that is related with to use of the distributed
10  * software, or derived software, must contain a reference to "Extending
11  * quick hypervolume. Luís M. S. Russo, Alexandre P. Francisco:
12  * J. Heuristics 22(3): 245-271 (2016)".
13  *
14  * Permission to use, copy, modify, and/or distribute this software for
15  * any purpose with or without fee is hereby granted, provided that the
16  * above copyright notice and this permission notice appear in all
17  * copies.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
20  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
22  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
23  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
24  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
25  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
26  * PERFORMANCE OF THIS SOFTWARE.
27  *
28  */
29 
30 /* Note: Based on the geometrical distribution. */
31 
32 #define _XOPEN_SOURCE
33 #define _XOPEN_SOURCE_EXTENDED
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <math.h>
37 
38 
39 #define DIM 40 /* Maximal number of dimensions */
40 
41 double P[DIM];
42 
43 double Norm(double* V, int d)
44 {
45  double r;
46 
47  r = 0;
48  while(d > 0)
49  {
50  d--;
51  r += V[d]*V[d];
52  }
53 
54  return sqrt(r);
55 }
56 
57 void Scale(double* V, int d, double s)
58 {
59  while(d > 0)
60  {
61  d--;
62  V[d] *= s;
63  }
64 }
65 
66 
67 /* Choosing a point from a normal distribution with average 0 */
68 void chooseRandom(double* V, int d)
69 {
70  /* The distribution is obtained by adding S uniform values */
71 #define SAMPS 20
72  int j;
73 
74  while(d > 0)
75  {
76  d--;
77  V[d] = 0;
78  j = SAMPS;
79  while(j > 0)
80  {
81  V[d] += drand48() - 0.5;
82  j--;
83  }
84  V[d] = fabs(V[d]);
85  }
86 #undef S
87 }
88 
89 void printV(double* V, int d)
90 {
91  while(d > 0)
92  {
93  d--;
94  printf("%.10le ", V[d]);
95  }
96  printf("\n");
97 }
98 
99 int main(int argc, char** argv)
100 {
101  int dim; /* Dimension */
102  int n; /* Number of points */
103  int k;
104  int seed;
105  double r;
106  int i;
107 
108  if(argc != 5)
109  {
110  printf("Usage %s Dimension Number_of_points seed Numbers_of_tests\n", argv[0]);
111  }
112  else
113  {
114  sscanf(argv[1], "%d", &dim);
115  sscanf(argv[2], "%d", &n);
116  sscanf(argv[3], "%d", &seed);
117  sscanf(argv[4], "%d", &k);
118 
119  srand48(seed);
120 
121  while (k--) {
122 
123  printf("#\n");
124 
125  i = 0;
126  while(i < n)
127  {
128  chooseRandom(P, dim);
129  r = Norm(P, dim);
130  Scale(P, dim, 1/r);
131  printV(P, dim);
132  i++;
133  }
134  }
135  printf("#\n");
136  }
137 
138  return 0;
139 }