Copyright | © 2014 Johan Kiviniemi |
---|---|
License | MIT |
Maintainer | Johan Kiviniemi <devel@johan.kiviniemi.name> |
Stability | provisional |
Portability | ViewPatterns |
Safe Haskell | None |
Language | Haskell2010 |
An implementation of quadratic irrationals with support for conversion from and to periodic continued fractions.
- data QI
- qi :: Integer -> Integer -> Integer -> Integer -> QI
- qi' :: Rational -> Rational -> Integer -> QI
- runQI :: QI -> (Integer -> Integer -> Integer -> Integer -> a) -> a
- runQI' :: QI -> (Rational -> Rational -> Integer -> a) -> a
- unQI :: QI -> (Integer, Integer, Integer, Integer)
- unQI' :: QI -> (Rational, Rational, Integer)
- _qi :: Lens' QI (Integer, Integer, Integer, Integer)
- _qi' :: Lens' QI (Rational, Rational, Integer)
- _qiABD :: Lens' QI (Integer, Integer, Integer)
- _qiA :: Lens' QI Integer
- _qiB :: Lens' QI Integer
- _qiC :: Lens' QI Integer
- _qiD :: Lens' QI Integer
- qiZero :: QI
- qiOne :: QI
- qiIsZero :: QI -> Bool
- qiToFloat :: Floating a => QI -> a
- qiAddI :: QI -> Integer -> QI
- qiSubI :: QI -> Integer -> QI
- qiMulI :: QI -> Integer -> QI
- qiDivI :: QI -> Integer -> QI
- qiAddR :: QI -> Rational -> QI
- qiSubR :: QI -> Rational -> QI
- qiMulR :: QI -> Rational -> QI
- qiDivR :: QI -> Rational -> QI
- qiNegate :: QI -> QI
- qiRecip :: QI -> Maybe QI
- qiAdd :: QI -> QI -> Maybe QI
- qiSub :: QI -> QI -> Maybe QI
- qiMul :: QI -> QI -> Maybe QI
- qiDiv :: QI -> QI -> Maybe QI
- qiPow :: QI -> Integer -> QI
- qiFloor :: QI -> Integer
- continuedFractionToQI :: (Integer, CycList Integer) -> QI
- qiToContinuedFraction :: QI -> (Integer, CycList Integer)
- module Numeric.QuadraticIrrational.CyclicList
Constructors and deconstructors
Given a
, b
, c
and d
such that n = (a + b √c)/d
, constuct a QI
corresponding to n
.
>>>
qi 3 4 5 6
qi 3 4 5 6
The fractions are reduced:
>>>
qi 30 40 5 60
qi 3 4 5 6
If b = 0
then c
is zeroed and vice versa:
>>>
qi 3 0 42 1
qi 3 0 0 1
>>>
qi 3 42 0 1
qi 3 0 0 1
The b √c
term is simplified:
>>>
qi 0 1 (5*5*6) 1
qi 0 5 6 1
If c = 1
(after simplification) then b
is moved to a
:
>>>
qi 1 5 (2*2) 1
qi 11 0 0 1
Given a
, b
and c
such that n = a + b √c
, constuct a QI
corresponding to n
.
>>>
qi' 0.5 0.7 2
qi 5 7 2 10
runQI :: QI -> (Integer -> Integer -> Integer -> Integer -> a) -> a Source
Given n
and f
such that n = (a + b √c)/d
, run f a b c d
.
>>>
runQI (qi 3 4 5 6) (\a b c d -> (a,b,c,d))
(3,4,5,6)
runQI' :: QI -> (Rational -> Rational -> Integer -> a) -> a Source
Given n
and f
such that n = a + b √c
, run f a b c
.
>>>
runQI' (qi' 0.5 0.7 2) (\a b c -> (a, b, c))
(1 % 2,7 % 10,2)
unQI :: QI -> (Integer, Integer, Integer, Integer) Source
Given n
such that n = (a + b √c)/d
, return (a, b, c, d)
.
>>>
unQI (qi 3 4 5 6)
(3,4,5,6)
unQI' :: QI -> (Rational, Rational, Integer) Source
Given n
such that n = a + b √c
, return (a, b, c)
.
>>>
unQI' (qi' 0.5 0.7 2)
(1 % 2,7 % 10,2)
Lenses
_qi :: Lens' QI (Integer, Integer, Integer, Integer) Source
Given a QI
corresponding to n = (a + b √c)/d
, access (a, b, c, d)
.
>>>
view _qi (qi 3 4 5 6)
(3,4,5,6)
>>>
over _qi (\(a,b,c,d) -> (a+10, b+10, c+10, d+10)) (qi 3 4 5 6)
qi 13 14 15 16
_qi' :: Lens' QI (Rational, Rational, Integer) Source
Given a QI
corresponding to n = a + b √c
, access (a, b, c)
.
>>>
view _qi' (qi' 0.5 0.7 2)
(1 % 2,7 % 10,2)
>>>
over _qi' (\(a,b,c) -> (a/5, b/6, c*3)) (qi 3 4 5 6)
qi 9 10 15 90
_qiABD :: Lens' QI (Integer, Integer, Integer) Source
Given a QI
corresponding to n = (a + b √c)/d
, access (a, b, d)
.
Avoids having to simplify b √c
upon reconstruction.
>>>
view _qiABD (qi 3 4 5 6)
(3,4,6)
>>>
over _qiABD (\(a,b,d) -> (a+10, b+10, d+10)) (qi 3 4 5 6)
qi 13 14 5 16
Numerical operations
Check if the value is zero.
>>>
map qiIsZero [qiZero, qiOne, qiSubR (qi 7 0 0 2) 3.5]
[True,False,True]
qiRecip :: QI -> Maybe QI Source
Compute the reciprocal of a QI
.
>>>
qiRecip (qi 5 0 0 2)
Just (qi 2 0 0 5)
>>>
qiRecip (qi 0 1 5 2)
Just (qi 0 2 5 5)
>>>
qiRecip qiZero
Nothing
qiAdd :: QI -> QI -> Maybe QI Source
Add two QI
s if the square root terms are the same or zeros.
>>>
qi 3 4 5 6 `qiAdd` qiOne
Just (qi 9 4 5 6)
>>>
qi 3 4 5 6 `qiAdd` qi 3 4 5 6
Just (qi 3 4 5 3)
>>>
qi 0 1 5 1 `qiAdd` qi 0 1 6 1
Nothing
qiSub :: QI -> QI -> Maybe QI Source
Subtract two QI
s if the square root terms are the same or zeros.
>>>
qi 3 4 5 6 `qiSub` qiOne
Just (qi (-3) 4 5 6)
>>>
qi 3 4 5 6 `qiSub` qi 3 4 5 6
Just (qi 0 0 0 1)
>>>
qi 0 1 5 1 `qiSub` qi 0 1 6 1
Nothing
qiMul :: QI -> QI -> Maybe QI Source
Multiply two QI
s if the square root terms are the same or zeros.
>>>
qi 3 4 5 6 `qiMul` qiZero
Just (qi 0 0 0 1)
>>>
qi 3 4 5 6 `qiMul` qiOne
Just (qi 3 4 5 6)
>>>
qi 3 4 5 6 `qiMul` qi 3 4 5 6
Just (qi 89 24 5 36)
>>>
qi 0 1 5 1 `qiMul` qi 0 1 6 1
Nothing
qiDiv :: QI -> QI -> Maybe QI Source
Divide two QI
s if the square root terms are the same or zeros.
>>>
qi 3 4 5 6 `qiDiv` qiZero
Nothing
>>>
qi 3 4 5 6 `qiDiv` qiOne
Just (qi 3 4 5 6)
>>>
qi 3 4 5 6 `qiDiv` qi 3 4 5 6
Just (qi 1 0 0 1)
>>>
qi 3 4 5 6 `qiDiv` qi 0 1 5 1
Just (qi 20 3 5 30)
>>>
qi 0 1 5 1 `qiDiv` qi 0 1 6 1
Nothing
qiFloor :: QI -> Integer Source
Compute the floor of a QI
.
>>>
qiFloor (qi 10 0 0 2)
5
>>>
qiFloor (qi 10 2 2 2)
6
>>>
qiFloor (qi 10 2 5 2)
7
Continued fractions
continuedFractionToQI :: (Integer, CycList Integer) -> QI Source
Convert a (possibly periodic) continued fraction to a QI
.
[2; 2] = 2 + 1/2 = 5/2
.
>>>
continuedFractionToQI (2,NonCyc [2])
qi 5 0 0 2
[2; 1, 1, 1, 4, 1, 1, 1, 4, …] = √7
.
>>>
continuedFractionToQI (2,Cyc [] 1 [1,1,4])
qi 0 1 7 1
>>>
continuedFractionToQI (0,Cyc [83,78,65,75,69] 32 [66,65,68,71,69,82])
qi 987601513930253257378987883 1 14116473325908285531353005 81983584717737887813195873886
qiToContinuedFraction :: QI -> (Integer, CycList Integer) Source
Convert a QI
into a (possibly periodic) continued fraction.
5/2 = 2 + 1/2 = [2; 2]
.
>>>
qiToContinuedFraction (qi 5 0 0 2)
(2,NonCyc [2])
√7 = [2; 1, 1, 1, 4, 1, 1, 1, 4, …]
.
>>>
qiToContinuedFraction (qi 0 1 7 1)
(2,Cyc [] 1 [1,1,4])
>>>
qiToContinuedFraction (qi 987601513930253257378987883 1 14116473325908285531353005 81983584717737887813195873886)
(0,Cyc [83,78,65,75,69] 32 [66,65,68,71,69,82])