packages feed

cyclotomic 0.4.4.1 → 0.5.0.0

raw patch · 4 files changed

+384/−12 lines, 4 filesdep +HUnitdep +QuickCheckdep +cyclotomicdep ~basePVP ok

version bump matches the API change (PVP)

Dependencies added: HUnit, QuickCheck, cyclotomic, test-framework, test-framework-hunit, test-framework-quickcheck2, test-framework-smallcheck

Dependency ranges changed: base

API changes (from Hackage documentation)

+ Data.Complex.Cyclotomic: heron :: Rational -> Rational -> Rational -> Cyclotomic
+ Data.Number.RealCyclotomic: cosDeg :: Rational -> RealCyclotomic
+ Data.Number.RealCyclotomic: cosRev :: Rational -> RealCyclotomic
+ Data.Number.RealCyclotomic: data RealCyclotomic
+ Data.Number.RealCyclotomic: goldenRatio :: RealCyclotomic
+ Data.Number.RealCyclotomic: heron :: Rational -> Rational -> Rational -> RealCyclotomic
+ Data.Number.RealCyclotomic: instance GHC.Classes.Eq Data.Number.RealCyclotomic.RealCyclotomic
+ Data.Number.RealCyclotomic: instance GHC.Num.Num Data.Number.RealCyclotomic.RealCyclotomic
+ Data.Number.RealCyclotomic: instance GHC.Real.Fractional Data.Number.RealCyclotomic.RealCyclotomic
+ Data.Number.RealCyclotomic: instance GHC.Show.Show Data.Number.RealCyclotomic.RealCyclotomic
+ Data.Number.RealCyclotomic: isRat :: RealCyclotomic -> Bool
+ Data.Number.RealCyclotomic: sinDeg :: Rational -> RealCyclotomic
+ Data.Number.RealCyclotomic: sinRev :: Rational -> RealCyclotomic
+ Data.Number.RealCyclotomic: sqrtRat :: Rational -> RealCyclotomic
+ Data.Number.RealCyclotomic: toRat :: RealCyclotomic -> Maybe Rational
+ Data.Number.RealCyclotomic: toReal :: RealFloat a => RealCyclotomic -> a
- Data.Complex.Cyclotomic: toComplex :: Cyclotomic -> Complex Double
+ Data.Complex.Cyclotomic: toComplex :: RealFloat a => Cyclotomic -> Complex a
- Data.Complex.Cyclotomic: toReal :: Cyclotomic -> Maybe Double
+ Data.Complex.Cyclotomic: toReal :: RealFloat a => Cyclotomic -> Maybe a

Files

cyclotomic.cabal view
@@ -1,5 +1,6 @@ Name:                cyclotomic-Version:             0.4.4.1+Version:             0.5.0.0+Stability:           experimental Synopsis:            A subfield of the complex numbers for exact calculation. Description:         The cyclotomic numbers are a subset of the                      complex numbers that are represented exactly, enabling exact@@ -16,16 +17,33 @@ License-file:        LICENSE Author:              Scott N. Walck Maintainer:          Scott N. Walck <walck@lvc.edu>+Copyright:           (c) Scott N. Walck 2012-2017 Category:            Math Build-type:          Simple-Cabal-version:       >=1.6-Tested-with:         GHC == 7.8.4, GHC == 7.10.2+Extra-source-files:  test/Properties.hs+Cabal-version:       >= 1.10+Tested-with:         GHC == 7.8.4, GHC == 7.10.2,  GHC == 7.10.3,  GHC == 8.0.1+Bug-reports:         https://github.com/walck/cyclotomic/issues++Test-suite cyclotomic-tests+  type:              exitcode-stdio-1.0+  main-is:           Properties.hs+  build-depends:     base, QuickCheck >= 2.4, cyclotomic,+                     test-framework, HUnit, test-framework-hunit,+                     test-framework-quickcheck2,+                     test-framework-smallcheck+  default-language:  Haskell2010+  Hs-source-dirs:    test+ Library-  Exposed-modules:     Data.Complex.Cyclotomic-  Build-depends:       base >= 4.2 && < 5,-                       containers >= 0.3,-                       arithmoi >= 0.4-  Hs-source-dirs:      src+  ghc-options:       -Wall+  Exposed-modules:   Data.Complex.Cyclotomic, Data.Number.RealCyclotomic+  Build-depends:     base >= 4.2 && < 4.11,+                     containers >= 0.3,+                     arithmoi >= 0.4+  default-language:  Haskell2010+  Hs-source-dirs:    src+ Source-repository head   type:                git-  location:            https://github.com/walck/cyclotomic+  location:            https://github.com/walck/cyclotomic.git
src/Data/Complex/Cyclotomic.hs view
@@ -3,7 +3,7 @@  {- |  Module      :  Data.Complex.Cyclotomic-Copyright   :  (c) Scott N. Walck 2012-2013+Copyright   :  (c) Scott N. Walck 2012-2017 License     :  GPL-3 (see LICENSE) Maintainer  :  Scott N. Walck <walck@lvc.edu> Stability   :  experimental@@ -86,6 +86,7 @@     , dft     , dftInv     , rootsQuadEq+    , heron     )     where @@ -473,13 +474,13 @@ isGaussianRat c = isRat (real c) && isRat (imag c)  -- | Export as an inexact complex number.-toComplex :: Cyclotomic -> Complex Double+toComplex :: RealFloat a => Cyclotomic -> Complex a toComplex c = sum [fromRational r * en^p | (p,r) <- M.toList (coeffs c)]     where en = exp (0 :+ 2*pi/n)           n = fromIntegral (order c)  -- | Export as an inexact real number if possible.-toReal :: Cyclotomic -> Maybe Double+toReal :: RealFloat a => Cyclotomic -> Maybe a toReal c     | isReal c   = Just $ realPart (toComplex c)     | otherwise  = Nothing@@ -561,3 +562,14 @@       aa = fromRational a       bb = fromRational b       sqrtDisc = sqrtRat (b*b - 4*a*c)++-- | Heron's formula for the area of a triangle with+--   side lengths a, b, c.+heron :: Rational    -- ^ a+      -> Rational    -- ^ b+      -> Rational    -- ^ c+      -> Cyclotomic  -- ^ area of triangle+heron a b c+    = sqrtRat (s * (s-a) * (s-b) * (s-c))+      where+        s = (a + b + c) / 2
+ src/Data/Number/RealCyclotomic.hs view
@@ -0,0 +1,149 @@+{-# OPTIONS_GHC -Wall #-}+{-# LANGUAGE Safe #-}++{- |+Module      :  Data.Number.RealCyclotomic+Copyright   :  (c) Scott N. Walck 2012-2017+License     :  GPL-3 (see LICENSE)+Maintainer  :  Scott N. Walck <walck@lvc.edu>+Stability   :  experimental++The real cyclotomic numbers are a subset of the real numbers with+the following properties:++     1.  The real cyclotomic numbers are represented exactly, enabling exact+     computations and equality comparisons.++     2.  The real cyclotomic numbers contain the rationals.+     As a consequence, the real cyclotomic numbers are a dense subset of the+     real numbers.++     3.  The real cyclotomic numbers contain the square roots of all nonnegative rational numbers.++     4.  The real cyclotomic numbers form a field:  they are closed under addition, subtraction,+     multiplication, and division.++     5.  The real cyclotomic numbers contain the sine and cosine of all rational+     multiples of pi (equivalently, the sine and cosine of any rational number+     of degrees or any rational number of revolutions).++     Floating point numbers do not do well with equality comparison:++>(sqrt 2 + sqrt 3)^2 == 5 + 2 * sqrt 6+> -> False++     "Data.Number.RealCyclotomic" represents these numbers exactly, allowing equality comparison:++>(sqrtRat 2 + sqrtRat 3)^2 == 5 + 2 * sqrtRat 6+> -> True++     'RealCyclotomic's can be exported as inexact real numbers using the 'toReal' function:++>sqrtRat 2+> -> e(8) - e(8)^3+>toReal $ sqrtRat 2+> -> 1.414213562373095++This module is based on the module 'Data.Complex.Cyclotomic'.+Usually you would only import one of the modules 'Data.Number.RealCyclotomic'+or 'Data.Complex.Cyclotomic', depending on whether you wanted only+real numbers (this module) or complex numbers (the other).+Functions such as @sqrtRat@, @sinDeg@, @cosDeg@ are defined+in both modules, with different type signatures, so their+names will conflict if both modules are imported.+-}++module Data.Number.RealCyclotomic+    ( RealCyclotomic+    , sqrtRat+    , sinDeg+    , cosDeg+    , sinRev+    , cosRev+    , isRat+    , toRat+    , toReal+    , goldenRatio+    , heron+    )+    where++import qualified Data.Complex.Cyclotomic as Cyc+import Data.Complex+    ( realPart+    )++-- | A real cyclotomic number.+newtype RealCyclotomic = RealCyclotomic Cyc.Cyclotomic+    deriving (Eq)++-- | @abs@ and @signum@ are undefined.+instance Num RealCyclotomic where+    RealCyclotomic x + RealCyclotomic y = RealCyclotomic (x + y)+    RealCyclotomic x - RealCyclotomic y = RealCyclotomic (x - y)+    RealCyclotomic x * RealCyclotomic y = RealCyclotomic (x * y)+    negate (RealCyclotomic x) = RealCyclotomic (negate x)+    fromInteger n = RealCyclotomic (fromInteger n)+    abs    = undefined+    signum = undefined++instance Fractional RealCyclotomic where+    recip (RealCyclotomic x) = RealCyclotomic (recip x)+    fromRational r = RealCyclotomic (fromRational r)++instance Show RealCyclotomic where+    show (RealCyclotomic x) = show x++-- I need to do Ord first.+-- A Real instance would make realToFrac work.+-- instance Real RealCyclotomic where+--     toRational c = toRational (toReal c)++-- | The square root of a 'Rational' number.+sqrtRat :: Rational -> RealCyclotomic+sqrtRat r+    | r >= 0  = RealCyclotomic (Cyc.sqrtRat r)+    | otherwise  = error "sqrtRational needs a nonnegative argument"++-- | Sine function with argument in degrees.+sinDeg :: Rational -> RealCyclotomic+sinDeg r = RealCyclotomic (Cyc.sinDeg r)++-- | Cosine function with argument in degrees.+cosDeg :: Rational -> RealCyclotomic+cosDeg r = RealCyclotomic (Cyc.cosDeg r)++-- | Sine function with argument in revolutions.+sinRev :: Rational -> RealCyclotomic+sinRev r = RealCyclotomic (Cyc.sinRev r)++-- | Cosine function with argument in revolutions.+cosRev :: Rational -> RealCyclotomic+cosRev r = RealCyclotomic (Cyc.cosRev r)++-- | Is the cyclotomic a rational?+isRat :: RealCyclotomic -> Bool+isRat (RealCyclotomic r) = Cyc.isRat r++-- | Return an exact rational number if possible.+toRat :: RealCyclotomic -> Maybe Rational+toRat (RealCyclotomic r) = Cyc.toRat r++-- | Export as an inexact real number.+toReal :: RealFloat a => RealCyclotomic -> a+toReal (RealCyclotomic r) = realPart (Cyc.toComplex r)++-- | The golden ratio, @(1 + √5)/2@.+goldenRatio :: RealCyclotomic+goldenRatio = (1 + sqrtRat 5) / 2++-- | Heron's formula for the area of a triangle with+--   side lengths a, b, c.+heron :: Rational        -- ^ a+      -> Rational        -- ^ b+      -> Rational        -- ^ c+      -> RealCyclotomic  -- ^ area of triangle+heron a b c+    = sqrtRat (s * (s-a) * (s-b) * (s-c))+      where+        s = (a + b + c) / 2
+ test/Properties.hs view
@@ -0,0 +1,193 @@+{-# OPTIONS_GHC -Wall #-}++module Main where++import Data.Complex.Cyclotomic+import Test.Framework+    ( defaultMain+    , testGroup+    )+import Test.Framework.Providers.HUnit+    ( testCase+    )+import Test.Framework.Providers.QuickCheck2+    ( testProperty+    )+import qualified Test.Framework.Providers.SmallCheck as S+import qualified Test.Framework.Providers.API as T+import Test.QuickCheck+    ( Gen+    , elements+    , Arbitrary(..)+    , shrinkRealFrac+    )+import Test.HUnit+    ( (@?=)+    , Assertion+    )+import Data.List+    ( nub+    )+import Data.Ratio+    ( (%)+    )++main :: IO ()+main = defaultMain tests++tests :: [T.Test]+tests = [test1a+        ,test2b+        ,test3b+        ,test4b+        ,test5+        ,S.withDepth 10 (S.testProperty "SmallCheck prop_square_sqrtRat" prop_square_sqrtRat)+        ,qc_square_sqrtRat+        ,qc_Gauss+        ,qc_dftInv_dft+        ,qc_dft_dftInv+        ,qc_sum_quadratic_roots+        ]++rationals :: [Rational]+rationals = 0 % 1 : [sign * k % j | n <- [0..], m <- [0..n-1], sign <- [1,-1]+                    , let k = m + 1, let j = n - m, gcd k j == 1]++rationalList :: Integer -> [Rational]+rationalList m = nub [n % d | n <- [-m..m], d <- [1..m]]++test1a :: T.Test+test1a = testGroup "polarRat" [polarRatTest p q | p <- [0..10], q <- [1..10]]++polarRatAssertion :: Integer -> Integer -> Assertion+polarRatAssertion p q = polarRat 1 (p % q) @?= e q^p++polarRatTest :: Integer -> Integer -> T.Test+polarRatTest p q = testCase ("polarRat 1 (" ++ show p ++ " % " ++ show q ++ ")") (polarRatAssertion p q)++test2b :: T.Test+test2b = testGroup "sqrtRat r ^ 2 == r for the following values of r"+         [testCase (show r) (sqrtRat r ^ (2::Int) @?= fromRational r)+              | r <- take 100 rationals]++test3b :: T.Test+test3b = testGroup "sqrtRat (r*r) == abs r for the following values of r"+         [testCase (show r) (sqrtRat (r*r) @?= fromRational (abs r))+              | r <- take 100 rationals]++test4b :: T.Test+test4b = testGroup "z * (1 / z) == 1 for the following values of z"+         [testCase (show z) (z * (1 / z) @?= 1)+              | n <- [1..10], m <- [1..10], let z = e n + e m, z /= 0]++test5 :: T.Test+test5 = testGroup "Heron's formula"+        [testCase "Try Heron" (heron 3 4 5 @?= 6)]++----------------+-- Properties --+----------------++prop_square_sqrtRat :: Int -> Bool+prop_square_sqrtRat n = sqrtRat (fromIntegral n) ^ (2::Int) == fromIntegral n++prop_Gauss :: Integer -> Bool+prop_Gauss n = let nn = 2 * abs n + 1+               in sum [e nn^(j*j `mod` nn) | j <- [1..(nn - 1) `div` 2]]+                      == if nn `mod` 4 == 1+                         then (-1 + sqrtInteger nn) / 2+                         else (-1 + i*sqrtInteger nn) / 2++prop_dftInv_dft :: [Rational] -> Bool+prop_dftInv_dft rs = dftInv (dft cs) == cs+    where cs = map fromRational rs++prop_dft_dftInv :: [Rational] -> Bool+prop_dft_dftInv rs = dft (dftInv cs) == cs+    where cs = map fromRational rs++prop_sum_quadratic_roots :: (Rational, Rational, Rational) -> Bool+prop_sum_quadratic_roots (a, b, c)+    = case rootsQuadEq a b c of+        Nothing      -> a == 0+        Just (r1,r2) -> r1 + r2 == fromRational (-b / a)++prop_sum_quadratic_roots_small :: (SmallRational, SmallRational, SmallRational) -> Bool+prop_sum_quadratic_roots_small (SmallRational a, SmallRational b, SmallRational c)+    = case rootsQuadEq a b c of+        Nothing      -> a == 0+        Just (r1,r2) -> r1 + r2 == fromRational (-b / a)++----------------------+-- QuickCheck Tests --+----------------------++qc_square_sqrtRat :: T.Test+qc_square_sqrtRat+    = T.plusTestOptions (T.TestOptions+                         {T.topt_seed                               = Nothing+                         ,T.topt_maximum_generated_tests            = Just 15+                         ,T.topt_maximum_unsuitable_generated_tests = Nothing+                         ,T.topt_maximum_test_size                  = Just 15+                         ,T.topt_maximum_test_depth                 = Nothing+                         ,T.topt_timeout                            = Nothing+                         })+      $ testProperty "QuickCheck prop_square_sqrtRat" prop_square_sqrtRat++qc_Gauss :: T.Test+qc_Gauss+    = T.plusTestOptions (T.TestOptions+                         {T.topt_seed                               = Nothing+                         ,T.topt_maximum_generated_tests            = Nothing+                         ,T.topt_maximum_unsuitable_generated_tests = Nothing+                         ,T.topt_maximum_test_size                  = Nothing+                         ,T.topt_maximum_test_depth                 = Nothing+                         ,T.topt_timeout                            = Nothing+                         })+      $ testProperty "QuickCheck prop_Gauss" prop_Gauss++qc_dftInv_dft :: T.Test+qc_dftInv_dft+    = T.plusTestOptions (T.TestOptions+                         {T.topt_seed                               = Nothing+                         ,T.topt_maximum_generated_tests            = Just 15+                         ,T.topt_maximum_unsuitable_generated_tests = Nothing+                         ,T.topt_maximum_test_size                  = Just 30+                         ,T.topt_maximum_test_depth                 = Nothing+                         ,T.topt_timeout                            = Nothing+                         })+      $ testProperty "QuickCheck prop_dftInv_dft" prop_dftInv_dft++qc_dft_dftInv :: T.Test+qc_dft_dftInv+    = T.plusTestOptions (T.TestOptions+                         {T.topt_seed                               = Nothing+                         ,T.topt_maximum_generated_tests            = Just 15+                         ,T.topt_maximum_unsuitable_generated_tests = Nothing+                         ,T.topt_maximum_test_size                  = Just 30+                         ,T.topt_maximum_test_depth                 = Nothing+                         ,T.topt_timeout                            = Nothing+                         })+      $ testProperty "QuickCheck prop_dft_dftInv" prop_dft_dftInv++qc_sum_quadratic_roots :: T.Test+qc_sum_quadratic_roots+    = testProperty "QuickCheck prop_sum_quadratic_roots" prop_sum_quadratic_roots_small++----------------------+-- QuickCheck Stuff --+----------------------++data SmallRational = SmallRational Rational+                     deriving (Show,Ord,Eq)++smallRationalList :: [SmallRational]+smallRationalList = map SmallRational (rationalList 3)++smallRationalGen :: Gen SmallRational+smallRationalGen = elements smallRationalList++instance Arbitrary SmallRational where+    arbitrary = smallRationalGen+    shrink (SmallRational r) = map SmallRational (shrinkRealFrac r)+