-- |
-- Module      :  Data.Statistics.RulesIntervals
-- Copyright   :  (c) OleksandrZhabenko 2020
-- License     :  MIT
-- Stability   :  Experimental
-- Maintainer  :  olexandr543@yahoo.com
--
-- Additional statistic rules to choose the number of the intervals.

{-# LANGUAGE BangPatterns #-}

module Data.Statistics.RulesIntervals where

import Data.Lists.FLines (newLineEnding)
import GHC.Real (ceiling)
import GHC.Float (int2Float)
import Data.Maybe (fromMaybe)
import Text.Read (readMaybe)

sturgesH :: Int -> Int
sturgesH :: Int -> Int
sturgesH Int
n
  | Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
n Int
0 Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
GT = Float -> Int
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Float -> Float -> Float
forall a. Floating a => a -> a -> a
logBase Float
2 (Int -> Float
int2Float Int
n))
  | Bool
otherwise = [Char] -> Int
forall a. HasCallStack => [Char] -> a
error ([Char] -> Int) -> [Char] -> Int
forall a b. (a -> b) -> a -> b
$ [Char]
"sturgesH: undefined for the argument " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
n [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
newLineEnding
{-# INLINE sturgesH #-}

-- | According to @В. П. Левинський@ (V. P. Levynskyi) from @Опря А. Т. Статистика (модульний варіант з програмованою формою контролю знань).
-- Навч. посіб. --- К.: Центр учбової літератури, 2012. --- 448 с. ISBN 978-611-01-0266-7@) page 60. Always return odd values.
levynskyiMod :: Int -> Int
levynskyiMod :: Int -> Int
levynskyiMod Int
n
  | Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
n Int
100 Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
LT = Int -> Int
forall a p. (Ord a, Num a, Num p) => a -> p
g Int
n
  | Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
n Int
200 Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
LT = Int
11
  | Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
n Int
300 Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
LT = Int
13
  | Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
n Int
400 Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
LT = Int
15
  | Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
n Int
500 Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
LT = Int
17
  | Bool
otherwise = let !k :: Int
k = Int -> Int
sturgesH Int
n in if Int -> Bool
forall a. Integral a => a -> Bool
even Int
k then Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
7 else Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
8
       where g :: a -> p
g a
n
              | a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a
n a
60 Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
GT = p
9
              | a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a
n a
40 Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
GT = p
7
              | a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a
n a
20 Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
GT = p
5
              | Bool
otherwise = p
3
{-# INLINABLE levynskyiMod #-}