random.nim 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702
  1. #
  2. #
  3. # Nim's Runtime Library
  4. # (c) Copyright 2017 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## Nim's standard random number generator.
  10. ##
  11. ## Its implementation is based on the ``xoroshiro128+``
  12. ## (xor/rotate/shift/rotate) library.
  13. ## * More information: http://xoroshiro.di.unimi.it/
  14. ## * C implementation: http://xoroshiro.di.unimi.it/xoroshiro128plus.c
  15. ##
  16. ## **Do not use this module for cryptographic purposes!**
  17. ##
  18. ## Basic usage
  19. ## ===========
  20. ##
  21. ## To get started, here are some examples:
  22. ##
  23. ## .. code-block::
  24. ##
  25. ## import random
  26. ##
  27. ## # Call randomize() once to initialize the default random number generator
  28. ## # If this is not called, the same results will occur every time these
  29. ## # examples are run
  30. ## randomize()
  31. ##
  32. ## # Pick a number between 0 and 100
  33. ## let num = rand(100)
  34. ## echo num
  35. ##
  36. ## # Roll a six-sided die
  37. ## let roll = rand(1..6)
  38. ## echo roll
  39. ##
  40. ## # Pick a marble from a bag
  41. ## let marbles = ["red", "blue", "green", "yellow", "purple"]
  42. ## let pick = sample(marbles)
  43. ## echo pick
  44. ##
  45. ## # Shuffle some cards
  46. ## var cards = ["Ace", "King", "Queen", "Jack", "Ten"]
  47. ## shuffle(cards)
  48. ## echo cards
  49. ##
  50. ## These examples all use the default random number generator. The
  51. ## `Rand type<#Rand>`_ represents the state of a random number generator.
  52. ## For convenience, this module contains a default Rand state that corresponds
  53. ## to the default random number generator. Most procs in this module which do
  54. ## not take in a Rand parameter, including those called in the above examples,
  55. ## use the default generator. Those procs are **not** thread-safe.
  56. ##
  57. ## Note that the default generator always starts in the same state.
  58. ## The `randomize proc<#randomize>`_ can be called to initialize the default
  59. ## generator with a seed based on the current time, and it only needs to be
  60. ## called once before the first usage of procs from this module. If
  61. ## ``randomize`` is not called, then the default generator will always produce
  62. ## the same results.
  63. ##
  64. ## Generators that are independent of the default one can be created with the
  65. ## `initRand proc<#initRand,int64>`_.
  66. ##
  67. ## Again, it is important to remember that this module must **not** be used for
  68. ## cryptographic applications.
  69. ##
  70. ## See also
  71. ## ========
  72. ## * `math module<math.html>`_ for basic math routines
  73. ## * `mersenne module<mersenne.html>`_ for the Mersenne Twister random number
  74. ## generator
  75. ## * `stats module<stats.html>`_ for statistical analysis
  76. ## * `list of cryptographic and hashing modules
  77. ## <lib.html#pure-libraries-hashing>`_
  78. ## in the standard library
  79. import algorithm, math
  80. import std/private/since
  81. include "system/inclrtl"
  82. {.push debugger: off.}
  83. when defined(js):
  84. type Ui = uint32
  85. const randMax = 4_294_967_295u32
  86. else:
  87. type Ui = uint64
  88. const randMax = 18_446_744_073_709_551_615u64
  89. type
  90. Rand* = object ## State of a random number generator.
  91. ##
  92. ## Create a new Rand state using the `initRand proc<#initRand,int64>`_.
  93. ##
  94. ## The module contains a default Rand state for convenience.
  95. ## It corresponds to the default random number generator's state.
  96. ## The default Rand state always starts with the same values, but the
  97. ## `randomize proc<#randomize>`_ can be used to seed the default generator
  98. ## with a value based on the current time.
  99. ##
  100. ## Many procs have two variations: one that takes in a Rand parameter and
  101. ## another that uses the default generator. The procs that use the default
  102. ## generator are **not** thread-safe!
  103. a0, a1: Ui
  104. when defined(js):
  105. var state = Rand(
  106. a0: 0x69B4C98Cu32,
  107. a1: 0xFED1DD30u32) # global for backwards compatibility
  108. else:
  109. # racy for multi-threading but good enough for now:
  110. var state = Rand(
  111. a0: 0x69B4C98CB8530805u64,
  112. a1: 0xFED1DD3004688D67CAu64) # global for backwards compatibility
  113. proc rotl(x, k: Ui): Ui =
  114. result = (x shl k) or (x shr (Ui(64) - k))
  115. proc next*(r: var Rand): uint64 =
  116. ## Computes a random ``uint64`` number using the given state.
  117. ##
  118. ## See also:
  119. ## * `rand proc<#rand,Rand,Natural>`_ that returns an integer between zero and
  120. ## a given upper bound
  121. ## * `rand proc<#rand,Rand,range[]>`_ that returns a float
  122. ## * `rand proc<#rand,Rand,HSlice[T,T]>`_ that accepts a slice
  123. ## * `rand proc<#rand,typedesc[T]>`_ that accepts an integer or range type
  124. ## * `skipRandomNumbers proc<#skipRandomNumbers,Rand>`_
  125. runnableExamples:
  126. var r = initRand(2019)
  127. doAssert r.next() == 138_744_656_611_299'u64
  128. doAssert r.next() == 979_810_537_855_049_344'u64
  129. doAssert r.next() == 3_628_232_584_225_300_704'u64
  130. let s0 = r.a0
  131. var s1 = r.a1
  132. result = s0 + s1
  133. s1 = s1 xor s0
  134. r.a0 = rotl(s0, 55) xor s1 xor (s1 shl 14) # a, b
  135. r.a1 = rotl(s1, 36) # c
  136. proc skipRandomNumbers*(s: var Rand) =
  137. ## The jump function for the generator.
  138. ##
  139. ## This proc is equivalent to 2^64 calls to `next<#next,Rand>`_, and it can
  140. ## be used to generate 2^64 non-overlapping subsequences for parallel
  141. ## computations.
  142. ##
  143. ## When multiple threads are generating random numbers, each thread must
  144. ## own the `Rand<#Rand>`_ state it is using so that the thread can safely
  145. ## obtain random numbers. However, if each thread creates its own Rand state,
  146. ## the subsequences of random numbers that each thread generates may overlap,
  147. ## even if the provided seeds are unique. This is more likely to happen as the
  148. ## number of threads and amount of random numbers generated increases.
  149. ##
  150. ## If many threads will generate random numbers concurrently, it is better to
  151. ## create a single Rand state and pass it to each thread. After passing the
  152. ## Rand state to a thread, call this proc before passing it to the next one.
  153. ## By using the Rand state this way, the subsequences of random numbers
  154. ## generated in each thread will never overlap as long as no thread generates
  155. ## more than 2^64 random numbers.
  156. ##
  157. ## The following example below demonstrates this pattern:
  158. ##
  159. ## .. code-block::
  160. ## # Compile this example with --threads:on
  161. ## import random
  162. ## import threadpool
  163. ##
  164. ## const spawns = 4
  165. ## const numbers = 100000
  166. ##
  167. ## proc randomSum(rand: Rand): int =
  168. ## var r = rand
  169. ## for i in 1..numbers:
  170. ## result += rand(1..10)
  171. ##
  172. ## var r = initRand(2019)
  173. ## var vals: array[spawns, FlowVar[int]]
  174. ## for val in vals.mitems:
  175. ## val = spawn(randomSum(r))
  176. ## r.skipRandomNumbers()
  177. ##
  178. ## for val in vals:
  179. ## echo ^val
  180. ##
  181. ## See also:
  182. ## * `next proc<#next,Rand>`_
  183. when defined(js):
  184. const helper = [0xbeac0467u32, 0xd86b048bu32]
  185. else:
  186. const helper = [0xbeac0467eba5facbu64, 0xd86b048b86aa9922u64]
  187. var
  188. s0 = Ui 0
  189. s1 = Ui 0
  190. for i in 0..high(helper):
  191. for b in 0 ..< 64:
  192. if (helper[i] and (Ui(1) shl Ui(b))) != 0:
  193. s0 = s0 xor s.a0
  194. s1 = s1 xor s.a1
  195. discard next(s)
  196. s.a0 = s0
  197. s.a1 = s1
  198. proc rand*(r: var Rand; max: Natural): int {.benign.} =
  199. ## Returns a random integer in the range `0..max` using the given state.
  200. ##
  201. ## See also:
  202. ## * `rand proc<#rand,int>`_ that returns an integer using the default
  203. ## random number generator
  204. ## * `rand proc<#rand,Rand,range[]>`_ that returns a float
  205. ## * `rand proc<#rand,Rand,HSlice[T,T]>`_ that accepts a slice
  206. ## * `rand proc<#rand,typedesc[T]>`_ that accepts an integer or range type
  207. runnableExamples:
  208. var r = initRand(123)
  209. doAssert r.rand(100) == 0
  210. doAssert r.rand(100) == 96
  211. doAssert r.rand(100) == 66
  212. if max == 0: return
  213. while true:
  214. let x = next(r)
  215. if x <= randMax - (randMax mod Ui(max)):
  216. return int(x mod (uint64(max)+1u64))
  217. proc rand*(max: int): int {.benign.} =
  218. ## Returns a random integer in the range `0..max`.
  219. ##
  220. ## If `randomize<#randomize>`_ has not been called, the sequence of random
  221. ## numbers returned from this proc will always be the same.
  222. ##
  223. ## This proc uses the default random number generator. Thus, it is **not**
  224. ## thread-safe.
  225. ##
  226. ## See also:
  227. ## * `rand proc<#rand,Rand,Natural>`_ that returns an integer using a
  228. ## provided state
  229. ## * `rand proc<#rand,float>`_ that returns a float
  230. ## * `rand proc<#rand,HSlice[T,T]>`_ that accepts a slice
  231. ## * `rand proc<#rand,typedesc[T]>`_ that accepts an integer or range type
  232. runnableExamples:
  233. randomize(123)
  234. doAssert rand(100) == 0
  235. doAssert rand(100) == 96
  236. doAssert rand(100) == 66
  237. rand(state, max)
  238. proc rand*(r: var Rand; max: range[0.0 .. high(float)]): float {.benign.} =
  239. ## Returns a random floating point number in the range `0.0..max`
  240. ## using the given state.
  241. ##
  242. ## See also:
  243. ## * `rand proc<#rand,float>`_ that returns a float using the default
  244. ## random number generator
  245. ## * `rand proc<#rand,Rand,Natural>`_ that returns an integer
  246. ## * `rand proc<#rand,Rand,HSlice[T,T]>`_ that accepts a slice
  247. ## * `rand proc<#rand,typedesc[T]>`_ that accepts an integer or range type
  248. runnableExamples:
  249. var r = initRand(234)
  250. let f = r.rand(1.0)
  251. ## f = 8.717181376738381e-07
  252. let x = next(r)
  253. when defined(js):
  254. result = (float(x) / float(high(uint32))) * max
  255. else:
  256. let u = (0x3FFu64 shl 52u64) or (x shr 12u64)
  257. result = (cast[float](u) - 1.0) * max
  258. proc rand*(max: float): float {.benign.} =
  259. ## Returns a random floating point number in the range `0.0..max`.
  260. ##
  261. ## If `randomize<#randomize>`_ has not been called, the sequence of random
  262. ## numbers returned from this proc will always be the same.
  263. ##
  264. ## This proc uses the default random number generator. Thus, it is **not**
  265. ## thread-safe.
  266. ##
  267. ## See also:
  268. ## * `rand proc<#rand,Rand,range[]>`_ that returns a float using a
  269. ## provided state
  270. ## * `rand proc<#rand,int>`_ that returns an integer
  271. ## * `rand proc<#rand,HSlice[T,T]>`_ that accepts a slice
  272. ## * `rand proc<#rand,typedesc[T]>`_ that accepts an integer or range type
  273. runnableExamples:
  274. randomize(234)
  275. let f = rand(1.0)
  276. ## f = 8.717181376738381e-07
  277. rand(state, max)
  278. proc rand*[T: Ordinal or SomeFloat](r: var Rand; x: HSlice[T, T]): T =
  279. ## For a slice `a..b`, returns a value in the range `a..b` using the given
  280. ## state.
  281. ##
  282. ## Allowed types for `T` are integers, floats, and enums without holes.
  283. ##
  284. ## See also:
  285. ## * `rand proc<#rand,HSlice[T,T]>`_ that accepts a slice and uses the
  286. ## default random number generator
  287. ## * `rand proc<#rand,Rand,Natural>`_ that returns an integer
  288. ## * `rand proc<#rand,Rand,range[]>`_ that returns a float
  289. ## * `rand proc<#rand,typedesc[T]>`_ that accepts an integer or range type
  290. runnableExamples:
  291. var r = initRand(345)
  292. doAssert r.rand(1..6) == 4
  293. doAssert r.rand(1..6) == 4
  294. doAssert r.rand(1..6) == 6
  295. let f = r.rand(-1.0 .. 1.0)
  296. ## f = 0.8741183448756229
  297. when T is SomeFloat:
  298. result = rand(r, x.b - x.a) + x.a
  299. else: # Integers and Enum types
  300. result = T(rand(r, int(x.b) - int(x.a)) + int(x.a))
  301. proc rand*[T: Ordinal or SomeFloat](x: HSlice[T, T]): T =
  302. ## For a slice `a..b`, returns a value in the range `a..b`.
  303. ##
  304. ## Allowed types for `T` are integers, floats, and enums without holes.
  305. ##
  306. ## If `randomize<#randomize>`_ has not been called, the sequence of random
  307. ## numbers returned from this proc will always be the same.
  308. ##
  309. ## This proc uses the default random number generator. Thus, it is **not**
  310. ## thread-safe.
  311. ##
  312. ## See also:
  313. ## * `rand proc<#rand,Rand,HSlice[T,T]>`_ that accepts a slice and uses
  314. ## a provided state
  315. ## * `rand proc<#rand,int>`_ that returns an integer
  316. ## * `rand proc<#rand,float>`_ that returns a floating point number
  317. ## * `rand proc<#rand,typedesc[T]>`_ that accepts an integer or range type
  318. runnableExamples:
  319. randomize(345)
  320. doAssert rand(1..6) == 4
  321. doAssert rand(1..6) == 4
  322. doAssert rand(1..6) == 6
  323. result = rand(state, x)
  324. proc rand*[T: SomeInteger](t: typedesc[T]): T =
  325. ## Returns a random integer in the range `low(T)..high(T)`.
  326. ##
  327. ## If `randomize<#randomize>`_ has not been called, the sequence of random
  328. ## numbers returned from this proc will always be the same.
  329. ##
  330. ## This proc uses the default random number generator. Thus, it is **not**
  331. ## thread-safe.
  332. ##
  333. ## See also:
  334. ## * `rand proc<#rand,int>`_ that returns an integer
  335. ## * `rand proc<#rand,float>`_ that returns a floating point number
  336. ## * `rand proc<#rand,HSlice[T,T]>`_ that accepts a slice
  337. runnableExamples:
  338. randomize(567)
  339. doAssert rand(int8) == 55
  340. doAssert rand(int8) == -42
  341. doAssert rand(int8) == 43
  342. doAssert rand(uint32) == 578980729'u32
  343. doAssert rand(uint32) == 4052940463'u32
  344. doAssert rand(uint32) == 2163872389'u32
  345. doAssert rand(range[1..16]) == 11
  346. doAssert rand(range[1..16]) == 4
  347. doAssert rand(range[1..16]) == 16
  348. when T is range:
  349. result = rand(state, low(T)..high(T))
  350. else:
  351. result = cast[T](state.next)
  352. proc sample*[T](r: var Rand; s: set[T]): T =
  353. ## Returns a random element from the set ``s`` using the given state.
  354. ##
  355. ## See also:
  356. ## * `sample proc<#sample,set[T]>`_ that uses the default random number
  357. ## generator
  358. ## * `sample proc<#sample,Rand,openArray[T]>`_ for openarrays
  359. ## * `sample proc<#sample,Rand,openArray[T],openArray[U]>`_ that uses a
  360. ## cumulative distribution function
  361. runnableExamples:
  362. var r = initRand(987)
  363. let s = {1, 3, 5, 7, 9}
  364. doAssert r.sample(s) == 5
  365. doAssert r.sample(s) == 7
  366. doAssert r.sample(s) == 1
  367. assert card(s) != 0
  368. var i = rand(r, card(s) - 1)
  369. for e in s:
  370. if i == 0: return e
  371. dec(i)
  372. proc sample*[T](s: set[T]): T =
  373. ## Returns a random element from the set ``s``.
  374. ##
  375. ## If `randomize<#randomize>`_ has not been called, the order of outcomes
  376. ## from this proc will always be the same.
  377. ##
  378. ## This proc uses the default random number generator. Thus, it is **not**
  379. ## thread-safe.
  380. ##
  381. ## See also:
  382. ## * `sample proc<#sample,Rand,set[T]>`_ that uses a provided state
  383. ## * `sample proc<#sample,openArray[T]>`_ for openarrays
  384. ## * `sample proc<#sample,openArray[T],openArray[U]>`_ that uses a
  385. ## cumulative distribution function
  386. runnableExamples:
  387. randomize(987)
  388. let s = {1, 3, 5, 7, 9}
  389. doAssert sample(s) == 5
  390. doAssert sample(s) == 7
  391. doAssert sample(s) == 1
  392. sample(state, s)
  393. proc sample*[T](r: var Rand; a: openArray[T]): T =
  394. ## Returns a random element from ``a`` using the given state.
  395. ##
  396. ## See also:
  397. ## * `sample proc<#sample,openArray[T]>`_ that uses the default
  398. ## random number generator
  399. ## * `sample proc<#sample,Rand,openArray[T],openArray[U]>`_ that uses a
  400. ## cumulative distribution function
  401. ## * `sample proc<#sample,Rand,set[T]>`_ for sets
  402. runnableExamples:
  403. let marbles = ["red", "blue", "green", "yellow", "purple"]
  404. var r = initRand(456)
  405. doAssert r.sample(marbles) == "blue"
  406. doAssert r.sample(marbles) == "yellow"
  407. doAssert r.sample(marbles) == "red"
  408. result = a[r.rand(a.low..a.high)]
  409. proc sample*[T](a: openArray[T]): T =
  410. ## Returns a random element from ``a``.
  411. ##
  412. ## If `randomize<#randomize>`_ has not been called, the order of outcomes
  413. ## from this proc will always be the same.
  414. ##
  415. ## This proc uses the default random number generator. Thus, it is **not**
  416. ## thread-safe.
  417. ##
  418. ## See also:
  419. ## * `sample proc<#sample,Rand,openArray[T]>`_ that uses a provided state
  420. ## * `sample proc<#sample,openArray[T],openArray[U]>`_ that uses a
  421. ## cumulative distribution function
  422. ## * `sample proc<#sample,set[T]>`_ for sets
  423. runnableExamples:
  424. let marbles = ["red", "blue", "green", "yellow", "purple"]
  425. randomize(456)
  426. doAssert sample(marbles) == "blue"
  427. doAssert sample(marbles) == "yellow"
  428. doAssert sample(marbles) == "red"
  429. result = a[rand(a.low..a.high)]
  430. proc sample*[T, U](r: var Rand; a: openArray[T]; cdf: openArray[U]): T =
  431. ## Returns an element from ``a`` using a cumulative distribution function
  432. ## (CDF) and the given state.
  433. ##
  434. ## The ``cdf`` argument does not have to be normalized, and it could contain
  435. ## any type of elements that can be converted to a ``float``. It must be
  436. ## the same length as ``a``. Each element in ``cdf`` should be greater than
  437. ## or equal to the previous element.
  438. ##
  439. ## The outcome of the `cumsum<math.html#cumsum,openArray[T]>`_ proc and the
  440. ## return value of the `cumsummed<math.html#cumsummed,openArray[T]>`_ proc,
  441. ## which are both in the math module, can be used as the ``cdf`` argument.
  442. ##
  443. ## See also:
  444. ## * `sample proc<#sample,openArray[T],openArray[U]>`_ that also utilizes
  445. ## a CDF but uses the default random number generator
  446. ## * `sample proc<#sample,Rand,openArray[T]>`_ that does not use a CDF
  447. ## * `sample proc<#sample,Rand,set[T]>`_ for sets
  448. runnableExamples:
  449. from math import cumsummed
  450. let marbles = ["red", "blue", "green", "yellow", "purple"]
  451. let count = [1, 6, 8, 3, 4]
  452. let cdf = count.cumsummed
  453. var r = initRand(789)
  454. doAssert r.sample(marbles, cdf) == "red"
  455. doAssert r.sample(marbles, cdf) == "green"
  456. doAssert r.sample(marbles, cdf) == "blue"
  457. assert(cdf.len == a.len) # Two basic sanity checks.
  458. assert(float(cdf[^1]) > 0.0)
  459. #While we could check cdf[i-1] <= cdf[i] for i in 1..cdf.len, that could get
  460. #awfully expensive even in debugging modes.
  461. let u = r.rand(float(cdf[^1]))
  462. a[cdf.upperBound(U(u))]
  463. proc sample*[T, U](a: openArray[T]; cdf: openArray[U]): T =
  464. ## Returns an element from ``a`` using a cumulative distribution function
  465. ## (CDF).
  466. ##
  467. ## This proc works similarly to
  468. ## `sample[T, U](Rand, openArray[T], openArray[U])
  469. ## <#sample,Rand,openArray[T],openArray[U]>`_.
  470. ## See that proc's documentation for more details.
  471. ##
  472. ## If `randomize<#randomize>`_ has not been called, the order of outcomes
  473. ## from this proc will always be the same.
  474. ##
  475. ## This proc uses the default random number generator. Thus, it is **not**
  476. ## thread-safe.
  477. ##
  478. ## See also:
  479. ## * `sample proc<#sample,Rand,openArray[T],openArray[U]>`_ that also utilizes
  480. ## a CDF but uses a provided state
  481. ## * `sample proc<#sample,openArray[T]>`_ that does not use a CDF
  482. ## * `sample proc<#sample,set[T]>`_ for sets
  483. runnableExamples:
  484. from math import cumsummed
  485. let marbles = ["red", "blue", "green", "yellow", "purple"]
  486. let count = [1, 6, 8, 3, 4]
  487. let cdf = count.cumsummed
  488. randomize(789)
  489. doAssert sample(marbles, cdf) == "red"
  490. doAssert sample(marbles, cdf) == "green"
  491. doAssert sample(marbles, cdf) == "blue"
  492. state.sample(a, cdf)
  493. proc gauss*(r: var Rand; mu = 0.0; sigma = 1.0): float {.since: (1, 3).} =
  494. ## Returns a Gaussian random variate,
  495. ## with mean ``mu`` and standard deviation ``sigma``
  496. ## using the given state.
  497. # Ratio of uniforms method for normal
  498. # http://www2.econ.osaka-u.ac.jp/~tanizaki/class/2013/econome3/13.pdf
  499. const K = sqrt(2 / E)
  500. var
  501. a = 0.0
  502. b = 0.0
  503. while true:
  504. a = rand(r, 1.0)
  505. b = (2.0 * rand(r, 1.0) - 1.0) * K
  506. if b * b <= -4.0 * a * a * ln(a): break
  507. result = mu + sigma * (b / a)
  508. proc gauss*(mu = 0.0, sigma = 1.0): float {.since: (1, 3).} =
  509. ## Returns a Gaussian random variate,
  510. ## with mean ``mu`` and standard deviation ``sigma``.
  511. ##
  512. ## If `randomize<#randomize>`_ has not been called, the order of outcomes
  513. ## from this proc will always be the same.
  514. ##
  515. ## This proc uses the default random number generator. Thus, it is **not**
  516. ## thread-safe.
  517. result = gauss(state, mu, sigma)
  518. proc initRand*(seed: int64): Rand =
  519. ## Initializes a new `Rand<#Rand>`_ state using the given seed.
  520. ##
  521. ## `seed` must not be zero. Providing a specific seed will produce
  522. ## the same results for that seed each time.
  523. ##
  524. ## The resulting state is independent of the default random number
  525. ## generator's state.
  526. ##
  527. ## See also:
  528. ## * `randomize proc<#randomize,int64>`_ that accepts a seed for the default
  529. ## random number generator
  530. ## * `randomize proc<#randomize>`_ that initializes the default random
  531. ## number generator using the current time
  532. runnableExamples:
  533. from times import getTime, toUnix, nanosecond
  534. var r1 = initRand(123)
  535. let now = getTime()
  536. var r2 = initRand(now.toUnix * 1_000_000_000 + now.nanosecond)
  537. doAssert seed != 0 # 0 causes `rand(int)` to always return 0 for example.
  538. result.a0 = Ui(seed shr 16)
  539. result.a1 = Ui(seed and 0xffff)
  540. discard next(result)
  541. proc randomize*(seed: int64) {.benign.} =
  542. ## Initializes the default random number generator with the given seed.
  543. ##
  544. ## `seed` must not be zero. Providing a specific seed will produce
  545. ## the same results for that seed each time.
  546. ##
  547. ## See also:
  548. ## * `initRand proc<#initRand,int64>`_
  549. ## * `randomize proc<#randomize>`_ that uses the current time instead
  550. runnableExamples:
  551. from times import getTime, toUnix, nanosecond
  552. randomize(123)
  553. let now = getTime()
  554. randomize(now.toUnix * 1_000_000_000 + now.nanosecond)
  555. state = initRand(seed)
  556. proc shuffle*[T](r: var Rand; x: var openArray[T]) =
  557. ## Shuffles a sequence of elements in-place using the given state.
  558. ##
  559. ## See also:
  560. ## * `shuffle proc<#shuffle,openArray[T]>`_ that uses the default
  561. ## random number generator
  562. runnableExamples:
  563. var cards = ["Ace", "King", "Queen", "Jack", "Ten"]
  564. var r = initRand(678)
  565. r.shuffle(cards)
  566. doAssert cards == ["King", "Ace", "Queen", "Ten", "Jack"]
  567. for i in countdown(x.high, 1):
  568. let j = r.rand(i)
  569. swap(x[i], x[j])
  570. proc shuffle*[T](x: var openArray[T]) =
  571. ## Shuffles a sequence of elements in-place.
  572. ##
  573. ## If `randomize<#randomize>`_ has not been called, the order of outcomes
  574. ## from this proc will always be the same.
  575. ##
  576. ## This proc uses the default random number generator. Thus, it is **not**
  577. ## thread-safe.
  578. ##
  579. ## See also:
  580. ## * `shuffle proc<#shuffle,Rand,openArray[T]>`_ that uses a provided state
  581. runnableExamples:
  582. var cards = ["Ace", "King", "Queen", "Jack", "Ten"]
  583. randomize(678)
  584. shuffle(cards)
  585. doAssert cards == ["King", "Ace", "Queen", "Ten", "Jack"]
  586. shuffle(state, x)
  587. when not defined(nimscript) and not defined(standalone):
  588. import times
  589. proc randomize*() {.benign.} =
  590. ## Initializes the default random number generator with a value based on
  591. ## the current time.
  592. ##
  593. ## This proc only needs to be called once, and it should be called before
  594. ## the first usage of procs from this module that use the default random
  595. ## number generator.
  596. ##
  597. ## **Note:** Does not work for NimScript.
  598. ##
  599. ## See also:
  600. ## * `randomize proc<#randomize,int64>`_ that accepts a seed
  601. ## * `initRand proc<#initRand,int64>`_
  602. when defined(js):
  603. let time = int64(times.epochTime() * 1000) and 0x7fff_ffff
  604. randomize(time)
  605. else:
  606. let now = times.getTime()
  607. randomize(convert(Seconds, Nanoseconds, now.toUnix) + now.nanosecond)
  608. {.pop.}
  609. when isMainModule:
  610. import stats
  611. proc main =
  612. var occur: array[1000, int]
  613. var x = 8234
  614. for i in 0..100_000:
  615. x = rand(high(occur))
  616. inc occur[x]
  617. for i, oc in occur:
  618. if oc < 69:
  619. doAssert false, "too few occurrences of " & $i
  620. elif oc > 150:
  621. doAssert false, "too many occurrences of " & $i
  622. when false:
  623. var rs: RunningStat
  624. for j in 1..5:
  625. for i in 1 .. 1_000:
  626. rs.push(gauss())
  627. echo("mean: ", rs.mean,
  628. " stdDev: ", rs.standardDeviation(),
  629. " min: ", rs.min,
  630. " max: ", rs.max)
  631. rs.clear()
  632. var a = [0, 1]
  633. shuffle(a)
  634. doAssert a[0] == 1
  635. doAssert a[1] == 0
  636. doAssert rand(0) == 0
  637. doAssert sample("a") == 'a'
  638. when compileOption("rangeChecks"):
  639. try:
  640. discard rand(-1)
  641. doAssert false
  642. except RangeDefect:
  643. discard
  644. try:
  645. discard rand(-1.0)
  646. doAssert false
  647. except RangeDefect:
  648. discard
  649. # don't use causes integer overflow
  650. doAssert compiles(rand[int](low(int) .. high(int)))
  651. main()