factory 0.3.0.0 → 0.3.1.4
raw patch · 15 files changed
+79/−52 lines, 15 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Factory.Data.Interval: splitAt' :: (Enum endPoint, Num endPoint, Ord endPoint, Show endPoint) => endPoint -> Interval endPoint -> (Interval endPoint, Interval endPoint)
+ Factory.Data.Interval: splitAt' :: (Enum endPoint, Ord endPoint, Show endPoint) => endPoint -> Interval endPoint -> (Interval endPoint, Interval endPoint)
- Factory.Data.MonicPolynomial: mkMonicPolynomial :: (Eq c, Num c, Ord e, Show c, Show e) => Polynomial c e -> MonicPolynomial c e
+ Factory.Data.MonicPolynomial: mkMonicPolynomial :: (Eq c, Num c, Show c, Show e) => Polynomial c e -> MonicPolynomial c e
- Factory.Data.Ring: class Ring r where l =-= r = l =+= additiveInverse r square r = r =*= r
+ Factory.Data.Ring: class Ring r
- Factory.Math.Pi: class Algorithmic algorithm where openI _ 1 = 3 openI algorithm decimalDigits | decimalDigits <= 0 = error $ "Factory.Math.Pi.openI:\tinsufficient decimalDigits=" ++ show decimalDigits | otherwise = round . promote (openR algorithm decimalDigits) $ pred decimalDigits openS _ 1 = "3" openS algorithm decimalDigits | decimalDigits <= 0 = "" | decimalDigits <= 16 = take (succ decimalDigits) $ show (pi :: Double) | otherwise = "3." ++ tail (show $ openI algorithm decimalDigits)
+ Factory.Math.Pi: class Algorithmic algorithm
- Factory.Math.Probability: class Distribution probabilityDistribution where getStandardDeviation = sqrt . getVariance getVariance = square . getStandardDeviation
+ Factory.Math.Probability: class Distribution probabilityDistribution
- Factory.Math.SquareRoot: class Algorithmic algorithm where squareRoot algorithm decimalDigits operand = squareRootFrom algorithm (getEstimate operand) decimalDigits operand
+ Factory.Math.SquareRoot: class Algorithmic algorithm
- Factory.Math.Statistics: getWeightedMean :: (Foldable foldable, Eq result, Fractional result, Real value, Real weight) => foldable (value, weight) -> result
+ Factory.Math.Statistics: getWeightedMean :: (Foldable foldable, Fractional result, Real value, Real weight) => foldable (value, weight) -> result
Files
- .ghci +1/−1
- README.markdown +1/−1
- changelog.markdown +10/−0
- factory.cabal +14/−12
- src-lib/Factory/Data/Interval.hs +0/−1
- src-lib/Factory/Data/MonicPolynomial.hs +0/−1
- src-lib/Factory/Math/Hyperoperation.hs +2/−2
- src-lib/Factory/Math/Implementations/Primality.hs +2/−1
- src-lib/Factory/Math/Implementations/PrimeFactorisation.hs +3/−3
- src-lib/Factory/Math/Implementations/Primes/TrialDivision.hs +1/−2
- src-lib/Factory/Math/Pi.hs +1/−1
- src-lib/Factory/Math/Probability.hs +1/−1
- src-lib/Factory/Math/Statistics.hs +33/−13
- src-test/Factory/Test/QuickCheck/Polynomial.hs +9/−12
- src-test/Factory/Test/QuickCheck/Probability.hs +1/−1
.ghci view
@@ -1,1 +1,1 @@-:set -isrc-lib:src-exe:src-test:dist/build/autogen -optP-include -optPdist/build/autogen/cabal_macros.h+:set -isrc-lib:src-exe:src-test:dist/build/autogen -optP-include -optPdist/build/autogen/cabal_macros.h -Wall -fno-warn-tabs
README.markdown view
@@ -1,6 +1,6 @@ # **Factory** -[](https://hackage.haskell.org/package/factory)+[](https://hackage.haskell.org/package/factory) [](https://travis-ci.org/functionalley/Factory) This is "**Factory**", a library of number-theory functions.
changelog.markdown view
@@ -147,10 +147,20 @@ * Added function **Factory.Test.QuickCheck.Statistics.prop_standardDeviationRMS**. * Added **Eq** type-constraint to function **Factory.Math.Statistics.getWeightedMean**. * Tested with **ghc-8.0.1**.+ ## 0.2.2.1 * Commented-out flakey square-root test.+ ## 0.3.0.0 * Used strictness to improve efficiency of functions **getMean**, **getRootMeanSquare**, **getWeightedMean** & replaced **error** with **Control.Exception.assert**, in module **Factory.Math.Statistics** * Replaced 'Data.List.genericLength' with the more efficient @fromIntegral . length@. * Removed dependency on **Distribution.Package.PackageName**. * Checked for null-string in **Factory.Math.Radix.fromBase**.++## 0.3.1.0+* Replaced '+negate' with 'subtract'.+* Removed **Eq** type-constraint from **Factory.Math.Statistics.getWeightedMean**.+* Added specialisation-pragmas to **Factory.Math.Statistics**.++## 0.3.1.4+
factory.cabal view
@@ -14,7 +14,7 @@ -- along with Factory. If not, see <http://www.gnu.org/licenses/>. Name: factory-Version: 0.3.0.0+Version: 0.3.1.4 Cabal-version: >= 1.10 Copyright: (C) 2011-2015 Dr. Alistair Ward License: GPL@@ -25,7 +25,7 @@ Build-type: Simple Description: A library of number-theory functions, for; factorials, square-roots, Pi and primes. Category: Math, Number Theory-Tested-with: GHC == 7.4, GHC == 7.6, GHC == 7.8, GHC == 7.10.1, GHC == 8.0.1+Tested-with: GHC == 7.4, GHC == 7.6, GHC == 7.8, GHC == 7.10, GHC == 8.0, GHC == 8.2 Homepage: http://functionalley.eu/Factory/factory.html Maintainer: mailto:factory@functionalley.eu Bug-reports: mailto:factory@functionalley.eu@@ -41,7 +41,7 @@ type: git location: https://github.com/functionalley/Factory --- Enable using: 'cabal configure -f llvm'.+-- Enable using: 'runhaskell Setup configure -f llvm --verbose'. flag llvm Description: Whether the 'llvm' compiler-backend has been installed and is required for code-generation. Manual: True@@ -127,17 +127,17 @@ random, toolshed >= 0.17 - if impl(ghc >= 7.4.1)- GHC-prof-options: -fprof-auto -fprof-cafs- else- GHC-prof-options: -auto-all -caf-all- if impl(ghc >= 7.0) if flag(llvm) GHC-options: -fllvm - if impl(ghc >= 8.0)- GHC-options: -Wredundant-constraints+ if impl(ghc >= 7.4.1)+ GHC-prof-options: -fprof-auto -fprof-cafs+ + if impl(ghc >= 8.0)+ GHC-options: -j -Wredundant-constraints+ else+ GHC-prof-options: -auto-all -caf-all Executable factory Default-language: Haskell2010@@ -183,7 +183,7 @@ GHC-options: -fllvm if impl(ghc >= 8.0)- GHC-options: -Wredundant-constraints+ GHC-options: -j -Wredundant-constraints Test-Suite test Default-language: Haskell2010@@ -224,6 +224,8 @@ random, toolshed >= 0.17 + GHC-options: -rtsopts "-with-rtsopts=-k100M"+ if impl(ghc >= 8.0)- GHC-options: -Wredundant-constraints+ GHC-options: -j -Wredundant-constraints
src-lib/Factory/Data/Interval.hs view
@@ -116,7 +116,6 @@ -- | Bisect the /interval/ at the specified /end-point/; which should be between the two existing /end-points/. splitAt' :: ( Enum endPoint,- Num endPoint, Ord endPoint, Show endPoint ) => endPoint -> Interval endPoint -> (Interval endPoint, Interval endPoint)
src-lib/Factory/Data/MonicPolynomial.hs view
@@ -50,7 +50,6 @@ mkMonicPolynomial :: ( Eq c, Num c,- Ord e, Show c, Show e ) => Data.Polynomial.Polynomial c e -> MonicPolynomial c e
src-lib/Factory/Math/Hyperoperation.hs view
@@ -1,5 +1,5 @@ {-- Copyright (C) 2011 Dr. Alistair Ward+ Copyright (C) 2011-2017 Dr. Alistair Ward This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by@@ -102,7 +102,7 @@ -- | The /Ackermann-Peter/-function; <https://en.wikipedia.org/wiki/Ackermann_function#Ackermann_numbers>. ackermannPeter :: (Integral rank, Show rank) => rank -> HyperExponent -> Base-ackermannPeter rank = (+ negate 3) . hyperoperation rank 2 {-base-} . (+ 3)+ackermannPeter rank = subtract 3 . hyperoperation rank 2 {-base-} . (+ 3) -- | True if @hyperoperation base hyperExponent@ has the same value for each specified 'rank'. areCoincidental :: (Integral rank, Show rank) => Base -> HyperExponent -> [rank] -> Bool
src-lib/Factory/Math/Implementations/Primality.hs view
@@ -43,6 +43,7 @@ import qualified Control.DeepSeq import qualified Control.Parallel.Strategies import qualified Data.Default+import qualified Data.List import qualified Data.Numbers.Primes import qualified Factory.Data.MonicPolynomial as Data.MonicPolynomial import qualified Factory.Data.Polynomial as Data.Polynomial@@ -111,7 +112,7 @@ ) => factorisationAlgorithm -> i -> Bool isPrimeByAKS factorisationAlgorithm n = and [ not $ Math.PerfectPower.isPerfectPower n, -- Step 1.- Math.Primality.areCoprime n `all` filter (/= n) [2 .. r], -- Step 3.+ Math.Primality.areCoprime n `all` Data.List.delete n [2 .. r], -- Step 3. and $ Control.Parallel.Strategies.parMap Control.Parallel.Strategies.rdeepseq {-Benefits from '+RTS -H100M', which reduces garbage-collections-} ( \a -> let -- lhs, rhs :: Data.Polynomial.Polynomial i i
src-lib/Factory/Math/Implementations/PrimeFactorisation.hs view
@@ -1,5 +1,5 @@ {-- Copyright (C) 2011-2015 Dr. Alistair Ward+ Copyright (C) 2011-2017 Dr. Alistair Ward This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by@@ -70,7 +70,7 @@ TrialDivision -> factoriseByTrialDivision -- | <https://en.wikipedia.org/wiki/Dixon%27s_factorization_method>.-factoriseByDixonsMethod :: Integral base => base -> Data.PrimeFactors.Factors base exponent+factoriseByDixonsMethod :: base -> Data.PrimeFactors.Factors base exponent factoriseByDixonsMethod = undefined {- |@@ -118,7 +118,7 @@ ) . filter ( Data.Maybe.isJust . snd -- Search for a perfect square. ) . map (- Control.Arrow.second $ Math.PerfectPower.maybeSquareNumber {-hotspot-} . (+ negate i) -- Associate the corresponding value of /smaller/.+ Control.Arrow.second $ Math.PerfectPower.maybeSquareNumber {-hotspot-} . subtract i -- Associate the corresponding value of /smaller/. ) . takeWhile ( (<= (i + 9) `div` 6) . fst -- Terminate the search at the maximum value of /larger/. ) . Math.Power.squaresFrom {-hotspot-} . ceiling $ sqrt (fromIntegral i :: Double) -- Start the search at the minimum value of /larger/.
src-lib/Factory/Math/Implementations/Primes/TrialDivision.hs view
@@ -28,7 +28,6 @@ ) where import qualified Control.Arrow-import qualified Data.List import qualified Factory.Math.Power as Math.Power import qualified Factory.Math.PrimeFactorisation as Math.PrimeFactorisation import qualified Factory.Data.PrimeWheel as Data.PrimeWheel@@ -53,7 +52,7 @@ candidates = map fst $ Data.PrimeWheel.roll primeWheel indivisible = uncurry (++) . Control.Arrow.second ( filter (`isIndivisibleBy` indivisible {-recurse-})- ) $ Data.List.span (+ ) $ span ( < Math.Power.square (head candidates) -- The first composite candidate, is the square of the next prime after the wheel's constituent ones. ) candidates
src-lib/Factory/Math/Pi.hs view
@@ -64,7 +64,7 @@ | Spigot spigot -- ^ Algorithms from which the digits of /Pi/ slowly drip, one by one. deriving (Eq, Read, Show) -instance Data.Default.Default bbp => Data.Default.Default (Category agm bbp borwein ramanujan spigot) where+instance Data.Default.Default bbp => Data.Default.Default (Category agm bbp borwein ramanujan spigot) where def = BBP Data.Default.def instance (
src-lib/Factory/Math/Probability.hs view
@@ -50,7 +50,7 @@ import qualified ToolShed.SelfValidate -- | The maximum integer which can be accurately represented as a Double.-maxPreciseInteger :: RealFloat a => a -> Integer+maxPreciseInteger :: RealFloat a => a -> Integer maxPreciseInteger = (2 ^) . floatDigits {- |
src-lib/Factory/Math/Statistics.hs view
@@ -1,5 +1,6 @@+{-# LANGUAGE CPP #-} {-- Copyright (C) 2011 Dr. Alistair Ward+ Copyright (C) 2011-2017 Dr. Alistair Ward This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by@@ -55,6 +56,10 @@ ) => foldable value -> result+{-# SPECIALISE getMean :: Data.Foldable.Foldable foldable => foldable Double -> Double #-}+#if MIN_TOOL_VERSION_ghc(7,10,0)+{-# SPECIALISE getMean :: Data.Foldable.Foldable foldable => foldable Rational -> Rational #-}+#endif getMean foldable = Control.Exception.assert (denominator /= 0) $ realToFrac numerator / fromIntegral denominator where denominator :: Int (numerator, denominator) = Data.Foldable.foldl' (@@ -71,7 +76,8 @@ ) => foldable value -> result-getRootMeanSquare foldable = Control.Exception.assert (denominator /= 0) $ sqrt $ realToFrac numerator / fromIntegral denominator where+{-# SPECIALISE getRootMeanSquare :: Data.Foldable.Foldable foldable => foldable Double -> Double #-}+getRootMeanSquare foldable = Control.Exception.assert (denominator /= 0) . sqrt $ realToFrac numerator / fromIntegral denominator where denominator :: Int (numerator, denominator) = Data.Foldable.foldl' ( \acc x -> let@@ -84,26 +90,27 @@ * The specified value is only evaluated if the corresponding weight is non-zero. - * Should the caller define the result-type as 'Rational', then it will be free from rounding-errors.- * CAVEAT: because the operand is more general than a list, no optimisation is performed when supplied a singleton. -} getWeightedMean :: ( Data.Foldable.Foldable foldable,- Eq result, Fractional result, Real value, Real weight ) => foldable (value, weight) -- ^ Each pair consists of a value & the corresponding weight. -> result-getWeightedMean foldable = Control.Exception.assert (denominator /= 0) $ numerator / denominator where+{-# SPECIALISE getWeightedMean :: Data.Foldable.Foldable foldable => foldable (Double, Double) -> Double #-}+#if MIN_TOOL_VERSION_ghc(7,10,0)+{-# SPECIALISE getWeightedMean :: Data.Foldable.Foldable foldable => foldable (Rational, Rational) -> Rational #-}+#endif+getWeightedMean foldable = Control.Exception.assert (denominator /= 0) $ numerator / realToFrac denominator where (numerator, denominator) = Data.Foldable.foldl' (- \acc (value, weight) -> case realToFrac weight of- 0 -> acc -- Avoid unnecessarily evaluation.- w -> let- acc'@(n, d) = (+ realToFrac value * w) *** (+ w) $ acc -- Perform the arithmetic in the specified result-type.- in n `seq` d `seq` acc'+ \acc (value, weight) -> if weight == 0+ then acc -- Avoid unnecessary evaluation.+ else let+ acc'@(n, d) = (+ realToFrac weight * realToFrac value) *** (+ weight) $ acc+ in n `seq` d `seq` acc' ) (0, 0) foldable {- |@@ -117,8 +124,11 @@ Functor foldable, Real value ) => (Rational -> Rational) -> foldable value -> result-getDispersionFromMean weight foldable = getMean $ fmap (weight . (+ negate mean) . toRational) foldable where- mean :: Rational+{-# SPECIALISE getDispersionFromMean :: (Data.Foldable.Foldable foldable, Functor foldable) => (Rational -> Rational) -> foldable Double -> Double #-}+#if MIN_TOOL_VERSION_ghc(7,10,0)+{-# SPECIALISE getDispersionFromMean :: (Data.Foldable.Foldable foldable, Functor foldable) => (Rational -> Rational) -> foldable Rational -> Rational #-}+#endif+getDispersionFromMean weight foldable = getMean $ fmap (weight . subtract mean . toRational) foldable where mean = getMean foldable {- |@@ -132,6 +142,10 @@ Functor foldable, Real value ) => foldable value -> variance+{-# SPECIALISE getVariance :: (Data.Foldable.Foldable foldable, Functor foldable) => foldable Double -> Double #-}+#if MIN_TOOL_VERSION_ghc(7,10,0)+{-# SPECIALISE getVariance :: (Data.Foldable.Foldable foldable, Functor foldable) => foldable Rational -> Rational #-}+#endif getVariance = getDispersionFromMean Math.Power.square -- | Determines the /standard-deviation/ of the specified numbers; <https://en.wikipedia.org/wiki/Standard_deviation>.@@ -141,6 +155,7 @@ Functor foldable, Real value ) => foldable value -> result+{-# SPECIALISE getStandardDeviation :: (Data.Foldable.Foldable foldable, Functor foldable) => foldable Double -> Double #-} getStandardDeviation = sqrt . getVariance {- |@@ -154,6 +169,10 @@ Functor foldable, Real value ) => foldable value -> result+{-# SPECIALISE getAverageAbsoluteDeviation :: (Data.Foldable.Foldable foldable, Functor foldable) => foldable Double -> Double #-}+#if MIN_TOOL_VERSION_ghc(7,10,0)+{-# SPECIALISE getAverageAbsoluteDeviation :: (Data.Foldable.Foldable foldable, Functor foldable) => foldable Rational -> Rational #-}+#endif getAverageAbsoluteDeviation = getDispersionFromMean abs -- | Determines the /coefficient-of-variance/ of the specified numbers; <https://en.wikipedia.org/wiki/Coefficient_of_variation>.@@ -164,6 +183,7 @@ Functor foldable, Real value ) => foldable value -> result+{-# SPECIALISE getCoefficientOfVariance :: (Data.Foldable.Foldable foldable, Functor foldable) => foldable Double -> Double #-} getCoefficientOfVariance l = Control.Exception.assert (mean /= 0) $ getStandardDeviation l / abs mean where mean = getMean l
src-test/Factory/Test/QuickCheck/Polynomial.hs view
@@ -1,6 +1,6 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} {-- Copyright (C) 2011-2015 Dr. Alistair Ward+ Copyright (C) 2011-2017 Dr. Alistair Ward This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by@@ -26,7 +26,7 @@ results ) where -import Control.Arrow((***))+import Control.Arrow((&&&), (***)) import Factory.Data.Ring((=*=), (=+=), (=-=), (=^)) import qualified Data.Numbers.Primes import qualified Factory.Data.Polynomial as Data.Polynomial@@ -36,12 +36,12 @@ import Test.QuickCheck((==>)) instance (- Test.QuickCheck.Arbitrary c, Integral c,- Test.QuickCheck.Arbitrary e,- Integral e+ Integral e,+ Test.QuickCheck.Arbitrary c,+ Test.QuickCheck.Arbitrary e ) => Test.QuickCheck.Arbitrary (Data.Polynomial.Polynomial c e) where- arbitrary = (Data.Polynomial.mkPolynomial . map ((+ negate 4) . (`mod` 8) *** (`mod` 8))) `fmap` Test.QuickCheck.arbitrary+ arbitrary = (Data.Polynomial.mkPolynomial . map (subtract 4 . (`mod` 8) *** (`mod` 8))) `fmap` Test.QuickCheck.arbitrary -- | The constant test-results for this data-type. results :: IO [Test.QuickCheck.Result]@@ -66,15 +66,13 @@ prop_quotRem, prop_degree, prop_ringNormalised, prop_quotientRingNormalised :: Data.Polynomial.Polynomial Integer Integer -> Data.Polynomial.Polynomial Integer Integer -> Test.QuickCheck.Property prop_quotRem numerator denominator = denominator' /= Data.Polynomial.zero ==> Test.QuickCheck.label "prop_quotRem" $ numerator' == denominator' =*= quotient =+= remainder where numerator', denominator' :: Data.Polynomial.Polynomial Rational Integer- numerator' = Data.Polynomial.realCoefficientsToFrac numerator- denominator' = Data.Polynomial.realCoefficientsToFrac denominator+ (numerator', denominator') = ($ numerator) &&& ($ denominator) $ Data.Polynomial.realCoefficientsToFrac (quotient, remainder) = numerator' `Data.QuotientRing.quotRem'` denominator' prop_degree numerator denominator = denominator' /= Data.Polynomial.zero ==> Test.QuickCheck.label "prop_degree" $ remainder == Data.Polynomial.zero || Data.Polynomial.getDegree remainder < Data.Polynomial.getDegree denominator' where numerator', denominator' :: Data.Polynomial.Polynomial Rational Integer- numerator' = Data.Polynomial.realCoefficientsToFrac numerator- denominator' = Data.Polynomial.realCoefficientsToFrac denominator+ (numerator', denominator') = ($ numerator) &&& ($ denominator) $ Data.Polynomial.realCoefficientsToFrac remainder = numerator' `Data.QuotientRing.rem'` denominator' @@ -82,8 +80,7 @@ prop_quotientRingNormalised numerator denominator = denominator' /= Data.Polynomial.zero ==> Test.QuickCheck.label "prop_quotientRingNormalised" $ all Data.Polynomial.isNormalised [numerator' `Data.QuotientRing.quot'` denominator', numerator' `Data.QuotientRing.rem'` denominator'] where numerator', denominator' :: Data.Polynomial.Polynomial Rational Integer- numerator' = Data.Polynomial.realCoefficientsToFrac numerator- denominator' = Data.Polynomial.realCoefficientsToFrac denominator+ (numerator', denominator') = ($ numerator) &&& ($ denominator) $ Data.Polynomial.realCoefficientsToFrac prop_power, prop_perfectPower, prop_normalised :: Data.Polynomial.Polynomial Integer Integer -> Int -> Test.QuickCheck.Property prop_power polynomial power = Test.QuickCheck.label "prop_power" $ polynomial =^ power' == iterate (=*= polynomial) polynomial !! pred power' where
src-test/Factory/Test/QuickCheck/Probability.hs view
@@ -45,7 +45,7 @@ ) => distribution -> [f] -> [f] normalise distribution | variance == 0 = error "Factory.Test.Quick.Probability.normalise:\tzero variance => can't stretch to one."- | otherwise = map $ (/ sqrt variance) . (+ negate mean)+ | otherwise = map $ (/ sqrt variance) . subtract mean where (mean, variance) = Math.Probability.getMean &&& Math.Probability.getVariance $ distribution