Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:23
erlang
2872-Implement-seeding-with-default-algorithm.p...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 2872-Implement-seeding-with-default-algorithm.patch of Package erlang
From 9b8f09a991242b2ff737b3b7cd0e309a5cc1f2d2 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen <raimo@erlang.org> Date: Tue, 8 Dec 2020 16:44:51 +0100 Subject: [PATCH 2/6] Implement seeding with 'default' algorithm --- lib/stdlib/doc/src/rand.xml | 34 ++++++++++++++++++++++------- lib/stdlib/src/rand.erl | 11 ++++++++-- lib/stdlib/test/rand_SUITE.erl | 39 ++++++++++++++++++++++------------ 3 files changed, 60 insertions(+), 24 deletions(-) diff --git a/lib/stdlib/doc/src/rand.xml b/lib/stdlib/doc/src/rand.xml index ac99736761..0eed1c2e49 100644 --- a/lib/stdlib/doc/src/rand.xml +++ b/lib/stdlib/doc/src/rand.xml @@ -310,6 +310,8 @@ tests. We suggest to use a sign test to extract a random Boolean value.</pre> A list of integers sets the generator's internal state directly, after algorithm-dependent checks of the value and masking to the proper word size. + The number of integers must be equal to the + number of state words in the generator. </p> <p> An integer is used as the initial state for a SplitMix64 generator. @@ -432,7 +434,8 @@ tests. We suggest to use a sign test to extract a random Boolean value.</pre> </func> <func> - <name name="seed" arity="1" since="OTP 18.0"/> + <name name="seed" arity="1" clause_i="1" since="OTP 18.0"/> + <name name="seed" arity="1" clause_i="2" since="OTP 24.0"/> <fsummary>Seed random number generator.</fsummary> <desc> <marker id="seed-1"/> @@ -440,6 +443,8 @@ tests. We suggest to use a sign test to extract a random Boolean value.</pre> Seeds random number generation with the specifed algorithm and time-dependent data if <c><anno>AlgOrStateOrExpState</anno></c> is an algorithm. + <c><anno>Alg</anno> = default</c> + is an alias for the default algorithm. </p> <p>Otherwise recreates the exported seed in the process dictionary, and returns the state. See also @@ -448,22 +453,30 @@ tests. We suggest to use a sign test to extract a random Boolean value.</pre> </func> <func> - <name name="seed" arity="2" since="OTP 18.0"/> + <name name="seed" arity="2" clause_i="1" since="OTP 18.0"/> + <name name="seed" arity="2" clause_i="2" since="OTP 24.0"/> <fsummary>Seed the random number generation.</fsummary> <desc> - <p>Seeds random number generation with the specified algorithm and - integers in the process dictionary and returns the state.</p> + <p> + Seeds random number generation with the specified algorithm and + integers in the process dictionary and returns the state. + <c><anno>Alg</anno> = default</c> + is an alias for the default algorithm. + </p> </desc> </func> <func> - <name name="seed_s" arity="1" since="OTP 18.0"/> + <name name="seed_s" arity="1" clause_i="1" since="OTP 18.0"/> + <name name="seed_s" arity="1" clause_i="2" since="OTP 24.0"/> <fsummary>Seed random number generator.</fsummary> <desc> <p> Seeds random number generation with the specifed algorithm and time-dependent data if <c><anno>AlgOrStateOrExpState</anno></c> is an algorithm. + <c><anno>Alg</anno> = default</c> + is an alias for the default algorithm. </p> <p>Otherwise recreates the exported seed and returns the state. See also <seemfa marker="#export_seed/0"> @@ -472,11 +485,16 @@ tests. We suggest to use a sign test to extract a random Boolean value.</pre> </func> <func> - <name name="seed_s" arity="2" since="OTP 18.0"/> + <name name="seed_s" arity="2" clause_i="1" since="OTP 18.0"/> + <name name="seed_s" arity="2" clause_i="2" since="OTP 24.0"/> <fsummary>Seed the random number generation.</fsummary> <desc> - <p>Seeds random number generation with the specified algorithm and - integers and returns the state.</p> + <p> + Seeds random number generation with the specified algorithm and + integers and returns the state. + <c><anno>Alg</anno> = default</c> + is an alias for the default algorithm. + </p> </desc> </func> diff --git a/lib/stdlib/src/rand.erl b/lib/stdlib/src/rand.erl index b743bd5798..1de78a23ac 100644 --- a/lib/stdlib/src/rand.erl +++ b/lib/stdlib/src/rand.erl @@ -248,12 +248,16 @@ export_seed_s({#{type:=Alg}, AlgState}) -> {Alg, AlgState}. -spec seed( AlgOrStateOrExpState :: builtin_alg() | state() | export_state()) -> + state(); + (Alg :: 'default') -> state(). seed(Alg) -> seed_put(seed_s(Alg)). -spec seed_s( AlgOrStateOrExpState :: builtin_alg() | state() | export_state()) -> + state(); + (Alg :: 'default') -> state(). seed_s({AlgHandler, _AlgState} = State) when is_map(AlgHandler) -> State; @@ -268,11 +272,14 @@ seed_s(Alg) -> %% seed/2: seeds RNG with the algorithm and given values %% and returns the NEW state. --spec seed(Alg :: builtin_alg(), Seed :: seed()) -> state(). +-spec seed(Alg :: builtin_alg(), Seed :: seed()) -> state(); + (Alg :: 'default', Seed :: seed()) -> state(). seed(Alg, Seed) -> seed_put(seed_s(Alg, Seed)). --spec seed_s(Alg :: builtin_alg(), Seed :: seed()) -> state(). +-spec seed_s(Alg :: builtin_alg(), Seed :: seed()) -> state(); + (Alg :: 'default', Seed :: seed()) -> state(). +seed_s(default, Seed) -> seed_s(?DEFAULT_ALG_HANDLER, Seed); seed_s(Alg, Seed) -> {AlgHandler,SeedFun} = mk_alg(Alg), AlgState = SeedFun(Seed), diff --git a/lib/stdlib/test/rand_SUITE.erl b/lib/stdlib/test/rand_SUITE.erl index d368fb3fc6..230020857f 100644 --- a/lib/stdlib/test/rand_SUITE.erl +++ b/lib/stdlib/test/rand_SUITE.erl @@ -85,7 +85,7 @@ algs() -> %% Test that seed and seed_s and export_seed/0 is working. seed(Config) when is_list(Config) -> - Algs = algs(), + Algs = [default|algs()], Test = fun(Alg) -> try seed_1(Alg) catch _:Reason:Stacktrace -> @@ -93,6 +93,13 @@ seed(Config) when is_list(Config) -> end end, [Test(Alg) || Alg <- Algs], + %% + %% Check that export_seed/1 returns 'undefined' if there is no seed + erase(rand_seed), + undefined = rand:export_seed(), + %% + %% Other seed terms shall not work + {'EXIT', _} = (catch rand:seed_s(foobar, os:timestamp())), ok. seed_1(Alg) -> @@ -121,22 +128,26 @@ seed_1(Alg) -> false = (S1 =:= rand:seed_s(Alg)), %% Negative integers works _ = rand:seed_s(Alg, {-1,-1,-1}), - %% Check that export_seed/1 returns 'undefined' if there is no seed - erase(rand_seed), - undefined = rand:export_seed(), - - %% Other term do not work - {'EXIT', _} = (catch rand:seed_s(foobar, os:timestamp())), + %% + %% Other seed terms shall not work {'EXIT', _} = (catch rand:seed_s(Alg, {asd, 1, 1})), {'EXIT', _} = (catch rand:seed_s(Alg, {0, 234.1234, 1})), {'EXIT', _} = (catch rand:seed_s(Alg, {0, 234, [1, 123, 123]})), + {'EXIT', _} = (catch rand:seed_s(Alg, asd)), + {'EXIT', _} = (catch rand:seed_s(Alg, make_ref())), + {'EXIT', _} = (catch rand:seed_s(Alg, fun () -> 0 end)), + {'EXIT', _} = (catch rand:seed_s(Alg, self())), + {'EXIT', _} = (catch rand:seed_s(Alg, {1,2})), + {'EXIT', _} = (catch rand:seed_s(Alg, {1,2,3,4})), + {'EXIT', _} = (catch rand:seed_s(Alg, #{})), + {'EXIT', _} = (catch rand:seed_s(Alg, [1|2])), ok. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Check that both APIs are consistent with each other. api_eq(_Config) -> - Algs = algs(), + Algs = [default|algs()], Small = fun(Alg) -> Seed = rand:seed(Alg), io:format("Seed ~p~n",[rand:export_seed_s(Seed)]), @@ -182,7 +193,7 @@ api_eq_1(S00) -> %% Check that uniform/1 returns values within the proper interval. interval_int(Config) when is_list(Config) -> - Algs = algs(), + Algs = [default|algs()], Small = fun(Alg) -> Seed = rand:seed(Alg), io:format("Seed ~p~n",[rand:export_seed_s(Seed)]), @@ -216,7 +227,7 @@ interval_int_1(N, Top, Max) -> %% Check that uniform/0 returns values within the proper interval. interval_float(Config) when is_list(Config) -> - Algs = algs(), + Algs = [default|algs()], Test = fun(Alg) -> _ = rand:seed(Alg), interval_float_1(100000) @@ -307,13 +318,13 @@ gen(_, _, _, Acc) -> lists:reverse(Acc). basic_stats_uniform_1(Config) when is_list(Config) -> ct:timetrap({minutes,15}), %% valgrind needs a lot of time [basic_uniform_1(?LOOP, rand:seed_s(Alg), 0.0, array:new([{default, 0}])) - || Alg <- algs()], + || Alg <- [default|algs()]], ok. basic_stats_uniform_2(Config) when is_list(Config) -> ct:timetrap({minutes,15}), %% valgrind needs a lot of time [basic_uniform_2(?LOOP, rand:seed_s(Alg), 0, array:new([{default, 0}])) - || Alg <- algs()], + || Alg <- [default|algs()]], ok. basic_stats_standard_normal(Config) when is_list(Config) -> @@ -323,7 +334,7 @@ basic_stats_standard_normal(Config) when is_list(Config) -> IntendedVariance = 1, [basic_normal_1(?LOOP, IntendedMean, IntendedVariance, rand:seed_s(Alg), 0, 0) - || Alg <- algs()], + || Alg <- [default|algs()]], ok. basic_stats_normal(Config) when is_list(Config) -> @@ -342,7 +353,7 @@ basic_stats_normal(Config) when is_list(Config) -> [float(IntendedMean), float(IntendedVariance)]), [basic_normal_1(?LOOP, IntendedMean, IntendedVariance, rand:seed_s(Alg), 0, 0) - || Alg <- algs()] + || Alg <- [default|algs()]] end, IntendedMeanVariancePairs). -- 2.26.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor