diff options
Diffstat (limited to 'lib/stdlib/src/rand.erl')
-rw-r--r-- | lib/stdlib/src/rand.erl | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/lib/stdlib/src/rand.erl b/lib/stdlib/src/rand.erl index 2ee0ddb036..7a8a5e6d4a 100644 --- a/lib/stdlib/src/rand.erl +++ b/lib/stdlib/src/rand.erl @@ -31,7 +31,7 @@ export_seed/0, export_seed_s/1, uniform/0, uniform/1, uniform_s/1, uniform_s/2, jump/0, jump/1, - normal/0, normal_s/1 + normal/0, normal/2, normal_s/1, normal_s/3 ]). -compile({inline, [exs64_next/1, exsplus_next/1, @@ -265,7 +265,7 @@ seed_s(Alg0, S0 = {_, _, _}) -> %%% uniform/0, uniform/1, uniform_s/1, uniform_s/2 are all %%% uniformly distributed random numbers. -%% uniform/0: returns a random float X where 0.0 < X < 1.0, +%% uniform/0: returns a random float X where 0.0 =< X < 1.0, %% updating the state in the process dictionary. -spec uniform() -> X :: float(). @@ -285,7 +285,7 @@ uniform(N) -> X. %% uniform_s/1: given a state, uniform_s/1 -%% returns a random float X where 0.0 < X < 1.0, +%% returns a random float X where 0.0 =< X < 1.0, %% and a new state. -spec uniform_s(State :: state()) -> {X :: float(), NewState :: state()}. @@ -358,6 +358,13 @@ normal() -> _ = seed_put(Seed), X. +%% normal/2: returns a random float with N(μ, σ²) normal distribution +%% updating the state in the process dictionary. + +-spec normal(Mean :: number(), Variance :: number()) -> float(). +normal(Mean, Variance) -> + Mean + (math:sqrt(Variance) * normal()). + %% normal_s/1: returns a random float with standard normal distribution %% The Ziggurat Method for generating random variables - Marsaglia and Tsang %% Paper and reference code: http://www.jstatsoft.org/v05/i08/ @@ -378,6 +385,13 @@ normal_s(State0) -> false -> normal_s(Idx, Sign, -X, State) end. +%% normal_s/3: returns a random float with normal N(μ, σ²) distribution + +-spec normal_s(Mean :: number(), Variance :: number(), state()) -> {float(), NewS :: state()}. +normal_s(Mean, Variance, State0) when Variance > 0 -> + {X, State} = normal_s(State0), + {Mean + (math:sqrt(Variance) * X), State}. + %% ===================================================================== %% Internal functions @@ -728,20 +742,20 @@ exrop_uniform(Range, {Alg, R}) -> MaxMinusRange = ?BIT(58) - Range, ?uniform_range(Range, Alg, R1, V, MaxMinusRange, I). -%% Split a 116 bit constant into two '1'++58 bit words, -%% the top '1' marks the top of the word +%% Split a 116 bit constant into two 58 bit words, +%% a top '1' marks the end of the low word. -define( JUMP_116(Jump), - [?BIT(58) bor ?MASK(58, (Jump)),?BIT(58) bor ((Jump) bsr 58)]). + [?BIT(58) bor ?MASK(58, (Jump)),(Jump) bsr 58]). %% exrop_jump({Alg,S}) -> [J|Js] = ?JUMP_116(16#9863200f83fcd4a11293241fcb12a), {Alg, exrop_jump(S, 0, 0, J, Js)}. %% -dialyzer({no_improper_lists, exrop_jump/5}). -exrop_jump(_S, S0, S1, 1, []) -> % End of jump constant +exrop_jump(_S, S0, S1, 0, []) -> % End of jump constant [S0|S1]; -exrop_jump(S, S0, S1, 1, [J|Js]) -> % End of the word +exrop_jump(S, S0, S1, 1, [J|Js]) -> % End of word exrop_jump(S, S0, S1, J, Js); exrop_jump([S__0|S__1] = _S, S0, S1, J, Js) -> case ?MASK(1, J) of |