{-# LANGUAGE OverloadedStrings #-}
module Futhark.Data.Compare
( compareValues,
compareSeveralValues,
Tolerance (..),
Mismatch,
)
where
import Data.List (intersperse)
import qualified Data.Text as T
import qualified Data.Vector.Storable as SVec
import Futhark.Data
data Mismatch
=
PrimValueMismatch Int [Int] T.Text T.Text
| ArrayShapeMismatch Int [Int] [Int]
| TypeMismatch Int T.Text T.Text
| ValueCountMismatch Int Int
showText :: (Show a) => a -> T.Text
showText :: forall a. Show a => a -> Text
showText = String -> Text
T.pack (String -> Text) -> (a -> String) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show
explainMismatch :: T.Text -> T.Text -> T.Text -> T.Text -> T.Text
explainMismatch :: Text -> Text -> Text -> Text -> Text
explainMismatch Text
i Text
what Text
got Text
expected =
Text
"Value #" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
": expected " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
what Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
expected Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
", got " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
got
instance Show Mismatch where
show :: Mismatch -> String
show (PrimValueMismatch Int
vi [] Text
got Text
expected) =
Text -> String
T.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Text -> Text -> Text -> Text -> Text
explainMismatch (Int -> Text
forall a. Show a => a -> Text
showText Int
vi) Text
"" Text
got Text
expected
show (PrimValueMismatch Int
vi [Int]
js Text
got Text
expected) =
Text -> String
T.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Text -> Text -> Text -> Text -> Text
explainMismatch (Int -> Text
forall a. Show a => a -> Text
showText Int
vi Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" index [" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat (Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
intersperse Text
"," ((Int -> Text) -> [Int] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Int -> Text
forall a. Show a => a -> Text
showText [Int]
js)) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"]") Text
"" Text
got Text
expected
show (ArrayShapeMismatch Int
i [Int]
got [Int]
expected) =
Text -> String
T.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Text -> Text -> Text -> Text -> Text
explainMismatch (Int -> Text
forall a. Show a => a -> Text
showText Int
i) Text
"array of shape " ([Int] -> Text
forall a. Show a => a -> Text
showText [Int]
got) ([Int] -> Text
forall a. Show a => a -> Text
showText [Int]
expected)
show (TypeMismatch Int
i Text
got Text
expected) =
Text -> String
T.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Text -> Text -> Text -> Text -> Text
explainMismatch (Int -> Text
forall a. Show a => a -> Text
showText Int
i) Text
"value of type " Text
got Text
expected
show (ValueCountMismatch Int
got Int
expected) =
Text -> String
T.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Text
"Expected " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
showText Int
expected Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" values, got " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
showText Int
got
newtype Tolerance = Tolerance Double
deriving (Tolerance -> Tolerance -> Bool
(Tolerance -> Tolerance -> Bool)
-> (Tolerance -> Tolerance -> Bool) -> Eq Tolerance
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Tolerance -> Tolerance -> Bool
== :: Tolerance -> Tolerance -> Bool
$c/= :: Tolerance -> Tolerance -> Bool
/= :: Tolerance -> Tolerance -> Bool
Eq, Eq Tolerance
Eq Tolerance =>
(Tolerance -> Tolerance -> Ordering)
-> (Tolerance -> Tolerance -> Bool)
-> (Tolerance -> Tolerance -> Bool)
-> (Tolerance -> Tolerance -> Bool)
-> (Tolerance -> Tolerance -> Bool)
-> (Tolerance -> Tolerance -> Tolerance)
-> (Tolerance -> Tolerance -> Tolerance)
-> Ord Tolerance
Tolerance -> Tolerance -> Bool
Tolerance -> Tolerance -> Ordering
Tolerance -> Tolerance -> Tolerance
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Tolerance -> Tolerance -> Ordering
compare :: Tolerance -> Tolerance -> Ordering
$c< :: Tolerance -> Tolerance -> Bool
< :: Tolerance -> Tolerance -> Bool
$c<= :: Tolerance -> Tolerance -> Bool
<= :: Tolerance -> Tolerance -> Bool
$c> :: Tolerance -> Tolerance -> Bool
> :: Tolerance -> Tolerance -> Bool
$c>= :: Tolerance -> Tolerance -> Bool
>= :: Tolerance -> Tolerance -> Bool
$cmax :: Tolerance -> Tolerance -> Tolerance
max :: Tolerance -> Tolerance -> Tolerance
$cmin :: Tolerance -> Tolerance -> Tolerance
min :: Tolerance -> Tolerance -> Tolerance
Ord, Int -> Tolerance -> ShowS
[Tolerance] -> ShowS
Tolerance -> String
(Int -> Tolerance -> ShowS)
-> (Tolerance -> String)
-> ([Tolerance] -> ShowS)
-> Show Tolerance
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Tolerance -> ShowS
showsPrec :: Int -> Tolerance -> ShowS
$cshow :: Tolerance -> String
show :: Tolerance -> String
$cshowList :: [Tolerance] -> ShowS
showList :: [Tolerance] -> ShowS
Show)
toleranceFloat :: (RealFloat a) => Tolerance -> a
toleranceFloat :: forall a. RealFloat a => Tolerance -> a
toleranceFloat (Tolerance Double
x) = Rational -> a
forall a. Fractional a => Rational -> a
fromRational (Rational -> a) -> Rational -> a
forall a b. (a -> b) -> a -> b
$ Double -> Rational
forall a. Real a => a -> Rational
toRational Double
x
compareValues :: Tolerance -> Value -> Value -> [Mismatch]
compareValues :: Tolerance -> Value -> Value -> [Mismatch]
compareValues Tolerance
tol = Tolerance -> Int -> Value -> Value -> [Mismatch]
compareValue Tolerance
tol Int
0
compareSeveralValues :: Tolerance -> [Value] -> [Value] -> [Mismatch]
compareSeveralValues :: Tolerance -> [Value] -> [Value] -> [Mismatch]
compareSeveralValues Tolerance
tol [Value]
got [Value]
expected
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
m = [Int -> Int -> Mismatch
ValueCountMismatch Int
n Int
m]
| Bool
otherwise = [[Mismatch]] -> [Mismatch]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Mismatch]] -> [Mismatch]) -> [[Mismatch]] -> [Mismatch]
forall a b. (a -> b) -> a -> b
$ (Int -> Value -> Value -> [Mismatch])
-> [Int] -> [Value] -> [Value] -> [[Mismatch]]
forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3 (Tolerance -> Int -> Value -> Value -> [Mismatch]
compareValue Tolerance
tol) [Int
0 ..] [Value]
got [Value]
expected
where
n :: Int
n = [Value] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Value]
got
m :: Int
m = [Value] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Value]
expected
unflattenIndex :: [Int] -> Int -> [Int]
unflattenIndex :: [Int] -> Int -> [Int]
unflattenIndex = [Int] -> Int -> [Int]
forall {t}. Integral t => [t] -> t -> [t]
unflattenIndexFromSlices ([Int] -> Int -> [Int])
-> ([Int] -> [Int]) -> [Int] -> Int -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
drop Int
1 ([Int] -> [Int]) -> ([Int] -> [Int]) -> [Int] -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> [Int]
forall {a}. Num a => [a] -> [a]
sliceSizes
where
sliceSizes :: [a] -> [a]
sliceSizes [] = [a
1]
sliceSizes (a
n : [a]
ns) = [a] -> a
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product (a
n a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
ns) a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a] -> [a]
sliceSizes [a]
ns
unflattenIndexFromSlices :: [t] -> t -> [t]
unflattenIndexFromSlices [] t
_ = []
unflattenIndexFromSlices (t
size : [t]
slices) t
i =
(t
i t -> t -> t
forall a. Integral a => a -> a -> a
`quot` t
size) t -> [t] -> [t]
forall a. a -> [a] -> [a]
: [t] -> t -> [t]
unflattenIndexFromSlices [t]
slices (t
i t -> t -> t
forall a. Num a => a -> a -> a
- (t
i t -> t -> t
forall a. Integral a => a -> a -> a
`quot` t
size) t -> t -> t
forall a. Num a => a -> a -> a
* t
size)
compareValue :: Tolerance -> Int -> Value -> Value -> [Mismatch]
compareValue :: Tolerance -> Int -> Value -> Value -> [Mismatch]
compareValue Tolerance
tol Int
i Value
got_v Value
expected_v
| Value -> [Int]
valueShape Value
got_v [Int] -> [Int] -> Bool
forall a. Eq a => a -> a -> Bool
== Value -> [Int]
valueShape Value
expected_v =
case (Value
got_v, Value
expected_v) of
(I8Value Vector Int
_ Vector Int8
got_vs, I8Value Vector Int
_ Vector Int8
expected_vs) ->
Vector Int8 -> Vector Int8 -> [Mismatch]
forall a.
(Storable a, Eq a, Show a) =>
Vector a -> Vector a -> [Mismatch]
compareNum Vector Int8
got_vs Vector Int8
expected_vs
(I16Value Vector Int
_ Vector Int16
got_vs, I16Value Vector Int
_ Vector Int16
expected_vs) ->
Vector Int16 -> Vector Int16 -> [Mismatch]
forall a.
(Storable a, Eq a, Show a) =>
Vector a -> Vector a -> [Mismatch]
compareNum Vector Int16
got_vs Vector Int16
expected_vs
(I32Value Vector Int
_ Vector Int32
got_vs, I32Value Vector Int
_ Vector Int32
expected_vs) ->
Vector Int32 -> Vector Int32 -> [Mismatch]
forall a.
(Storable a, Eq a, Show a) =>
Vector a -> Vector a -> [Mismatch]
compareNum Vector Int32
got_vs Vector Int32
expected_vs
(I64Value Vector Int
_ Vector Int64
got_vs, I64Value Vector Int
_ Vector Int64
expected_vs) ->
Vector Int64 -> Vector Int64 -> [Mismatch]
forall a.
(Storable a, Eq a, Show a) =>
Vector a -> Vector a -> [Mismatch]
compareNum Vector Int64
got_vs Vector Int64
expected_vs
(U8Value Vector Int
_ Vector Word8
got_vs, U8Value Vector Int
_ Vector Word8
expected_vs) ->
Vector Word8 -> Vector Word8 -> [Mismatch]
forall a.
(Storable a, Eq a, Show a) =>
Vector a -> Vector a -> [Mismatch]
compareNum Vector Word8
got_vs Vector Word8
expected_vs
(U16Value Vector Int
_ Vector Word16
got_vs, U16Value Vector Int
_ Vector Word16
expected_vs) ->
Vector Word16 -> Vector Word16 -> [Mismatch]
forall a.
(Storable a, Eq a, Show a) =>
Vector a -> Vector a -> [Mismatch]
compareNum Vector Word16
got_vs Vector Word16
expected_vs
(U32Value Vector Int
_ Vector Word32
got_vs, U32Value Vector Int
_ Vector Word32
expected_vs) ->
Vector Word32 -> Vector Word32 -> [Mismatch]
forall a.
(Storable a, Eq a, Show a) =>
Vector a -> Vector a -> [Mismatch]
compareNum Vector Word32
got_vs Vector Word32
expected_vs
(U64Value Vector Int
_ Vector Word64
got_vs, U64Value Vector Int
_ Vector Word64
expected_vs) ->
Vector Word64 -> Vector Word64 -> [Mismatch]
forall a.
(Storable a, Eq a, Show a) =>
Vector a -> Vector a -> [Mismatch]
compareNum Vector Word64
got_vs Vector Word64
expected_vs
(F16Value Vector Int
_ Vector Half
got_vs, F16Value Vector Int
_ Vector Half
expected_vs) ->
Half -> Vector Half -> Vector Half -> [Mismatch]
forall a.
(Storable a, RealFloat a, Show a) =>
a -> Vector a -> Vector a -> [Mismatch]
compareFloat (Half -> Vector Half -> Half
forall a. (RealFloat a, Storable a) => a -> Vector a -> a
tolerance (Tolerance -> Half
forall a. RealFloat a => Tolerance -> a
toleranceFloat Tolerance
tol) Vector Half
expected_vs) Vector Half
got_vs Vector Half
expected_vs
(F32Value Vector Int
_ Vector Float
got_vs, F32Value Vector Int
_ Vector Float
expected_vs) ->
Float -> Vector Float -> Vector Float -> [Mismatch]
forall a.
(Storable a, RealFloat a, Show a) =>
a -> Vector a -> Vector a -> [Mismatch]
compareFloat (Float -> Vector Float -> Float
forall a. (RealFloat a, Storable a) => a -> Vector a -> a
tolerance (Tolerance -> Float
forall a. RealFloat a => Tolerance -> a
toleranceFloat Tolerance
tol) Vector Float
expected_vs) Vector Float
got_vs Vector Float
expected_vs
(F64Value Vector Int
_ Vector Double
got_vs, F64Value Vector Int
_ Vector Double
expected_vs) ->
Double -> Vector Double -> Vector Double -> [Mismatch]
forall a.
(Storable a, RealFloat a, Show a) =>
a -> Vector a -> Vector a -> [Mismatch]
compareFloat (Double -> Vector Double -> Double
forall a. (RealFloat a, Storable a) => a -> Vector a -> a
tolerance (Tolerance -> Double
forall a. RealFloat a => Tolerance -> a
toleranceFloat Tolerance
tol) Vector Double
expected_vs) Vector Double
got_vs Vector Double
expected_vs
(BoolValue Vector Int
_ Vector Bool
got_vs, BoolValue Vector Int
_ Vector Bool
expected_vs) ->
(Int -> Bool -> Bool -> Maybe Mismatch)
-> Vector Bool -> Vector Bool -> [Mismatch]
forall {a} {t} {a}.
(Storable a, Storable t) =>
(Int -> a -> t -> Maybe a) -> Vector a -> Vector t -> [a]
compareGen Int -> Bool -> Bool -> Maybe Mismatch
forall {a}. (Eq a, Show a) => Int -> a -> a -> Maybe Mismatch
compareBool Vector Bool
got_vs Vector Bool
expected_vs
(Value, Value)
_ ->
[Int -> Text -> Text -> Mismatch
TypeMismatch Int
i (PrimType -> Text
primTypeText (PrimType -> Text) -> PrimType -> Text
forall a b. (a -> b) -> a -> b
$ Value -> PrimType
valueElemType Value
got_v) (PrimType -> Text
primTypeText (PrimType -> Text) -> PrimType -> Text
forall a b. (a -> b) -> a -> b
$ Value -> PrimType
valueElemType Value
expected_v)]
| Bool
otherwise =
[Int -> [Int] -> [Int] -> Mismatch
ArrayShapeMismatch Int
i (Value -> [Int]
valueShape Value
got_v) (Value -> [Int]
valueShape Value
expected_v)]
where
unflatten :: Int -> [Int]
unflatten = [Int] -> Int -> [Int]
unflattenIndex (Value -> [Int]
valueShape Value
got_v)
value :: (Show a) => a -> T.Text
value :: forall a. Show a => a -> Text
value = String -> Text
T.pack (String -> Text) -> (a -> String) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show
{-# INLINE compareGen #-}
{-# INLINE compareNum #-}
{-# INLINE compareFloat #-}
{-# INLINE compareFloatElement #-}
{-# INLINE compareElement #-}
compareNum :: (SVec.Storable a, Eq a, Show a) => SVec.Vector a -> SVec.Vector a -> [Mismatch]
compareNum :: forall a.
(Storable a, Eq a, Show a) =>
Vector a -> Vector a -> [Mismatch]
compareNum = (Int -> a -> a -> Maybe Mismatch)
-> Vector a -> Vector a -> [Mismatch]
forall {a} {t} {a}.
(Storable a, Storable t) =>
(Int -> a -> t -> Maybe a) -> Vector a -> Vector t -> [a]
compareGen Int -> a -> a -> Maybe Mismatch
forall a. (Show a, Eq a) => Int -> a -> a -> Maybe Mismatch
compareElement
compareFloat :: (SVec.Storable a, RealFloat a, Show a) => a -> SVec.Vector a -> SVec.Vector a -> [Mismatch]
compareFloat :: forall a.
(Storable a, RealFloat a, Show a) =>
a -> Vector a -> Vector a -> [Mismatch]
compareFloat = (Int -> a -> a -> Maybe Mismatch)
-> Vector a -> Vector a -> [Mismatch]
forall {a} {t} {a}.
(Storable a, Storable t) =>
(Int -> a -> t -> Maybe a) -> Vector a -> Vector t -> [a]
compareGen ((Int -> a -> a -> Maybe Mismatch)
-> Vector a -> Vector a -> [Mismatch])
-> (a -> Int -> a -> a -> Maybe Mismatch)
-> a
-> Vector a
-> Vector a
-> [Mismatch]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Int -> a -> a -> Maybe Mismatch
forall a.
(Show a, RealFloat a) =>
a -> Int -> a -> a -> Maybe Mismatch
compareFloatElement
compareGen :: (Int -> a -> t -> Maybe a) -> Vector a -> Vector t -> [a]
compareGen Int -> a -> t -> Maybe a
cmp Vector a
got Vector t
expected =
let l :: Int
l = Vector a -> Int
forall a. Storable a => Vector a -> Int
SVec.length Vector a
got
check :: [a] -> Int -> [a]
check [a]
acc Int
j
| Int
j Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
l =
case Int -> a -> t -> Maybe a
cmp Int
j (Vector a
got Vector a -> Int -> a
forall a. Storable a => Vector a -> Int -> a
SVec.! Int
j) (Vector t
expected Vector t -> Int -> t
forall a. Storable a => Vector a -> Int -> a
SVec.! Int
j) of
Just a
mismatch ->
[a] -> Int -> [a]
check (a
mismatch a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
acc) (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
Maybe a
Nothing ->
[a] -> Int -> [a]
check [a]
acc (Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
| Bool
otherwise =
[a]
acc
in [a] -> [a]
forall a. [a] -> [a]
reverse ([a] -> [a]) -> [a] -> [a]
forall a b. (a -> b) -> a -> b
$ [a] -> Int -> [a]
check [] Int
0
compareElement :: (Show a, Eq a) => Int -> a -> a -> Maybe Mismatch
compareElement :: forall a. (Show a, Eq a) => Int -> a -> a -> Maybe Mismatch
compareElement Int
j a
got a
expected
| a
got a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
expected = Maybe Mismatch
forall a. Maybe a
Nothing
| Bool
otherwise = Mismatch -> Maybe Mismatch
forall a. a -> Maybe a
Just (Mismatch -> Maybe Mismatch) -> Mismatch -> Maybe Mismatch
forall a b. (a -> b) -> a -> b
$ Int -> [Int] -> Text -> Text -> Mismatch
PrimValueMismatch Int
i (Int -> [Int]
unflatten Int
j) (a -> Text
forall a. Show a => a -> Text
value a
got) (a -> Text
forall a. Show a => a -> Text
value a
expected)
compareFloatElement :: (Show a, RealFloat a) => a -> Int -> a -> a -> Maybe Mismatch
compareFloatElement :: forall a.
(Show a, RealFloat a) =>
a -> Int -> a -> a -> Maybe Mismatch
compareFloatElement a
abstol Int
j a
got a
expected
| a -> Bool
forall a. RealFloat a => a -> Bool
isNaN a
got,
a -> Bool
forall a. RealFloat a => a -> Bool
isNaN a
expected =
Maybe Mismatch
forall a. Maybe a
Nothing
| a -> Bool
forall a. RealFloat a => a -> Bool
isInfinite a
got,
a -> Bool
forall a. RealFloat a => a -> Bool
isInfinite a
expected,
a -> a
forall a. Num a => a -> a
signum a
got a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a -> a
forall a. Num a => a -> a
signum a
expected =
Maybe Mismatch
forall a. Maybe a
Nothing
| a -> a
forall a. Num a => a -> a
abs (a
got a -> a -> a
forall a. Num a => a -> a -> a
- a
expected) a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
abstol = Maybe Mismatch
forall a. Maybe a
Nothing
| Bool
otherwise = Mismatch -> Maybe Mismatch
forall a. a -> Maybe a
Just (Mismatch -> Maybe Mismatch) -> Mismatch -> Maybe Mismatch
forall a b. (a -> b) -> a -> b
$ Int -> [Int] -> Text -> Text -> Mismatch
PrimValueMismatch Int
i (Int -> [Int]
unflatten Int
j) (a -> Text
forall a. Show a => a -> Text
value a
got) (a -> Text
forall a. Show a => a -> Text
value a
expected)
compareBool :: Int -> a -> a -> Maybe Mismatch
compareBool Int
j a
got a
expected
| a
got a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
expected = Maybe Mismatch
forall a. Maybe a
Nothing
| Bool
otherwise = Mismatch -> Maybe Mismatch
forall a. a -> Maybe a
Just (Mismatch -> Maybe Mismatch) -> Mismatch -> Maybe Mismatch
forall a b. (a -> b) -> a -> b
$ Int -> [Int] -> Text -> Text -> Mismatch
PrimValueMismatch Int
i (Int -> [Int]
unflatten Int
j) (a -> Text
forall a. Show a => a -> Text
value a
got) (a -> Text
forall a. Show a => a -> Text
value a
expected)
tolerance :: (RealFloat a, SVec.Storable a) => a -> Vector a -> a
tolerance :: forall a. (RealFloat a, Storable a) => a -> Vector a -> a
tolerance a
tol = (a -> a -> a) -> a -> Vector a -> a
forall b a. Storable b => (a -> b -> a) -> a -> Vector b -> a
SVec.foldl a -> a -> a
tolerance' a
tol (Vector a -> a) -> (Vector a -> Vector a) -> Vector a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Bool) -> Vector a -> Vector a
forall a. Storable a => (a -> Bool) -> Vector a -> Vector a
SVec.filter (Bool -> Bool
not (Bool -> Bool) -> (a -> Bool) -> a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Bool
forall a. RealFloat a => a -> Bool
nanOrInf)
where
tolerance' :: a -> a -> a
tolerance' a
t a
v = a -> a -> a
forall a. Ord a => a -> a -> a
max a
t (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ a
tol a -> a -> a
forall a. Num a => a -> a -> a
* a
v
nanOrInf :: a -> Bool
nanOrInf a
x = a -> Bool
forall a. RealFloat a => a -> Bool
isInfinite a
x Bool -> Bool -> Bool
|| a -> Bool
forall a. RealFloat a => a -> Bool
isNaN a
x