module Network.Mux.DeltaQ.TraceStatsSupport where

-- This module is making use of hackage statistical libraries. They
-- are not the most efficient approaches for this particular use
-- case, and they may increase the package dependencies for the final
-- binaries (they have a lot of dependencies).
--
-- It may well be worthwhile constructing specialised version for the
-- specific use case, but building those and creating the associated
-- test suite was not deemed a good use of time (at the time of
-- creation).
--
-- Definite space/time optimisation task here.

import Network.Mux.DeltaQ.TraceTypes

import Data.Vector.Unboxed qualified as V
import Statistics.LinearRegression

estimateGS :: [(Int, SISec)] -> (Double, Double, Double)
estimateGS :: [(Int, SISec)] -> (Double, Double, Double)
estimateGS [(Int, SISec)]
xys
  = let ([Int]
xs', [SISec]
ys') = [(Int, SISec)] -> ([Int], [SISec])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Int, SISec)]
xys
        xs :: Vector Double
xs = [Double] -> Vector Double
forall a. Unbox a => [a] -> Vector a
V.fromList ([Double] -> Vector Double) -> [Double] -> Vector Double
forall a b. (a -> b) -> a -> b
$ (Int -> Double) -> [Int] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral [Int]
xs'
        ys :: Vector Double
ys = [Double] -> Vector Double
forall a. Unbox a => [a] -> Vector a
V.fromList ([Double] -> Vector Double) -> [Double] -> Vector Double
forall a b. (a -> b) -> a -> b
$ (SISec -> Double) -> [SISec] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map (\(S Float
x) -> Rational -> Double
forall a. Fractional a => Rational -> a
fromRational (Rational -> Double) -> (Float -> Rational) -> Float -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Float -> Rational
forall a. Real a => a -> Rational
toRational (Float -> Double) -> Float -> Double
forall a b. (a -> b) -> a -> b
$ Float
x) [SISec]
ys'
    in Vector Double -> Vector Double -> (Double, Double, Double)
forall (v :: * -> *).
Vector v Double =>
v Double -> v Double -> (Double, Double, Double)
linearRegressionRSqr Vector Double
xs Vector Double
ys