{-|
    Module      :  Data.Number.ER.RnToRm.UnitDom.Base.Tests.Properties.Enclosure
    Description :  (testing) properties of basic enclosure operations
    Copyright   :  (c) 2007-2008 Michal Konecny
    License     :  BSD3

    Maintainer  :  mik@konecny.aow.cz
    Stability   :  experimental
    Portability :  portable
    
    Quickcheck properties of basic enclosure operations, 
    mainly ring operations.
-}
module Data.Number.ER.RnToRm.UnitDom.Base.Tests.Properties.Enclosure
where

import Data.Number.ER.RnToRm.UnitDom.Base.Tests.Generate
import Data.Number.ER.RnToRm.UnitDom.Base.Tests.Properties.Common

import qualified Data.Number.ER.RnToRm.UnitDom.Base as UFB

import Data.Number.ER.BasicTypes.Tests.Generate

import qualified Data.Number.ER.Real.Approx as RA

{--- addition ----}

prop_enclAdd_ThickEncls_consistent ::
    (UFB.ERUnitFnBaseEncl boxb boxra varid b ra t, Show boxra, RA.ERInnerOuterApprox ra) =>
    (t,t) -> String -> (Deg5Size10, (FBEnclThickSize10 t, FBEnclThickSize10 t)) -> 
    Bool
prop_enclAdd_ThickEncls_consistent =
    prop_binary_ThickEncls_consistent (RA.+:) UFB.addEncl


prop_enclAdd_ParalEncls_consistent ::
    (UFB.ERUnitFnBaseEncl boxb boxra varid b ra t, Show boxra, RA.ERInnerOuterApprox ra) =>
    (t,t) -> String -> (Deg5Size10, (FBEnclParalSize10 t, FBEnclParalSize10 t)) -> 
    Bool    
prop_enclAdd_ParalEncls_consistent =
    prop_binary_ParalEncls_consistent (RA.+:) UFB.addEncl

    
prop_enclAdd_ThinEncls_consistent ::
    (UFB.ERUnitFnBaseEncl boxb boxra varid b ra t, Show boxra, RA.ERInnerOuterApprox ra) =>
    (t,t) -> String -> (Deg5Size10, (FBEnclThinSize10 t, FBEnclThinSize10 t)) -> 
    Bool
prop_enclAdd_ThinEncls_consistent =
    prop_binary_ThinEncls_consistent (RA.+:) UFB.addEncl

{--- multiplication ----}

prop_enclMult_ThickEncls_consistent ::
    (UFB.ERUnitFnBaseEncl boxb boxra varid b ra t, Show boxra, RA.ERInnerOuterApprox ra) =>
    (t,t) -> String -> (Deg5Size10, (FBEnclThickSize10 t, FBEnclThickSize10 t)) -> 
    Bool
prop_enclMult_ThickEncls_consistent =
    prop_binary_ThickEncls_consistent (RA.*:) UFB.multiplyEncl


prop_enclMult_ParalEncls_consistent ::
    (UFB.ERUnitFnBaseEncl boxb boxra varid b ra t, Show boxra, RA.ERInnerOuterApprox ra) =>
    (t,t) -> String -> (Deg5Size10, (FBEnclParalSize10 t, FBEnclParalSize10 t)) -> 
    Bool    
prop_enclMult_ParalEncls_consistent =
    prop_binary_ParalEncls_consistent (RA.*:) UFB.multiplyEncl

    
prop_enclMult_ThinEncls_consistent ::
    (UFB.ERUnitFnBaseEncl boxb boxra varid b ra t, Show boxra, RA.ERInnerOuterApprox ra) =>
    (t,t) -> String -> (Deg5Size10, (FBEnclThinSize10 t, FBEnclThinSize10 t)) -> 
    Bool
prop_enclMult_ThinEncls_consistent =
    prop_binary_ThinEncls_consistent (RA.*:) UFB.multiplyEncl
    
{--- scaling ----}

prop_enclScale_ThickEncl_consistent
        sampleE reportFileName
        (Deg10Size10 maxDegree maxSize,
         SmallRatio num denom,
         FBEnclThickSize10 (n, e)) =
    enclAtKeyPointsPointwiseBinaryInnerInOuter
        reportFileName 
        ((maxDegree, maxSize), (num, denom), n)
        (RA.*:)
        cEncl e scaledEncl
    where
    _ = [e,sampleE]
    scaledEncl = UFB.scaleEncl maxDegree maxSize cB e
    cEncl = UFB.constEncl (cB,cB)
    cB = numB / denomB
    numB = fromInteger $ toInteger num
    denomB = fromInteger $ toInteger denom

prop_enclScale_ParalEncl_consistent
        sampleE reportFileName
        (Deg10Size10 maxDegree maxSize,
         SmallRatio num denom,
         FBEnclParalSize10 (n, e)) =
    enclAtKeyPointsPointwiseBinaryInnerInOuter
        reportFileName 
        ((maxDegree, maxSize), (num, denom), n)
        (RA.*:)
        cEncl e scaledEncl
    where
    _ = [e,sampleE]
    scaledEncl = UFB.scaleEncl maxDegree maxSize cB e
    cEncl = UFB.constEncl (cB,cB)
    cB = numB / denomB
    numB = fromInteger $ toInteger num
    denomB = fromInteger $ toInteger denom

prop_enclScale_ThinEncl_consistent
        sampleE reportFileName
        (Deg10Size10 maxDegree maxSize,
         SmallRatio num denom,
         FBEnclThinSize10 (n, e)) =
    enclAtKeyPointsPointwiseBinaryInnerInOuter
        reportFileName 
        ((maxDegree, maxSize), (num, denom), n)
        (RA.*:)
        cEncl e scaledEncl
    where
    _ = [e,sampleE]
    scaledEncl = UFB.scaleEncl maxDegree maxSize cB e
    cEncl = UFB.constEncl (cB,cB)
    cB = numB / denomB
    numB = fromInteger $ toInteger num
    denomB = fromInteger $ toInteger denom
    
prop_binary_ThickEncls_consistent
        opInner opEncl 
        sampleE reportFileName
        (Deg5Size10 maxDegree maxSize,
         (FBEnclThickSize10 (n1,e1), 
          FBEnclThickSize10 (n2,e2))) =
    enclAtKeyPointsPointwiseBinaryInnerInOuter
        reportFileName
        ((maxDegree, maxSize), (n1, n2))
        opInner
        e1 e2 resE
    where
    _ = [sampleE, e1]
    resE = opEncl maxDegree maxSize e1 e2
    
prop_binary_ParalEncls_consistent
        opInner opEncl 
        sampleE reportFileName
        (Deg5Size10 maxDegree maxSize,
         (FBEnclParalSize10 (n1,e1), 
          FBEnclParalSize10 (n2,e2))) =
    enclAtKeyPointsPointwiseBinaryInnerInOuter
        reportFileName
        ((maxDegree, maxSize), (n1, n2))
        opInner
        e1 e2 sumE
    where
    _ = [sampleE, e1]
    sumE = opEncl maxDegree maxSize e1 e2
    
prop_binary_ThinEncls_consistent
        opInner opEncl 
        sampleE reportFileName
        (Deg5Size10 maxDegree maxSize,
         (FBEnclThinSize10 (n1,e1), 
          FBEnclThinSize10 (n2,e2))) =
    enclAtKeyPointsPointwiseBinaryInnerInOuter
        reportFileName
        ((maxDegree, maxSize), (n1, n2))
        opInner
        e1 e2 sumE
    where
    _ = [sampleE, e1]
    sumE = opEncl maxDegree maxSize e1 e2