random.nim 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748
  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 (RNG).
  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. runnableExamples:
  22. # Call randomize() once to initialize the default random number generator.
  23. # If this is not called, the same results will occur every time these
  24. # examples are run.
  25. randomize()
  26. # Pick a number in 0..100.
  27. let num = rand(100)
  28. doAssert num in 0..100
  29. # Roll a six-sided die.
  30. let roll = rand(1..6)
  31. doAssert roll in 1..6
  32. # Pick a marble from a bag.
  33. let marbles = ["red", "blue", "green", "yellow", "purple"]
  34. let pick = sample(marbles)
  35. doAssert pick in marbles
  36. # Shuffle some cards.
  37. var cards = ["Ace", "King", "Queen", "Jack", "Ten"]
  38. shuffle(cards)
  39. doAssert cards.len == 5
  40. ## These examples all use the default RNG. The
  41. ## `Rand type <#Rand>`_ represents the state of an RNG.
  42. ## For convenience, this module contains a default Rand state that corresponds
  43. ## to the default RNG. Most procs in this module which do
  44. ## not take in a Rand parameter, including those called in the above examples,
  45. ## use the default generator. Those procs are **not** thread-safe.
  46. ##
  47. ## Note that the default generator always starts in the same state.
  48. ## The `randomize proc <#randomize>`_ can be called to initialize the default
  49. ## generator with a seed based on the current time, and it only needs to be
  50. ## called once before the first usage of procs from this module. If
  51. ## `randomize` is not called, the default generator will always produce
  52. ## the same results.
  53. ##
  54. ## RNGs that are independent of the default one can be created with the
  55. ## `initRand proc <#initRand,int64>`_.
  56. ##
  57. ## Again, it is important to remember that this module must **not** be used for
  58. ## cryptographic applications.
  59. ##
  60. ## See also
  61. ## ========
  62. ## * `std/sysrand module <sysrand.html>`_ for a cryptographically secure pseudorandom number generator
  63. ## * `math module <math.html>`_ for basic math routines
  64. ## * `stats module <stats.html>`_ for statistical analysis
  65. ## * `list of cryptographic and hashing modules <lib.html#pure-libraries-hashing>`_
  66. ## in the standard library
  67. import algorithm, math
  68. import std/private/[since, jsutils]
  69. when defined(nimPreviewSlimSystem):
  70. import std/[assertions]
  71. include system/inclrtl
  72. {.push debugger: off.}
  73. when defined(js):
  74. type Ui = uint32
  75. const randMax = 4_294_967_295u32
  76. else:
  77. type Ui = uint64
  78. const randMax = 18_446_744_073_709_551_615u64
  79. type
  80. Rand* = object ## State of a random number generator.
  81. ##
  82. ## Create a new Rand state using the `initRand proc <#initRand,int64>`_.
  83. ##
  84. ## The module contains a default Rand state for convenience.
  85. ## It corresponds to the default RNG's state.
  86. ## The default Rand state always starts with the same values, but the
  87. ## `randomize proc <#randomize>`_ can be used to seed the default generator
  88. ## with a value based on the current time.
  89. ##
  90. ## Many procs have two variations: one that takes in a Rand parameter and
  91. ## another that uses the default generator. The procs that use the default
  92. ## generator are **not** thread-safe!
  93. a0, a1: Ui
  94. when defined(js):
  95. var state = Rand(
  96. a0: 0x69B4C98Cu32,
  97. a1: 0xFED1DD30u32) # global for backwards compatibility
  98. else:
  99. const DefaultRandSeed = Rand(
  100. a0: 0x69B4C98CB8530805u64,
  101. a1: 0xFED1DD3004688D67CAu64)
  102. # racy for multi-threading but good enough for now:
  103. var state = DefaultRandSeed # global for backwards compatibility
  104. func isValid(r: Rand): bool {.inline.} =
  105. ## Check whether state of `r` is valid.
  106. ##
  107. ## In `xoroshiro128+`, if all bits of `a0` and `a1` are zero,
  108. ## they are always zero after calling `next(r: var Rand)`.
  109. not (r.a0 == 0 and r.a1 == 0)
  110. since (1, 5):
  111. template randState*(): untyped =
  112. ## Makes the default Rand state accessible from other modules.
  113. ## Useful for module authors.
  114. state
  115. proc rotl(x, k: Ui): Ui =
  116. result = (x shl k) or (x shr (Ui(64) - k))
  117. proc next*(r: var Rand): uint64 =
  118. ## Computes a random `uint64` number using the given state.
  119. ##
  120. ## **See also:**
  121. ## * `rand proc<#rand,Rand,Natural>`_ that returns an integer between zero and
  122. ## a given upper bound
  123. ## * `rand proc<#rand,Rand,range[]>`_ that returns a float
  124. ## * `rand proc<#rand,Rand,HSlice[T: Ordinal or float or float32 or float64,T: Ordinal or float or float32 or float64]>`_
  125. ## that accepts a slice
  126. ## * `rand proc<#rand,typedesc[T]>`_ that accepts an integer or range type
  127. ## * `skipRandomNumbers proc<#skipRandomNumbers,Rand>`_
  128. runnableExamples("-r:off"):
  129. var r = initRand(2019)
  130. assert r.next() == 13223559681708962501'u64 # implementation defined
  131. assert r.next() == 7229677234260823147'u64 # ditto
  132. let s0 = r.a0
  133. var s1 = r.a1
  134. result = s0 + s1
  135. s1 = s1 xor s0
  136. r.a0 = rotl(s0, 55) xor s1 xor (s1 shl 14) # a, b
  137. r.a1 = rotl(s1, 36) # c
  138. proc skipRandomNumbers*(s: var Rand) =
  139. ## The jump function for the generator.
  140. ##
  141. ## This proc is equivalent to `2^64` calls to `next <#next,Rand>`_, and it can
  142. ## be used to generate `2^64` non-overlapping subsequences for parallel
  143. ## computations.
  144. ##
  145. ## When multiple threads are generating random numbers, each thread must
  146. ## own the `Rand <#Rand>`_ state it is using so that the thread can safely
  147. ## obtain random numbers. However, if each thread creates its own Rand state,
  148. ## the subsequences of random numbers that each thread generates may overlap,
  149. ## even if the provided seeds are unique. This is more likely to happen as the
  150. ## number of threads and amount of random numbers generated increases.
  151. ##
  152. ## If many threads will generate random numbers concurrently, it is better to
  153. ## create a single Rand state and pass it to each thread. After passing the
  154. ## Rand state to a thread, call this proc before passing it to the next one.
  155. ## By using the Rand state this way, the subsequences of random numbers
  156. ## generated in each thread will never overlap as long as no thread generates
  157. ## more than `2^64` random numbers.
  158. ##
  159. ## **See also:**
  160. ## * `next proc<#next,Rand>`_
  161. runnableExamples("--threads:on"):
  162. import std/random
  163. const numbers = 100000
  164. var
  165. thr: array[0..3, Thread[(Rand, int)]]
  166. vals: array[0..3, int]
  167. proc randomSum(params: tuple[r: Rand, index: int]) {.thread.} =
  168. var r = params.r
  169. var s = 0 # avoid cache thrashing
  170. for i in 1..numbers:
  171. s += r.rand(0..10)
  172. vals[params.index] = s
  173. var r = initRand(2019)
  174. for i in 0..<thr.len:
  175. createThread(thr[i], randomSum, (r, i))
  176. r.skipRandomNumbers()
  177. joinThreads(thr)
  178. for val in vals:
  179. doAssert abs(val - numbers * 5) / numbers < 0.1
  180. doAssert vals == [501737, 497901, 500683, 500157]
  181. when defined(js):
  182. const helper = [0xbeac0467u32, 0xd86b048bu32]
  183. else:
  184. const helper = [0xbeac0467eba5facbu64, 0xd86b048b86aa9922u64]
  185. var
  186. s0 = Ui 0
  187. s1 = Ui 0
  188. for i in 0..high(helper):
  189. for b in 0 ..< 64:
  190. if (helper[i] and (Ui(1) shl Ui(b))) != 0:
  191. s0 = s0 xor s.a0
  192. s1 = s1 xor s.a1
  193. discard next(s)
  194. s.a0 = s0
  195. s.a1 = s1
  196. proc rand[T: uint | uint64](r: var Rand; max: T): T =
  197. # xxx export in future work
  198. if max == 0: return
  199. else:
  200. let max = uint64(max)
  201. when T.high.uint64 == uint64.high:
  202. if max == uint64.high: return T(next(r))
  203. var iters = 0
  204. while true:
  205. let x = next(r)
  206. # avoid `mod` bias
  207. if x <= randMax - (randMax mod max) or iters > 20:
  208. return T(x mod (max + 1))
  209. else:
  210. inc iters
  211. proc rand*(r: var Rand; max: Natural): int {.benign.} =
  212. ## Returns a random integer in the range `0..max` using the given state.
  213. ##
  214. ## **See also:**
  215. ## * `rand proc<#rand,int>`_ that returns an integer using the default RNG
  216. ## * `rand proc<#rand,Rand,range[]>`_ that returns a float
  217. ## * `rand proc<#rand,Rand,HSlice[T: Ordinal or float or float32 or float64,T: Ordinal or float or float32 or float64]>`_
  218. ## that accepts a slice
  219. ## * `rand proc<#rand,typedesc[T]>`_ that accepts an integer or range type
  220. runnableExamples:
  221. var r = initRand(123)
  222. if false:
  223. assert r.rand(100) == 96 # implementation defined
  224. # bootstrap: can't use `runnableExamples("-r:off")`
  225. cast[int](rand(r, uint64(max)))
  226. # xxx toUnsigned pending https://github.com/nim-lang/Nim/pull/18445
  227. proc rand*(max: int): int {.benign.} =
  228. ## Returns a random integer in the range `0..max`.
  229. ##
  230. ## If `randomize <#randomize>`_ has not been called, the sequence of random
  231. ## numbers returned from this proc will always be the same.
  232. ##
  233. ## This proc uses the default RNG. Thus, it is **not** thread-safe.
  234. ##
  235. ## **See also:**
  236. ## * `rand proc<#rand,Rand,Natural>`_ that returns an integer using a
  237. ## provided state
  238. ## * `rand proc<#rand,float>`_ that returns a float
  239. ## * `rand proc<#rand,HSlice[T: Ordinal or float or float32 or float64,T: Ordinal or float or float32 or float64]>`_
  240. ## that accepts a slice
  241. ## * `rand proc<#rand,typedesc[T]>`_ that accepts an integer or range type
  242. runnableExamples("-r:off"):
  243. randomize(123)
  244. assert [rand(100), rand(100)] == [96, 63] # implementation defined
  245. rand(state, max)
  246. proc rand*(r: var Rand; max: range[0.0 .. high(float)]): float {.benign.} =
  247. ## Returns a random floating point number in the range `0.0..max`
  248. ## using the given state.
  249. ##
  250. ## **See also:**
  251. ## * `rand proc<#rand,float>`_ that returns a float using the default RNG
  252. ## * `rand proc<#rand,Rand,Natural>`_ that returns an integer
  253. ## * `rand proc<#rand,Rand,HSlice[T: Ordinal or float or float32 or float64,T: Ordinal or float or float32 or float64]>`_
  254. ## that accepts a slice
  255. ## * `rand proc<#rand,typedesc[T]>`_ that accepts an integer or range type
  256. runnableExamples:
  257. var r = initRand(234)
  258. let f = r.rand(1.0) # 8.717181376738381e-07
  259. let x = next(r)
  260. when defined(js):
  261. result = (float(x) / float(high(uint32))) * max
  262. else:
  263. let u = (0x3FFu64 shl 52u64) or (x shr 12u64)
  264. result = (cast[float](u) - 1.0) * max
  265. proc rand*(max: float): float {.benign.} =
  266. ## Returns a random floating point number in the range `0.0..max`.
  267. ##
  268. ## If `randomize <#randomize>`_ has not been called, the sequence of random
  269. ## numbers returned from this proc will always be the same.
  270. ##
  271. ## This proc uses the default RNG. Thus, it is **not** thread-safe.
  272. ##
  273. ## **See also:**
  274. ## * `rand proc<#rand,Rand,range[]>`_ that returns a float using a
  275. ## provided state
  276. ## * `rand proc<#rand,int>`_ that returns an integer
  277. ## * `rand proc<#rand,HSlice[T: Ordinal or float or float32 or float64,T: Ordinal or float or float32 or float64]>`_
  278. ## that accepts a slice
  279. ## * `rand proc<#rand,typedesc[T]>`_ that accepts an integer or range type
  280. runnableExamples:
  281. randomize(234)
  282. let f = rand(1.0) # 8.717181376738381e-07
  283. rand(state, max)
  284. proc rand*[T: Ordinal or SomeFloat](r: var Rand; x: HSlice[T, T]): T =
  285. ## For a slice `a..b`, returns a value in the range `a..b` using the given
  286. ## state.
  287. ##
  288. ## Allowed types for `T` are integers, floats, and enums without holes.
  289. ##
  290. ## **See also:**
  291. ## * `rand proc<#rand,HSlice[T: Ordinal or float or float32 or float64,T: Ordinal or float or float32 or float64]>`_
  292. ## that accepts a slice and uses the default RNG
  293. ## * `rand proc<#rand,Rand,Natural>`_ that returns an integer
  294. ## * `rand proc<#rand,Rand,range[]>`_ that returns a float
  295. ## * `rand proc<#rand,typedesc[T]>`_ that accepts an integer or range type
  296. runnableExamples:
  297. var r = initRand(345)
  298. assert r.rand(1..5) <= 5
  299. assert r.rand(-1.1 .. 1.2) >= -1.1
  300. assert x.a <= x.b
  301. when T is SomeFloat:
  302. result = rand(r, x.b - x.a) + x.a
  303. else: # Integers and Enum types
  304. whenJsNoBigInt64:
  305. result = cast[T](rand(r, cast[uint](x.b) - cast[uint](x.a)) + cast[uint](x.a))
  306. do:
  307. result = cast[T](rand(r, cast[uint64](x.b) - cast[uint64](x.a)) + cast[uint64](x.a))
  308. proc rand*[T: Ordinal or SomeFloat](x: HSlice[T, T]): T =
  309. ## For a slice `a..b`, returns a value in the range `a..b`.
  310. ##
  311. ## Allowed types for `T` are integers, floats, and enums without holes.
  312. ##
  313. ## If `randomize <#randomize>`_ has not been called, the sequence of random
  314. ## numbers returned from this proc will always be the same.
  315. ##
  316. ## This proc uses the default RNG. Thus, it is **not** thread-safe.
  317. ##
  318. ## **See also:**
  319. ## * `rand proc<#rand,Rand,HSlice[T: Ordinal or float or float32 or float64,T: Ordinal or float or float32 or float64]>`_
  320. ## that accepts a slice and uses a provided state
  321. ## * `rand proc<#rand,int>`_ that returns an integer
  322. ## * `rand proc<#rand,float>`_ that returns a floating point number
  323. ## * `rand proc<#rand,typedesc[T]>`_ that accepts an integer or range type
  324. runnableExamples:
  325. randomize(345)
  326. assert rand(1..6) <= 6
  327. result = rand(state, x)
  328. proc rand*[T: Ordinal](r: var Rand; t: typedesc[T]): T {.since: (1, 7, 1).} =
  329. ## Returns a random Ordinal in the range `low(T)..high(T)`.
  330. ##
  331. ## If `randomize <#randomize>`_ has not been called, the sequence of random
  332. ## numbers returned from this proc will always be the same.
  333. ##
  334. ## **See also:**
  335. ## * `rand proc<#rand,int>`_ that returns an integer
  336. ## * `rand proc<#rand,float>`_ that returns a floating point number
  337. ## * `rand proc<#rand,HSlice[T: Ordinal or float or float32 or float64,T: Ordinal or float or float32 or float64]>`_
  338. ## that accepts a slice
  339. when T is range or T is enum:
  340. result = rand(r, low(T)..high(T))
  341. elif T is bool:
  342. result = r.next < randMax div 2
  343. else:
  344. whenJsNoBigInt64:
  345. result = cast[T](r.next shr (sizeof(uint)*8 - sizeof(T)*8))
  346. do:
  347. result = cast[T](r.next shr (sizeof(uint64)*8 - sizeof(T)*8))
  348. proc rand*[T: Ordinal](t: typedesc[T]): T =
  349. ## Returns a random Ordinal in the range `low(T)..high(T)`.
  350. ##
  351. ## If `randomize <#randomize>`_ has not been called, the sequence of random
  352. ## numbers returned from this proc will always be the same.
  353. ##
  354. ## This proc uses the default RNG. Thus, it is **not** thread-safe.
  355. ##
  356. ## **See also:**
  357. ## * `rand proc<#rand,int>`_ that returns an integer
  358. ## * `rand proc<#rand,float>`_ that returns a floating point number
  359. ## * `rand proc<#rand,HSlice[T: Ordinal or float or float32 or float64,T: Ordinal or float or float32 or float64]>`_
  360. ## that accepts a slice
  361. runnableExamples:
  362. randomize(567)
  363. type E = enum a, b, c, d
  364. assert rand(E) in a..d
  365. assert rand(char) in low(char)..high(char)
  366. assert rand(int8) in low(int8)..high(int8)
  367. assert rand(uint32) in low(uint32)..high(uint32)
  368. assert rand(range[1..16]) in 1..16
  369. result = rand(state, t)
  370. proc sample*[T](r: var Rand; s: set[T]): T =
  371. ## Returns a random element from the set `s` using the given state.
  372. ##
  373. ## **See also:**
  374. ## * `sample proc<#sample,set[T]>`_ that uses the default RNG
  375. ## * `sample proc<#sample,Rand,openArray[T]>`_ for `openArray`s
  376. ## * `sample proc<#sample,Rand,openArray[T],openArray[U]>`_ that uses a
  377. ## cumulative distribution function
  378. runnableExamples:
  379. var r = initRand(987)
  380. let s = {1, 3, 5, 7, 9}
  381. assert r.sample(s) in s
  382. assert card(s) != 0
  383. var i = rand(r, card(s) - 1)
  384. for e in s:
  385. if i == 0: return e
  386. dec(i)
  387. proc sample*[T](s: set[T]): T =
  388. ## Returns a random element from the set `s`.
  389. ##
  390. ## If `randomize <#randomize>`_ has not been called, the order of outcomes
  391. ## from this proc will always be the same.
  392. ##
  393. ## This proc uses the default RNG. Thus, it is **not** thread-safe.
  394. ##
  395. ## **See also:**
  396. ## * `sample proc<#sample,Rand,set[T]>`_ that uses a provided state
  397. ## * `sample proc<#sample,openArray[T]>`_ for `openArray`s
  398. ## * `sample proc<#sample,openArray[T],openArray[U]>`_ that uses a
  399. ## cumulative distribution function
  400. runnableExamples:
  401. randomize(987)
  402. let s = {1, 3, 5, 7, 9}
  403. assert sample(s) in s
  404. sample(state, s)
  405. proc sample*[T](r: var Rand; a: openArray[T]): T =
  406. ## Returns a random element from `a` using the given state.
  407. ##
  408. ## **See also:**
  409. ## * `sample proc<#sample,openArray[T]>`_ that uses the default RNG
  410. ## * `sample proc<#sample,Rand,openArray[T],openArray[U]>`_ that uses a
  411. ## cumulative distribution function
  412. ## * `sample proc<#sample,Rand,set[T]>`_ for sets
  413. runnableExamples:
  414. let marbles = ["red", "blue", "green", "yellow", "purple"]
  415. var r = initRand(456)
  416. assert r.sample(marbles) in marbles
  417. result = a[r.rand(a.low..a.high)]
  418. proc sample*[T](a: openArray[T]): lent T =
  419. ## Returns a random element from `a`.
  420. ##
  421. ## If `randomize <#randomize>`_ has not been called, the order of outcomes
  422. ## from this proc will always be the same.
  423. ##
  424. ## This proc uses the default RNG. Thus, it is **not** thread-safe.
  425. ##
  426. ## **See also:**
  427. ## * `sample proc<#sample,Rand,openArray[T]>`_ that uses a provided state
  428. ## * `sample proc<#sample,openArray[T],openArray[U]>`_ that uses a
  429. ## cumulative distribution function
  430. ## * `sample proc<#sample,set[T]>`_ for sets
  431. runnableExamples:
  432. let marbles = ["red", "blue", "green", "yellow", "purple"]
  433. randomize(456)
  434. assert sample(marbles) in marbles
  435. result = a[rand(a.low..a.high)]
  436. proc sample*[T, U](r: var Rand; a: openArray[T]; cdf: openArray[U]): T =
  437. ## Returns an element from `a` using a cumulative distribution function
  438. ## (CDF) and the given state.
  439. ##
  440. ## The `cdf` argument does not have to be normalized, and it could contain
  441. ## any type of elements that can be converted to a `float`. It must be
  442. ## the same length as `a`. Each element in `cdf` should be greater than
  443. ## or equal to the previous element.
  444. ##
  445. ## The outcome of the `cumsum<math.html#cumsum,openArray[T]>`_ proc and the
  446. ## return value of the `cumsummed<math.html#cumsummed,openArray[T]>`_ proc,
  447. ## which are both in the math module, can be used as the `cdf` argument.
  448. ##
  449. ## **See also:**
  450. ## * `sample proc<#sample,openArray[T],openArray[U]>`_ that also utilizes
  451. ## a CDF but uses the default RNG
  452. ## * `sample proc<#sample,Rand,openArray[T]>`_ that does not use a CDF
  453. ## * `sample proc<#sample,Rand,set[T]>`_ for sets
  454. runnableExamples:
  455. from std/math import cumsummed
  456. let marbles = ["red", "blue", "green", "yellow", "purple"]
  457. let count = [1, 6, 8, 3, 4]
  458. let cdf = count.cumsummed
  459. var r = initRand(789)
  460. assert r.sample(marbles, cdf) in marbles
  461. assert(cdf.len == a.len) # Two basic sanity checks.
  462. assert(float(cdf[^1]) > 0.0)
  463. # While we could check cdf[i-1] <= cdf[i] for i in 1..cdf.len, that could get
  464. # awfully expensive even in debugging modes.
  465. let u = r.rand(float(cdf[^1]))
  466. a[cdf.upperBound(U(u))]
  467. proc sample*[T, U](a: openArray[T]; cdf: openArray[U]): T =
  468. ## Returns an element from `a` using a cumulative distribution function
  469. ## (CDF).
  470. ##
  471. ## This proc works similarly to
  472. ## `sample <#sample,Rand,openArray[T],openArray[U]>`_.
  473. ## See that proc's documentation for more details.
  474. ##
  475. ## If `randomize <#randomize>`_ has not been called, the order of outcomes
  476. ## from this proc will always be the same.
  477. ##
  478. ## This proc uses the default RNG. Thus, it is **not** thread-safe.
  479. ##
  480. ## **See also:**
  481. ## * `sample proc<#sample,Rand,openArray[T],openArray[U]>`_ that also utilizes
  482. ## a CDF but uses a provided state
  483. ## * `sample proc<#sample,openArray[T]>`_ that does not use a CDF
  484. ## * `sample proc<#sample,set[T]>`_ for sets
  485. runnableExamples:
  486. from std/math import cumsummed
  487. let marbles = ["red", "blue", "green", "yellow", "purple"]
  488. let count = [1, 6, 8, 3, 4]
  489. let cdf = count.cumsummed
  490. randomize(789)
  491. assert sample(marbles, cdf) in marbles
  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. # https://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 RNG. Thus, it is **not** thread-safe.
  516. result = gauss(state, mu, sigma)
  517. proc initRand*(seed: int64): Rand =
  518. ## Initializes a new `Rand <#Rand>`_ state using the given seed.
  519. ##
  520. ## Providing a specific seed will produce the same results for that seed each time.
  521. ##
  522. ## The resulting state is independent of the default RNG's state. When `seed == 0`,
  523. ## we internally set the seed to an implementation defined non-zero value.
  524. ##
  525. ## **See also:**
  526. ## * `initRand proc<#initRand>`_ that uses the current time
  527. ## * `randomize proc<#randomize,int64>`_ that accepts a seed for the default RNG
  528. ## * `randomize proc<#randomize>`_ that initializes the default RNG using the current time
  529. runnableExamples:
  530. from std/times import getTime, toUnix, nanosecond
  531. var r1 = initRand(123)
  532. let now = getTime()
  533. var r2 = initRand(now.toUnix * 1_000_000_000 + now.nanosecond)
  534. const seedFallback0 = int32.high # arbitrary
  535. let seed = if seed != 0: seed else: seedFallback0 # because 0 is a fixed point
  536. result.a0 = Ui(seed shr 16)
  537. result.a1 = Ui(seed and 0xffff)
  538. when not defined(nimLegacyRandomInitRand):
  539. # calling `discard next(result)` (even a few times) would still produce
  540. # skewed numbers for the 1st call to `rand()`.
  541. skipRandomNumbers(result)
  542. discard next(result)
  543. proc randomize*(seed: int64) {.benign.} =
  544. ## Initializes the default random number generator with the given seed.
  545. ##
  546. ## Providing a specific seed will produce the same results for that seed each time.
  547. ##
  548. ## **See also:**
  549. ## * `initRand proc<#initRand,int64>`_ that initializes a Rand state
  550. ## with a given seed
  551. ## * `randomize proc<#randomize>`_ that uses the current time instead
  552. ## * `initRand proc<#initRand>`_ that initializes a Rand state using
  553. ## the current time
  554. runnableExamples:
  555. from std/times import getTime, toUnix, nanosecond
  556. randomize(123)
  557. let now = getTime()
  558. randomize(now.toUnix * 1_000_000_000 + now.nanosecond)
  559. state = initRand(seed)
  560. proc shuffle*[T](r: var Rand; x: var openArray[T]) =
  561. ## Shuffles a sequence of elements in-place using the given state.
  562. ##
  563. ## **See also:**
  564. ## * `shuffle proc<#shuffle,openArray[T]>`_ that uses the default RNG
  565. runnableExamples:
  566. var cards = ["Ace", "King", "Queen", "Jack", "Ten"]
  567. var r = initRand(678)
  568. r.shuffle(cards)
  569. import std/algorithm
  570. assert cards.sorted == @["Ace", "Jack", "King", "Queen", "Ten"]
  571. for i in countdown(x.high, 1):
  572. let j = r.rand(i)
  573. swap(x[i], x[j])
  574. proc shuffle*[T](x: var openArray[T]) =
  575. ## Shuffles a sequence of elements in-place.
  576. ##
  577. ## If `randomize <#randomize>`_ has not been called, the order of outcomes
  578. ## from this proc will always be the same.
  579. ##
  580. ## This proc uses the default RNG. Thus, it is **not** thread-safe.
  581. ##
  582. ## **See also:**
  583. ## * `shuffle proc<#shuffle,Rand,openArray[T]>`_ that uses a provided state
  584. runnableExamples:
  585. var cards = ["Ace", "King", "Queen", "Jack", "Ten"]
  586. randomize(678)
  587. shuffle(cards)
  588. import std/algorithm
  589. assert cards.sorted == @["Ace", "Jack", "King", "Queen", "Ten"]
  590. shuffle(state, x)
  591. when not defined(standalone):
  592. when defined(js):
  593. import std/times
  594. else:
  595. when defined(nimscript):
  596. import std/hashes
  597. else:
  598. import std/[hashes, os, sysrand, monotimes]
  599. when compileOption("threads"):
  600. import locks
  601. var baseSeedLock: Lock
  602. baseSeedLock.initLock
  603. var baseState: Rand
  604. proc initRand(): Rand =
  605. ## Initializes a new Rand state.
  606. ##
  607. ## The resulting state is independent of the default RNG's state.
  608. ##
  609. ## **Note:** Does not work for the compile-time VM.
  610. ##
  611. ## See also:
  612. ## * `initRand proc<#initRand,int64>`_ that accepts a seed for a new Rand state
  613. ## * `randomize proc<#randomize>`_ that initializes the default RNG using the current time
  614. ## * `randomize proc<#randomize,int64>`_ that accepts a seed for the default RNG
  615. when defined(js):
  616. let time = int64(times.epochTime() * 1000) and 0x7fff_ffff
  617. result = initRand(time)
  618. else:
  619. proc getRandomState(): Rand =
  620. when defined(nimscript):
  621. result = Rand(
  622. a0: CompileTime.hash.Ui,
  623. a1: CompileDate.hash.Ui)
  624. if not result.isValid:
  625. result = DefaultRandSeed
  626. else:
  627. var urand: array[sizeof(Rand), byte]
  628. for i in 0 .. 7:
  629. if sysrand.urandom(urand):
  630. copyMem(result.addr, urand[0].addr, sizeof(Rand))
  631. if result.isValid:
  632. break
  633. if not result.isValid:
  634. # Don't try to get alternative random values from other source like time or process/thread id,
  635. # because such code would be never tested and is a liability for security.
  636. quit("Failed to initializes baseState in random module as sysrand.urandom doesn't work.")
  637. when compileOption("threads"):
  638. baseSeedLock.withLock:
  639. if not baseState.isValid:
  640. baseState = getRandomState()
  641. result = baseState
  642. baseState.skipRandomNumbers
  643. else:
  644. if not baseState.isValid:
  645. baseState = getRandomState()
  646. result = baseState
  647. baseState.skipRandomNumbers
  648. since (1, 5, 1):
  649. export initRand
  650. proc randomize*() {.benign.} =
  651. ## Initializes the default random number generator with a seed based on
  652. ## random number source.
  653. ##
  654. ## This proc only needs to be called once, and it should be called before
  655. ## the first usage of procs from this module that use the default RNG.
  656. ##
  657. ## **Note:** Does not work for the compile-time VM.
  658. ##
  659. ## **See also:**
  660. ## * `randomize proc<#randomize,int64>`_ that accepts a seed
  661. ## * `initRand proc<#initRand>`_ that initializes a Rand state using
  662. ## the current time
  663. ## * `initRand proc<#initRand,int64>`_ that initializes a Rand state
  664. ## with a given seed
  665. state = initRand()
  666. {.pop.}