File bear-1.0.0-git.patch of Package bear
diff --git a/rebar.config b/rebar.config
index 3ee1ec7..2334adf 100644
--- a/rebar.config
+++ b/rebar.config
@@ -1,3 +1,7 @@
{deps, []}.
{erl_opts, [debug_info]}.
{cover_enabled, true}.
+
+%% xref - default checks except export_not_used, which is pointless here
+{xref_checks, [undefined_function_calls,undefined_functions,locals_not_used,
+ deprecated_function_calls,deprecated_functions]}.
diff --git a/src/bear.erl b/src/bear.erl
index 79ee4dc..d9f9b63 100644
--- a/src/bear.erl
+++ b/src/bear.erl
@@ -42,6 +42,37 @@
tied_rank_worker/3
]).
+-ifdef(TEST).
+-export([ arithmetic_mean/1
+ , geometric_mean/1
+ , get_bin_count/3
+ , get_bin_width/2
+ , get_covariance/2
+ , get_hist_bins/4
+ , get_kendall_correlation/2
+ , get_pearson_correlation/2
+ , get_spearman_correlation/2
+ , harmonic_mean/1
+ , inverse/1
+ , kurtosis/2
+ , math_log/1
+ , perc/2
+ , percentile/3
+ , ranks_of/1
+ , revsort/1
+ , round_bin/1
+ , round_bin/2
+ , scan_values/1
+ , scan_values/2
+ , scan_values2/2
+ , scan_values2/3
+ , skewness/2
+ , std_deviation/2
+ , update_bin/3
+ , variance/2
+ ]).
+-endif.
+
-define(HIST_BINS, 10).
-define(STATS_MIN, 5).
@@ -219,8 +250,7 @@ arithmetic_mean(#scan_result{n=N, sumX=Sum}) ->
geometric_mean(#scan_result{n=N, sumLog=SumLog}) ->
math:exp(SumLog/N).
-harmonic_mean(#scan_result{sumInv=Zero}) when Zero =:= 0 orelse
- Zero =:= 0.0 ->
+harmonic_mean(#scan_result{sumInv=Zero}) when Zero == 0 ->
%% Protect against divide by 0 if we have all 0 values
0;
harmonic_mean(#scan_result{n=N, sumInv=Sum}) ->
@@ -249,7 +279,7 @@ std_deviation(Scan_res, Scan_res2) ->
%% }
skewness(#scan_result{n=N}=Scan_res, #scan_result2{x3=X3}=Scan_res2) ->
case math:pow(std_deviation(Scan_res,Scan_res2), 3) of
- 0.0 ->
+ Num when Num == 0.0 ->
0.0; %% Is this really the correct thing to do here?
Else ->
(X3/N)/Else
@@ -265,7 +295,7 @@ skewness(#scan_result{n=N}=Scan_res, #scan_result2{x3=X3}=Scan_res2) ->
%% }
kurtosis(#scan_result{n=N}=Scan_res, #scan_result2{x4=X4}=Scan_res2) ->
case math:pow(std_deviation(Scan_res,Scan_res2), 4) of
- 0.0 ->
+ Num when Num == 0.0 ->
0.0; %% Is this really the correct thing to do here?
Else ->
((X4/N)/Else) - 3
@@ -367,7 +397,7 @@ get_pearson_correlation(Values1, Values2) ->
end, {0,0,0,0,0,0}, Values1, Values2),
Numer = (N*SumXY) - (SumX * SumY),
case math:sqrt(((N*SumXX)-(SumX*SumX)) * ((N*SumYY)-(SumY*SumY))) of
- 0.0 ->
+ Denom when Denom == 0.0 ->
0.0; %% Is this really the correct thing to do here?
Denom ->
Numer/Denom
@@ -385,7 +415,7 @@ foldl2(_F, Acc, [], []) ->
%% wrapper for math:log/1 to avoid dividing by zero
math_log(0) ->
1;
-math_log(0.0) ->
+math_log(Num) when Num == 0.0 ->
1.0;
math_log(X) when X < 0 ->
0; % it's not possible to take a log of a negative number, return 0
@@ -395,7 +425,7 @@ math_log(X) ->
%% wrapper for calculating inverse to avoid dividing by zero
inverse(0) ->
0;
-inverse(0.0) ->
+inverse(Num) when Num == 0.0 ->
0.0;
inverse(X) ->
1/X.
diff --git a/test/bear_test.erl b/test/bear_test.erl
index 27e61db..8adcf75 100644
--- a/test/bear_test.erl
+++ b/test/bear_test.erl
@@ -23,6 +23,7 @@
%%% ====================================================================
-module(bear_test).
+-compile(nowarn_export_all).
-compile(export_all).
-record(scan_result, {n=0, sumX=0, sumXX=0, sumInv=0, sumLog, max, min}).
@@ -127,6 +128,8 @@ geometric_mean_test() ->
harmonic_mean_test() ->
?assertEqual(0, bear:harmonic_mean(#scan_result{n=100, sumInv=0})),
+ ?assertEqual(0, bear:harmonic_mean(#scan_result{n=100, sumInv=0.0})),
+ ?assertEqual(0, bear:harmonic_mean(#scan_result{n=100, sumInv=-0.0})),
?assertEqual(10.0, bear:harmonic_mean(#scan_result{n=100, sumInv=10})).
percentile_test() ->
@@ -140,10 +143,18 @@ std_deviation_test() ->
?assertEqual(3.0, bear:std_deviation(#scan_result{n=10},#scan_result2{x2=81})).
skewness_test() ->
+ %% check the handling of -0.0 and +0.0 from math:pow/2 in bear:skewness/2
+ ?assertEqual(0.0, bear:skewness(#scan_result{n=0},#scan_result2{x2=0.0})),
+ ?assertEqual(0.0, bear:skewness(#scan_result{n=2},#scan_result2{x2=0.0})),
+ %%
?assertEqual(0.0, bear:skewness(#scan_result{n=10},#scan_result2{x2=0,x3=81})),
?assertEqual(3.0, bear:skewness(#scan_result{n=10},#scan_result2{x2=81,x3=810})).
kurtosis_test() ->
+ %% check the handling of -0.0 and +0.0 from math:pow/2 in bear:kurtosis/2
+ ?assertEqual(0.0, bear:skewness(#scan_result{n=0},#scan_result2{x2=0.0})),
+ ?assertEqual(0.0, bear:skewness(#scan_result{n=2},#scan_result2{x2=0.0})),
+ %%
?assertEqual(0.0, bear:kurtosis(#scan_result{n=10},#scan_result2{x2=0,x4=81})),
?assertEqual(-2.0, bear:kurtosis(#scan_result{n=10},#scan_result2{x2=81,x4=810})).
@@ -187,6 +198,11 @@ get_pearson_correlation_nullresult_test() ->
B = [1,0.25,0,0.25,1],
?assertEqual(0.0, bear:get_pearson_correlation(A, B)).
+get_pearson_correlation_zeros_test() ->
+ %% check the handling of +0.0 from math:sqrt/1 in bear:get_pearson_correlation/2
+ Zeros = lists:duplicate(5, 0),
+ ?assertEqual(0.0, bear:get_pearson_correlation(Zeros, Zeros)).
+
round_bin_test() ->
?assertEqual(10, bear:round_bin(10)),
?assertEqual(10, bear:round_bin(10, 5)),
@@ -227,11 +243,13 @@ get_spearman_correlation_regular_test()->
math_log_test() ->
?assertEqual(1, bear:math_log(0)),
?assertEqual(1.0, bear:math_log(0.0)),
+ ?assertEqual(1.0, bear:math_log(-0.0)),
?assertEqual(true, approx(3.737669618283368, bear:math_log(42))).
inverse_test() ->
?assertEqual(0, bear:inverse(0)),
?assertEqual(0.0, bear:inverse(0.0)),
+ ?assertEqual(0.0, bear:inverse(-0.0)),
?assertEqual(0.5, bear:inverse(2)).
get_hist_bins_test() ->