{-# LANGUAGE BangPatterns      #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts  #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeOperators     #-}
{-# OPTIONS_HADDOCK hide #-}
-- |
-- Module      : Data.Array.Accelerate.Test.Similar
-- Copyright   : [2009..2020] The Accelerate Team
-- License     : BSD3
--
-- Maintainer  : Trevor L. McDonell <trevor.mcdonell@gmail.com>
-- Stability   : experimental
-- Portability : non-portable (GHC extensions)
--

module Data.Array.Accelerate.Test.Similar
  where

import Data.Array.Accelerate.Data.Complex
import Data.Array.Accelerate.Sugar.Array
import Data.Array.Accelerate.Sugar.Elt
import Data.Array.Accelerate.Sugar.Shape
import Data.Array.Accelerate.Type

import Hedgehog
import Hedgehog.Internal.Source                           ( HasCallStack, withFrozenCallStack )

import Prelude                                            hiding ( (!!) )


-- | Fails the test if the two arguments are not equal, allowing for a small
-- amount of floating point inaccuracy.
--
infix 4 ~~~
(~~~) :: (MonadTest m, Similar a, Show a, HasCallStack) => a -> a -> m ()
a
a ~~~ :: a -> a -> m ()
~~~ a
b = (HasCallStack => m ()) -> m ()
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => m ()) -> m ()) -> (HasCallStack => m ()) -> m ()
forall a b. (a -> b) -> a -> b
$ a -> Sim a
forall a. a -> Sim a
Sim a
a Sim a -> Sim a -> m ()
forall (m :: * -> *) a.
(MonadTest m, Eq a, Show a, HasCallStack) =>
a -> a -> m ()
=== a -> Sim a
forall a. a -> Sim a
Sim a
b

data Sim a = Sim a

instance Similar a => Eq (Sim a) where
  Sim a
a == :: Sim a -> Sim a -> Bool
== Sim a
b = a
a a -> a -> Bool
forall a. Similar a => a -> a -> Bool
~= a
b

instance Show a => Show (Sim a) where
  show :: Sim a -> String
show (Sim a
a) = a -> String
forall a. Show a => a -> String
show a
a


-- | A class of things that support almost-equality, so that we can disregard
-- small amounts of floating-point round-off error.
--
class Similar a where
  {-# INLINE (~=) #-}
  (~=) :: a -> a -> Bool
  default (~=) :: Eq a => a -> a -> Bool
  (~=) = a -> a -> Bool
forall a. Eq a => a -> a -> Bool
(==)

infix 4 ~=

instance Similar ()
instance Similar Z
instance Similar All
instance Similar Int
instance Similar Int8
instance Similar Int16
instance Similar Int32
instance Similar Int64
instance Similar Word8
instance Similar Word16
instance Similar Word32
instance Similar Word64
instance Similar Char
instance Similar Bool
instance Similar CShort
instance Similar CUShort
instance Similar CInt
instance Similar CUInt
instance Similar CLong
instance Similar CULong
instance Similar CLLong
instance Similar CULLong
instance Similar CChar
instance Similar CSChar
instance Similar CUChar

instance                   Similar (Any Z)
instance (Eq sh, Eq sz) => Similar (sh:.sz)
instance (Eq sh)        => Similar (Any (sh:.Int))

instance Similar Half    where ~= :: Half -> Half -> Bool
(~=) = Half -> Half -> Half -> Half -> Bool
forall a. RealFloat a => a -> a -> a -> a -> Bool
absRelTol Half
0.05    Half
0.5
instance Similar Float   where ~= :: Float -> Float -> Bool
(~=) = Float -> Float -> Float -> Float -> Bool
forall a. RealFloat a => a -> a -> a -> a -> Bool
absRelTol Float
0.00005 Float
0.005
instance Similar Double  where ~= :: Double -> Double -> Bool
(~=) = Double -> Double -> Double -> Double -> Bool
forall a. RealFloat a => a -> a -> a -> a -> Bool
absRelTol Double
0.00005 Double
0.005
instance Similar CFloat  where ~= :: CFloat -> CFloat -> Bool
(~=) = CFloat -> CFloat -> CFloat -> CFloat -> Bool
forall a. RealFloat a => a -> a -> a -> a -> Bool
absRelTol CFloat
0.00005 CFloat
0.005
instance Similar CDouble where ~= :: CDouble -> CDouble -> Bool
(~=) = CDouble -> CDouble -> CDouble -> CDouble -> Bool
forall a. RealFloat a => a -> a -> a -> a -> Bool
absRelTol CDouble
0.00005 CDouble
0.005

instance (Similar a, Similar b) => Similar (a, b) where
  (a
x1, b
x2) ~= :: (a, b) -> (a, b) -> Bool
~= (a
y1, b
y2) = a
x1 a -> a -> Bool
forall a. Similar a => a -> a -> Bool
~= a
y1 Bool -> Bool -> Bool
&& b
x2 b -> b -> Bool
forall a. Similar a => a -> a -> Bool
~= b
y2

instance (Similar a, Similar b, Similar c) => Similar (a, b, c) where
  (a
x1, b
x2, c
x3) ~= :: (a, b, c) -> (a, b, c) -> Bool
~= (a
y1, b
y2, c
y3) = a
x1 a -> a -> Bool
forall a. Similar a => a -> a -> Bool
~= a
y1 Bool -> Bool -> Bool
&& b
x2 b -> b -> Bool
forall a. Similar a => a -> a -> Bool
~= b
y2 Bool -> Bool -> Bool
&& c
x3 c -> c -> Bool
forall a. Similar a => a -> a -> Bool
~= c
y3

instance (Similar a, Similar b, Similar c, Similar d) => Similar (a, b, c, d) where
  (a
x1, b
x2, c
x3, d
x4) ~= :: (a, b, c, d) -> (a, b, c, d) -> Bool
~= (a
y1, b
y2, c
y3, d
y4) = a
x1 a -> a -> Bool
forall a. Similar a => a -> a -> Bool
~= a
y1 Bool -> Bool -> Bool
&& b
x2 b -> b -> Bool
forall a. Similar a => a -> a -> Bool
~= b
y2 Bool -> Bool -> Bool
&& c
x3 c -> c -> Bool
forall a. Similar a => a -> a -> Bool
~= c
y3 Bool -> Bool -> Bool
&& d
x4 d -> d -> Bool
forall a. Similar a => a -> a -> Bool
~= d
y4

instance (Similar a, Similar b, Similar c, Similar d, Similar e)
    => Similar (a, b, c, d, e) where
  (a
x1, b
x2, c
x3, d
x4, e
x5) ~= :: (a, b, c, d, e) -> (a, b, c, d, e) -> Bool
~= (a
y1, b
y2, c
y3, d
y4, e
y5) =
    a
x1 a -> a -> Bool
forall a. Similar a => a -> a -> Bool
~= a
y1 Bool -> Bool -> Bool
&& b
x2 b -> b -> Bool
forall a. Similar a => a -> a -> Bool
~= b
y2 Bool -> Bool -> Bool
&& c
x3 c -> c -> Bool
forall a. Similar a => a -> a -> Bool
~= c
y3 Bool -> Bool -> Bool
&& d
x4 d -> d -> Bool
forall a. Similar a => a -> a -> Bool
~= d
y4 Bool -> Bool -> Bool
&& e
x5 e -> e -> Bool
forall a. Similar a => a -> a -> Bool
~= e
y5

instance (Similar a, Similar b, Similar c, Similar d, Similar e, Similar f)
    => Similar (a, b, c, d, e, f) where
  (a
x1, b
x2, c
x3, d
x4, e
x5, f
x6) ~= :: (a, b, c, d, e, f) -> (a, b, c, d, e, f) -> Bool
~= (a
y1, b
y2, c
y3, d
y4, e
y5, f
y6) =
    a
x1 a -> a -> Bool
forall a. Similar a => a -> a -> Bool
~= a
y1 Bool -> Bool -> Bool
&& b
x2 b -> b -> Bool
forall a. Similar a => a -> a -> Bool
~= b
y2 Bool -> Bool -> Bool
&& c
x3 c -> c -> Bool
forall a. Similar a => a -> a -> Bool
~= c
y3 Bool -> Bool -> Bool
&& d
x4 d -> d -> Bool
forall a. Similar a => a -> a -> Bool
~= d
y4 Bool -> Bool -> Bool
&& e
x5 e -> e -> Bool
forall a. Similar a => a -> a -> Bool
~= e
y5 Bool -> Bool -> Bool
&& f
x6 f -> f -> Bool
forall a. Similar a => a -> a -> Bool
~= f
y6

instance (Similar a, Similar b, Similar c, Similar d, Similar e, Similar f, Similar g)
    => Similar (a, b, c, d, e, f, g) where
  (a
x1, b
x2, c
x3, d
x4, e
x5, f
x6, g
x7) ~= :: (a, b, c, d, e, f, g) -> (a, b, c, d, e, f, g) -> Bool
~= (a
y1, b
y2, c
y3, d
y4, e
y5, f
y6, g
y7) =
    a
x1 a -> a -> Bool
forall a. Similar a => a -> a -> Bool
~= a
y1 Bool -> Bool -> Bool
&& b
x2 b -> b -> Bool
forall a. Similar a => a -> a -> Bool
~= b
y2 Bool -> Bool -> Bool
&& c
x3 c -> c -> Bool
forall a. Similar a => a -> a -> Bool
~= c
y3 Bool -> Bool -> Bool
&& d
x4 d -> d -> Bool
forall a. Similar a => a -> a -> Bool
~= d
y4 Bool -> Bool -> Bool
&& e
x5 e -> e -> Bool
forall a. Similar a => a -> a -> Bool
~= e
y5 Bool -> Bool -> Bool
&& f
x6 f -> f -> Bool
forall a. Similar a => a -> a -> Bool
~= f
y6 Bool -> Bool -> Bool
&& g
x7 g -> g -> Bool
forall a. Similar a => a -> a -> Bool
~= g
y7

instance (Similar a, Similar b, Similar c, Similar d, Similar e, Similar f, Similar g, Similar h)
    => Similar (a, b, c, d, e, f, g, h) where
  (a
x1, b
x2, c
x3, d
x4, e
x5, f
x6, g
x7, h
x8) ~= :: (a, b, c, d, e, f, g, h) -> (a, b, c, d, e, f, g, h) -> Bool
~= (a
y1, b
y2, c
y3, d
y4, e
y5, f
y6, g
y7, h
y8) =
    a
x1 a -> a -> Bool
forall a. Similar a => a -> a -> Bool
~= a
y1 Bool -> Bool -> Bool
&& b
x2 b -> b -> Bool
forall a. Similar a => a -> a -> Bool
~= b
y2 Bool -> Bool -> Bool
&& c
x3 c -> c -> Bool
forall a. Similar a => a -> a -> Bool
~= c
y3 Bool -> Bool -> Bool
&& d
x4 d -> d -> Bool
forall a. Similar a => a -> a -> Bool
~= d
y4 Bool -> Bool -> Bool
&& e
x5 e -> e -> Bool
forall a. Similar a => a -> a -> Bool
~= e
y5 Bool -> Bool -> Bool
&& f
x6 f -> f -> Bool
forall a. Similar a => a -> a -> Bool
~= f
y6 Bool -> Bool -> Bool
&& g
x7 g -> g -> Bool
forall a. Similar a => a -> a -> Bool
~= g
y7 Bool -> Bool -> Bool
&& h
x8 h -> h -> Bool
forall a. Similar a => a -> a -> Bool
~= h
y8

instance (Similar a, Similar b, Similar c, Similar d, Similar e, Similar f, Similar g, Similar h, Similar i)
    => Similar (a, b, c, d, e, f, g, h, i) where
  (a
x1, b
x2, c
x3, d
x4, e
x5, f
x6, g
x7, h
x8, i
x9) ~= :: (a, b, c, d, e, f, g, h, i) -> (a, b, c, d, e, f, g, h, i) -> Bool
~= (a
y1, b
y2, c
y3, d
y4, e
y5, f
y6, g
y7, h
y8, i
y9) =
    a
x1 a -> a -> Bool
forall a. Similar a => a -> a -> Bool
~= a
y1 Bool -> Bool -> Bool
&& b
x2 b -> b -> Bool
forall a. Similar a => a -> a -> Bool
~= b
y2 Bool -> Bool -> Bool
&& c
x3 c -> c -> Bool
forall a. Similar a => a -> a -> Bool
~= c
y3 Bool -> Bool -> Bool
&& d
x4 d -> d -> Bool
forall a. Similar a => a -> a -> Bool
~= d
y4 Bool -> Bool -> Bool
&& e
x5 e -> e -> Bool
forall a. Similar a => a -> a -> Bool
~= e
y5 Bool -> Bool -> Bool
&& f
x6 f -> f -> Bool
forall a. Similar a => a -> a -> Bool
~= f
y6 Bool -> Bool -> Bool
&& g
x7 g -> g -> Bool
forall a. Similar a => a -> a -> Bool
~= g
y7 Bool -> Bool -> Bool
&& h
x8 h -> h -> Bool
forall a. Similar a => a -> a -> Bool
~= h
y8 Bool -> Bool -> Bool
&& i
x9 i -> i -> Bool
forall a. Similar a => a -> a -> Bool
~= i
y9

instance (Similar a, Similar b, Similar c, Similar d, Similar e, Similar f, Similar g, Similar h, Similar i, Similar j)
    => Similar (a, b, c, d, e, f, g, h, i, j) where
  (a
x1, b
x2, c
x3, d
x4, e
x5, f
x6, g
x7, h
x8, i
x9, j
x10) ~= :: (a, b, c, d, e, f, g, h, i, j)
-> (a, b, c, d, e, f, g, h, i, j) -> Bool
~= (a
y1, b
y2, c
y3, d
y4, e
y5, f
y6, g
y7, h
y8, i
y9, j
y10) =
    a
x1 a -> a -> Bool
forall a. Similar a => a -> a -> Bool
~= a
y1 Bool -> Bool -> Bool
&& b
x2 b -> b -> Bool
forall a. Similar a => a -> a -> Bool
~= b
y2 Bool -> Bool -> Bool
&& c
x3 c -> c -> Bool
forall a. Similar a => a -> a -> Bool
~= c
y3 Bool -> Bool -> Bool
&& d
x4 d -> d -> Bool
forall a. Similar a => a -> a -> Bool
~= d
y4 Bool -> Bool -> Bool
&& e
x5 e -> e -> Bool
forall a. Similar a => a -> a -> Bool
~= e
y5 Bool -> Bool -> Bool
&& f
x6 f -> f -> Bool
forall a. Similar a => a -> a -> Bool
~= f
y6 Bool -> Bool -> Bool
&& g
x7 g -> g -> Bool
forall a. Similar a => a -> a -> Bool
~= g
y7 Bool -> Bool -> Bool
&& h
x8 h -> h -> Bool
forall a. Similar a => a -> a -> Bool
~= h
y8 Bool -> Bool -> Bool
&& i
x9 i -> i -> Bool
forall a. Similar a => a -> a -> Bool
~= i
y9 Bool -> Bool -> Bool
&& j
x10 j -> j -> Bool
forall a. Similar a => a -> a -> Bool
~= j
y10

instance (Similar a, Similar b, Similar c, Similar d, Similar e, Similar f, Similar g, Similar h, Similar i, Similar j, Similar k)
    => Similar (a, b, c, d, e, f, g, h, i, j, k) where
  (a
x1, b
x2, c
x3, d
x4, e
x5, f
x6, g
x7, h
x8, i
x9, j
x10, k
x11) ~= :: (a, b, c, d, e, f, g, h, i, j, k)
-> (a, b, c, d, e, f, g, h, i, j, k) -> Bool
~= (a
y1, b
y2, c
y3, d
y4, e
y5, f
y6, g
y7, h
y8, i
y9, j
y10, k
y11) =
    a
x1 a -> a -> Bool
forall a. Similar a => a -> a -> Bool
~= a
y1 Bool -> Bool -> Bool
&& b
x2 b -> b -> Bool
forall a. Similar a => a -> a -> Bool
~= b
y2 Bool -> Bool -> Bool
&& c
x3 c -> c -> Bool
forall a. Similar a => a -> a -> Bool
~= c
y3 Bool -> Bool -> Bool
&& d
x4 d -> d -> Bool
forall a. Similar a => a -> a -> Bool
~= d
y4 Bool -> Bool -> Bool
&& e
x5 e -> e -> Bool
forall a. Similar a => a -> a -> Bool
~= e
y5 Bool -> Bool -> Bool
&& f
x6 f -> f -> Bool
forall a. Similar a => a -> a -> Bool
~= f
y6 Bool -> Bool -> Bool
&& g
x7 g -> g -> Bool
forall a. Similar a => a -> a -> Bool
~= g
y7 Bool -> Bool -> Bool
&& h
x8 h -> h -> Bool
forall a. Similar a => a -> a -> Bool
~= h
y8 Bool -> Bool -> Bool
&& i
x9 i -> i -> Bool
forall a. Similar a => a -> a -> Bool
~= i
y9 Bool -> Bool -> Bool
&& j
x10 j -> j -> Bool
forall a. Similar a => a -> a -> Bool
~= j
y10 Bool -> Bool -> Bool
&& k
x11 k -> k -> Bool
forall a. Similar a => a -> a -> Bool
~= k
y11

instance (Similar a, Similar b, Similar c, Similar d, Similar e, Similar f, Similar g, Similar h, Similar i, Similar j, Similar k, Similar l)
    => Similar (a, b, c, d, e, f, g, h, i, j, k, l) where
  (a
x1, b
x2, c
x3, d
x4, e
x5, f
x6, g
x7, h
x8, i
x9, j
x10, k
x11, l
x12) ~= :: (a, b, c, d, e, f, g, h, i, j, k, l)
-> (a, b, c, d, e, f, g, h, i, j, k, l) -> Bool
~= (a
y1, b
y2, c
y3, d
y4, e
y5, f
y6, g
y7, h
y8, i
y9, j
y10, k
y11, l
y12) =
    a
x1 a -> a -> Bool
forall a. Similar a => a -> a -> Bool
~= a
y1 Bool -> Bool -> Bool
&& b
x2 b -> b -> Bool
forall a. Similar a => a -> a -> Bool
~= b
y2 Bool -> Bool -> Bool
&& c
x3 c -> c -> Bool
forall a. Similar a => a -> a -> Bool
~= c
y3 Bool -> Bool -> Bool
&& d
x4 d -> d -> Bool
forall a. Similar a => a -> a -> Bool
~= d
y4 Bool -> Bool -> Bool
&& e
x5 e -> e -> Bool
forall a. Similar a => a -> a -> Bool
~= e
y5 Bool -> Bool -> Bool
&& f
x6 f -> f -> Bool
forall a. Similar a => a -> a -> Bool
~= f
y6 Bool -> Bool -> Bool
&& g
x7 g -> g -> Bool
forall a. Similar a => a -> a -> Bool
~= g
y7 Bool -> Bool -> Bool
&& h
x8 h -> h -> Bool
forall a. Similar a => a -> a -> Bool
~= h
y8 Bool -> Bool -> Bool
&& i
x9 i -> i -> Bool
forall a. Similar a => a -> a -> Bool
~= i
y9 Bool -> Bool -> Bool
&& j
x10 j -> j -> Bool
forall a. Similar a => a -> a -> Bool
~= j
y10 Bool -> Bool -> Bool
&& k
x11 k -> k -> Bool
forall a. Similar a => a -> a -> Bool
~= k
y11 Bool -> Bool -> Bool
&& l
x12 l -> l -> Bool
forall a. Similar a => a -> a -> Bool
~= l
y12

instance (Similar a, Similar b, Similar c, Similar d, Similar e, Similar f, Similar g, Similar h, Similar i, Similar j, Similar k, Similar l, Similar m)
    => Similar (a, b, c, d, e, f, g, h, i, j, k, l, m) where
  (a
x1, b
x2, c
x3, d
x4, e
x5, f
x6, g
x7, h
x8, i
x9, j
x10, k
x11, l
x12, m
x13) ~= :: (a, b, c, d, e, f, g, h, i, j, k, l, m)
-> (a, b, c, d, e, f, g, h, i, j, k, l, m) -> Bool
~= (a
y1, b
y2, c
y3, d
y4, e
y5, f
y6, g
y7, h
y8, i
y9, j
y10, k
y11, l
y12, m
y13) =
    a
x1 a -> a -> Bool
forall a. Similar a => a -> a -> Bool
~= a
y1 Bool -> Bool -> Bool
&& b
x2 b -> b -> Bool
forall a. Similar a => a -> a -> Bool
~= b
y2 Bool -> Bool -> Bool
&& c
x3 c -> c -> Bool
forall a. Similar a => a -> a -> Bool
~= c
y3 Bool -> Bool -> Bool
&& d
x4 d -> d -> Bool
forall a. Similar a => a -> a -> Bool
~= d
y4 Bool -> Bool -> Bool
&& e
x5 e -> e -> Bool
forall a. Similar a => a -> a -> Bool
~= e
y5 Bool -> Bool -> Bool
&& f
x6 f -> f -> Bool
forall a. Similar a => a -> a -> Bool
~= f
y6 Bool -> Bool -> Bool
&& g
x7 g -> g -> Bool
forall a. Similar a => a -> a -> Bool
~= g
y7 Bool -> Bool -> Bool
&& h
x8 h -> h -> Bool
forall a. Similar a => a -> a -> Bool
~= h
y8 Bool -> Bool -> Bool
&& i
x9 i -> i -> Bool
forall a. Similar a => a -> a -> Bool
~= i
y9 Bool -> Bool -> Bool
&& j
x10 j -> j -> Bool
forall a. Similar a => a -> a -> Bool
~= j
y10 Bool -> Bool -> Bool
&& k
x11 k -> k -> Bool
forall a. Similar a => a -> a -> Bool
~= k
y11 Bool -> Bool -> Bool
&& l
x12 l -> l -> Bool
forall a. Similar a => a -> a -> Bool
~= l
y12 Bool -> Bool -> Bool
&& m
x13 m -> m -> Bool
forall a. Similar a => a -> a -> Bool
~= m
y13

instance (Similar a, Similar b, Similar c, Similar d, Similar e, Similar f, Similar g, Similar h, Similar i, Similar j, Similar k, Similar l, Similar m, Similar n)
    => Similar (a, b, c, d, e, f, g, h, i, j, k, l, m, n) where
  (a
x1, b
x2, c
x3, d
x4, e
x5, f
x6, g
x7, h
x8, i
x9, j
x10, k
x11, l
x12, m
x13, n
x14) ~= :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n)
-> (a, b, c, d, e, f, g, h, i, j, k, l, m, n) -> Bool
~= (a
y1, b
y2, c
y3, d
y4, e
y5, f
y6, g
y7, h
y8, i
y9, j
y10, k
y11, l
y12, m
y13, n
y14) =
    a
x1 a -> a -> Bool
forall a. Similar a => a -> a -> Bool
~= a
y1 Bool -> Bool -> Bool
&& b
x2 b -> b -> Bool
forall a. Similar a => a -> a -> Bool
~= b
y2 Bool -> Bool -> Bool
&& c
x3 c -> c -> Bool
forall a. Similar a => a -> a -> Bool
~= c
y3 Bool -> Bool -> Bool
&& d
x4 d -> d -> Bool
forall a. Similar a => a -> a -> Bool
~= d
y4 Bool -> Bool -> Bool
&& e
x5 e -> e -> Bool
forall a. Similar a => a -> a -> Bool
~= e
y5 Bool -> Bool -> Bool
&& f
x6 f -> f -> Bool
forall a. Similar a => a -> a -> Bool
~= f
y6 Bool -> Bool -> Bool
&& g
x7 g -> g -> Bool
forall a. Similar a => a -> a -> Bool
~= g
y7 Bool -> Bool -> Bool
&& h
x8 h -> h -> Bool
forall a. Similar a => a -> a -> Bool
~= h
y8 Bool -> Bool -> Bool
&& i
x9 i -> i -> Bool
forall a. Similar a => a -> a -> Bool
~= i
y9 Bool -> Bool -> Bool
&& j
x10 j -> j -> Bool
forall a. Similar a => a -> a -> Bool
~= j
y10 Bool -> Bool -> Bool
&& k
x11 k -> k -> Bool
forall a. Similar a => a -> a -> Bool
~= k
y11 Bool -> Bool -> Bool
&& l
x12 l -> l -> Bool
forall a. Similar a => a -> a -> Bool
~= l
y12 Bool -> Bool -> Bool
&& m
x13 m -> m -> Bool
forall a. Similar a => a -> a -> Bool
~= m
y13 Bool -> Bool -> Bool
&& n
x14 n -> n -> Bool
forall a. Similar a => a -> a -> Bool
~= n
y14

instance (Similar a, Similar b, Similar c, Similar d, Similar e, Similar f, Similar g, Similar h, Similar i, Similar j, Similar k, Similar l, Similar m, Similar n, Similar o)
    => Similar (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) where
  (a
x1, b
x2, c
x3, d
x4, e
x5, f
x6, g
x7, h
x8, i
x9, j
x10, k
x11, l
x12, m
x13, n
x14, o
x15) ~= :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
-> (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) -> Bool
~= (a
y1, b
y2, c
y3, d
y4, e
y5, f
y6, g
y7, h
y8, i
y9, j
y10, k
y11, l
y12, m
y13, n
y14, o
y15) =
    a
x1 a -> a -> Bool
forall a. Similar a => a -> a -> Bool
~= a
y1 Bool -> Bool -> Bool
&& b
x2 b -> b -> Bool
forall a. Similar a => a -> a -> Bool
~= b
y2 Bool -> Bool -> Bool
&& c
x3 c -> c -> Bool
forall a. Similar a => a -> a -> Bool
~= c
y3 Bool -> Bool -> Bool
&& d
x4 d -> d -> Bool
forall a. Similar a => a -> a -> Bool
~= d
y4 Bool -> Bool -> Bool
&& e
x5 e -> e -> Bool
forall a. Similar a => a -> a -> Bool
~= e
y5 Bool -> Bool -> Bool
&& f
x6 f -> f -> Bool
forall a. Similar a => a -> a -> Bool
~= f
y6 Bool -> Bool -> Bool
&& g
x7 g -> g -> Bool
forall a. Similar a => a -> a -> Bool
~= g
y7 Bool -> Bool -> Bool
&& h
x8 h -> h -> Bool
forall a. Similar a => a -> a -> Bool
~= h
y8 Bool -> Bool -> Bool
&& i
x9 i -> i -> Bool
forall a. Similar a => a -> a -> Bool
~= i
y9 Bool -> Bool -> Bool
&& j
x10 j -> j -> Bool
forall a. Similar a => a -> a -> Bool
~= j
y10 Bool -> Bool -> Bool
&& k
x11 k -> k -> Bool
forall a. Similar a => a -> a -> Bool
~= k
y11 Bool -> Bool -> Bool
&& l
x12 l -> l -> Bool
forall a. Similar a => a -> a -> Bool
~= l
y12 Bool -> Bool -> Bool
&& m
x13 m -> m -> Bool
forall a. Similar a => a -> a -> Bool
~= m
y13 Bool -> Bool -> Bool
&& n
x14 n -> n -> Bool
forall a. Similar a => a -> a -> Bool
~= n
y14 Bool -> Bool -> Bool
&& o
x15 o -> o -> Bool
forall a. Similar a => a -> a -> Bool
~= o
y15

instance (Similar a, Similar b, Similar c, Similar d, Similar e, Similar f, Similar g, Similar h, Similar i, Similar j, Similar k, Similar l, Similar m, Similar n, Similar o, Similar p)
    => Similar (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) where
  (a
x1, b
x2, c
x3, d
x4, e
x5, f
x6, g
x7, h
x8, i
x9, j
x10, k
x11, l
x12, m
x13, n
x14, o
x15, p
x16) ~= :: (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p)
-> (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) -> Bool
~= (a
y1, b
y2, c
y3, d
y4, e
y5, f
y6, g
y7, h
y8, i
y9, j
y10, k
y11, l
y12, m
y13, n
y14, o
y15, p
y16) =
    a
x1 a -> a -> Bool
forall a. Similar a => a -> a -> Bool
~= a
y1 Bool -> Bool -> Bool
&& b
x2 b -> b -> Bool
forall a. Similar a => a -> a -> Bool
~= b
y2 Bool -> Bool -> Bool
&& c
x3 c -> c -> Bool
forall a. Similar a => a -> a -> Bool
~= c
y3 Bool -> Bool -> Bool
&& d
x4 d -> d -> Bool
forall a. Similar a => a -> a -> Bool
~= d
y4 Bool -> Bool -> Bool
&& e
x5 e -> e -> Bool
forall a. Similar a => a -> a -> Bool
~= e
y5 Bool -> Bool -> Bool
&& f
x6 f -> f -> Bool
forall a. Similar a => a -> a -> Bool
~= f
y6 Bool -> Bool -> Bool
&& g
x7 g -> g -> Bool
forall a. Similar a => a -> a -> Bool
~= g
y7 Bool -> Bool -> Bool
&& h
x8 h -> h -> Bool
forall a. Similar a => a -> a -> Bool
~= h
y8 Bool -> Bool -> Bool
&& i
x9 i -> i -> Bool
forall a. Similar a => a -> a -> Bool
~= i
y9 Bool -> Bool -> Bool
&& j
x10 j -> j -> Bool
forall a. Similar a => a -> a -> Bool
~= j
y10 Bool -> Bool -> Bool
&& k
x11 k -> k -> Bool
forall a. Similar a => a -> a -> Bool
~= k
y11 Bool -> Bool -> Bool
&& l
x12 l -> l -> Bool
forall a. Similar a => a -> a -> Bool
~= l
y12 Bool -> Bool -> Bool
&& m
x13 m -> m -> Bool
forall a. Similar a => a -> a -> Bool
~= m
y13 Bool -> Bool -> Bool
&& n
x14 n -> n -> Bool
forall a. Similar a => a -> a -> Bool
~= n
y14 Bool -> Bool -> Bool
&& o
x15 o -> o -> Bool
forall a. Similar a => a -> a -> Bool
~= o
y15 Bool -> Bool -> Bool
&& p
x16 p -> p -> Bool
forall a. Similar a => a -> a -> Bool
~= p
y16

instance Similar e => Similar (Complex e) where
  (e
r1 :+ e
i1) ~= :: Complex e -> Complex e -> Bool
~= (e
r2 :+ e
i2) = e
r1 e -> e -> Bool
forall a. Similar a => a -> a -> Bool
~= e
r2 Bool -> Bool -> Bool
&& e
i1 e -> e -> Bool
forall a. Similar a => a -> a -> Bool
~= e
i2

instance Similar a => Similar [a] where
  []     ~= :: [a] -> [a] -> Bool
~= []     = Bool
True
  (a
x:[a]
xs) ~= (a
y:[a]
ys) = a
x a -> a -> Bool
forall a. Similar a => a -> a -> Bool
~= a
y Bool -> Bool -> Bool
&& [a]
xs [a] -> [a] -> Bool
forall a. Similar a => a -> a -> Bool
~= [a]
ys
  [a]
_      ~= [a]
_      = Bool
False

instance (Similar e, Eq sh, Shape sh, Elt e) => Similar (Array sh e) where
  Array sh e
a1 ~= :: Array sh e -> Array sh e -> Bool
~= Array sh e
a2 = Array sh e -> sh
forall sh e. Shape sh => Array sh e -> sh
shape Array sh e
a1 sh -> sh -> Bool
forall a. Eq a => a -> a -> Bool
== Array sh e -> sh
forall sh e. Shape sh => Array sh e -> sh
shape Array sh e
a2 Bool -> Bool -> Bool
&& Int -> Bool
go Int
0
    where
      n :: Int
n     = sh -> Int
forall sh. Shape sh => sh -> Int
size (Array sh e -> sh
forall sh e. Shape sh => Array sh e -> sh
shape Array sh e
a1)
      go :: Int -> Bool
go !Int
i
        | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
n              = Bool
True
        | Array sh e
a1 Array sh e -> Int -> e
forall sh e. Elt e => Array sh e -> Int -> e
!! Int
i e -> e -> Bool
forall a. Similar a => a -> a -> Bool
~= Array sh e
a2 Array sh e -> Int -> e
forall sh e. Elt e => Array sh e -> Int -> e
!! Int
i  = Int -> Bool
go (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
        | Bool
otherwise           = Bool
False

{-# INLINEABLE absRelTol #-}
absRelTol :: RealFloat a => a -> a -> a -> a -> Bool
absRelTol :: a -> a -> a -> a -> Bool
absRelTol a
epsilonAbs a
epsilonRel a
u a
v
  |  a -> Bool
forall a. RealFloat a => a -> Bool
isInfinite a
u
  Bool -> Bool -> Bool
&& a -> Bool
forall a. RealFloat a => a -> Bool
isInfinite a
v          = Bool
True
  |  a -> Bool
forall a. RealFloat a => a -> Bool
isNaN a
u
  Bool -> Bool -> Bool
&& a -> Bool
forall a. RealFloat a => a -> Bool
isNaN a
v               = Bool
True
  | a -> a
forall a. Num a => a -> a
abs (a
ua -> a -> a
forall a. Num a => a -> a -> a
-a
v) a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
epsilonAbs = Bool
True
  | a -> a
forall a. Num a => a -> a
abs a
u a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a -> a
forall a. Num a => a -> a
abs a
v          = a -> a
forall a. Num a => a -> a
abs ((a
ua -> a -> a
forall a. Num a => a -> a -> a
-a
v) a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
u) a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
epsilonRel
  | Bool
otherwise              = a -> a
forall a. Num a => a -> a
abs ((a
va -> a -> a
forall a. Num a => a -> a -> a
-a
u) a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
v) a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
epsilonRel