Current section

Files

Jump to
gleam_stats src gleam_stats@math.erl
Raw

src/gleam_stats@math.erl

-module(gleam_stats@math).
-compile(no_auto_import).
-export([sin/1, pi/0, tau/0, acos/1, acosh/1, asin/1, atan/1, atan2/2, atanh/1, cos/1, cosh/1, exp/1, ceil/1, floor/1, pow/2, log/1, log10/1, log2/1, sinh/1, tanh/1, sign/1, erf/1, gamma/1, gammainc/2, beta/2, round/2, factorial/1, combination/2, permutation/2]).
-spec sin(float()) -> float().
sin(X) ->
math:sin(X).
-spec pi() -> float().
pi() ->
math:pi().
-spec tau() -> float().
tau() ->
2.0 * pi().
-spec acos(float()) -> float().
acos(X) ->
math:acos(X).
-spec acosh(float()) -> float().
acosh(X) ->
math:acosh(X).
-spec asin(float()) -> float().
asin(X) ->
math:asin(X).
-spec atan(float()) -> float().
atan(X) ->
math:atan(X).
-spec atan2(float(), float()) -> float().
atan2(Y, X) ->
math:atan2(Y, X).
-spec atanh(float()) -> float().
atanh(X) ->
math:atanh(X).
-spec cos(float()) -> float().
cos(X) ->
math:cos(X).
-spec cosh(float()) -> float().
cosh(X) ->
math:cosh(X).
-spec exp(float()) -> float().
exp(X) ->
math:exp(X).
-spec ceil(float()) -> float().
ceil(X) ->
math:ceil(X).
-spec floor(float()) -> float().
floor(X) ->
math:floor(X).
-spec pow(float(), float()) -> float().
pow(X, Y) ->
math:pow(X, Y).
-spec log(float()) -> float().
log(X) ->
math:log(X).
-spec log10(float()) -> float().
log10(X) ->
math:log10(X).
-spec log2(float()) -> float().
log2(X) ->
math:log2(X).
-spec sinh(float()) -> float().
sinh(X) ->
math:sinh(X).
-spec tanh(float()) -> float().
tanh(X) ->
math:tanh(X).
-spec sign(float()) -> float().
sign(X) ->
do_sign(X).
-spec do_sign(float()) -> float().
do_sign(X) ->
case X < 0.0 of
true ->
-1.0;
false ->
case X =:= 0.0 of
true ->
0.0;
false ->
1.0
end
end.
-spec erf(float()) -> float().
erf(X) ->
[A1, A2, A3, A4, A5] = [0.254829592,
-0.284496736,
1.421413741,
-1.453152027,
1.061405429],
P = 0.3275911,
Sign = case X < 0.0 of
true ->
-1.0;
false ->
1.0
end,
X@1 = gleam@float:absolute_value(X),
T = case (1.0 + (P * X@1)) of
0.0 -> 0.0;
Gleam@denominator -> 1.0 / Gleam@denominator
end,
Y = 1.0 - ((((((((((A5 * T) + A4) * T) + A3) * T) + A2) * T) + A1) * T) * exp(
(-1.0
* X@1)
* X@1
)),
Sign * Y.
-spec gamma(float()) -> float().
gamma(X) ->
gamma_lanczos(X).
-spec gamma_lanczos(float()) -> float().
gamma_lanczos(X) ->
case X < 0.5 of
true ->
case (sin(pi() * X) * gamma_lanczos(1.0 - X)) of
0.0 -> 0.0;
Gleam@denominator -> pi() / Gleam@denominator
end;
false ->
Z = X - 1.0,
X@1 = gleam@list:index_fold(
[0.99999999999980993,
676.5203681218851,
-1259.1392167224028,
771.32342877765313,
-176.61502916214059,
12.507343278686905,
-0.13857109526572012,
0.0000099843695780195716,
0.00000015056327351493116],
0.0,
fun(Acc, V, Index) -> case Index > 0 of
true ->
Acc + (case (Z + gleam@int:to_float(Index)) of
0.0 -> 0.0;
Gleam@denominator@1 -> V / Gleam@denominator@1
end);
false ->
V
end end
),
T = (Z + 7.0) + 0.5,
((gleam@float:power(2.0 * pi(), 0.5) * gleam@float:power(T, Z + 0.5)) * exp(
-1.0
* T
)) * X@1
end.
-spec gammainc(float(), float()) -> {ok, float()} | {error, binary()}.
gammainc(A, X) ->
case (A > 0.0) andalso (X >= 0.0) of
true ->
_pipe = (gleam@float:power(X, A) * exp(-1.0 * X)) * gammainc_sum(
A,
X,
case A of
0.0 -> 0.0;
Gleam@denominator -> 1.0
/ Gleam@denominator
end,
0.0,
1.0
),
{ok, _pipe};
false ->
gleam@io:debug(A),
gleam@io:debug(X),
_pipe@1 = <<"Invlaid input argument: a <= 0 or x < 0. Valid input is a > 0 and x >= 0."/utf8>>,
{error, _pipe@1}
end.
-spec gammainc_sum(float(), float(), float(), float(), float()) -> float().
gammainc_sum(A, X, T, S, N) ->
case T of
0.0 ->
S;
_@1 ->
Ns = S + T,
Nt = T * (case (A + N) of
0.0 -> 0.0;
Gleam@denominator -> X / Gleam@denominator
end),
gammainc_sum(A, X, Nt, Ns, N + 1.0)
end.
-spec beta(float(), float()) -> float().
beta(X, Y) ->
case gamma(X + Y) of
0.0 -> 0.0;
Gleam@denominator -> (gamma(X) * gamma(Y)) / Gleam@denominator
end.
-spec round(float(), integer()) -> float().
round(X, Precision) ->
P = gleam@float:power(10.0, gleam@int:to_float(Precision)),
case P of
0.0 -> 0.0;
Gleam@denominator -> gleam@int:to_float(gleam@float:round(X * P)) / Gleam@denominator
end.
-spec factorial(integer()) -> {ok, integer()} | {error, binary()}.
factorial(N) ->
case N < 0 of
true ->
_pipe = <<"Invalid input argument: n < 0. Valid input is n > 0."/utf8>>,
{error, _pipe};
false ->
case N of
0 ->
_pipe@1 = 1,
{ok, _pipe@1};
1 ->
_pipe@2 = 1,
{ok, _pipe@2};
_@1 ->
_pipe@3 = gleam@list:range(1, N + 1),
_pipe@4 = gleam@list:fold(
_pipe@3,
1,
fun(Acc, X) -> Acc * X end
),
{ok, _pipe@4}
end
end.
-spec combination(integer(), integer()) -> {ok, integer()} | {error, binary()}.
combination(N, K) ->
case N < 0 of
true ->
_pipe = <<"Invalid input argument: n < 0. Valid input is n > 0."/utf8>>,
{error, _pipe};
false ->
case (K < 0) orelse (K > N) of
true ->
_pipe@1 = 0,
{ok, _pipe@1};
false ->
case (K =:= 0) orelse (K =:= N) of
true ->
_pipe@2 = 1,
{ok, _pipe@2};
false ->
{ok, Min@1} = case gleam_stats@stats:amin(
[gleam@int:to_float(K),
gleam@int:to_float(N - K)]
) of
{ok, Min} -> {ok, Min};
_try ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try,
module => <<"gleam_stats/math"/utf8>>,
function => <<"combination"/utf8>>,
line => 940})
end,
_pipe@3 = gleam@list:range(
0,
gleam@float:round(Min@1)
),
_pipe@4 = gleam@list:fold(
_pipe@3,
1,
fun(Acc, X) -> case (X + 1) of
0 -> 0;
Gleam@denominator -> (Acc * (N - X)) div Gleam@denominator
end end
),
{ok, _pipe@4}
end
end
end.
-spec permutation(integer(), integer()) -> {ok, integer()} | {error, binary()}.
permutation(N, K) ->
case N < 0 of
true ->
_pipe = <<"Invalid input argument: n < 0. Valid input is n > 0."/utf8>>,
{error, _pipe};
false ->
case (K < 0) orelse (K > N) of
true ->
_pipe@1 = 0,
{ok, _pipe@1};
false ->
case K =:= N of
true ->
_pipe@2 = 1,
{ok, _pipe@2};
false ->
{ok, V1@1} = case factorial(N) of
{ok, V1} -> {ok, V1};
_try ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try,
module => <<"gleam_stats/math"/utf8>>,
function => <<"permutation"/utf8>>,
line => 1008})
end,
{ok, V2@1} = case factorial(N - K) of
{ok, V2} -> {ok, V2};
_try@1 ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try@1,
module => <<"gleam_stats/math"/utf8>>,
function => <<"permutation"/utf8>>,
line => 1009})
end,
_pipe@3 = case V2@1 of
0 -> 0;
Gleam@denominator -> V1@1 div Gleam@denominator
end,
{ok, _pipe@3}
end
end
end.