continued-fraction (empty) → 0.1.0.0
raw patch · 9 files changed
+205/−0 lines, 9 filesdep +basedep +continued-fractiondep +criterionsetup-changed
Dependencies added: base, continued-fraction, criterion, hspec, recursion-schemes
Files
- .travis.yml +21/−0
- LICENSE +11/−0
- README.md +14/−0
- Setup.hs +2/−0
- bench/Bench.hs +10/−0
- continued-fraction.cabal +58/−0
- src/Num/ContinuedFraction.hs +70/−0
- stack.yaml +8/−0
- test/Spec.hs +11/−0
+ .travis.yml view
@@ -0,0 +1,21 @@+sudo: false+language: default+cache:+ directories:+ - $HOME/.stack+addons:+ apt:+ packages:+ - libgmp3-dev+before_install:+- mkdir -p ~/.local/bin+- export PATH=$HOME/.local/bin:$PATH+- travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack'+- chmod a+x ~/.local/bin/stack+install:+- stack --no-terminal --install-ghc test --only-dependencies+- stack install hlint weeder+script:+- stack --no-terminal test --bench --haddock --no-haddock-deps+- hlint .+- weeder .
+ LICENSE view
@@ -0,0 +1,11 @@+Copyright Vanessa McHale (c) 2017++Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:++1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.++3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,14 @@+# continued-fraction++This is a library for working with continued fractions and rational+approximations in Haskell.++## The pitch++ * Simple, easy to use library+ * Documentation with examples++## The anti-pitch++ * Not optimized for performance+ * Missing some features present in other libraries
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ bench/Bench.hs view
@@ -0,0 +1,10 @@+module Main where++import Criterion.Main+import Num.ContinuedFraction++main :: IO ()+main =+ defaultMain [ bgroup "under"+ [ bench "pi" $ nf (approximate (pi :: Double)) (100 :: Integer) ]+ ]
+ continued-fraction.cabal view
@@ -0,0 +1,58 @@+name: continued-fraction+version: 0.1.0.0+synopsis: Types and functions for working with continued fractions in Haskell+description: This package provides facilities for working with both continued fractions+ and rational approximants. It uses lists internally, so it will probably+ not be fast if you need large convergents.+homepage: https://github.com/vmchale/continued-fractions#readme+license: BSD3+license-file: LICENSE+author: Vanessa McHale+maintainer: vanessa.mchale@reconfigure.io+copyright: Copyright: (c) 2017 Vanessa McHale+category: Math+build-type: Simple+extra-source-files: README.md+ , stack.yaml+ , .travis.yml+cabal-version: >=1.10++Flag development {+ Description: Enable `-Werror`+ manual: True+ default: False+}++library+ hs-source-dirs: src+ exposed-modules: Num.ContinuedFraction+ build-depends: base >= 4.7 && < 5+ , recursion-schemes >= 5.0+ default-language: Haskell2010+ if flag(development)+ ghc-options: -Werror+ ghc-options: -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates -Wcompat++test-suite continued-fractions-test+ type: exitcode-stdio-1.0+ hs-source-dirs: test+ main-is: Spec.hs+ build-depends: base+ , continued-fraction+ , hspec+ ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates -Wcompat+ default-language: Haskell2010++benchmark continued-fractions-bench+ type: exitcode-stdio-1.0+ hs-source-dirs: bench+ main-is: Bench.hs+ build-depends: base+ , continued-fraction+ , criterion+ ghc-options: -O2 -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates -Wcompat+ default-language: Haskell2010++source-repository head+ type: git+ location: https://github.com/vmchale/continued-fractions
+ src/Num/ContinuedFraction.hs view
@@ -0,0 +1,70 @@+module Num.ContinuedFraction+ ( -- * Conversion between numbers and continued fractions+ continuedFraction+ , collapseFraction+ -- * Rational approximations using continued fractions+ , approximate+ , convergent+ ) where++import Control.Applicative (liftA2)+import Data.Functor.Foldable (ListF (..), ana)+import Data.List.NonEmpty (NonEmpty (..), fromList)+import Data.Maybe (fromJust)+import Data.Ratio (Ratio, denominator, (%))++-- | Check if it's an integer+--+-- >>> isInteger 3+-- True+-- >>> isInteger 2.5+-- False+isInteger :: (RealFrac a) => a -> Bool+isInteger = idem down+ where+ idem = ((==) <*>)+ down = realToFrac . (floor :: (RealFrac a) => a -> Integer)++-- | This take a number and returns its continued fraction expansion as a list of `Integer`s.+--+-- >>> continuedFraction 2+-- [2]+continuedFraction :: (RealFrac a, Integral b) => a -> [b]+continuedFraction = liftA2 (:) floor (ana coalgebra)+ where coalgebra x+ | isInteger x = Nil+ | otherwise = Cons (floor alpha) alpha+ where alpha = 1 / (x - realToFrac (floor x :: Int))++-- | This takes a list of integers and returns the corresponding rational number, returning "Nothing" on empty lists.+--+-- >>> collapseFractionM []+-- Nothing+-- >>> collapseFractionM [1,2,2,2]+-- Just (17 % 12)+collapseFractionM :: (Integral a) => [Integer] -> Maybe (Ratio a)+collapseFractionM [] = Nothing+collapseFractionM [x] = Just $ fromIntegral x % 1+collapseFractionM (x:xs) = fmap ((fromIntegral x % 1 +) . (1 /)) (collapseFractionM xs)++-- | Take a non-empty list of integers and return the corresponding rational number.+--+-- >>> collapseFraction (1 :| [2,2,2])+-- 17 % 12+collapseFraction :: (Integral a, Integral b) => NonEmpty b -> Ratio a+collapseFraction (x:|[]) = fromIntegral x % 1+collapseFraction (x:|xs) = (fromIntegral x % 1) + 1 / collapseFraction (fromList xs)++-- | Find a given convergent of the continued fraction expansion of a number+--+-- >>> convergent 4 $ sqrt 2+-- 17 % 12+convergent :: (RealFrac a, Integral b) => Int -> a -> Ratio b+convergent n x = fromJust . collapseFractionM $ take n (continuedFraction x)++-- | Find the best rational approximation to a number such that the denominator is bounded by a given value.+--+-- >>> approximate pi 100+-- 22 % 7+approximate :: (RealFrac a, Integral b) => a -> b -> Ratio b+approximate x d = last . takeWhile ((<= d) . denominator) $ fmap (flip convergent x) [1..]
+ stack.yaml view
@@ -0,0 +1,8 @@+resolver: lts-9.3+packages:+- '.'+extra-deps:+flags:+ continued-fraction:+ development: true+extra-package-dbs: []
+ test/Spec.hs view
@@ -0,0 +1,11 @@+import Data.Ratio ((%))+import Num.ContinuedFraction+import Test.Hspec++main :: IO ()+main = hspec $+ describe "continuedFraction" $ do+ parallel $ it "should work on integers" $+ continuedFraction (2 :: Double) `shouldBe` [2 :: Integer]+ parallel $ it "should give an approximation of pi" $+ approximate (pi :: Double) (100 :: Integer) `shouldBe` (22 :: Integer) % (7 :: Integer)