packages feed

numeric-prelude-0.2: test/Test/MathObj/RefinementMask2.hs

{-# LANGUAGE NoImplicitPrelude #-}
module Test.MathObj.RefinementMask2 where

import qualified MathObj.RefinementMask2 as Mask
import qualified Algebra.Differential    as D

import qualified MathObj.Polynomial      as Poly
import qualified MathObj.Polynomial.Core as PolyCore

import qualified Algebra.RealField      as RealField
import qualified Algebra.Ring           as Ring

import qualified Algebra.ZeroTestable   as ZeroTestable

import Data.Maybe (fromMaybe, )

import Test.NumericPrelude.Utility (testUnit)
import Test.QuickCheck (Property, quickCheck, (==>), Testable, )
import qualified Test.HUnit as HUnit


import NumericPrelude.Base as P
import NumericPrelude.Numeric as NP



hasMultipleZero :: (Ring.C a, Eq a) => Int -> a -> Poly.T a -> Bool
hasMultipleZero n x poly =
   all (zero==) $ take n $
   map (flip Poly.evaluate x) $
   iterate D.differentiate poly

inverse0 :: (RealField.C a) => Mask.T a -> Property
inverse0 mask0 =
   let (b,poly) =
          case Mask.toPolynomial mask0 of
             Just p -> (True, p)
             Nothing -> (False, error "RefinementMask2.inverse0: no admissible mask")
       mask1 = Mask.fromPolynomial poly
       maskD =
          Poly.fromCoeffs (Mask.coeffs mask1) -
          Poly.fromCoeffs (Mask.coeffs mask0)
   in  b ==>
          hasMultipleZero (fromMaybe 0 $ Poly.degree poly)
             1 maskD

truncatePolynomial :: (ZeroTestable.C a) => Int -> Poly.T a -> Poly.T a
truncatePolynomial n =
   Poly.fromCoeffs . PolyCore.normalize . take n . Poly.coeffs

inverse1 :: (RealField.C a) => Poly.T a -> Bool
inverse1 poly0 =
   case Mask.toPolynomial (Mask.fromPolynomial poly0) of
      Just poly1 -> Poly.collinear poly0 poly1
      Nothing -> False

refining :: (RealField.C a) => Poly.T a -> Bool
refining poly =
   poly == Mask.refinePolynomial (Mask.fromPolynomial poly) poly



test :: Testable a => (Poly.T Integer -> a) -> IO ()
test = quickCheck

testRat :: Testable a => (Poly.T Rational -> a) -> IO ()
testRat = quickCheck


tests :: HUnit.Test
tests =
   HUnit.TestLabel "refinement mask" $
   HUnit.TestList $
   map testUnit $
      ("inverse0", quickCheck (inverse0 :: Mask.T Rational -> Property)) :
      ("inverse1", quickCheck (inverse1 . truncatePolynomial 5 :: Poly.T Rational -> Bool)) :
      ("refining", quickCheck (refining . truncatePolynomial 5 :: Poly.T Rational -> Bool)) :
      []