-- | -- Module : ELynx.Tools.Equality -- Copyright : (c) Dominik Schrempf 2021 -- License : GPL-3.0-or-later -- -- Maintainer : dominik.schrempf@gmail.com -- Stability : unstable -- Portability : portable -- -- Creation date: Thu Feb 14 13:27:05 2019. -- -- Equality tests. module ELynx.Tools.Equality ( -- * Equality allEqual, allNearlyEqualWith, allNearlyEqual, nearlyEqWith, eps, nearlyEq, (=~=), nearlyEqListWith, nearlyEqList, nearlyEqVecWith, nearlyEqVec, nearlyEqMatWith, nearlyEqMat, ) where import ELynx.Tools.Definitions import Numeric.LinearAlgebra -- | Test if all elements of a list are equal; returns True for empty list. allEqual :: Eq a => [a] -> Bool -- Well, maybe it should be False, but then, it is True that all elements are -- equal :). allEqual [] = True allEqual xs = all (== head xs) (tail xs) -- | Test if all elements of a list are nearly equal; returns True for empty list. allNearlyEqualWith :: Double -> [Double] -> Bool allNearlyEqualWith _ [] = True allNearlyEqualWith tol xs = all (nearlyEqWith tol $ head xs) (tail xs) -- | Test if all elements of a list are nearly equal; returns True for empty list. allNearlyEqual :: [Double] -> Bool allNearlyEqual = allNearlyEqualWith eps -- | Test for equality with given tolerance (needed because of machine precision). nearlyEqWith :: Double -> Double -> Double -> Bool nearlyEqWith tol a b = tol > abs (a - b) -- | Test for equality with predefined tolerance 'eps' (needed because of -- machine precision). nearlyEq :: Double -> Double -> Bool nearlyEq = nearlyEqWith eps -- | Infix synonym for 'nearlyEq'. (=~=) :: Double -> Double -> Bool (=~=) = nearlyEq -- Test if the given number is nearly equal to all elements of a list. nearlyEqValListWith :: Double -> Double -> [Double] -> Bool nearlyEqValListWith tol a = all (nearlyEqWith tol a) -- | Test if two lists are nearly equal. nearlyEqListWith :: Double -> [Double] -> [Double] -> Bool nearlyEqListWith tol xs ys = nearlyEqValListWith tol 0 (zipWith (-) xs ys) -- | Test if two lists are nearly equal; use tolerance 'eps'. nearlyEqList :: [Double] -> [Double] -> Bool nearlyEqList = nearlyEqListWith eps -- | Test if two vectors are nearly equal. nearlyEqVecWith :: Double -> Vector R -> Vector R -> Bool nearlyEqVecWith tol a b = nearlyEqValListWith tol 0 (toList $ a - b) -- | Test if two vectors are nearly equal; use tolerance 'eps'. nearlyEqVec :: Vector R -> Vector R -> Bool nearlyEqVec = nearlyEqVecWith eps -- | Test if two vectors are nearly equal. nearlyEqMatWith :: Double -> Matrix R -> Matrix R -> Bool nearlyEqMatWith tol a b = nearlyEqValListWith tol 0 (concat . toLists $ a - b) -- | Test if two vectors are nearly equal; use tolerance 'eps'. nearlyEqMat :: Matrix R -> Matrix R -> Bool nearlyEqMat = nearlyEqMatWith eps