### merge and work on exercises

parent d4d2f203
 ... @@ -22,7 +22,7 @@ TODO 2014-09-04 Musterloesungen erstellen ... @@ -22,7 +22,7 @@ TODO 2014-09-04 Musterloesungen erstellen ex19 parallel arrays: rsa neu erstellen ex19 parallel arrays: rsa neu erstellen ex20p5 jacobi solver ex20p5 jacobi solver ex21p3 centralized differences + noise ex21p3 centralized differences + noise ex22p4 auf cg umstellen (siam problem 20000) ex22p4 auf cg umstellen (siam problem 20000) (pending..) ex24p3 solution missing ex24p3 solution missing ex24 mandelbrot-irgendwas ex24 mandelbrot-irgendwas ex24 change to endtime? ex24 change to endtime? ... @@ -50,22 +50,25 @@ WAITING 2015-07-23 parallel and concurrent, cloudhaskell ... @@ -50,22 +50,25 @@ WAITING 2015-07-23 parallel and concurrent, cloudhaskell :LOGBOOK: :LOGBOOK: WAITING: 2015-07-23 11:08:18 WAITING: 2015-07-23 11:08:18 xx *gerlind plonka waveleti bildverarbeitung ?? pde> meshless methods (heat equation, euler equation? xx lube: finite elements (schwache formulierung) heat equation (hmatrix) xx lube: finite elements (schwache formulierung) heat equation (hmatrix) xx+1 *differentialgeometrie -> henrik (laplace weak implementieren) (hmatrix) xx+1 *differentialgeometrie -> henrik (laplace weak implementieren) (hmatrix) xx *inverse probleme: intergralgleichungen, xx *inverse probleme: intergralgleichungen, xx *gerlind plonka waveleti bildverarbeitung volterra intergralgleichungen (numeric differentiation) (schon in ex27?) ?? pde> meshless methods (heat equation, euler equation? TODO 2015-09-01 data analysis testen (fehlen auf jeden fall pakete) TODO 2015-09-01 data analysis testen (fehlen auf jeden fall pakete) TODO 2015-08-05 allgemein: interpolation/fitting TODO 2015-08-05 allgemein: interpolation/fitting TODO 2014-08-21 immutable/mutable TODO 2014-08-21 immutable/mutable WAITING 2014-08-08 algebraische typen detaillierter DONE 2014-08-08 algebraische typen detaillierter CLOSED: 2016-03-21 16:13:21 :LOGBOOK: :LOGBOOK: DONE: 2016-03-21 16:13:21 WAITING: 2015-07-02 17:28:15 WAITING: 2015-07-02 17:28:15 WAITING 2014-09-01 (spline-interpolation? , (siehe auch mapy)) WAITING 2014-09-01 (spline-interpolation? , (siehe auch mapy)) ... @@ -80,6 +83,8 @@ WAITING 2014-07-29 headmay : http://hackage.haskell.org/package/safe-0.3/docs/Sa ... @@ -80,6 +83,8 @@ WAITING 2014-07-29 headmay : http://hackage.haskell.org/package/safe-0.3/docs/Sa :LOGBOOK: :LOGBOOK: WAITING: 2015-06-12 12:28:11 WAITING: 2015-06-12 12:28:11 ANDEREVORLESUNG: WAITING 2014-08-05 (Lambda Kalkuel einfuehren) WAITING 2014-08-05 (Lambda Kalkuel einfuehren) :LOGBOOK: :LOGBOOK: WAITING: 2015-06-12 12:28:12 WAITING: 2015-06-12 12:28:12 ... ...
 -- ghc -O2 -prof -fprof-auto -rtsopts factorial.hs && ./factorial +RTS -pi -hc -sstderr -RTS -- ghc -O2 -prof -fprof-auto -rtsopts factorial.hs && ./factorial +RTS -pi -hc -sstderr -RTS {-# LANGUAGE BangPatterns #-} {-# LANGUAGE BangPatterns #-} facE :: (Show a, Integral a) => a -> a facE :: (Show a, Integral a) => a -> a facE i facE i | i<0 = error "Negative Faculty not defined" | i<0 = error "Negative Faculty not defined" ... @@ -20,6 +21,8 @@ facRf x = fac' x 1 where ... @@ -20,6 +21,8 @@ facRf x = fac' x 1 where fac' 1 y = y fac' 1 y = y fac' f y = fac' (f-1) $! (f*y) fac' f y = fac' (f-1)$! (f*y) Fractional main :: IO () main :: IO () main = do main = do let g = facNE 10000 let g = facNE 10000 ... ...
 %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: # Exercises: type classes # Exercises: type classes ## problem 1 ## problem 1 Explain the difference between Explain the difference between haskell haskell type Point = (Double, Double) type Point = (Double, Double)   and and haskell haskell data Point = Point Double Double data Point = Point Double Double   %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell   %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: ## problem 2 ## problem 2 Write an instance of Show for Shape Write an instance of Show for Shape haskell haskell data Point = Point Double Double data Point = Point Double Double instance Show Point where instance Show Point where show (Point x y) = "(" ++ show x ++ ", " ++ show y ++ ")" show (Point x y) = "(" ++ show x ++ ", " ++ show y ++ ")" data Shape = Circle Point Double data Shape = Circle Point Double | Rectangle Point Double Double | Rectangle Point Double Double   %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell   %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: ## problem 3 ## problem 3 - Write an instance of Eq for Shape. - Write an instance of Eq for Shape. - Write an instance of Ord for Shape. - Write an instance of Ord for Shape. - Compare to the behaviour of the automatically generated Ord instance from a deriving clause and explain. - Compare to the behaviour of the automatically generated Ord instance from a deriving clause and explain. %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell   %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: ## problem 4 ## problem 4 Vectors (in the mathematical sense) are required in many numerical applications. Vectors (in the mathematical sense) are required in many numerical applications. - Implement a typeclass for vectors of arbitrary dimensions. - Implement a typeclass for vectors of arbitrary dimensions. - Implement addition, scalar multiplication and inner product. - Implement addition, scalar multiplication and inner product. - How could matrices be represented? - How could matrices be represented? %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell   %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: ## problem 5 ## problem 5 Write classes ShowHex and ShowBin which output numbers in hex and binary, and implement them for Int. Write classes ShowHex and ShowBin which output numbers in hex and binary, and implement them for Int. %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell   %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: ## problem 6 ## problem 6 lookup the function unfoldr and first write an own version of iterate by using unfoldr. Then rewrite the instances of problem 5 via using unfoldr. lookup the function unfoldr and first write an own version of iterate by using unfoldr. Then rewrite the instances of problem 5 via using unfoldr. %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell   %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: ## problem 7 ## problem 7 Converting between metric and imperial units: Write a function convertUnit :: (Double, String) -> (Double, String) that behaves like Converting between metric and imperial units: Write a function convertUnit :: (Double, String) -> (Double, String) that behaves like haskell haskell convertUnit (1, "m") == (1.09361, "yd") convertUnit (1, "m") == (1.09361, "yd") convertUnit (1, "kg") == (2.20462, "lb") convertUnit (1, "kg") == (2.20462, "lb")   etc... etc... Is there a more type-safe way of doing this? Is there a more type-safe way of doing this? %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell   %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: ## problem 8 ## problem 8 Prove the second functor law for lists: Prove the second functor law for lists: haskell haskell fmap (f . g) == fmap f . fmap g fmap (f . g) == fmap f . fmap g   %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell   %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: ## problem 9 ## problem 9 Create a data type for polynominial rings with real coefficients and write the instances for Show, Eq and Num. Create a data type for polynomial rings with real coefficients and write the instances for Show, Eq and Num. *Note*: a formal polynominial is nothing else than a list of coefficents. *Note*: a formal polynomial is nothing else than a list of coefficents. %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell   ... ...
 %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: # Exercises: boundary value problems # Exercises: boundary value problems ## problem 1 ## problem 1 implement a *Gauss-Seidel* algorithm for solving linear equations. implement a *Gauss-Seidel* algorithm for solving linear equations. The Gauss–Seidel method is an iterative technique for solving a square system of n linear equations with unknown x: The Gauss–Seidel method is an iterative technique for solving a square system of n linear equations with unknown x: $$A x = b$$ $$A x = b$$ It is defined by the iteration It is defined by the iteration $$L_∗ x^{( k + 1 )} = b − U x^{( k )}$$ $$L_∗ x^{( k + 1 )} = b − U x^{( k )}$$ where $x^{( k )}$ is the $k$-th approximation or iteration of $x$ ,$x^{k + 1}$ is the next value of $x$ , and the matrix $A$ is decomposed into a lower triangular component $L_∗$ , and a strictly upper triangular component $U$: $A = L_∗ + U$ where $x^{( k )}$ is the $k$-th approximation or iteration of $x$ ,$x^{k + 1}$ is the next value of $x$ , and the matrix $A$ is decomposed into a lower triangular component $L_∗$ , and a strictly upper triangular component $U$: $A = L_∗ + U$ We rewrite this a little bit to for the algorithm: We rewrite this a little bit to for the algorithm: $$x^{( k + 1 )} = T x^{( k )} + C$$ $$x^{( k + 1 )} = T x^{( k )} + C$$ where where $$T = - L_∗^{-1} U$$ and $$C = L_∗^{-1} b$$ $$T = - L_∗^{-1} U$$ and $$C = L_∗^{-1} b$$ Write a recursive function which makes this iteration. The iteration should stop both from a tolerance value of the difference of adjacent $x$ and a maximum of iterations. Write a recursive function which makes this iteration. The iteration should stop both from a tolerance value of the difference of adjacent $x$ and a maximum of iterations. For a test case use the matrix and right hand side from the lecture. For a test case use the matrix and right hand side from the lecture. %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell   %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: ## problem 2 ## problem 2 Implement the *jacobi* iterative algorithm for solving linear equations. First decompose the Implement the *jacobi* iterative algorithm for solving linear equations. First decompose the matrix $A$ into the diagonal part $D$ and the remnant $R$: matrix $A$ into the diagonal part $D$ and the remnant $R$: $$A = D + R$$ $$A = D + R$$ Then iterate the following Then iterate the following $$x^{( k + 1 )} = D^{ - 1} ( b - R x^{( k )} )$$ $$x^{( k + 1 )} = D^{ - 1} ( b - R x^{( k )} )$$ where $x^{ ( k )}$ is the $k$-th approximation or iteration of $x$ and $x^{ ( k + 1 )}$ is the next. where $x^{ ( k )}$ is the $k$-th approximation or iteration of $x$ and $x^{ ( k + 1 )}$ is the next. Write a recursive function which makes this iteration. The iteration should stop both from a tolerance value of the difference of adjacent x and a maximum of iterations. For a testcase use the matrix and right hand side from the lecture. Write a recursive function which makes this iteration. The iteration should stop both from a tolerance value of the difference of adjacent x and a maximum of iterations. For a testcase use the matrix and right hand side from the lecture. %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell   %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: ## problem 3 ## problem 3 Write an implementation of the *conjugate gradient* (CG) method. This method solves Write an implementation of the *conjugate gradient* (CG) method. This method solves $$A x = b$$ $$A x = b$$ by an iteration of the form $x_0 = 0$, $r_0 = p_0 = b$, by an iteration of the form $x_0 = 0$, $r_0 = p_0 = b$,  \begin{align} \begin{align} \alpha_k &= \frac{{\lVert r_k \rVert}^2}{\langle p_k, A p_k \rangle} \\ \alpha_k &= \frac{{\lVert r_k \rVert}^2}{\langle p_k, A p_k \rangle} \\ x_{k+1} &= x_k + \alpha_k p_k \\ x_{k+1} &= x_k + \alpha_k p_k \\ r_{k+1} &= r_k - \alpha_k A p_k \\ r_{k+1} &= r_k - \alpha_k A p_k \\ p_{k+1} &= r_{k+1} + \frac{{\lVert r_{k+1} \rVert}^2}{{\lVert r_k \rVert}^2} p_k p_{k+1} &= r_{k+1} + \frac{{\lVert r_{k+1} \rVert}^2}{{\lVert r_k \rVert}^2} p_k \end{align}, \end{align},  stopping the iterations at the smallest $K$ for which $\lVert r_K \rVert < \text{tol}$. stopping the iterations at the smallest $K$ for which $\lVert r_K \rVert < \text{tol}$. An interesting property of this method in contrast to the ones from the previous problems is that it does not need $A$ in form of a matrix; it suffices to be able to apply $A$ to any given vector $p$, so $A$ can also be passed as a function Vec Double -> Vec Double. An interesting property of this method in contrast to the ones from the previous problems is that it does not need $A$ in form of a matrix; it suffices to be able to apply $A$ to any given vector $p$, so $A$ can also be passed as a function Vec Double -> Vec Double. The CG implementation should therefore have a signature like this: The CG implementation should therefore have a signature like this: haskell haskell cg :: Double -> (Vec Double -> Vec Double) -> Vec Double -> Vec Double cg :: Double -> (Vec Double -> Vec Double) -> Vec Double -> Vec Double cg tol f rhs = [...] cg tol f rhs = [...]   Apply the method to the same test case as above, but this time reimplement it using the function Apply the method to the same test case as above, but this time reimplement it using the function haskell haskell conv :: Vec t -> Vec t -> Vec t conv :: Vec t -> Vec t -> Vec t   from Numeric.LinearAlgebra.Repa, which implements a convolution without actually creating the matrix. Note that conv returns a vector that is larger than the input; use the boundary values to handle this. from Numeric.LinearAlgebra.Repa, which implements a convolution without actually creating the matrix. Note that conv returns a vector that is larger than the input; use the boundary values to handle this. %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell   %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: ## problem 4 ## problem 4 Let A be a $20.000 \times 20.000$ matrix, which entries are all zero besides the prime numbers $2, 3, 5, 7, \ldots, 224737$ on the diagonal and the number 1 in all entries $a_{ij}$ with Let A be a $20.000 \times 20.000$ matrix, which entries are all zero besides the prime numbers $2, 3, 5, 7, \ldots, 224737$ on the diagonal and the number 1 in all entries $a_{ij}$ with $$|i − j| = 1, 2, 4, 8, \ldots , 16384.$$ $$|i − j| = 1, 2, 4, 8, \ldots , 16384.$$ What is the $(1, 1)$ entry of $A^{−1}$? How can you check/visualize the structure of the matrix? Be sure to use a good method for saving the matrix (use sparse..). What is the $(1, 1)$ entry of $A^{−1}$? How can you check/visualize the structure of the matrix? Be sure to use a good method for saving the matrix. *bonus*: implement sparse variants of gauss-seidel and/or conjugate gradiant and try to use them as solver here. %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell   ... ...
 %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: # Exercises: type classes # Exercises: type classes ## problem 1 ## problem 1 Explain the difference between Explain the difference between haskell haskell type Point = (Double, Double) type Point = (Double, Double)   and and haskell haskell data Point = Point Double Double data Point = Point Double Double   %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: ## problem 2 ## problem 2 Write an instance of Show for Shape Write an instance of Show for Shape haskell haskell data Point = Point Double Double data Point = Point Double Double instance Show Point where instance Show Point where show (Point x y) = "(" ++ show x ++ ", " ++ show y ++ ")" show (Point x y) = "(" ++ show x ++ ", " ++ show y ++ ")" data Shape = Circle Point Double data Shape = Circle Point Double | Rectangle Point Double Double | Rectangle Point Double Double   %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell data Point = Point Double Double data Point = Point Double Double instance Show Point where instance Show Point where show (Point x y) = "(" ++ show x ++ ", " ++ show y ++ ")" show (Point x y) = "(" ++ show x ++ ", " ++ show y ++ ")" data Shape = Circle Point Double data Shape = Circle Point Double | Rectangle Point Double Double | Rectangle Point Double Double instance Show Shape where instance Show Shape where show (Circle c r) = "Circle with center " ++ show c ++ " and radius " ++ show r show (Circle c r) = "Circle with center " ++ show c ++ " and radius " ++ show r show (Rectangle p a b) = "Rectangle with top-left corner " ++ show p ++ show (Rectangle p a b) = "Rectangle with top-left corner " ++ show p ++ " and edges " ++ show a ++ " and " ++ show b " and edges " ++ show a ++ " and " ++ show b   %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: ## problem 3 ## problem 3 - Write an instance of Eq for Shape. - Write an instance of Eq for Shape. - Write an instance of Ord for Shape. - Write an instance of Ord for Shape. - Compare to the behaviour of the automatically generated Ord instance from a deriving clause and explain. - Compare to the behaviour of the automatically generated Ord instance from a deriving clause and explain. %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell instance Eq Point where instance Eq Point where (Point x1 y1) == (Point x2 y2) = (x1 == x2) && (y1 == y2) (Point x1 y1) == (Point x2 y2) = (x1 == x2) && (y1 == y2) instance Eq Shape where instance Eq Shape where (Circle c1 r1) == (Circle c2 r2) = (c1 == c2) && (r1 == r2) (Circle c1 r1) == (Circle c2 r2) = (c1 == c2) && (r1 == r2) (Rectangle p1 a1 b1) == (Rectangle p2 a2 b2) = (p1 == p2) && (a1 == a2) && (b1 == b2) (Rectangle p1 a1 b1) == (Rectangle p2 a2 b2) = (p1 == p2) && (a1 == a2) && (b1 == b2) _ == _ = False _ == _ = False   %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell import Data.Function import Data.Function -- problem: unclear how to compare shapes. e.g. compare areas: -- problem: unclear how to compare shapes. e.g. compare areas: instance Ord Shape where instance Ord Shape where compare = compare on area compare = compare on area where area (Rectangle _ a b) = a * b where area (Rectangle _ a b) = a * b area (Circle _ r) = pi * r**2 area (Circle _ r) = pi * r**2   %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell data PointDeriv = PointDeriv Double Double deriving (Eq, Ord) data PointDeriv = PointDeriv Double Double deriving (Eq, Ord) data ShapeDeriv = CircleDeriv PointDeriv Double data ShapeDeriv = CircleDeriv PointDeriv Double | RectangleDeriv PointDeriv Double Double | RectangleDeriv PointDeriv Double Double deriving (Eq, Ord) deriving (Eq, Ord)   %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell CircleDeriv (PointDeriv 0 0) 1 < CircleDeriv (PointDeriv 1 0) 10 CircleDeriv (PointDeriv 0 0) 1 < CircleDeriv (PointDeriv 1 0) 10   %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell CircleDeriv (PointDeriv 0 0) 10 < RectangleDeriv (PointDeriv 0 0) 1 1 CircleDeriv (PointDeriv 0 0) 10 < RectangleDeriv (PointDeriv 0 0) 1 1   %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell RectangleDeriv (PointDeriv 0 0) 2 3 < RectangleDeriv (PointDeriv 0 0) 3 2 RectangleDeriv (PointDeriv 0 0) 2 3 < RectangleDeriv (PointDeriv 0 0) 3 2   %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: ## problem 4 ## problem 4 Vectors (in the mathematical sense) are required in many numerical applications. Vectors (in the mathematical sense) are required in many numerical applications. - Implement a typeclass for vectors of arbitrary dimensions. - Implement a typeclass for vectors of arbitrary dimensions. - Implement addition, scalar multiplication and inner product. - Implement addition, scalar multiplication and inner product. - How could matrices be represented? - How could matrices be represented? %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell data Vector = Vector { vec :: [Double] } deriving (Show) data Vector = Vector { vec :: [Double] } deriving (Show) -- Downside: length of vector is unspecified, needs to be checked at runtime. -- Downside: length of vector is unspecified, needs to be checked at runtime. -- Otherwise, we would need a seperate type for each dimension: Vector1d, Vector2d, ... -- Otherwise, we would need a seperate type for each dimension: Vector1d, Vector2d, ... addVector :: Vector -> Vector -> Vector addVector :: Vector -> Vector -> Vector addVector a b addVector a b | length c /= length d = error "Dimensions are not equal" | length c /= length d = error "Dimensions are not equal" | otherwise = Vector (zipWith (+) c d) | otherwise = Vector (zipWith (+) c d) where c = vec a where c = vec a d = vec b d = vec b scalar :: Vector -> Double -> Vector scalar :: Vector -> Double -> Vector scalar a b = Vector (map (*b) (vec a)) scalar a b = Vector (map (*b) (vec a)) scalarProd :: Vector -> Vector -> Double scalarProd :: Vector -> Vector -> Double scalarProd a b scalarProd a b | length c /= length d = error "Vector sizes must match" | length c /= length d = error "Vector sizes must match" | otherwise = sum (zipWith (*) c d) | otherwise = sum (zipWith (*) c d) where c = vec a where c = vec a d = vec b d = vec b   %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell data Matrix = Matrix { columns :: [Vector] } data Matrix = Matrix { columns :: [Vector] }   %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: ## problem 5 ## problem 5 Write classes ShowHex and ShowBin which output numbers in hex and binary, and implement them for Int. Write classes ShowHex and ShowBin which output numbers in hex and binary, and implement them for Int. %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell class ShowHex a where class ShowHex a where showHex :: a -> String showHex :: a -> String instance ShowHex Int where instance ShowHex Int where showHex 0 = "0x0" showHex 0 = "0x0" showHex n = "0x" ++ (reverse $showHex' n) showHex n = "0x" ++ (reverse$ showHex' n) where showHex' 0 = "" where showHex' 0 = "" showHex' m = let (q, r) = quotRem m 16 showHex' m = let (q, r) = quotRem m 16 in ((['0'..'9']++['a'..'f']) !! r) : showHex' q in ((['0'..'9']++['a'..'f']) !! r) : showHex' q   %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell class ShowBin a where class ShowBin a where showBin :: a -> String showBin :: a -> String instance ShowBin Int where instance ShowBin Int where showBin 0 = "0" showBin 0 = "0" showBin n = reverse $showBin' n showBin n = reverse$ showBin' n where showBin' 0 = "" where showBin' 0 = "" showBin' m = let (q, r) = quotRem m 2 showBin' m = let (q, r) = quotRem m 2 in (['0','1'] !! r) : showBin' q in (['0','1'] !! r) : showBin' q   %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: ## problem 6 ## problem 6 lookup the function unfoldr and first write an own version of iterate by using unfoldr. Then rewrite the instances of problem 5 via using unfoldr. lookup the function unfoldr and first write an own version of iterate by using unfoldr. Then rewrite the instances of problem 5 via using unfoldr. %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell import Data.List import Data.List iterate' f = unfoldr (\x -> Just (x, f x)) iterate' f = unfoldr (\x -> Just (x, f x))   %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell -- The recursion pattern above is abstracted by -- The recursion pattern above is abstracted by -- unfoldr :: (a -> Maybe (b, a)) -> a -> [b] -- unfoldr :: (a -> Maybe (b, a)) -> a -> [b] -- So a nicer way to write the instances is this: -- So a nicer way to write the instances is this: import Data.List import Data.List import Data.Tuple import Data.Tuple toRadix rad 0 =  toRadix rad 0 =  toRadix rad n = reverse . unfoldr (\m -> if m == 0 then Nothing else Just (swap $quotRem m rad))$ n toRadix rad n = reverse . unfoldr (\m -> if m == 0 then Nothing else Just (swap $quotRem m rad))$ n toDigit = ((['0'..'9'] ++ ['a'..'z']) !!) toDigit = ((['0'..'9'] ++ ['a'..'z']) !!) instance ShowHex Int where instance ShowHex Int where showHex = ("0x" ++) . map toDigit . toRadix 16 showHex = ("0x" ++) . map toDigit . toRadix 16 instance ShowBin Int where instance ShowBin Int where showBin = ("0x" ++) . map toDigit . toRadix 2 showBin = ("0x" ++) . map toDigit . toRadix 2   %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: ## problem 7 ## problem 7 Converting between metric and imperial units: Write a function convertUnit :: (Double, String) -> (Double, String) that behaves like Converting between metric and imperial units: Write a function convertUnit :: (Double, String) -> (Double, String) that behaves like haskell haskell convertUnit (1, "m") == (1.09361, "yd") convertUnit (1, "m") == (1.09361, "yd") convertUnit (1, "kg") == (2.20462, "lb") convertUnit (1, "kg") == (2.20462, "lb")   etc... etc... Is there a more type-safe way of doing this? Is there a more type-safe way of doing this? %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell convertUnit :: (Double, String) -> (Double, String) convertUnit :: (Double, String) -> (Double, String) convertUnit (x, l) convertUnit (x, l) | l == "m" = (1.09361 * x, "yd") | l == "m" = (1.09361 * x, "yd") | l == "l" = (0.264172 * x, "gal") | l == "l" = (0.264172 * x, "gal") | l == "kg" = (2.20462 * x, "lb") | l == "kg" = (2.20462 * x, "lb") | l == "yd" = (x / 1.09361, "m") | l == "yd" = (x / 1.09361, "m") | l == "gal" = (x / 0.264172, "l") | l == "gal" = (x / 0.264172, "l") | l == "lb" = (x / 2.20462, "kg") | l == "lb" = (x / 2.20462, "kg") | otherwise = error "Invalid input" | otherwise = error "Invalid input"   %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell -- Using types (via http://shuklan.com/haskell/lec05.html): -- Using types (via http://shuklan.com/haskell/lec05.html): data MetricUnit = Meter data MetricUnit = Meter | Liter | Liter | KiloGram | KiloGram deriving (Show, Eq) deriving (Show, Eq)   %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell data ImperialUnit = Yard data ImperialUnit = Yard | Gallon | Gallon | Pound | Pound deriving (Show, Eq) deriving (Show, Eq)   %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell data Measurement = MetricMeasurement Double MetricUnit data Measurement = MetricMeasurement Double MetricUnit | ImperialMeasurement Double ImperialUnit | ImperialMeasurement Double ImperialUnit deriving (Show, Eq) deriving (Show, Eq)   %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell convertUnit :: Measurement -> Measurement convertUnit :: Measurement -> Measurement convertUnit (MetricMeasurement x u) convertUnit (MetricMeasurement x u) | u == Meter = ImperialMeasurement (1.0936*x) Yard | u == Meter = ImperialMeasurement (1.0936*x) Yard | u == Liter = ImperialMeasurement (0.2642*x) Gallon | u == Liter = ImperialMeasurement (0.2642*x) Gallon | u == KiloGram = ImperialMeasurement (2.2046*x) Pound | u == KiloGram = ImperialMeasurement (2.2046*x) Pound convertUnit (ImperialMeasurement x u) convertUnit (ImperialMeasurement x u) | u == Yard = MetricMeasurement (0.9144*x) Meter | u == Yard = MetricMeasurement (0.9144*x) Meter | u == Gallon = MetricMeasurement (3.7854*x) Liter | u == Gallon = MetricMeasurement (3.7854*x) Liter | u == Pound = MetricMeasurement (0.4536*x) KiloGram | u == Pound = MetricMeasurement (0.4536*x) KiloGram   %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: ## problem 8 ## problem 8 Prove the second functor law for lists: Prove the second functor law for lists: haskell haskell fmap (f . g) == fmap f . fmap g fmap (f . g) == fmap f . fmap g   %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell -- Induction start: -- Induction start: fmap (f . g) [] == [] == fmap f (fmap g []) fmap (f . g) [] == [] == fmap f (fmap g []) -- Induction step: -- Induction step: fmap (f . g) (x:xs) fmap (f . g) (x:xs) == (f . g) x : fmap (f . g) xs == (f . g) x : fmap (f . g) xs == f (g x) : fmap f (fmap g xs) == f (g x) : fmap f (fmap g xs) == fmap f (g x : fmap g xs) == fmap f (g x : fmap g xs) == fmap f (fmap g (x:xs)) == fmap f (fmap g (x:xs))   %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: ## problem 9 ## problem 9 Create a data type for polynominial rings with real coefficients and write the instances for Show, Eq and Num. Create a data type for polynomial rings with real coefficients and write the instances for Show, Eq and Num. *Note*: a formal polynominial is nothing else than a list of coefficents. *Note*: a formal polynomial is nothing else than a list of coefficents. %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell -- TODO : cleanup -- TODO : cleanup import Data.List import Data.List newtype Polynomial = Polynomial [Double] newtype Polynomial = Polynomial [Double] cleanPoly (Polynomial a) = Polynomial (dropWhileEnd (==0) a) cleanPoly (Polynomial a) = Polynomial (dropWhileEnd (==0) a) deg :: Polynomial -> Int deg :: Polynomial -> Int deg (Polynomial a) = length a - 1 deg (Polynomial a) = length a - 1 lcoeff :: Polynomial -> Double lcoeff :: Polynomial -> Double lcoeff (Polynomial a) = last a lcoeff (Polynomial a) = last a monomial :: Int -> Double -> Polynomial monomial :: Int -> Double -> Polynomial monomial d a = Polynomial (replicate d 0 ++ [a]) monomial d a = Polynomial (replicate d 0 ++ [a]) fromDouble :: Double -> Polynomial fromDouble :: Double -> Polynomial fromDouble a = Polynomial [a] -- also: fromDouble = monomial 0 fromDouble a = Polynomial [a] -- also: fromDouble = monomial 0 zero = Polynomial [] zero = Polynomial [] printPoly a = ((++) "P(X) = " . intercalate " + " . reverse . filter (/= "") . zipWith zipper [0..length a-1]) a printPoly a = ((++) "P(X) = " . intercalate " + " . reverse . filter (/= "") . zipWith zipper [0..length a-1]) a where where zipper _ 0 = "" zipper _ 0 = "" zipper power coeff = show coeff ++ "*X^" ++ show power zipper power coeff = show coeff ++ "*X^" ++ show power instance Show Polynomial where instance Show Polynomial where show (Polynomial a) = printPoly a show (Polynomial a) = printPoly a instance Eq Polynomial where instance Eq Polynomial where (Polynomial a) == (Polynomial b) = a == b (Polynomial a) == (Polynomial b) = a == b addPoly [] p = p addPoly [] p = p addPoly p [] = p addPoly p [] = p addPoly (x:xs) (y:ys) = (x+y:addPoly xs ys) addPoly (x:xs) (y:ys) = (x+y:addPoly xs ys) cauchyProd p q = [sum [(p !! i) * (q !! j) | i <- [0..lp-1], j <- [0..lq-1], i+j == n] | n <- [0..lp+lq-2]] cauchyProd p q = [sum [(p !! i) * (q !! j) | i <- [0..lp-1], j <- [0..lq-1], i+j == n] | n <- [0..lp+lq-2]] where where lp = length p lp = length p lq = length q lq = length q instance Num Polynomial where instance Num Polynomial where (Polynomial a) + (Polynomial b) = cleanPoly (Polynomial (addPoly a b)) (Polynomial a) + (Polynomial b) = cleanPoly (Polynomial (addPoly a b)) negate (Polynomial a) = Polynomial (map negate a) negate (Polynomial a) = Polynomial (map negate a) fromInteger a = Polynomial [fromInteger a] fromInteger a = Polynomial [fromInteger a] abs (Polynomial a) = Polynomial (map abs a) abs (Polynomial a) = Polynomial (map abs a) signum (Polynomial a) = Polynomial (map signum a) signum (Polynomial a) = Polynomial (map signum a) (Polynomial a) * (Polynomial b) = Polynomial (cauchyProd a b) (Polynomial a) * (Polynomial b) = Polynomial (cauchyProd a b)   %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell -- example -- example p1 = fromDouble 3.14 p1 = fromDouble 3.14 p2 = monomial 3 2.17 p2 = monomial 3 2.17 p1 p1 p2 p2   %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell   ... ...
 %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: # Exercises: integration and differentiation # Exercises: integration and differentiation ## problem 1 ## problem 1 Find an approximate solution for the fixed point equation Find an approximate solution for the fixed point equation $$x = e^{-x}.$$ $$x = e^{-x}.$$ Use $x_0 = 1.1$ as initial value and break after 1000 iterations or if the error is small enough. Use $x_0 = 1.1$ as initial value and break after 1000 iterations or if the error is small enough. %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell fixp :: Double -> Int -> Double -> (Double -> Double) -> Double fixp :: Double -> Int -> Double -> (Double -> Double) -> Double fixp tol maxit x0 f = fixp tol maxit x0 f = case converged of case converged of x:_ -> x x:_ -> x otherwise -> last iterates otherwise -> last iterates where iterates = take maxit $iterate f x0 where iterates = take maxit$ iterate f x0 converged = [ x | (x, xprev) <- zip (tail iterates) iterates converged = [ x | (x, xprev) <- zip (tail iterates) iterates , abs (x - xprev) < tol ] , abs (x - xprev) < tol ] fixp 1e-5 1000 1.1 $\x -> exp (-x) fixp 1e-5 1000 1.1$ \x -> exp (-x)   %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: ## problem 2 ## problem 2 Write a function that performs simple numerical (Riemann) integration using step functions. Write a function that performs simple numerical (Riemann) integration using step functions. A function $\phi:[a,b] \rightarrow \mathbb{R}$ is called step function if there exists a partion of $[a,b]$ into intervals such that $\phi$ is constant on each interval. A function $\phi:[a,b] \rightarrow \mathbb{R}$ is called step function if there exists a partion of $[a,b]$ into intervals such that $\phi$ is constant on each interval. %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell int :: Double -> Double -> Int -> (Double -> Double) -> Double int :: Double -> Double -> Int -> (Double -> Double) -> Double int a b n f = (b-a) / n' * sum (map f xs) int a b n f = (b-a) / n' * sum (map f xs) where xs = [ a + fromIntegral k / n' * (b-a) | k <- [0..n] ] where xs = [ a + fromIntegral k / n' * (b-a) | k <- [0..n] ] n' = fromIntegral n n' = fromIntegral n   %% Cell type:markdown id: tags: %% Cell type:markdown id: tags: ## problem 3 ## problem 3 Numerically compute the derivative of $f(x) = \sin(15x)$, $x \in [0, 2\pi]$ given a vector of noisy values $f(x_k) + \epsilon_k$, for $x_k = 2 \pi k / N$, $k \in \{0, 1, \ldots, N-1\}$. Here, $\epsilon_k$ are normally distributed noise variables with mean 0 and variance $\sigma$. Compare the result to the analytical derivative by computing a suitably scaled norm of the difference, averaged over sufficiently many noise realizations, and present the results graphically for varying $N$ and $\sigma$. Numerically compute the derivative of $f(x) = \sin(15x)$, $x \in [0, 2\pi]$ given a vector of noisy values $f(x_k) + \epsilon_k$, for $x_k = 2 \pi k / N$, $k \in \{0, 1, \ldots, N-1\}$. Here, $\epsilon_k$ are normally distributed noise variables with mean 0 and variance $\sigma$. Compare the result to the analytical derivative by computing a suitably scaled norm of the difference, averaged over sufficiently many noise realizations, and present the results graphically for varying $N$ and $\sigma$. *Note*: You can generate random vectors either using the standard System.Random functions, or *Note*: You can generate random vectors either using the standard System.Random functions, or haskell haskell randomVector :: Seed -> RandDist -> Int -> Vec Double randomVector :: Seed -> RandDist -> Int -> Vec Double   from Numeric.LinearAlgebra.Repa. As seed values for the different noise realization, you can use [0..] for simplicity. from Numeric.LinearAlgebra.Repa. As seed values for the different noise realization, you can use [0..] for simplicity. %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell import Graphics.Rendering.Plot import Graphics.Rendering.Plot import qualified Data.Array.Repa as Repa import qualified Data.Array.Repa as Repa import Data.Array.Repa hiding (map, (++)) import Data.Array.Repa hiding (map, (++)) import Numeric.LinearAlgebra.Helpers import Numeric.LinearAlgebra.Helpers import Numeric.LinearAlgebra.Repa import Numeric.LinearAlgebra.Repa   %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell periodicCentralDiff :: Double -> Vec Double -> Vec Double periodicCentralDiff :: Double -> Vec Double -> Vec Double periodicCentralDiff h f = computeS $scale (1/(2*h)) (computeS (fLeft -^ fRight) :: Vec Double) periodicCentralDiff h f = computeS$ scale (1/(2*h)) (computeS (fLeft -^ fRight) :: Vec Double) where where n = vlength f n = vlength f fLeft = subVector 1 (n-1) f append subVector 0 1 f fLeft = subVector 1 (n-1) f append subVector 0 1 f fRight = subVector (n-1) 1 f append subVector 0 (n-1) f fRight = subVector (n-1) 1 f append subVector 0 (n-1) f periodicCentralDiff 1 (vec [1,2,3,2,1,0]) :: Vec Double periodicCentralDiff 1 (vec [1,2,3,2,1,0]) :: Vec Double   %% Cell type:code id: tags: %% Cell type:code id: tags:  haskell  haskell steps = 200 xs = subVector 0 steps $computeS$ linspace (steps + 1) (0, 2*pi) --xs fs :: Vec Double fs = computeS $Repa.map (\x -> sin (15*x)) xs --fs dfs :: Vec Double dfs = computeS$ Repa.map (\x -> 15*cos (15*x)) xs --dfs  %% Cell type:code id: tags:  haskell h = 2*pi/(steps+1) --h --periodicCentralDiff h fs  %% Cell type:code id: tags:  haskell computeS $Repa.map (\x -> sin (x*2)) (vec [0,1,3.14,6.28]) :: Vec Double  %% Cell type:code id: tags:  haskell normInf :: Vec Double -> Double normInf :: Vec Double -> Double normInf = maximum . map abs . toList normInf = maximum . map abs . toList errs :: Int -> Double -> [Double] -- create vals x and step size h errs steps variance = map (err . makeNoise) [0..] coords :: Int -> (Vec Double, Double) where coords steps = (xs,h) xs :: Vec Double -- all x locations where xs = subVector 0 steps$ computeS $linspace (steps + 1) (0, 2*pi) xs = subVector 0 steps$ computeS $linspace (steps + 1) (0, 2*pi) f :: Vec Double -- f at all x locations h = xs!(ix1 1) - xs!(ix1 0) f = computeS$ Repa.map (\x -> sin (15*x)) xs f'exact :: Vec Double -- exact derivative at the locations err :: Int -> Double -> Seed -> Double -- one norm error for one seed f'exact = computeS $Repa.map (\x -> 15*cos (15*x)) xs err steps variance seed = sqrt h * normInf (computeS (fdt -^ fdn)) h :: Double -- the step size where h = xs!(ix1 1) - xs!(ix1 0) (xs,h) = coords steps makeNoise :: Seed -> Vec Double -- generate noise for a given seed ft = computeS$ Repa.map (\x -> sin (15*x)) xs :: Vec Double