packages feed

mixed-types-num 0.3.1.5 → 0.3.2

raw patch · 10 files changed

+222/−12 lines, 10 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Numeric.MixedTypes.PreludeHiding: class (Real a, Enum a) => Integral a
- Numeric.MixedTypes.PreludeHiding: div :: Integral a => a -> a -> a
- Numeric.MixedTypes.PreludeHiding: divMod :: Integral a => a -> a -> (a, a)
- Numeric.MixedTypes.PreludeHiding: infixl 7 `mod`
- Numeric.MixedTypes.PreludeHiding: mod :: Integral a => a -> a -> a
- Numeric.MixedTypes.PreludeHiding: quot :: Integral a => a -> a -> a
- Numeric.MixedTypes.PreludeHiding: quotRem :: Integral a => a -> a -> (a, a)
- Numeric.MixedTypes.PreludeHiding: rem :: Integral a => a -> a -> a
- Numeric.MixedTypes.PreludeHiding: toInteger :: Integral a => a -> Integer
+ Numeric.MixedTypes.Eq: instance Numeric.MixedTypes.Eq.CanTestFinite GHC.Integer.Type.Integer
+ Numeric.MixedTypes.Eq: instance Numeric.MixedTypes.Eq.CanTestNaN GHC.Integer.Type.Integer
+ Numeric.MixedTypes.Round: class CanDivIMod t1 t2 where {
+ Numeric.MixedTypes.Round: divI :: CanDivIMod t1 t2 => t1 -> t2 -> DivIType t1 t2
+ Numeric.MixedTypes.Round: divIMod :: CanDivIMod t1 t2 => t1 -> t2 -> (DivIType t1 t2, ModType t1 t2)
+ Numeric.MixedTypes.Round: divIModNoCN :: (CanDivIMod t1 t2, ModType t1 t2 ~ EnsureCN t1, CanEnsureCN t1, DivIType t1 t2 ~ CN Integer) => t1 -> t2 -> (Integer, t1)
+ Numeric.MixedTypes.Round: divINoCN :: (CanDivIMod t1 t2, DivIType t1 t2 ~ CN Integer) => t1 -> t2 -> Integer
+ Numeric.MixedTypes.Round: instance Numeric.MixedTypes.Round.CanDivIMod GHC.Integer.Type.Integer GHC.Integer.Type.Integer
+ Numeric.MixedTypes.Round: instance Numeric.MixedTypes.Round.CanDivIMod GHC.Real.Rational GHC.Integer.Type.Integer
+ Numeric.MixedTypes.Round: instance Numeric.MixedTypes.Round.CanDivIMod GHC.Real.Rational GHC.Real.Rational
+ Numeric.MixedTypes.Round: instance Numeric.MixedTypes.Round.CanDivIMod GHC.Types.Double GHC.Integer.Type.Integer
+ Numeric.MixedTypes.Round: instance Numeric.MixedTypes.Round.CanDivIMod GHC.Types.Double GHC.Types.Double
+ Numeric.MixedTypes.Round: mod :: CanDivIMod t1 t2 => t1 -> t2 -> ModType t1 t2
+ Numeric.MixedTypes.Round: modNoCN :: (CanDivIMod t1 t2, ModType t1 t2 ~ EnsureCN t1, CanEnsureCN t1) => t1 -> t2 -> t1
+ Numeric.MixedTypes.Round: specCanDivIMod :: (CanDivIModX t, HasIntegers t) => T t -> Spec
+ Numeric.MixedTypes.Round: type CanDivIModIntegerSameType t = (CanDivIMod t t, CanEnsureCN t, DivIType t t ~ CN Integer, ModType t t ~ EnsureCN t)
+ Numeric.MixedTypes.Round: type DivIType t1 t2 = CN Integer;
+ Numeric.MixedTypes.Round: type ModType t1 t2 = EnsureCN t1;
+ Numeric.MixedTypes.Round: type family ModType t1 t2;
+ Numeric.MixedTypes.Round: }
+ Utils.Test.EnforceRange: enforceRange :: CanEnforceRange t b => (Maybe b, Maybe b) -> t -> t
+ Utils.Test.EnforceRange: type CanEnforceRange t b = (CanAddSubMulBy t Integer, CanAddSameType t, CanSubSameType t, CanAbsSameType t, CanDivIModIntegerSameType t, ConvertibleExactly b t, HasOrderCertainly t t)
- Numeric.MixedTypes.Elementary: specCanExpReal :: (Show t, Show (ExpType t), Show (DivType Integer (ExpType t)), Show (ExpType (AddType t t)), Show (MulType (ExpType t) (ExpType t)), Show (EnsureCN (ExpType t)), Arbitrary t, CanEnsureCN (ExpType t), CanTestCertainly (OrderCompareType Integer t), CanTestCertainly (OrderCompareType t Integer), CanTestCertainly (OrderCompareType (ExpType t) Integer), CanTestCertainly (EqCompareType (EnsureCN (ExpType t)) (DivType Integer (ExpType t))), CanTestCertainly (EqCompareType (ExpType (AddType t t)) (MulType (ExpType t) (ExpType t))), CanNeg t, HasEqAsymmetric (ExpType (AddType t t)) (MulType (ExpType t) (ExpType t)), HasEqAsymmetric (EnsureCN (ExpType t)) (DivType Integer (ExpType t)), HasOrderAsymmetric t Integer, HasOrderAsymmetric (ExpType t) Integer, HasOrderAsymmetric Integer t, CanAddAsymmetric t t, CanMulAsymmetric (ExpType t) (ExpType t), CanDiv Integer (ExpType t), CanExp t, CanExp (AddType t t), NegType t ~ t) => T t -> Spec
+ Numeric.MixedTypes.Elementary: specCanExpReal :: (Show t, Show (ExpType t), Show (DivType Integer (ExpType t)), Show (ExpType (AddType t t)), Show (MulType (ExpType t) (ExpType t)), Show (EnsureCN (ExpType t)), Arbitrary t, CanEnsureCN (ExpType t), CanTestCertainly (OrderCompareType Integer t), CanTestCertainly (OrderCompareType t Integer), CanTestCertainly (OrderCompareType (ExpType t) Integer), CanTestCertainly (EqCompareType (EnsureCN (ExpType t)) (DivType Integer (ExpType t))), CanTestCertainly (EqCompareType (ExpType (AddType t t)) (MulType (ExpType t) (ExpType t))), CanNeg t, HasEqAsymmetric (ExpType (AddType t t)) (MulType (ExpType t) (ExpType t)), HasEqAsymmetric (EnsureCN (ExpType t)) (DivType Integer (ExpType t)), HasOrderAsymmetric t Integer, HasOrderAsymmetric (ExpType t) Integer, HasOrderAsymmetric Integer t, CanAddAsymmetric t t, CanMulAsymmetric (ExpType t) (ExpType t), CanDiv Integer (ExpType t), CanExp t, CanExp (AddType t t), NegType t ~ t, CanEnforceRange t Integer) => T t -> Spec

Files

changelog.md view
@@ -1,3 +1,11 @@+# mixed-types-num change log++* v 0.3.2 2019-01-08+  * added divI and mod+  * added enforceRange+  * used enforceRange in exp tests+* v 0.3.1.5 2018-11-14+  * improved documentation * v 0.3.1.4 2017-12-06   * removed upper bounds for dependencies * v 0.3.1.3 2017-08-22
mixed-types-num.cabal view
@@ -1,5 +1,5 @@ name:           mixed-types-num-version:        0.3.1.5+version:        0.3.2 cabal-version:  >= 1.9.2 build-type:     Simple homepage:       https://github.com/michalkonecny/mixed-types-num@@ -10,7 +10,6 @@ license-file:   LICENSE extra-source-files:  changelog.md stability:      experimental-tested-with:    GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.4, GHC==8.6.1 category:       Math synopsis:       Alternative Prelude with numeric and logic expressions typed bottom-up Description:@@ -64,6 +63,7 @@     UndecidableInstances   exposed-modules:     Utils.TH.DeclForTypes+    Utils.Test.EnforceRange     Control.CollectErrors     Numeric.CollectErrors     Numeric.MixedTypes.PreludeHiding
src/MixedTypesNumPrelude.hs view
@@ -52,6 +52,7 @@   module Numeric.MixedTypes.Complex,   module Numeric.CollectErrors,   module Utils.TH.DeclForTypes,+  module Utils.Test.EnforceRange,   -- * Re-export for convenient Rational literals   (%) )@@ -59,6 +60,7 @@  import Data.Ratio ((%)) import Utils.TH.DeclForTypes+import Utils.Test.EnforceRange import Numeric.CollectErrors import Numeric.MixedTypes.PreludeHiding import Numeric.MixedTypes.Literals
src/Numeric/MixedTypes/Elementary.hs view
@@ -41,11 +41,14 @@ import Numeric.MixedTypes.Bool import Numeric.MixedTypes.Eq import Numeric.MixedTypes.Ord--- import Numeric.MixedTypes.MinMaxSqrt+-- import Numeric.MixedTypes.MinMaxAbs import Numeric.MixedTypes.AddSub import Numeric.MixedTypes.Ring import Numeric.MixedTypes.Field+-- import Numeric.MixedTypes.Round +import Utils.Test.EnforceRange + {----  sqrt -----}  {-|@@ -155,13 +158,14 @@    HasOrderAsymmetric Integer t, CanAddAsymmetric t t,    CanMulAsymmetric (ExpType t) (ExpType t),    CanDiv Integer (ExpType t), CanExp t, CanExp (AddType t t),-   NegType t ~ t) =>+   NegType t ~ t, +   CanEnforceRange t Integer) =>    T t -> Spec specCanExpReal (T typeName :: T t) =   describe (printf "CanExp %s" typeName) $ do     it "exp(x) >= 0" $ do-      property $ \ (x :: t) ->-        ((-100000) !<! x && x !<! 100000) ==>+      property $ \ (x_ :: t) ->+        let x = enforceRange (Just (-100000), Just 100000) x_ in           exp x ?>=?$ 0     it "exp(-x) == 1/(exp x)" $ do       property $ \ (x :: t) ->
src/Numeric/MixedTypes/Eq.hs view
@@ -312,8 +312,13 @@ instance CanTestNaN Double instance CanTestFinite Double +instance CanTestNaN Integer where+  isNaN = const False instance CanTestNaN Rational where   isNaN = const False+instance CanTestFinite Integer where+  isInfinite = const False+  isFinite = const True instance CanTestFinite Rational where   isInfinite = const False   isFinite = const True
src/Numeric/MixedTypes/PreludeHiding.hs view
@@ -20,7 +20,7 @@   (     fromInteger, fromRational     , (!!), length, replicate, take, drop, splitAt-    , Eq(..), Ord(..), Num(..), Fractional(..), RealFrac(..), Floating(..)+    , Eq(..), Ord(..), Num(..), Fractional(..), RealFrac(..), Floating(..), Integral(..)     , not, (&&), (||), and, or     , (^), (^^)     , minimum, maximum, sum, product
src/Numeric/MixedTypes/Ring.hs view
@@ -402,9 +402,9 @@     aux m       | m == 1 = x       | even m =-        let s = aux (m `div` 2) in s * s+        let s = aux (m `P.div` 2) in s * s       | otherwise =-        let s = aux ((m-1) `div` 2) in x * s * s+        let s = aux ((m-1) `P.div` 2) in x * s * s  type CanPowBy t1 t2 =   (CanPow t1 t2, PowType t1 t2 ~ t1, PowTypeNoCN t1 t2 ~ t1)
src/Numeric/MixedTypes/Round.hs view
@@ -12,28 +12,154 @@  module Numeric.MixedTypes.Round (-  -- * Rounding operations-  CanRound(..), HasIntegerBounds(..)+  -- * Rounded division + modulus+  CanDivIMod(..), CanDivIModIntegerSameType, modNoCN, divINoCN, divIModNoCN+  -- * Rounding+  , CanRound(..), HasIntegerBounds(..)   -- ** Tests-  , specCanRound, specHasIntegerBounds+  , specCanDivIMod, specCanRound, specHasIntegerBounds ) where  import Numeric.MixedTypes.PreludeHiding import qualified Prelude as P import Text.Printf+import Data.Fixed (divMod')  -- import qualified Data.List as List  import Test.Hspec import Test.QuickCheck as QC +import Numeric.CollectErrors+-- import Control.CollectErrors+ import Numeric.MixedTypes.Literals import Numeric.MixedTypes.Bool import Numeric.MixedTypes.Eq import Numeric.MixedTypes.Ord -- import Numeric.MixedTypes.MinMaxAbs import Numeric.MixedTypes.AddSub+import Numeric.MixedTypes.Ring++{----  rounded division + modulo -----}++class CanDivIMod t1 t2 where+  type DivIType t1 t2+  type DivIType t1 t2 = CN Integer+  type ModType t1 t2+  type ModType t1 t2 = EnsureCN t1+  divIMod :: t1 -> t2 -> (DivIType t1 t2, ModType t1 t2)+  mod :: t1 -> t2 -> ModType t1 t2+  mod a b = snd $ divIMod a b+  divI :: t1 -> t2 -> DivIType t1 t2+  divI a b = fst $ divIMod a b++type CanDivIModIntegerSameType t =+  (CanDivIMod t t, CanEnsureCN t, DivIType t t ~ CN Integer, ModType t t ~ EnsureCN t)++modNoCN :: +  (CanDivIMod t1 t2+  , ModType t1 t2 ~ EnsureCN t1, CanEnsureCN t1)+  => +  t1 -> t2 -> t1+modNoCN x m = +  case deEnsureCN $ x `mod` m of+    Left err -> error $ show err+    Right xm -> xm++divINoCN :: +  (CanDivIMod t1 t2, DivIType t1 t2 ~ CN Integer)+  => +  t1 -> t2 -> Integer+divINoCN x m = (~!) $ x `divI` m++divIModNoCN :: +  (CanDivIMod t1 t2+  , ModType t1 t2 ~ EnsureCN t1, CanEnsureCN t1+  , DivIType t1 t2 ~ CN Integer)+  => +  t1 -> t2 -> (Integer, t1)+divIModNoCN x m = +  case deEnsureCN xm of+    Left err -> error $ show err+    Right xm2 -> ((~!) d, xm2)+  where+  (d,xm) = divIMod x m++instance CanDivIMod Integer Integer where+  divIMod x m +    | m > 0 = (cn d, cn xm)+    | otherwise = (err, err)+    where+    (d,xm) = P.divMod x m+    err = noValueNumErrorCertainECN sample_v $ OutOfRange $ "modulus not positive: " ++ show m+    sample_v = Just x++instance CanDivIMod Rational Rational where+  divIMod x m +    | m > 0 = (cn d, cn xm)+    | otherwise = (err (d :: Integer), err xm)+    where+    (d,xm) = divMod' x m+    err :: (CanEnsureCN t) => t -> EnsureCN t+    err s = noValueNumErrorCertainECN (Just s) $ OutOfRange $ "modulus not positive: " ++ show m++instance CanDivIMod Rational Integer where+  divIMod x m = divIMod x (rational m)++instance CanDivIMod Double Double where+  divIMod x m +    | m > 0 = (cn d, cn xm)+    | otherwise = (err (d :: Integer), err xm)+    where+    (d,xm) = divMod' x m+    err :: (CanEnsureCN t) => t -> EnsureCN t+    err s = noValueNumErrorCertainECN (Just s) $ OutOfRange $ "modulus not positive: " ++ show m++instance CanDivIMod Double Integer where+  divIMod x m = divIMod x (double m)++type CanDivIModX t =+  (CanDivIMod t t,+   ModType t t ~ EnsureCN t,+   DivIType t t ~ CN Integer,+   EnsureNoCN t ~ t,+   CanEnsureCN t,+   CanMulBy t Integer,+   CanAddSameType t,+   HasOrderCertainly t Integer,+   HasOrderCertainly t t,+   HasEqCertainly t t,+   CanTestFinite t,+   Show t, Arbitrary t)++{-|+  HSpec properties that each implementation of CanRound should satisfy.+ -}+specCanDivIMod ::+  (CanDivIModX t, HasIntegers t)+  =>+  T t -> Spec+specCanDivIMod (T typeName :: T t) =+  describe (printf "CanDivMod %s %s" typeName typeName) $ do+    it "holds 0 <= x `mod` m < m" $ do+      property $ \ (x :: t)  (m :: t) ->+        isFinite x && m !>! 0 ==>+          let xm = x `modNoCN` m in+          (0 ?<=?$ xm) .&&. (xm ?<?$ m)+    it "holds x == (x `div'` m)*m + (x `mod` m)" $ do+      property $ \ (x :: t)  (m :: t) ->+        isFinite x && m !>! 0 ==>+          let (d,xm) = divIModNoCN x m in+          (x ?==?$ (d*m + xm))+  where+  (?<=?$) :: (HasOrderCertainlyAsymmetric a b, Show a, Show b) => a -> b -> Property+  (?<=?$) = printArgsIfFails2 "?<=?" (?<=?)+  (?<?$) :: (HasOrderCertainlyAsymmetric a b, Show a, Show b) => a -> b -> Property+  (?<?$) = printArgsIfFails2 "?<?" (?<?)+  (?==?$) :: (HasEqCertainlyAsymmetric a b, Show a, Show b) => a -> b -> Property+  (?==?$) = printArgsIfFails2 "?==?" (?==?)  {----  rounding -----} 
+ src/Utils/Test/EnforceRange.hs view
@@ -0,0 +1,63 @@+{-|+    Module      :  Utils.Test.EnforceRange+    Description :  squash generated numbers to a given range+    Copyright   :  (c) Michal Konecny+    License     :  BSD3++    Maintainer  :  mikkonecny@gmail.com+    Stability   :  experimental+    Portability :  portable++    Utility for squashing randomly generated numbers to a given range.+-}+module Utils.Test.EnforceRange +    (enforceRange, CanEnforceRange)+where++import Numeric.MixedTypes.PreludeHiding+-- import qualified Prelude as P++-- import Numeric.CollectErrors++import Numeric.MixedTypes.Literals+import Numeric.MixedTypes.Bool+-- import Numeric.MixedTypes.Eq+import Numeric.MixedTypes.Ord+import Numeric.MixedTypes.MinMaxAbs+import Numeric.MixedTypes.AddSub+import Numeric.MixedTypes.Ring+import Numeric.MixedTypes.Round++type CanEnforceRange t b =+    (CanAddSubMulBy t Integer+    , CanAddSameType t, CanSubSameType t, CanAbsSameType t+    , CanDivIModIntegerSameType t+    , ConvertibleExactly b t+    , HasOrderCertainly t t)++{-| +    @enforceRange (Just l, Just u) a@ where @l < u@ returns an arbitrary value @b@ with @u < b < l@.+    Moreover, the returned values are distributed roughly evenly if the input values @a@ are distributed +    roughly evenly in a large neighbourhood of the interval @[l,r]@.+    In most cases, when @l<a<u@, then @b=a@.+-}+enforceRange ::+    (CanEnforceRange t b) => (Maybe b, Maybe b) -> t -> t+enforceRange (Just l_, Just u_) (a::t) +    | not (l + 1 !<! u) = error "enforceRange: inconsistent range"+    | l !<! a && a !<! u = a+    | otherwise = l + 1 + ((abs a) `modNoCN` (u-l-1))+    where+    l = convertExactly l_ :: t+    u = convertExactly u_ :: t+enforceRange (Just l_, _) (a::t)+    | l !<! a = a+    | otherwise = (2*l-a+1)+    where+    l = convertExactly l_ :: t+enforceRange (_, Just u_) (a::t)+    | a !<! u = a+    | otherwise = (2*u-a-1)+    where+    u = convertExactly u_ :: t+enforceRange _ a = a
test/Numeric/MixedTypes/RoundSpec.hs view
@@ -17,5 +17,7 @@  spec :: Spec spec = do+  specCanDivIMod tInteger+  specCanDivIMod tRational   specCanRound tRational   -- specCanRound tDouble