Current section

Files

Jump to
gleam_stats src gleam_stats@distributions@normal.erl
Raw

src/gleam_stats@distributions@normal.erl

-module(gleam_stats@distributions@normal).
-compile(no_auto_import).
-export([normal_mean/2, normal_variance/2, normal_pdf/3, normal_cdf/3, normal_random/4]).
-spec check_normal_parameters(float(), float()) -> {ok, boolean()} |
{error, binary()}.
check_normal_parameters(Mu, Sigma) ->
case Sigma > 0.0 of
false ->
_pipe = <<"Invalid input argument: sigma < 0. Valid input is sigma > 0."/utf8>>,
{error, _pipe};
true ->
_pipe@1 = true,
{ok, _pipe@1}
end.
-spec normal_mean(float(), float()) -> {ok, float()} | {error, binary()}.
normal_mean(Mu, Sigma) ->
case check_normal_parameters(Mu, Sigma) of
{error, String} ->
_pipe = String,
{error, _pipe};
_@1 ->
_pipe@1 = Mu,
{ok, _pipe@1}
end.
-spec normal_variance(float(), float()) -> {ok, float()} | {error, binary()}.
normal_variance(Mu, Sigma) ->
case check_normal_parameters(Mu, Sigma) of
{error, String} ->
_pipe = String,
{error, _pipe};
_@1 ->
{ok, V@1} = case gleam_stats@math:pow(Sigma, 2.0) of
{ok, V} -> {ok, V};
_try ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try,
module => <<"gleam_stats/distributions/normal"/utf8>>,
function => <<"normal_variance"/utf8>>,
line => 85})
end,
_pipe@1 = V@1,
{ok, _pipe@1}
end.
-spec normal_pdf(float(), float(), float()) -> {ok, float()} | {error, binary()}.
normal_pdf(X, Mu, Sigma) ->
do_normal_pdf(X, Mu, Sigma).
-spec do_normal_pdf(float(), float(), float()) -> {ok, float()} |
{error, binary()}.
do_normal_pdf(X, Mu, Sigma) ->
case check_normal_parameters(Mu, Sigma) of
{error, String} ->
_pipe = String,
{error, _pipe};
_@1 ->
{ok, V1@1} = case gleam_stats@math:pow(X - Mu, 2.0) of
{ok, V1} -> {ok, V1};
_try ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try,
module => <<"gleam_stats/distributions/normal"/utf8>>,
function => <<"do_normal_pdf"/utf8>>,
line => 140})
end,
{ok, V2@1} = case gleam_stats@math:pow(Sigma, 2.0) of
{ok, V2} -> {ok, V2};
_try@1 ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try@1,
module => <<"gleam_stats/distributions/normal"/utf8>>,
function => <<"do_normal_pdf"/utf8>>,
line => 141})
end,
Numexp = case (2.0 * V2@1) of
0.0 -> 0.0;
Gleam@denominator -> V1@1 / Gleam@denominator
end,
{ok, V3@1} = case gleam_stats@math:pow(
2.0
* gleam_stats@math:pi(),
0.5
) of
{ok, V3} -> {ok, V3};
_try@2 ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try@2,
module => <<"gleam_stats/distributions/normal"/utf8>>,
function => <<"do_normal_pdf"/utf8>>,
line => 143})
end,
Denominator = Sigma * V3@1,
Numerator = gleam_stats@math:exp(Numexp * -1.0),
_pipe@1 = case Denominator of
0.0 -> 0.0;
Gleam@denominator@1 -> Numerator / Gleam@denominator@1
end,
{ok, _pipe@1}
end.
-spec normal_cdf(float(), float(), float()) -> {ok, float()} | {error, binary()}.
normal_cdf(X, Mu, Sigma) ->
do_normal_cdf(X, Mu, Sigma).
-spec do_normal_cdf(float(), float(), float()) -> {ok, float()} |
{error, binary()}.
do_normal_cdf(X, Mu, Sigma) ->
case check_normal_parameters(Mu, Sigma) of
{error, String} ->
_pipe = String,
{error, _pipe};
_@1 ->
{ok, V@1} = case gleam_stats@math:pow(2.0, 0.5) of
{ok, V} -> {ok, V};
_try ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try,
module => <<"gleam_stats/distributions/normal"/utf8>>,
function => <<"do_normal_cdf"/utf8>>,
line => 208})
end,
Denominator = Sigma * V@1,
_pipe@1 = 0.5 * (1.0 + gleam_stats@math:erf(case Denominator of
0.0 -> 0.0;
Gleam@denominator -> (X - Mu) / Gleam@denominator
end)),
{ok, _pipe@1}
end.
-spec box_muller(float(), float()) -> list(float()).
box_muller(U1, U2) ->
{ok, U@1} = case gleam_stats@math:log(U1) of
{ok, U} -> {ok, U};
_try ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try,
module => <<"gleam_stats/distributions/normal"/utf8>>,
function => <<"box_muller"/utf8>>,
line => 219})
end,
{ok, X@1} = case gleam_stats@math:pow(-2.0 * U@1, 0.5) of
{ok, X} -> {ok, X};
_try@1 ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try@1,
module => <<"gleam_stats/distributions/normal"/utf8>>,
function => <<"box_muller"/utf8>>,
line => 220})
end,
[X@1
* gleam_stats@math:cos((2.0 * gleam_stats@math:pi()) * U2),
X@1
* gleam_stats@math:sin((2.0 * gleam_stats@math:pi()) * U2)].
-spec normal_random(
gleam@iterator:iterator(integer()),
float(),
float(),
integer()
) -> {ok, {list(float()), gleam@iterator:iterator(integer())}} |
{error, binary()}.
normal_random(Stream, Mu, Sigma, M) ->
do_normal_random(Stream, Mu, Sigma, M).
-spec do_normal_random(
gleam@iterator:iterator(integer()),
float(),
float(),
integer()
) -> {ok, {list(float()), gleam@iterator:iterator(integer())}} |
{error, binary()}.
do_normal_random(Stream, Mu, Sigma, M) ->
case check_normal_parameters(Mu, Sigma) of
{error, String} ->
_pipe = String,
{error, _pipe};
_@1 ->
case M > 0 of
false ->
{error,
<<"Invalid input arugment: m < 0. Valid input is m > 0."/utf8>>};
true ->
M_even = M + (M rem 2),
{ok, Out@1} = case gleam_stats@distributions@uniform:uniform_random(
Stream,
0.0,
1.0,
M_even
) of
{ok, Out} -> {ok, Out};
_try ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try,
module => <<"gleam_stats/distributions/normal"/utf8>>,
function => <<"do_normal_random"/utf8>>,
line => 297})
end,
Numbers = begin
_pipe@1 = gleam@pair:first(Out@1),
_pipe@2 = gleam@list:sized_chunk(_pipe@1, 2),
_pipe@3 = gleam@list:map(_pipe@2, fun(X) -> case X of
[U1, U2] ->
case box_muller(U1, U2) of
[Z1, Z2] ->
[(Sigma
* Z1)
+ Mu,
(Sigma
* Z2)
+ Mu]
end
end end),
_pipe@4 = gleam@list:flatten(_pipe@3),
(fun(X@1) -> case M =:= gleam@list:length(X@1) of
true ->
X@1;
false ->
gleam@list:drop(X@1, 1)
end end)(_pipe@4)
end,
_pipe@5 = {Numbers, gleam@pair:second(Out@1)},
{ok, _pipe@5}
end
end.