added normal variate function (#14725)
* added normal variate function * change method only slightly faster * changelog + since Co-authored-by: b3liever <b3liever@yandex.com>
This commit is contained in:
parent
451129de42
commit
59ba4d8c03
2 changed files with 43 additions and 2 deletions
|
|
@ -113,7 +113,7 @@
|
||||||
- Add `rstgen.rstToLatex` convenience proc for `renderRstToOut` and `initRstGenerator` with `outLatex` output.
|
- Add `rstgen.rstToLatex` convenience proc for `renderRstToOut` and `initRstGenerator` with `outLatex` output.
|
||||||
- Add `os.normalizeExe`, eg: `koch` => `./koch`.
|
- Add `os.normalizeExe`, eg: `koch` => `./koch`.
|
||||||
- `macros.newLit` now preserves named vs unnamed tuples; use `-d:nimHasWorkaround14720` to keep old behavior
|
- `macros.newLit` now preserves named vs unnamed tuples; use `-d:nimHasWorkaround14720` to keep old behavior
|
||||||
|
- Add `random.gauss`, that uses the ratio of uniforms method of sampling from a Gaussian distribution.
|
||||||
|
|
||||||
## Language changes
|
## Language changes
|
||||||
- In the newruntime it is now allowed to assign discriminator field without restrictions as long as case object doesn't have custom destructor. Discriminator value doesn't have to be a constant either. If you have custom destructor for case object and you do want to freely assign discriminator fields, it is recommended to refactor object into 2 objects like this:
|
- In the newruntime it is now allowed to assign discriminator field without restrictions as long as case object doesn't have custom destructor. Discriminator value doesn't have to be a constant either. If you have custom destructor for case object and you do want to freely assign discriminator fields, it is recommended to refactor object into 2 objects like this:
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,8 @@
|
||||||
## <lib.html#pure-libraries-hashing>`_
|
## <lib.html#pure-libraries-hashing>`_
|
||||||
## in the standard library
|
## in the standard library
|
||||||
|
|
||||||
import algorithm #For upperBound
|
import algorithm, math
|
||||||
|
import std/private/since
|
||||||
|
|
||||||
include "system/inclrtl"
|
include "system/inclrtl"
|
||||||
{.push debugger: off.}
|
{.push debugger: off.}
|
||||||
|
|
@ -516,6 +517,33 @@ proc sample*[T, U](a: openArray[T]; cdf: openArray[U]): T =
|
||||||
doAssert sample(marbles, cdf) == "blue"
|
doAssert sample(marbles, cdf) == "blue"
|
||||||
state.sample(a, cdf)
|
state.sample(a, cdf)
|
||||||
|
|
||||||
|
proc gauss*(r: var Rand; mu = 0.0; sigma = 1.0): float {.since: (1, 3).} =
|
||||||
|
## Returns a Gaussian random variate,
|
||||||
|
## with mean ``mu`` and standard deviation ``sigma``
|
||||||
|
## using the given state.
|
||||||
|
# Ratio of uniforms method for normal
|
||||||
|
# http://www2.econ.osaka-u.ac.jp/~tanizaki/class/2013/econome3/13.pdf
|
||||||
|
const K = sqrt(2 / E)
|
||||||
|
var
|
||||||
|
a = 0.0
|
||||||
|
b = 0.0
|
||||||
|
while true:
|
||||||
|
a = rand(r, 1.0)
|
||||||
|
b = (2.0 * rand(r, 1.0) - 1.0) * K
|
||||||
|
if b * b <= -4.0 * a * a * ln(a): break
|
||||||
|
result = mu + sigma * (b / a)
|
||||||
|
|
||||||
|
proc gauss*(mu = 0.0, sigma = 1.0): float {.since: (1, 3).} =
|
||||||
|
## Returns a Gaussian random variate,
|
||||||
|
## with mean ``mu`` and standard deviation ``sigma``.
|
||||||
|
##
|
||||||
|
## If `randomize<#randomize>`_ has not been called, the order of outcomes
|
||||||
|
## from this proc will always be the same.
|
||||||
|
##
|
||||||
|
## This proc uses the default random number generator. Thus, it is **not**
|
||||||
|
## thread-safe.
|
||||||
|
result = gauss(state, mu, sigma)
|
||||||
|
|
||||||
proc initRand*(seed: int64): Rand =
|
proc initRand*(seed: int64): Rand =
|
||||||
## Initializes a new `Rand<#Rand>`_ state using the given seed.
|
## Initializes a new `Rand<#Rand>`_ state using the given seed.
|
||||||
##
|
##
|
||||||
|
|
@ -619,6 +647,8 @@ when not defined(nimscript) and not defined(standalone):
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
|
import stats
|
||||||
|
|
||||||
proc main =
|
proc main =
|
||||||
var occur: array[1000, int]
|
var occur: array[1000, int]
|
||||||
|
|
||||||
|
|
@ -632,6 +662,17 @@ when isMainModule:
|
||||||
elif oc > 150:
|
elif oc > 150:
|
||||||
doAssert false, "too many occurrences of " & $i
|
doAssert false, "too many occurrences of " & $i
|
||||||
|
|
||||||
|
when false:
|
||||||
|
var rs: RunningStat
|
||||||
|
for j in 1..5:
|
||||||
|
for i in 1 .. 1_000:
|
||||||
|
rs.push(gauss())
|
||||||
|
echo("mean: ", rs.mean,
|
||||||
|
" stdDev: ", rs.standardDeviation(),
|
||||||
|
" min: ", rs.min,
|
||||||
|
" max: ", rs.max)
|
||||||
|
rs.clear()
|
||||||
|
|
||||||
var a = [0, 1]
|
var a = [0, 1]
|
||||||
shuffle(a)
|
shuffle(a)
|
||||||
doAssert a[0] == 1
|
doAssert a[0] == 1
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue