packages feed

numeric-prelude-0.2.1: test/Test/MathObj/PowerSeries.hs

{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
module Test.MathObj.PowerSeries where

import qualified MathObj.PowerSeries.Core    as PS
import qualified MathObj.PowerSeries.Example as PSE

import Test.NumericPrelude.Utility (equalInfLists {- , testUnit -} )
-- import Test.QuickCheck (Property, quickCheck, (==>))
import qualified Test.HUnit as HUnit


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


identitiesExplODE, identitiesSeriesFunction, identitiesInverses ::
   [(String, Int, [Rational],[Rational])]

identitiesExplODE =
   ("exp",   500, PSE.expExpl,   PSE.expODE) :
   ("sin",   500, PSE.sinExpl,   PSE.sinODE) :
   ("cos",   500, PSE.cosExpl,   PSE.cosODE) :
   ("tan",    50, PSE.tanExpl,   PSE.tanODE) :
   ("tan",    50, PSE.tanExpl,   PSE.tanExplSieve) :
   ("tan",    50, PSE.tanODE,    PSE.tanODESieve) :
   ("log",   500, PSE.logExpl,   PSE.logODE) :
   ("asin",   50, PSE.asinODE,   snd (PS.inv PSE.sinODE)) :
   ("atan",  500, PSE.atanExpl,  PSE.atanODE) :
   ("sinh",  500, PSE.sinhExpl,  PSE.sinhODE) :
   ("cosh",  500, PSE.coshExpl,  PSE.coshODE) :
   ("atanh", 500, PSE.atanhExpl, PSE.atanhODE) :
   ("sqrt",  100, PSE.sqrtExpl,  PSE.sqrtODE) :
   []

identitiesSeriesFunction =
   ("exp",   500, PSE.expExpl,  PS.exp (\0 -> 1) [0,1]) :
   ("sin",   500, PSE.sinExpl,  PS.sin (\0 -> (0,1)) [0,1]) :
   ("cos",   500, PSE.cosExpl,  PS.cos (\0 -> (0,1)) [0,1]) :
   ("tan",    50, PSE.tanExpl,  PS.tan (\0 -> (0,1)) [0,1]) :
   ("sqrt",   50, PSE.sqrtExpl, PS.sqrt (\1 -> 1) [1,1]) :
   ("power", 500, PSE.powExpl (-1/3), PS.pow (\1 -> 1) (-1/3) [1,1]) :
   ("power",  50, PSE.powExpl (-1/3), PS.exp (\0 -> 1) (PS.scale (-1/3) PSE.log)) :
   ("log",   500, PSE.logExpl, PS.log (\1 -> 0) [1,1]) :
   ("asin",   50, PSE.asin, PS.asin (\1 -> 1) (\0 -> 0) [0,1]) :
 --  ("acos",  50, PSE.acos, PS.acos (\1 -> 1) (\0 -> pi/2) [0,1]) :
   ("atan",  500, PSE.atan, PS.atan (\0 -> 0) [0,1]) :
   []

identitiesInverses =
   ("exp",   100, 1:1:repeat 0, PS.exp  (\0 -> 1) PSE.log) :
   ("log",   100, 0:1:repeat 0, PS.log  (\1 -> 0) PSE.exp) :
   ("tan",    50, 0:1:repeat 0, PS.tan  (\0 -> (0,1)) PSE.atan) :
   ("atan",   50, 0:1:repeat 0, PS.atan (\0 -> 0) PSE.tan) :
   ("sin",    50, 0:1:repeat 0, PS.sin  (\0 -> (0,1)) PSE.asin) :
   ("asin",  100, 0:1:repeat 0, PS.asin (\1 -> 1) (\0 -> 0) PSE.sin) :
   ("sqrt",  500, 1:1:repeat 0, PS.sqrt (\1 -> 1) (PS.mul [1,1] [1,1])) :
   []

testSeriesIdentity :: (String, Int, [Rational], [Rational]) -> HUnit.Test
testSeriesIdentity (label, len, x, y) =
   HUnit.test (HUnit.assertBool label (equalInfLists len [x,y]))

testSeriesIdentities ::
   String -> [(String, Int, [Rational], [Rational])] -> HUnit.Test
testSeriesIdentities label ids =
   HUnit.TestLabel label $
     HUnit.TestList $ map testSeriesIdentity ids

checkSeriesIdentities ::
   [(String, Int, [Rational], [Rational])] -> [(String,Bool)]
checkSeriesIdentities =
   map (\(label, len, x, y) -> (label, equalInfLists len [x,y]))




powerMult :: Rational -> Rational -> Bool
powerMult exp0 exp1 =
   PS.mul (PSE.pow exp0) (PSE.pow exp1)  ==  PSE.pow (exp0+exp1)

powerExplODE :: Rational -> Bool
powerExplODE expon =
   PSE.powODE expon == PSE.powExpl expon


tests :: HUnit.Test
tests =
   HUnit.TestLabel "power series" $
   HUnit.TestList [
      testSeriesIdentities "explicit vs. ODE solution" identitiesExplODE,
      testSeriesIdentities "transcendent functions of series" identitiesSeriesFunction,
      testSeriesIdentities "inverses of some series" identitiesInverses
{-
      HUnit.TestLabel "laws" $
      HUnit.TestList $
         map testUnit $
            ("products of powers",     quickCheck (powerMult)) :
            ("power explicit vs. ODE", quickCheck (powerExplODE)) :
            []
-}
    ]