lemongraph 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +8 -0
  3. data/LICENSE +674 -0
  4. data/README.md +6 -0
  5. data/ext/lemon-1.3.1/AUTHORS +26 -0
  6. data/ext/lemon-1.3.1/CMakeLists.txt +371 -0
  7. data/ext/lemon-1.3.1/INSTALL +167 -0
  8. data/ext/lemon-1.3.1/LICENSE +32 -0
  9. data/ext/lemon-1.3.1/NEWS +337 -0
  10. data/ext/lemon-1.3.1/README +50 -0
  11. data/ext/lemon-1.3.1/cmake/FindCOIN.cmake +110 -0
  12. data/ext/lemon-1.3.1/cmake/FindGLPK.cmake +55 -0
  13. data/ext/lemon-1.3.1/cmake/FindGhostscript.cmake +10 -0
  14. data/ext/lemon-1.3.1/cmake/FindILOG.cmake +102 -0
  15. data/ext/lemon-1.3.1/cmake/FindSOPLEX.cmake +23 -0
  16. data/ext/lemon-1.3.1/cmake/LEMONConfig.cmake.in +13 -0
  17. data/ext/lemon-1.3.1/cmake/nsis/lemon.ico +0 -0
  18. data/ext/lemon-1.3.1/cmake/nsis/uninstall.ico +0 -0
  19. data/ext/lemon-1.3.1/cmake/version.cmake +1 -0
  20. data/ext/lemon-1.3.1/cmake/version.cmake.in +1 -0
  21. data/ext/lemon-1.3.1/contrib/CMakeLists.txt +19 -0
  22. data/ext/lemon-1.3.1/lemon/CMakeLists.txt +91 -0
  23. data/ext/lemon-1.3.1/lemon/adaptors.h +3638 -0
  24. data/ext/lemon-1.3.1/lemon/arg_parser.cc +474 -0
  25. data/ext/lemon-1.3.1/lemon/arg_parser.h +440 -0
  26. data/ext/lemon-1.3.1/lemon/assert.h +214 -0
  27. data/ext/lemon-1.3.1/lemon/base.cc +37 -0
  28. data/ext/lemon-1.3.1/lemon/bellman_ford.h +1116 -0
  29. data/ext/lemon-1.3.1/lemon/bfs.h +1754 -0
  30. data/ext/lemon-1.3.1/lemon/bin_heap.h +347 -0
  31. data/ext/lemon-1.3.1/lemon/binomial_heap.h +445 -0
  32. data/ext/lemon-1.3.1/lemon/bits/alteration_notifier.h +472 -0
  33. data/ext/lemon-1.3.1/lemon/bits/array_map.h +351 -0
  34. data/ext/lemon-1.3.1/lemon/bits/bezier.h +174 -0
  35. data/ext/lemon-1.3.1/lemon/bits/default_map.h +182 -0
  36. data/ext/lemon-1.3.1/lemon/bits/edge_set_extender.h +627 -0
  37. data/ext/lemon-1.3.1/lemon/bits/enable_if.h +131 -0
  38. data/ext/lemon-1.3.1/lemon/bits/graph_adaptor_extender.h +401 -0
  39. data/ext/lemon-1.3.1/lemon/bits/graph_extender.h +1332 -0
  40. data/ext/lemon-1.3.1/lemon/bits/lock.h +65 -0
  41. data/ext/lemon-1.3.1/lemon/bits/map_extender.h +332 -0
  42. data/ext/lemon-1.3.1/lemon/bits/path_dump.h +177 -0
  43. data/ext/lemon-1.3.1/lemon/bits/solver_bits.h +194 -0
  44. data/ext/lemon-1.3.1/lemon/bits/traits.h +388 -0
  45. data/ext/lemon-1.3.1/lemon/bits/variant.h +494 -0
  46. data/ext/lemon-1.3.1/lemon/bits/vector_map.h +244 -0
  47. data/ext/lemon-1.3.1/lemon/bits/windows.cc +166 -0
  48. data/ext/lemon-1.3.1/lemon/bits/windows.h +44 -0
  49. data/ext/lemon-1.3.1/lemon/bucket_heap.h +594 -0
  50. data/ext/lemon-1.3.1/lemon/capacity_scaling.h +1014 -0
  51. data/ext/lemon-1.3.1/lemon/cbc.cc +460 -0
  52. data/ext/lemon-1.3.1/lemon/cbc.h +129 -0
  53. data/ext/lemon-1.3.1/lemon/christofides_tsp.h +254 -0
  54. data/ext/lemon-1.3.1/lemon/circulation.h +807 -0
  55. data/ext/lemon-1.3.1/lemon/clp.cc +464 -0
  56. data/ext/lemon-1.3.1/lemon/clp.h +164 -0
  57. data/ext/lemon-1.3.1/lemon/color.cc +44 -0
  58. data/ext/lemon-1.3.1/lemon/color.h +204 -0
  59. data/ext/lemon-1.3.1/lemon/concept_check.h +77 -0
  60. data/ext/lemon-1.3.1/lemon/concepts/bpgraph.h +1029 -0
  61. data/ext/lemon-1.3.1/lemon/concepts/digraph.h +491 -0
  62. data/ext/lemon-1.3.1/lemon/concepts/graph.h +788 -0
  63. data/ext/lemon-1.3.1/lemon/concepts/graph_components.h +2134 -0
  64. data/ext/lemon-1.3.1/lemon/concepts/heap.h +324 -0
  65. data/ext/lemon-1.3.1/lemon/concepts/maps.h +223 -0
  66. data/ext/lemon-1.3.1/lemon/concepts/path.h +312 -0
  67. data/ext/lemon-1.3.1/lemon/config.h.in +22 -0
  68. data/ext/lemon-1.3.1/lemon/connectivity.h +1688 -0
  69. data/ext/lemon-1.3.1/lemon/core.h +2506 -0
  70. data/ext/lemon-1.3.1/lemon/cost_scaling.h +1607 -0
  71. data/ext/lemon-1.3.1/lemon/counter.h +249 -0
  72. data/ext/lemon-1.3.1/lemon/cplex.cc +994 -0
  73. data/ext/lemon-1.3.1/lemon/cplex.h +292 -0
  74. data/ext/lemon-1.3.1/lemon/cycle_canceling.h +1230 -0
  75. data/ext/lemon-1.3.1/lemon/dfs.h +1637 -0
  76. data/ext/lemon-1.3.1/lemon/dheap.h +352 -0
  77. data/ext/lemon-1.3.1/lemon/dijkstra.h +1303 -0
  78. data/ext/lemon-1.3.1/lemon/dim2.h +726 -0
  79. data/ext/lemon-1.3.1/lemon/dimacs.h +448 -0
  80. data/ext/lemon-1.3.1/lemon/edge_set.h +1420 -0
  81. data/ext/lemon-1.3.1/lemon/edmonds_karp.h +556 -0
  82. data/ext/lemon-1.3.1/lemon/elevator.h +982 -0
  83. data/ext/lemon-1.3.1/lemon/error.h +276 -0
  84. data/ext/lemon-1.3.1/lemon/euler.h +287 -0
  85. data/ext/lemon-1.3.1/lemon/fib_heap.h +475 -0
  86. data/ext/lemon-1.3.1/lemon/fractional_matching.h +2139 -0
  87. data/ext/lemon-1.3.1/lemon/full_graph.h +1082 -0
  88. data/ext/lemon-1.3.1/lemon/glpk.cc +1012 -0
  89. data/ext/lemon-1.3.1/lemon/glpk.h +263 -0
  90. data/ext/lemon-1.3.1/lemon/gomory_hu.h +568 -0
  91. data/ext/lemon-1.3.1/lemon/graph_to_eps.h +1186 -0
  92. data/ext/lemon-1.3.1/lemon/greedy_tsp.h +251 -0
  93. data/ext/lemon-1.3.1/lemon/grid_graph.h +699 -0
  94. data/ext/lemon-1.3.1/lemon/grosso_locatelli_pullan_mc.h +840 -0
  95. data/ext/lemon-1.3.1/lemon/hao_orlin.h +1015 -0
  96. data/ext/lemon-1.3.1/lemon/hartmann_orlin_mmc.h +654 -0
  97. data/ext/lemon-1.3.1/lemon/howard_mmc.h +651 -0
  98. data/ext/lemon-1.3.1/lemon/hypercube_graph.h +459 -0
  99. data/ext/lemon-1.3.1/lemon/insertion_tsp.h +533 -0
  100. data/ext/lemon-1.3.1/lemon/karp_mmc.h +590 -0
  101. data/ext/lemon-1.3.1/lemon/kruskal.h +324 -0
  102. data/ext/lemon-1.3.1/lemon/lemon.pc.in +10 -0
  103. data/ext/lemon-1.3.1/lemon/lgf_reader.h +3854 -0
  104. data/ext/lemon-1.3.1/lemon/lgf_writer.h +2687 -0
  105. data/ext/lemon-1.3.1/lemon/list_graph.h +2510 -0
  106. data/ext/lemon-1.3.1/lemon/lp.h +95 -0
  107. data/ext/lemon-1.3.1/lemon/lp_base.cc +30 -0
  108. data/ext/lemon-1.3.1/lemon/lp_base.h +2147 -0
  109. data/ext/lemon-1.3.1/lemon/lp_skeleton.cc +143 -0
  110. data/ext/lemon-1.3.1/lemon/lp_skeleton.h +234 -0
  111. data/ext/lemon-1.3.1/lemon/maps.h +4057 -0
  112. data/ext/lemon-1.3.1/lemon/matching.h +3505 -0
  113. data/ext/lemon-1.3.1/lemon/math.h +77 -0
  114. data/ext/lemon-1.3.1/lemon/max_cardinality_search.h +794 -0
  115. data/ext/lemon-1.3.1/lemon/min_cost_arborescence.h +808 -0
  116. data/ext/lemon-1.3.1/lemon/nagamochi_ibaraki.h +702 -0
  117. data/ext/lemon-1.3.1/lemon/nauty_reader.h +113 -0
  118. data/ext/lemon-1.3.1/lemon/nearest_neighbor_tsp.h +238 -0
  119. data/ext/lemon-1.3.1/lemon/network_simplex.h +1659 -0
  120. data/ext/lemon-1.3.1/lemon/opt2_tsp.h +367 -0
  121. data/ext/lemon-1.3.1/lemon/pairing_heap.h +474 -0
  122. data/ext/lemon-1.3.1/lemon/path.h +1164 -0
  123. data/ext/lemon-1.3.1/lemon/planarity.h +2754 -0
  124. data/ext/lemon-1.3.1/lemon/preflow.h +985 -0
  125. data/ext/lemon-1.3.1/lemon/quad_heap.h +343 -0
  126. data/ext/lemon-1.3.1/lemon/radix_heap.h +438 -0
  127. data/ext/lemon-1.3.1/lemon/radix_sort.h +487 -0
  128. data/ext/lemon-1.3.1/lemon/random.cc +29 -0
  129. data/ext/lemon-1.3.1/lemon/random.h +1005 -0
  130. data/ext/lemon-1.3.1/lemon/smart_graph.h +1344 -0
  131. data/ext/lemon-1.3.1/lemon/soplex.cc +465 -0
  132. data/ext/lemon-1.3.1/lemon/soplex.h +158 -0
  133. data/ext/lemon-1.3.1/lemon/static_graph.h +476 -0
  134. data/ext/lemon-1.3.1/lemon/suurballe.h +776 -0
  135. data/ext/lemon-1.3.1/lemon/time_measure.h +610 -0
  136. data/ext/lemon-1.3.1/lemon/tolerance.h +242 -0
  137. data/ext/lemon-1.3.1/lemon/unionfind.h +1824 -0
  138. data/ext/lemon-1.3.1/scripts/unify-sources.sh +390 -0
  139. data/ext/lemon-1.3.1/scripts/valgrind-wrapper.sh +22 -0
  140. data/ext/lemongraph/arc_map.cc +1007 -0
  141. data/ext/lemongraph/digraph.cc +282 -0
  142. data/ext/lemongraph/digraph_arc.cc +153 -0
  143. data/ext/lemongraph/digraph_node.cc +277 -0
  144. data/ext/lemongraph/edge_map.cc +770 -0
  145. data/ext/lemongraph/extconf.rb +53 -0
  146. data/ext/lemongraph/graph.cc +351 -0
  147. data/ext/lemongraph/graph_arc.cc +95 -0
  148. data/ext/lemongraph/graph_edge.cc +153 -0
  149. data/ext/lemongraph/graph_item.cc +76 -0
  150. data/ext/lemongraph/graph_node.cc +321 -0
  151. data/ext/lemongraph/lemongraph.cc +260 -0
  152. data/ext/lemongraph/lemongraph.hh +295 -0
  153. data/ext/lemongraph/lemongraph.map +6 -0
  154. data/ext/lemongraph/lemongraph_export.hh +31 -0
  155. data/ext/lemongraph/node_map.cc +1011 -0
  156. data/lemongraph.gemspec +176 -0
  157. data/lib/lemongraph/graphviz.rb +240 -0
  158. data/lib/lemongraph/version.rb +4 -0
  159. data/lib/lemongraph.rb +21 -0
  160. data/samples/lemondeps.rb +38 -0
  161. metadata +202 -0
@@ -0,0 +1,1005 @@
1
+ /* -*- mode: C++; indent-tabs-mode: nil; -*-
2
+ *
3
+ * This file is a part of LEMON, a generic C++ optimization library.
4
+ *
5
+ * Copyright (C) 2003-2009
6
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
+ *
9
+ * Permission to use, modify and distribute this software is granted
10
+ * provided that this copyright notice appears in all copies. For
11
+ * precise terms see the accompanying LICENSE file.
12
+ *
13
+ * This software is provided "AS IS" with no warranty of any kind,
14
+ * express or implied, and with no claim as to its suitability for any
15
+ * purpose.
16
+ *
17
+ */
18
+
19
+ /*
20
+ * This file contains the reimplemented version of the Mersenne Twister
21
+ * Generator of Matsumoto and Nishimura.
22
+ *
23
+ * See the appropriate copyright notice below.
24
+ *
25
+ * Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
26
+ * All rights reserved.
27
+ *
28
+ * Redistribution and use in source and binary forms, with or without
29
+ * modification, are permitted provided that the following conditions
30
+ * are met:
31
+ *
32
+ * 1. Redistributions of source code must retain the above copyright
33
+ * notice, this list of conditions and the following disclaimer.
34
+ *
35
+ * 2. Redistributions in binary form must reproduce the above copyright
36
+ * notice, this list of conditions and the following disclaimer in the
37
+ * documentation and/or other materials provided with the distribution.
38
+ *
39
+ * 3. The names of its contributors may not be used to endorse or promote
40
+ * products derived from this software without specific prior written
41
+ * permission.
42
+ *
43
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
46
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
47
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
48
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
50
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
52
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
53
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
54
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
55
+ *
56
+ *
57
+ * Any feedback is very welcome.
58
+ * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
59
+ * email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
60
+ */
61
+
62
+ #ifndef LEMON_RANDOM_H
63
+ #define LEMON_RANDOM_H
64
+
65
+ #include <algorithm>
66
+ #include <iterator>
67
+ #include <vector>
68
+ #include <limits>
69
+ #include <fstream>
70
+
71
+ #include <lemon/math.h>
72
+ #include <lemon/dim2.h>
73
+
74
+ #ifndef WIN32
75
+ #include <sys/time.h>
76
+ #include <ctime>
77
+ #include <sys/types.h>
78
+ #include <unistd.h>
79
+ #else
80
+ #include <lemon/bits/windows.h>
81
+ #endif
82
+
83
+ ///\ingroup misc
84
+ ///\file
85
+ ///\brief Mersenne Twister random number generator
86
+
87
+ namespace lemon {
88
+
89
+ namespace _random_bits {
90
+
91
+ template <typename _Word, int _bits = std::numeric_limits<_Word>::digits>
92
+ struct RandomTraits {};
93
+
94
+ template <typename _Word>
95
+ struct RandomTraits<_Word, 32> {
96
+
97
+ typedef _Word Word;
98
+ static const int bits = 32;
99
+
100
+ static const int length = 624;
101
+ static const int shift = 397;
102
+
103
+ static const Word mul = 0x6c078965u;
104
+ static const Word arrayInit = 0x012BD6AAu;
105
+ static const Word arrayMul1 = 0x0019660Du;
106
+ static const Word arrayMul2 = 0x5D588B65u;
107
+
108
+ static const Word mask = 0x9908B0DFu;
109
+ static const Word loMask = (1u << 31) - 1;
110
+ static const Word hiMask = ~loMask;
111
+
112
+
113
+ static Word tempering(Word rnd) {
114
+ rnd ^= (rnd >> 11);
115
+ rnd ^= (rnd << 7) & 0x9D2C5680u;
116
+ rnd ^= (rnd << 15) & 0xEFC60000u;
117
+ rnd ^= (rnd >> 18);
118
+ return rnd;
119
+ }
120
+
121
+ };
122
+
123
+ template <typename _Word>
124
+ struct RandomTraits<_Word, 64> {
125
+
126
+ typedef _Word Word;
127
+ static const int bits = 64;
128
+
129
+ static const int length = 312;
130
+ static const int shift = 156;
131
+
132
+ static const Word mul = Word(0x5851F42Du) << 32 | Word(0x4C957F2Du);
133
+ static const Word arrayInit = Word(0x00000000u) << 32 |Word(0x012BD6AAu);
134
+ static const Word arrayMul1 = Word(0x369DEA0Fu) << 32 |Word(0x31A53F85u);
135
+ static const Word arrayMul2 = Word(0x27BB2EE6u) << 32 |Word(0x87B0B0FDu);
136
+
137
+ static const Word mask = Word(0xB5026F5Au) << 32 | Word(0xA96619E9u);
138
+ static const Word loMask = (Word(1u) << 31) - 1;
139
+ static const Word hiMask = ~loMask;
140
+
141
+ static Word tempering(Word rnd) {
142
+ rnd ^= (rnd >> 29) & (Word(0x55555555u) << 32 | Word(0x55555555u));
143
+ rnd ^= (rnd << 17) & (Word(0x71D67FFFu) << 32 | Word(0xEDA60000u));
144
+ rnd ^= (rnd << 37) & (Word(0xFFF7EEE0u) << 32 | Word(0x00000000u));
145
+ rnd ^= (rnd >> 43);
146
+ return rnd;
147
+ }
148
+
149
+ };
150
+
151
+ template <typename _Word>
152
+ class RandomCore {
153
+ public:
154
+
155
+ typedef _Word Word;
156
+
157
+ private:
158
+
159
+ static const int bits = RandomTraits<Word>::bits;
160
+
161
+ static const int length = RandomTraits<Word>::length;
162
+ static const int shift = RandomTraits<Word>::shift;
163
+
164
+ public:
165
+
166
+ void initState() {
167
+ static const Word seedArray[4] = {
168
+ 0x12345u, 0x23456u, 0x34567u, 0x45678u
169
+ };
170
+
171
+ initState(seedArray, seedArray + 4);
172
+ }
173
+
174
+ void initState(Word seed) {
175
+
176
+ static const Word mul = RandomTraits<Word>::mul;
177
+
178
+ current = state;
179
+
180
+ Word *curr = state + length - 1;
181
+ curr[0] = seed; --curr;
182
+ for (int i = 1; i < length; ++i) {
183
+ curr[0] = (mul * ( curr[1] ^ (curr[1] >> (bits - 2)) ) + i);
184
+ --curr;
185
+ }
186
+ }
187
+
188
+ template <typename Iterator>
189
+ void initState(Iterator begin, Iterator end) {
190
+
191
+ static const Word init = RandomTraits<Word>::arrayInit;
192
+ static const Word mul1 = RandomTraits<Word>::arrayMul1;
193
+ static const Word mul2 = RandomTraits<Word>::arrayMul2;
194
+
195
+
196
+ Word *curr = state + length - 1; --curr;
197
+ Iterator it = begin; int cnt = 0;
198
+ int num;
199
+
200
+ initState(init);
201
+
202
+ num = length > end - begin ? length : end - begin;
203
+ while (num--) {
204
+ curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul1))
205
+ + *it + cnt;
206
+ ++it; ++cnt;
207
+ if (it == end) {
208
+ it = begin; cnt = 0;
209
+ }
210
+ if (curr == state) {
211
+ curr = state + length - 1; curr[0] = state[0];
212
+ }
213
+ --curr;
214
+ }
215
+
216
+ num = length - 1; cnt = length - (curr - state) - 1;
217
+ while (num--) {
218
+ curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul2))
219
+ - cnt;
220
+ --curr; ++cnt;
221
+ if (curr == state) {
222
+ curr = state + length - 1; curr[0] = state[0]; --curr;
223
+ cnt = 1;
224
+ }
225
+ }
226
+
227
+ state[length - 1] = Word(1) << (bits - 1);
228
+ }
229
+
230
+ void copyState(const RandomCore& other) {
231
+ std::copy(other.state, other.state + length, state);
232
+ current = state + (other.current - other.state);
233
+ }
234
+
235
+ Word operator()() {
236
+ if (current == state) fillState();
237
+ --current;
238
+ Word rnd = *current;
239
+ return RandomTraits<Word>::tempering(rnd);
240
+ }
241
+
242
+ private:
243
+
244
+
245
+ void fillState() {
246
+ static const Word mask[2] = { 0x0ul, RandomTraits<Word>::mask };
247
+ static const Word loMask = RandomTraits<Word>::loMask;
248
+ static const Word hiMask = RandomTraits<Word>::hiMask;
249
+
250
+ current = state + length;
251
+
252
+ register Word *curr = state + length - 1;
253
+ register long num;
254
+
255
+ num = length - shift;
256
+ while (num--) {
257
+ curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
258
+ curr[- shift] ^ mask[curr[-1] & 1ul];
259
+ --curr;
260
+ }
261
+ num = shift - 1;
262
+ while (num--) {
263
+ curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
264
+ curr[length - shift] ^ mask[curr[-1] & 1ul];
265
+ --curr;
266
+ }
267
+ state[0] = (((state[0] & hiMask) | (curr[length - 1] & loMask)) >> 1) ^
268
+ curr[length - shift] ^ mask[curr[length - 1] & 1ul];
269
+
270
+ }
271
+
272
+
273
+ Word *current;
274
+ Word state[length];
275
+
276
+ };
277
+
278
+
279
+ template <typename Result,
280
+ int shift = (std::numeric_limits<Result>::digits + 1) / 2>
281
+ struct Masker {
282
+ static Result mask(const Result& result) {
283
+ return Masker<Result, (shift + 1) / 2>::
284
+ mask(static_cast<Result>(result | (result >> shift)));
285
+ }
286
+ };
287
+
288
+ template <typename Result>
289
+ struct Masker<Result, 1> {
290
+ static Result mask(const Result& result) {
291
+ return static_cast<Result>(result | (result >> 1));
292
+ }
293
+ };
294
+
295
+ template <typename Result, typename Word,
296
+ int rest = std::numeric_limits<Result>::digits, int shift = 0,
297
+ bool last = rest <= std::numeric_limits<Word>::digits>
298
+ struct IntConversion {
299
+ static const int bits = std::numeric_limits<Word>::digits;
300
+
301
+ static Result convert(RandomCore<Word>& rnd) {
302
+ return static_cast<Result>(rnd() >> (bits - rest)) << shift;
303
+ }
304
+
305
+ };
306
+
307
+ template <typename Result, typename Word, int rest, int shift>
308
+ struct IntConversion<Result, Word, rest, shift, false> {
309
+ static const int bits = std::numeric_limits<Word>::digits;
310
+
311
+ static Result convert(RandomCore<Word>& rnd) {
312
+ return (static_cast<Result>(rnd()) << shift) |
313
+ IntConversion<Result, Word, rest - bits, shift + bits>::convert(rnd);
314
+ }
315
+ };
316
+
317
+
318
+ template <typename Result, typename Word,
319
+ bool one_word = (std::numeric_limits<Word>::digits <
320
+ std::numeric_limits<Result>::digits) >
321
+ struct Mapping {
322
+ static Result map(RandomCore<Word>& rnd, const Result& bound) {
323
+ Word max = Word(bound - 1);
324
+ Result mask = Masker<Result>::mask(bound - 1);
325
+ Result num;
326
+ do {
327
+ num = IntConversion<Result, Word>::convert(rnd) & mask;
328
+ } while (num > max);
329
+ return num;
330
+ }
331
+ };
332
+
333
+ template <typename Result, typename Word>
334
+ struct Mapping<Result, Word, false> {
335
+ static Result map(RandomCore<Word>& rnd, const Result& bound) {
336
+ Word max = Word(bound - 1);
337
+ Word mask = Masker<Word, (std::numeric_limits<Result>::digits + 1) / 2>
338
+ ::mask(max);
339
+ Word num;
340
+ do {
341
+ num = rnd() & mask;
342
+ } while (num > max);
343
+ return num;
344
+ }
345
+ };
346
+
347
+ template <typename Result, int exp>
348
+ struct ShiftMultiplier {
349
+ static const Result multiplier() {
350
+ Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
351
+ res *= res;
352
+ if ((exp & 1) == 1) res *= static_cast<Result>(0.5);
353
+ return res;
354
+ }
355
+ };
356
+
357
+ template <typename Result>
358
+ struct ShiftMultiplier<Result, 0> {
359
+ static const Result multiplier() {
360
+ return static_cast<Result>(1.0);
361
+ }
362
+ };
363
+
364
+ template <typename Result>
365
+ struct ShiftMultiplier<Result, 20> {
366
+ static const Result multiplier() {
367
+ return static_cast<Result>(1.0/1048576.0);
368
+ }
369
+ };
370
+
371
+ template <typename Result>
372
+ struct ShiftMultiplier<Result, 32> {
373
+ static const Result multiplier() {
374
+ return static_cast<Result>(1.0/4294967296.0);
375
+ }
376
+ };
377
+
378
+ template <typename Result>
379
+ struct ShiftMultiplier<Result, 53> {
380
+ static const Result multiplier() {
381
+ return static_cast<Result>(1.0/9007199254740992.0);
382
+ }
383
+ };
384
+
385
+ template <typename Result>
386
+ struct ShiftMultiplier<Result, 64> {
387
+ static const Result multiplier() {
388
+ return static_cast<Result>(1.0/18446744073709551616.0);
389
+ }
390
+ };
391
+
392
+ template <typename Result, int exp>
393
+ struct Shifting {
394
+ static Result shift(const Result& result) {
395
+ return result * ShiftMultiplier<Result, exp>::multiplier();
396
+ }
397
+ };
398
+
399
+ template <typename Result, typename Word,
400
+ int rest = std::numeric_limits<Result>::digits, int shift = 0,
401
+ bool last = rest <= std::numeric_limits<Word>::digits>
402
+ struct RealConversion{
403
+ static const int bits = std::numeric_limits<Word>::digits;
404
+
405
+ static Result convert(RandomCore<Word>& rnd) {
406
+ return Shifting<Result, shift + rest>::
407
+ shift(static_cast<Result>(rnd() >> (bits - rest)));
408
+ }
409
+ };
410
+
411
+ template <typename Result, typename Word, int rest, int shift>
412
+ struct RealConversion<Result, Word, rest, shift, false> {
413
+ static const int bits = std::numeric_limits<Word>::digits;
414
+
415
+ static Result convert(RandomCore<Word>& rnd) {
416
+ return Shifting<Result, shift + bits>::
417
+ shift(static_cast<Result>(rnd())) +
418
+ RealConversion<Result, Word, rest-bits, shift + bits>::
419
+ convert(rnd);
420
+ }
421
+ };
422
+
423
+ template <typename Result, typename Word>
424
+ struct Initializer {
425
+
426
+ template <typename Iterator>
427
+ static void init(RandomCore<Word>& rnd, Iterator begin, Iterator end) {
428
+ std::vector<Word> ws;
429
+ for (Iterator it = begin; it != end; ++it) {
430
+ ws.push_back(Word(*it));
431
+ }
432
+ rnd.initState(ws.begin(), ws.end());
433
+ }
434
+
435
+ static void init(RandomCore<Word>& rnd, Result seed) {
436
+ rnd.initState(seed);
437
+ }
438
+ };
439
+
440
+ template <typename Word>
441
+ struct BoolConversion {
442
+ static bool convert(RandomCore<Word>& rnd) {
443
+ return (rnd() & 1) == 1;
444
+ }
445
+ };
446
+
447
+ template <typename Word>
448
+ struct BoolProducer {
449
+ Word buffer;
450
+ int num;
451
+
452
+ BoolProducer() : num(0) {}
453
+
454
+ bool convert(RandomCore<Word>& rnd) {
455
+ if (num == 0) {
456
+ buffer = rnd();
457
+ num = RandomTraits<Word>::bits;
458
+ }
459
+ bool r = (buffer & 1);
460
+ buffer >>= 1;
461
+ --num;
462
+ return r;
463
+ }
464
+ };
465
+
466
+ }
467
+
468
+ /// \ingroup misc
469
+ ///
470
+ /// \brief Mersenne Twister random number generator
471
+ ///
472
+ /// The Mersenne Twister is a twisted generalized feedback
473
+ /// shift-register generator of Matsumoto and Nishimura. The period
474
+ /// of this generator is \f$ 2^{19937} - 1 \f$ and it is
475
+ /// equi-distributed in 623 dimensions for 32-bit numbers. The time
476
+ /// performance of this generator is comparable to the commonly used
477
+ /// generators.
478
+ ///
479
+ /// This implementation is specialized for both 32-bit and 64-bit
480
+ /// architectures. The generators differ sligthly in the
481
+ /// initialization and generation phase so they produce two
482
+ /// completly different sequences.
483
+ ///
484
+ /// The generator gives back random numbers of serveral types. To
485
+ /// get a random number from a range of a floating point type you
486
+ /// can use one form of the \c operator() or the \c real() member
487
+ /// function. If you want to get random number from the {0, 1, ...,
488
+ /// n-1} integer range use the \c operator[] or the \c integer()
489
+ /// method. And to get random number from the whole range of an
490
+ /// integer type you can use the argumentless \c integer() or \c
491
+ /// uinteger() functions. After all you can get random bool with
492
+ /// equal chance of true and false or given probability of true
493
+ /// result with the \c boolean() member functions.
494
+ ///
495
+ ///\code
496
+ /// // The commented code is identical to the other
497
+ /// double a = rnd(); // [0.0, 1.0)
498
+ /// // double a = rnd.real(); // [0.0, 1.0)
499
+ /// double b = rnd(100.0); // [0.0, 100.0)
500
+ /// // double b = rnd.real(100.0); // [0.0, 100.0)
501
+ /// double c = rnd(1.0, 2.0); // [1.0, 2.0)
502
+ /// // double c = rnd.real(1.0, 2.0); // [1.0, 2.0)
503
+ /// int d = rnd[100000]; // 0..99999
504
+ /// // int d = rnd.integer(100000); // 0..99999
505
+ /// int e = rnd[6] + 1; // 1..6
506
+ /// // int e = rnd.integer(1, 1 + 6); // 1..6
507
+ /// int b = rnd.uinteger<int>(); // 0 .. 2^31 - 1
508
+ /// int c = rnd.integer<int>(); // - 2^31 .. 2^31 - 1
509
+ /// bool g = rnd.boolean(); // P(g = true) = 0.5
510
+ /// bool h = rnd.boolean(0.8); // P(h = true) = 0.8
511
+ ///\endcode
512
+ ///
513
+ /// LEMON provides a global instance of the random number
514
+ /// generator which name is \ref lemon::rnd "rnd". Usually it is a
515
+ /// good programming convenience to use this global generator to get
516
+ /// random numbers.
517
+ class Random {
518
+ private:
519
+
520
+ // Architecture word
521
+ typedef unsigned long Word;
522
+
523
+ _random_bits::RandomCore<Word> core;
524
+ _random_bits::BoolProducer<Word> bool_producer;
525
+
526
+
527
+ public:
528
+
529
+ ///\name Initialization
530
+ ///
531
+ /// @{
532
+
533
+ /// \brief Default constructor
534
+ ///
535
+ /// Constructor with constant seeding.
536
+ Random() { core.initState(); }
537
+
538
+ /// \brief Constructor with seed
539
+ ///
540
+ /// Constructor with seed. The current number type will be converted
541
+ /// to the architecture word type.
542
+ template <typename Number>
543
+ Random(Number seed) {
544
+ _random_bits::Initializer<Number, Word>::init(core, seed);
545
+ }
546
+
547
+ /// \brief Constructor with array seeding
548
+ ///
549
+ /// Constructor with array seeding. The given range should contain
550
+ /// any number type and the numbers will be converted to the
551
+ /// architecture word type.
552
+ template <typename Iterator>
553
+ Random(Iterator begin, Iterator end) {
554
+ typedef typename std::iterator_traits<Iterator>::value_type Number;
555
+ _random_bits::Initializer<Number, Word>::init(core, begin, end);
556
+ }
557
+
558
+ /// \brief Copy constructor
559
+ ///
560
+ /// Copy constructor. The generated sequence will be identical to
561
+ /// the other sequence. It can be used to save the current state
562
+ /// of the generator and later use it to generate the same
563
+ /// sequence.
564
+ Random(const Random& other) {
565
+ core.copyState(other.core);
566
+ }
567
+
568
+ /// \brief Assign operator
569
+ ///
570
+ /// Assign operator. The generated sequence will be identical to
571
+ /// the other sequence. It can be used to save the current state
572
+ /// of the generator and later use it to generate the same
573
+ /// sequence.
574
+ Random& operator=(const Random& other) {
575
+ if (&other != this) {
576
+ core.copyState(other.core);
577
+ }
578
+ return *this;
579
+ }
580
+
581
+ /// \brief Seeding random sequence
582
+ ///
583
+ /// Seeding the random sequence. The current number type will be
584
+ /// converted to the architecture word type.
585
+ template <typename Number>
586
+ void seed(Number seed) {
587
+ _random_bits::Initializer<Number, Word>::init(core, seed);
588
+ }
589
+
590
+ /// \brief Seeding random sequence
591
+ ///
592
+ /// Seeding the random sequence. The given range should contain
593
+ /// any number type and the numbers will be converted to the
594
+ /// architecture word type.
595
+ template <typename Iterator>
596
+ void seed(Iterator begin, Iterator end) {
597
+ typedef typename std::iterator_traits<Iterator>::value_type Number;
598
+ _random_bits::Initializer<Number, Word>::init(core, begin, end);
599
+ }
600
+
601
+ /// \brief Seeding from file or from process id and time
602
+ ///
603
+ /// By default, this function calls the \c seedFromFile() member
604
+ /// function with the <tt>/dev/urandom</tt> file. If it does not success,
605
+ /// it uses the \c seedFromTime().
606
+ /// \return Currently always \c true.
607
+ bool seed() {
608
+ #ifndef WIN32
609
+ if (seedFromFile("/dev/urandom", 0)) return true;
610
+ #endif
611
+ if (seedFromTime()) return true;
612
+ return false;
613
+ }
614
+
615
+ /// \brief Seeding from file
616
+ ///
617
+ /// Seeding the random sequence from file. The linux kernel has two
618
+ /// devices, <tt>/dev/random</tt> and <tt>/dev/urandom</tt> which
619
+ /// could give good seed values for pseudo random generators (The
620
+ /// difference between two devices is that the <tt>random</tt> may
621
+ /// block the reading operation while the kernel can give good
622
+ /// source of randomness, while the <tt>urandom</tt> does not
623
+ /// block the input, but it could give back bytes with worse
624
+ /// entropy).
625
+ /// \param file The source file
626
+ /// \param offset The offset, from the file read.
627
+ /// \return \c true when the seeding successes.
628
+ #ifndef WIN32
629
+ bool seedFromFile(const std::string& file = "/dev/urandom", int offset = 0)
630
+ #else
631
+ bool seedFromFile(const std::string& file = "", int offset = 0)
632
+ #endif
633
+ {
634
+ std::ifstream rs(file.c_str());
635
+ const int size = 4;
636
+ Word buf[size];
637
+ if (offset != 0 && !rs.seekg(offset)) return false;
638
+ if (!rs.read(reinterpret_cast<char*>(buf), sizeof(buf))) return false;
639
+ seed(buf, buf + size);
640
+ return true;
641
+ }
642
+
643
+ /// \brief Seding from process id and time
644
+ ///
645
+ /// Seding from process id and time. This function uses the
646
+ /// current process id and the current time for initialize the
647
+ /// random sequence.
648
+ /// \return Currently always \c true.
649
+ bool seedFromTime() {
650
+ #ifndef WIN32
651
+ timeval tv;
652
+ gettimeofday(&tv, 0);
653
+ seed(getpid() + tv.tv_sec + tv.tv_usec);
654
+ #else
655
+ seed(bits::getWinRndSeed());
656
+ #endif
657
+ return true;
658
+ }
659
+
660
+ /// @}
661
+
662
+ ///\name Uniform Distributions
663
+ ///
664
+ /// @{
665
+
666
+ /// \brief Returns a random real number from the range [0, 1)
667
+ ///
668
+ /// It returns a random real number from the range [0, 1). The
669
+ /// default Number type is \c double.
670
+ template <typename Number>
671
+ Number real() {
672
+ return _random_bits::RealConversion<Number, Word>::convert(core);
673
+ }
674
+
675
+ double real() {
676
+ return real<double>();
677
+ }
678
+
679
+ /// \brief Returns a random real number from the range [0, 1)
680
+ ///
681
+ /// It returns a random double from the range [0, 1).
682
+ double operator()() {
683
+ return real<double>();
684
+ }
685
+
686
+ /// \brief Returns a random real number from the range [0, b)
687
+ ///
688
+ /// It returns a random real number from the range [0, b).
689
+ double operator()(double b) {
690
+ return real<double>() * b;
691
+ }
692
+
693
+ /// \brief Returns a random real number from the range [a, b)
694
+ ///
695
+ /// It returns a random real number from the range [a, b).
696
+ double operator()(double a, double b) {
697
+ return real<double>() * (b - a) + a;
698
+ }
699
+
700
+ /// \brief Returns a random integer from a range
701
+ ///
702
+ /// It returns a random integer from the range {0, 1, ..., b - 1}.
703
+ template <typename Number>
704
+ Number integer(Number b) {
705
+ return _random_bits::Mapping<Number, Word>::map(core, b);
706
+ }
707
+
708
+ /// \brief Returns a random integer from a range
709
+ ///
710
+ /// It returns a random integer from the range {a, a + 1, ..., b - 1}.
711
+ template <typename Number>
712
+ Number integer(Number a, Number b) {
713
+ return _random_bits::Mapping<Number, Word>::map(core, b - a) + a;
714
+ }
715
+
716
+ /// \brief Returns a random integer from a range
717
+ ///
718
+ /// It returns a random integer from the range {0, 1, ..., b - 1}.
719
+ template <typename Number>
720
+ Number operator[](Number b) {
721
+ return _random_bits::Mapping<Number, Word>::map(core, b);
722
+ }
723
+
724
+ /// \brief Returns a random non-negative integer
725
+ ///
726
+ /// It returns a random non-negative integer uniformly from the
727
+ /// whole range of the current \c Number type. The default result
728
+ /// type of this function is <tt>unsigned int</tt>.
729
+ template <typename Number>
730
+ Number uinteger() {
731
+ return _random_bits::IntConversion<Number, Word>::convert(core);
732
+ }
733
+
734
+ unsigned int uinteger() {
735
+ return uinteger<unsigned int>();
736
+ }
737
+
738
+ /// \brief Returns a random integer
739
+ ///
740
+ /// It returns a random integer uniformly from the whole range of
741
+ /// the current \c Number type. The default result type of this
742
+ /// function is \c int.
743
+ template <typename Number>
744
+ Number integer() {
745
+ static const int nb = std::numeric_limits<Number>::digits +
746
+ (std::numeric_limits<Number>::is_signed ? 1 : 0);
747
+ return _random_bits::IntConversion<Number, Word, nb>::convert(core);
748
+ }
749
+
750
+ int integer() {
751
+ return integer<int>();
752
+ }
753
+
754
+ /// \brief Returns a random bool
755
+ ///
756
+ /// It returns a random bool. The generator holds a buffer for
757
+ /// random bits. Every time when it become empty the generator makes
758
+ /// a new random word and fill the buffer up.
759
+ bool boolean() {
760
+ return bool_producer.convert(core);
761
+ }
762
+
763
+ /// @}
764
+
765
+ ///\name Non-uniform Distributions
766
+ ///
767
+ ///@{
768
+
769
+ /// \brief Returns a random bool with given probability of true result.
770
+ ///
771
+ /// It returns a random bool with given probability of true result.
772
+ bool boolean(double p) {
773
+ return operator()() < p;
774
+ }
775
+
776
+ /// Standard normal (Gauss) distribution
777
+
778
+ /// Standard normal (Gauss) distribution.
779
+ /// \note The Cartesian form of the Box-Muller
780
+ /// transformation is used to generate a random normal distribution.
781
+ double gauss()
782
+ {
783
+ double V1,V2,S;
784
+ do {
785
+ V1=2*real<double>()-1;
786
+ V2=2*real<double>()-1;
787
+ S=V1*V1+V2*V2;
788
+ } while(S>=1);
789
+ return std::sqrt(-2*std::log(S)/S)*V1;
790
+ }
791
+ /// Normal (Gauss) distribution with given mean and standard deviation
792
+
793
+ /// Normal (Gauss) distribution with given mean and standard deviation.
794
+ /// \sa gauss()
795
+ double gauss(double mean,double std_dev)
796
+ {
797
+ return gauss()*std_dev+mean;
798
+ }
799
+
800
+ /// Lognormal distribution
801
+
802
+ /// Lognormal distribution. The parameters are the mean and the standard
803
+ /// deviation of <tt>exp(X)</tt>.
804
+ ///
805
+ double lognormal(double n_mean,double n_std_dev)
806
+ {
807
+ return std::exp(gauss(n_mean,n_std_dev));
808
+ }
809
+ /// Lognormal distribution
810
+
811
+ /// Lognormal distribution. The parameter is an <tt>std::pair</tt> of
812
+ /// the mean and the standard deviation of <tt>exp(X)</tt>.
813
+ ///
814
+ double lognormal(const std::pair<double,double> &params)
815
+ {
816
+ return std::exp(gauss(params.first,params.second));
817
+ }
818
+ /// Compute the lognormal parameters from mean and standard deviation
819
+
820
+ /// This function computes the lognormal parameters from mean and
821
+ /// standard deviation. The return value can direcly be passed to
822
+ /// lognormal().
823
+ std::pair<double,double> lognormalParamsFromMD(double mean,
824
+ double std_dev)
825
+ {
826
+ double fr=std_dev/mean;
827
+ fr*=fr;
828
+ double lg=std::log(1+fr);
829
+ return std::pair<double,double>(std::log(mean)-lg/2.0,std::sqrt(lg));
830
+ }
831
+ /// Lognormal distribution with given mean and standard deviation
832
+
833
+ /// Lognormal distribution with given mean and standard deviation.
834
+ ///
835
+ double lognormalMD(double mean,double std_dev)
836
+ {
837
+ return lognormal(lognormalParamsFromMD(mean,std_dev));
838
+ }
839
+
840
+ /// Exponential distribution with given mean
841
+
842
+ /// This function generates an exponential distribution random number
843
+ /// with mean <tt>1/lambda</tt>.
844
+ ///
845
+ double exponential(double lambda=1.0)
846
+ {
847
+ return -std::log(1.0-real<double>())/lambda;
848
+ }
849
+
850
+ /// Gamma distribution with given integer shape
851
+
852
+ /// This function generates a gamma distribution random number.
853
+ ///
854
+ ///\param k shape parameter (<tt>k>0</tt> integer)
855
+ double gamma(int k)
856
+ {
857
+ double s = 0;
858
+ for(int i=0;i<k;i++) s-=std::log(1.0-real<double>());
859
+ return s;
860
+ }
861
+
862
+ /// Gamma distribution with given shape and scale parameter
863
+
864
+ /// This function generates a gamma distribution random number.
865
+ ///
866
+ ///\param k shape parameter (<tt>k>0</tt>)
867
+ ///\param theta scale parameter
868
+ ///
869
+ double gamma(double k,double theta=1.0)
870
+ {
871
+ double xi,nu;
872
+ const double delta = k-std::floor(k);
873
+ const double v0=E/(E-delta);
874
+ do {
875
+ double V0=1.0-real<double>();
876
+ double V1=1.0-real<double>();
877
+ double V2=1.0-real<double>();
878
+ if(V2<=v0)
879
+ {
880
+ xi=std::pow(V1,1.0/delta);
881
+ nu=V0*std::pow(xi,delta-1.0);
882
+ }
883
+ else
884
+ {
885
+ xi=1.0-std::log(V1);
886
+ nu=V0*std::exp(-xi);
887
+ }
888
+ } while(nu>std::pow(xi,delta-1.0)*std::exp(-xi));
889
+ return theta*(xi+gamma(int(std::floor(k))));
890
+ }
891
+
892
+ /// Weibull distribution
893
+
894
+ /// This function generates a Weibull distribution random number.
895
+ ///
896
+ ///\param k shape parameter (<tt>k>0</tt>)
897
+ ///\param lambda scale parameter (<tt>lambda>0</tt>)
898
+ ///
899
+ double weibull(double k,double lambda)
900
+ {
901
+ return lambda*pow(-std::log(1.0-real<double>()),1.0/k);
902
+ }
903
+
904
+ /// Pareto distribution
905
+
906
+ /// This function generates a Pareto distribution random number.
907
+ ///
908
+ ///\param k shape parameter (<tt>k>0</tt>)
909
+ ///\param x_min location parameter (<tt>x_min>0</tt>)
910
+ ///
911
+ double pareto(double k,double x_min)
912
+ {
913
+ return exponential(gamma(k,1.0/x_min))+x_min;
914
+ }
915
+
916
+ /// Poisson distribution
917
+
918
+ /// This function generates a Poisson distribution random number with
919
+ /// parameter \c lambda.
920
+ ///
921
+ /// The probability mass function of this distribusion is
922
+ /// \f[ \frac{e^{-\lambda}\lambda^k}{k!} \f]
923
+ /// \note The algorithm is taken from the book of Donald E. Knuth titled
924
+ /// ''Seminumerical Algorithms'' (1969). Its running time is linear in the
925
+ /// return value.
926
+
927
+ int poisson(double lambda)
928
+ {
929
+ const double l = std::exp(-lambda);
930
+ int k=0;
931
+ double p = 1.0;
932
+ do {
933
+ k++;
934
+ p*=real<double>();
935
+ } while (p>=l);
936
+ return k-1;
937
+ }
938
+
939
+ ///@}
940
+
941
+ ///\name Two Dimensional Distributions
942
+ ///
943
+ ///@{
944
+
945
+ /// Uniform distribution on the full unit circle
946
+
947
+ /// Uniform distribution on the full unit circle.
948
+ ///
949
+ dim2::Point<double> disc()
950
+ {
951
+ double V1,V2;
952
+ do {
953
+ V1=2*real<double>()-1;
954
+ V2=2*real<double>()-1;
955
+
956
+ } while(V1*V1+V2*V2>=1);
957
+ return dim2::Point<double>(V1,V2);
958
+ }
959
+ /// A kind of two dimensional normal (Gauss) distribution
960
+
961
+ /// This function provides a turning symmetric two-dimensional distribution.
962
+ /// Both coordinates are of standard normal distribution, but they are not
963
+ /// independent.
964
+ ///
965
+ /// \note The coordinates are the two random variables provided by
966
+ /// the Box-Muller method.
967
+ dim2::Point<double> gauss2()
968
+ {
969
+ double V1,V2,S;
970
+ do {
971
+ V1=2*real<double>()-1;
972
+ V2=2*real<double>()-1;
973
+ S=V1*V1+V2*V2;
974
+ } while(S>=1);
975
+ double W=std::sqrt(-2*std::log(S)/S);
976
+ return dim2::Point<double>(W*V1,W*V2);
977
+ }
978
+ /// A kind of two dimensional exponential distribution
979
+
980
+ /// This function provides a turning symmetric two-dimensional distribution.
981
+ /// The x-coordinate is of conditionally exponential distribution
982
+ /// with the condition that x is positive and y=0. If x is negative and
983
+ /// y=0 then, -x is of exponential distribution. The same is true for the
984
+ /// y-coordinate.
985
+ dim2::Point<double> exponential2()
986
+ {
987
+ double V1,V2,S;
988
+ do {
989
+ V1=2*real<double>()-1;
990
+ V2=2*real<double>()-1;
991
+ S=V1*V1+V2*V2;
992
+ } while(S>=1);
993
+ double W=-std::log(S)/S;
994
+ return dim2::Point<double>(W*V1,W*V2);
995
+ }
996
+
997
+ ///@}
998
+ };
999
+
1000
+
1001
+ extern Random rnd;
1002
+
1003
+ }
1004
+
1005
+ #endif