--------------------------------------infinite lists: examples

------------------------------------------------------numerics
-------------------------------------------auxiliary functions

withinEps:: Double->[Double]->Double    
withinEps eps (x1:x2:xs)
   |abs(x1 - x2) <= eps = x2
   |otherwise           = withinEps eps (x2:xs)


elimFstOrdError:: [Double]->[Double]                                            
elimFstOrdError (x1:x2:xs)       --assumes halving of distances
     = (2*x2-x1):(elimFstOrdError (x2:xs))


-------------------------------------------------differentiation
simpleDiff:: (Double->Double)->Double->Double->Double
simpleDiff f x h = (f(x+h)-f(x))/h

seqDiff:: (Double->Double)->Double->Double->[Double]
seqDiff f x = map (simpleDiff f x) . iterate (/2)

betterSeqDiff:: (Double->Double)->Double->Double->[Double]
betterSeqDiff f x = elimFstOrdError . seqDiff f x

{-
Main> take 5 (seqDiff cos 0 0.1)
[-0.0499582, -0.0249946, -0.0125003, -0.00625134, -0.00312805]
Main> take 5 (betterSeqDiff cos 0 0.1)
[-3.09944e-05, -5.96046e-06, -2.38419e-06, -4.76837e-06, 0.0]
Main> withinEps 0.001 (seqDiff cos 0 0.1)
-0.000762939
Main> withinEps 0.001 (betterSeqDiff cos 0 0.1)
-5.96046e-06
-}
-----------------------------------------------------integration
simpleIntegrate:: (Double->Double)->Double->Double->Double
simpleIntegrate f a b = (f a + f b) * (b-a)/2

seqIntegrate:: (Double->Double)->Double->Double->[Double]
seqIntegrate f a b = (simpleIntegrate f a b) 
                      : (zipWith (+) (seqIntegrate f a m)
                                     (seqIntegrate f m b))
                      where m = (a+b)/2
                      --inefficient: recomputations of fa,fb,fm


{-
Main> take 10 (seqIntegrate sin 0 pi)
[-1.37323e-07, 1.5708, 1.89612, 1.97423, 1.99357, 1.99839, 1.9996, 1.9999, 1.99997, 1.99999]
Main> withinEps 0.001 (seqIntegrate sin 0 pi)
1.9999
-}

---------------------------------------------------------------
--------------------------------------------------prime numbers

crossout::[Int]->[Int]         --elim multiples of head element
crossout (x:xs) = filter (\y->y`rem`x /= 0) xs

primeNumbers :: [Int]
primeNumbers = map head (iterate crossout [2..])

{-
Main> take 10 (crossout [2..])
[3, 5, 7, 9, 11, 13, 15, 17, 19, 21]
Main> take 10 primeNumbers
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
Main> take 1 (drop 9 primeNumbers)  -- 10. Primzahl
[29]
Main> primeNumbers !! 9   --Indexierung mit (!!) beginnt mit 0 
29
Main> primeNumbers !! 99
541
Main> primeNumbers !! 999


ERROR: Garbage collection fails to reclaim sufficient space
-}


--------------------------------------------------------------
-----------------------------------------------flip-flop model

data ThreeVal = U | L | H               --undefined, low, high
     deriving Show

nand:: ThreeVal->ThreeVal->ThreeVal
nand H H = L
nand L _ = H
nand _ L = H
nand _ _ = U

nandSeq:: [ThreeVal]->[ThreeVal]->[ThreeVal]
nandSeq = zipWith nand

q, q', set, reset:: [ThreeVal]

q = U : U : U : nandSeq set q'
q'= U : U : U : nandSeq reset q

set   = [L,L,L,L,L,L,L,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H,H]  
reset = [H,H,H,H,H,H,H,H,H,H,H,H,H,H,L,L,L,L,L,L,L,H,H,H,H,H]
                                                        --z.B.
{-
Main> q
[U, U, U, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, H, L, L, L, L, L, L, L, L, L]
Main> q'
[U, U, U, U, U, U, L, L, L, L, L, L, L, L, L, L, L, H, H, H, H, H, H, H, H, H, H, H, H]
-}
 





