{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
module Marvin.Test.TestUtils (
  isAround
  , nestedFromList
  , trainMatrix
  , equals
  , (+-)
) where

import Marvin.Test.Metric
import Marvin.API as Marvin

import Test.QuickCheck hiding (vector)
import qualified Test.QuickCheck as QC (vector)
import Numeric.LinearAlgebra.Data as LA
import Foreign.Storable

import qualified Data.Vector as Vec

nestedFromList = Vec.fromList . Prelude.map Vec.fromList

genVectorOfSize :: (Storable a, Arbitrary a) => Int -> Gen (Vector a)
genVectorOfSize n = do
  xs <- vectorOf n arbitrary
  return $ LA.fromList xs

instance (Storable a, Arbitrary a) => Arbitrary (Vector a) where
  arbitrary = sized genVectorOfSize

instance (Arbitrary a) => Arbitrary (Vec.Vector a) where
  arbitrary = Vec.fromList <$> arbitrary

instance Arbitrary NumericColumn where
  arbitrary = do
      t <- arbitrary
      h <- arbitrary
      let Right col = Marvin.fromList (h:t)
      return col

instance Arbitrary Error where
  arbitrary = do
    msg <- arbitrary
    return $ Marvin.Failure msg

isAround :: Metric a => a -> a -> Bool
isAround a x = dist a x <= threshold

infix 7 `equals`
equals :: Metric a => a -> a -> FloatPrecision -> Bool
equals x y (P e) = dist x y < e

newtype FloatPrecision = P Double

infix 8 +-
(+-) :: Double -> FloatPrecision
(+-) = P

threshold = 0.00001

trainMatrix = [
  [2,6,2,3,2,2,1,3,2,2,2,15.0],
  [1,6,1,3,3,1,1,2,2,4,2,14.5],
  [2,6,3,1,4,2,3,3,1,3,1,14.0],
  [2,6,1,4,4,2,2,3,2,4,2,16.0],
  [1,1,2,2,2,1,1,4,1,3,1,14.0],
  [1,3,2,1,1,1,2,2,1,2,1,16.5],
  [1,4,1,1,3,1,3,1,1,3,1,14.0],
  [1,3,2,3,2,1,2,3,1,3,1,16.5],
  [2,4,1,2,1,2,3,2,1,4,1,15.0],
  [2,4,1,1,2,2,3,3,1,3,1,16.0],
  [2,2,1,2,3,2,1,2,1,3,1,16.5],
  [2,5,2,2,1,2,3,1,2,1,2,15.0],
  [2,5,2,2,3,2,3,1,2,1,2,15.5],
  [2,6,1,4,3,2,2,3,2,4,2,15.5],
  [2,3,2,3,1,2,1,2,1,3,1,15.0],
  [1,1,2,4,3,1,1,1,1,2,1,15.0],
  [1,1,3,2,2,1,2,2,2,2,2,14.5],
  [1,2,1,1,2,1,2,1,1,4,1,16.0],
  [2,1,2,4,4,2,2,2,1,1,1,15.5],
  [2,2,2,2,3,2,3,4,1,2,1,14.5],
  [1,5,2,3,3,1,3,2,1,1,1,13.5],
  [2,5,3,4,4,2,2,4,2,3,2,16.0],
  [1,2,2,3,4,1,3,3,1,2,1,15.0],
  [2,3,1,2,2,2,2,2,1,1,1,14.5],
  [2,2,1,3,1,2,1,1,2,4,2,15.0],
  [1,1,2,3,4,1,1,2,1,4,1,14.5],
  [2,1,3,4,2,2,1,4,1,1,1,14.5],
  [1,3,3,4,3,1,3,4,2,4,2,15.5],
  [2,2,3,1,3,2,2,1,2,2,2,15.5],
  [1,5,1,2,4,1,2,1,2,4,2,15.5],
  [2,2,2,3,1,2,3,2,2,4,2,14.0],
  [1,2,3,4,2,1,1,4,1,3,1,17.0],
  [1,1,3,4,2,1,2,3,2,3,2,15.0],
  [1,2,1,2,1,1,2,3,1,3,1,16.0],
  [2,3,2,3,3,2,1,2,2,3,2,15.0],
  [2,5,1,1,4,2,1,4,2,1,2,16.0],
  [1,4,3,3,3,1,2,3,1,3,1,15.5],
  [1,2,3,3,3,1,1,3,2,1,2,16.5],
  [2,6,1,3,1,2,2,2,1,1,1,15.5],
  [1,6,2,1,1,1,2,3,2,3,2,15.0],
  [2,6,1,2,3,2,2,1,1,2,1,15.0],
  [2,2,1,4,2,2,1,4,2,1,2,15.0],
  [2,5,1,4,4,2,1,3,2,2,2,14.5],
  [1,5,1,3,1,1,2,2,2,2,2,14.5],
  [2,4,1,4,1,2,3,4,1,2,1,16.0],
  [1,6,1,4,2,1,1,4,2,3,2,14.5],
  [1,6,1,2,4,1,1,1,2,2,2,13.5],
  [2,6,1,1,2,2,2,4,1,3,1,15.0],
  [1,4,1,1,1,1,3,1,2,3,2,14.5],
  [2,1,1,4,3,2,3,3,2,3,2,15.0],
  [1,3,2,1,2,1,2,2,2,2,2,14.5],
  [2,5,1,2,2,2,1,1,1,4,1,15.5],
  [1,3,3,1,3,1,3,2,1,1,1,15.0],
  [1,2,3,4,3,1,1,4,2,3,2,16.5],
  [1,1,2,3,1,1,1,2,1,4,1,15.0],
  [1,5,3,1,2,1,1,1,1,2,1,14.0],
  [1,6,3,2,3,1,3,2,1,1,1,15.0],
  [2,5,3,1,3,2,2,3,1,4,1,14.0],
  [1,2,2,2,4,1,3,1,1,3,1,16.5],
  [2,1,2,3,4,2,2,3,1,4,1,16.0],
  [2,6,2,3,3,2,1,3,1,2,1,14.0],
  [1,3,3,1,1,1,3,2,2,1,2,15.5],
  [2,3,2,4,2,2,1,3,2,2,2,14.0],
  [1,5,2,2,1,1,3,4,1,4,1,14.5],
  [2,6,2,2,1,2,1,1,1,4,1,15.0],
  [1,2,3,1,4,1,1,2,2,4,2,16.0],
  [1,4,3,1,3,1,2,2,1,2,1,14.5],
  [2,5,3,4,3,2,2,4,2,3,2,15.0],
  [1,6,2,3,1,1,2,2,2,2,2,13.5],
  [2,4,1,3,4,2,3,1,1,1,1,15.0],
  [2,4,3,4,1,2,1,2,2,3,2,14.0],
  [1,4,3,4,1,1,2,4,2,1,2,15.5],
  [1,3,2,2,3,1,2,1,1,4,1,16.0],
  [1,6,3,3,2,1,3,4,1,4,1,15.0],
  [1,3,3,2,2,1,3,1,1,3,1,15.5],
  [1,6,2,4,3,1,2,1,2,4,2,15.5],
  [2,2,3,1,1,2,2,1,2,2,2,14.5],
  [2,2,2,3,2,2,3,2,1,4,1,14.5],
  [2,2,1,2,2,2,1,2,1,3,1,15.0],
  [2,5,2,3,2,2,3,3,1,3,1,15.0]]

testMatrix = [
  [1,1,1,4,4,1,3,4,1,4,1,16.0],
  [1,4,3,3,1,1,2,3,1,3,1,15.5],
  [2,2,1,4,4,2,1,4,2,1,2,15.0],
  [1,5,2,4,3,1,3,1,1,3,1,15.0],
  [1,4,2,1,2,1,1,2,2,4,2,14.5],
  [1,1,2,1,4,1,1,3,2,1,2,15.0],
  [1,1,3,1,3,1,2,1,2,4,2,15.0],
  [1,4,2,1,1,1,1,2,1,4,1,14.5],
  [2,6,1,4,2,2,2,3,1,4,1,15.0],
  [2,5,1,3,2,2,1,2,2,3,2,15.5],
  [1,6,1,3,1,1,1,2,1,4,1,15.0],
  [2,3,2,1,3,2,1,1,1,4,1,15.5],
  [1,2,2,3,3,1,3,3,2,2,2,14.0],
  [1,4,1,1,2,1,3,1,2,3,2,14.0],
  [1,2,1,2,4,1,2,3,2,3,2,15.0],
  [1,2,2,2,1,1,3,1,2,3,2,16.0],
  [1,5,1,1,1,1,2,3,1,3,1,15.5],
  [1,3,2,4,3,1,2,4,2,1,2,17.0],
  [2,1,3,4,3,2,1,4,2,1,2,15.5],
  [2,5,2,3,1,2,3,3,2,3,2,15.0]]
