Commit fd87ac2f authored by Jochen Schulz's avatar Jochen Schulz
Browse files

merge and work on exercises

parent d4d2f203
......@@ -22,7 +22,7 @@ TODO 2014-09-04 Musterloesungen erstellen
ex19 parallel arrays: rsa neu erstellen
ex20p5 jacobi solver
ex21p3 centralized differences + noise
ex22p4 auf cg umstellen (siam problem 20000)
ex22p4 auf cg umstellen (siam problem 20000) (pending..)
ex24p3 solution missing
ex24 mandelbrot-irgendwas
ex24 change to endtime?
......@@ -50,22 +50,25 @@ WAITING 2015-07-23 parallel and concurrent, cloudhaskell
:LOGBOOK:
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+1 *differentialgeometrie -> henrik (laplace weak implementieren) (hmatrix)
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-08-05 allgemein: interpolation/fitting
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:
DONE: 2016-03-21 16:13:21
WAITING: 2015-07-02 17:28:15
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
:LOGBOOK:
WAITING: 2015-06-12 12:28:11
ANDEREVORLESUNG:
WAITING 2014-08-05 (Lambda Kalkuel einfuehren)
:LOGBOOK:
WAITING: 2015-06-12 12:28:12
......
-- ghc -O2 -prof -fprof-auto -rtsopts factorial.hs && ./factorial +RTS -pi -hc -sstderr -RTS
{-# LANGUAGE BangPatterns #-}
facE :: (Show a, Integral a) => a -> a
facE i
| i<0 = error "Negative Faculty not defined"
......@@ -20,6 +21,8 @@ facRf x = fac' x 1 where
fac' 1 y = y
fac' f y = fac' (f-1) $! (f*y)
Fractional
main :: IO ()
main = do
let g = facNE 10000
......
%% Cell type:markdown id: tags:
# Exercises: type classes
## problem 1
Explain the difference between
```haskell
type Point = (Double, Double)
```
and
```haskell
data Point = Point Double Double
```
%% Cell type:code id: tags:
``` haskell
```
%% Cell type:markdown id: tags:
## problem 2
Write an instance of `Show` for `Shape`
```haskell
data Point = Point Double Double
instance Show Point where
show (Point x y) = "(" ++ show x ++ ", " ++ show y ++ ")"
data Shape = Circle Point Double
| Rectangle Point Double Double
```
%% Cell type:code id: tags:
``` haskell
```
%% Cell type:markdown id: tags:
## problem 3
- Write an instance of `Eq` 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.
%% Cell type:code id: tags:
``` haskell
```
%% Cell type:markdown id: tags:
## problem 4
Vectors (in the mathematical sense) are required in many numerical applications.
- Implement a typeclass for vectors of arbitrary dimensions.
- Implement addition, scalar multiplication and inner product.
- How could matrices be represented?
%% Cell type:code id: tags:
``` haskell
```
%% Cell type:markdown id: tags:
## problem 5
Write classes `ShowHex` and `ShowBin` which output numbers in hex and binary, and implement them for `Int`.
%% Cell type:code id: tags:
``` haskell
```
%% Cell type:markdown id: tags:
## 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`.
%% Cell type:code id: tags:
``` haskell
```
%% Cell type:markdown id: tags:
## problem 7
Converting between metric and imperial units: Write a function `convertUnit :: (Double, String) -> (Double, String)` that behaves like
```haskell
convertUnit (1, "m") == (1.09361, "yd")
convertUnit (1, "kg") == (2.20462, "lb")
```
etc...
Is there a more type-safe way of doing this?
%% Cell type:code id: tags:
``` haskell
```
%% Cell type:markdown id: tags:
## problem 8
Prove the second functor law for lists:
```haskell
fmap (f . g) == fmap f . fmap g
```
%% Cell type:code id: tags:
``` haskell
```
%% Cell type:markdown id: tags:
## 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:
``` haskell
```
......
%% Cell type:markdown id: tags:
# Exercises: boundary value problems
## problem 1
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:
$$A x = b$$
It is defined by the iteration
$$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$
We rewrite this a little bit to for the algorithm:
$$x^{( k + 1 )} = T x^{( k )} + C$$
where
$$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.
For a test case use the matrix and right hand side from the lecture.
%% Cell type:code id: tags:
``` haskell
```
%% Cell type:markdown id: tags:
## problem 2
Implement the *jacobi* iterative algorithm for solving linear equations. First decompose the
matrix $A$ into the diagonal part $D$ and the remnant $R$:
$$ A = D + R$$
Then iterate the following
$$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.
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:
``` haskell
```
%% Cell type:markdown id: tags:
## problem 3
Write an implementation of the *conjugate gradient* (CG) method. This method solves
$$A x = b$$
by an iteration of the form $x_0 = 0$, $r_0 = p_0 = b$,
$$
\begin{align}
\alpha_k &= \frac{{\lVert r_k \rVert}^2}{\langle p_k, A p_k \rangle} \\
x_{k+1} &= x_k + \alpha_k 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
\end{align},
$$
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`.
The CG implementation should therefore have a signature like this:
```haskell
cg :: Double -> (Vec Double -> Vec Double) -> Vec Double -> Vec Double
cg tol f rhs = [...]
```
Apply the method to the same test case as above, but this time reimplement it using the function
```haskell
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.
%% Cell type:code id: tags:
``` haskell
```
%% Cell type:markdown id: tags:
## 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
$$|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..).
*bonus*: implement sparse variants of gauss-seidel and/or conjugate gradiant and try to use them as solver here.
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.
%% Cell type:code id: tags:
``` haskell
```
......
%% Cell type:markdown id: tags:
# Exercises: type classes
## problem 1
Explain the difference between
```haskell
type Point = (Double, Double)
```
and
```haskell
data Point = Point Double Double
```
%% Cell type:markdown id: tags:
## problem 2
Write an instance of `Show` for `Shape`
```haskell
data Point = Point Double Double
instance Show Point where
show (Point x y) = "(" ++ show x ++ ", " ++ show y ++ ")"
data Shape = Circle Point Double
| Rectangle Point Double Double
```
%% Cell type:code id: tags:
``` haskell
data Point = Point Double Double
instance Show Point where
show (Point x y) = "(" ++ show x ++ ", " ++ show y ++ ")"
data Shape = Circle Point Double
| Rectangle Point Double Double
instance Show Shape where
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 ++
" and edges " ++ show a ++ " and " ++ show b
```
%% Cell type:markdown id: tags:
## problem 3
- Write an instance of `Eq` 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.
%% Cell type:code id: tags:
``` haskell
instance Eq Point where
(Point x1 y1) == (Point x2 y2) = (x1 == x2) && (y1 == y2)
instance Eq Shape where
(Circle c1 r1) == (Circle c2 r2) = (c1 == c2) && (r1 == r2)
(Rectangle p1 a1 b1) == (Rectangle p2 a2 b2) = (p1 == p2) && (a1 == a2) && (b1 == b2)
_ == _ = False
```
%% Cell type:code id: tags:
``` haskell
import Data.Function
-- problem: unclear how to compare shapes. e.g. compare areas:
instance Ord Shape where
compare = compare `on` area
where area (Rectangle _ a b) = a * b
area (Circle _ r) = pi * r**2
```
%% Cell type:code id: tags:
``` haskell
data PointDeriv = PointDeriv Double Double deriving (Eq, Ord)
data ShapeDeriv = CircleDeriv PointDeriv Double
| RectangleDeriv PointDeriv Double Double
deriving (Eq, Ord)
```
%% Cell type:code id: tags:
``` haskell
CircleDeriv (PointDeriv 0 0) 1 < CircleDeriv (PointDeriv 1 0) 10
```
%% Cell type:code id: tags:
``` haskell
CircleDeriv (PointDeriv 0 0) 10 < RectangleDeriv (PointDeriv 0 0) 1 1
```
%% Cell type:code id: tags:
``` haskell
RectangleDeriv (PointDeriv 0 0) 2 3 < RectangleDeriv (PointDeriv 0 0) 3 2
```
%% Cell type:markdown id: tags:
## problem 4
Vectors (in the mathematical sense) are required in many numerical applications.
- Implement a typeclass for vectors of arbitrary dimensions.
- Implement addition, scalar multiplication and inner product.
- How could matrices be represented?
%% Cell type:code id: tags:
``` haskell
data Vector = Vector { vec :: [Double] } deriving (Show)
-- Downside: length of vector is unspecified, needs to be checked at runtime.
-- Otherwise, we would need a seperate type for each dimension: Vector1d, Vector2d, ...
addVector :: Vector -> Vector -> Vector
addVector a b
| length c /= length d = error "Dimensions are not equal"
| otherwise = Vector (zipWith (+) c d)
where c = vec a
d = vec b
scalar :: Vector -> Double -> Vector
scalar a b = Vector (map (*b) (vec a))
scalarProd :: Vector -> Vector -> Double
scalarProd a b
| length c /= length d = error "Vector sizes must match"
| otherwise = sum (zipWith (*) c d)
where c = vec a
d = vec b
```
%% Cell type:code id: tags:
``` haskell
data Matrix = Matrix { columns :: [Vector] }
```
%% Cell type:markdown id: tags:
## problem 5
Write classes `ShowHex` and `ShowBin` which output numbers in hex and binary, and implement them for `Int`.
%% Cell type:code id: tags:
``` haskell
class ShowHex a where
showHex :: a -> String
instance ShowHex Int where
showHex 0 = "0x0"
showHex n = "0x" ++ (reverse $ showHex' n)
where showHex' 0 = ""
showHex' m = let (q, r) = quotRem m 16
in ((['0'..'9']++['a'..'f']) !! r) : showHex' q
```
%% Cell type:code id: tags:
``` haskell
class ShowBin a where
showBin :: a -> String
instance ShowBin Int where
showBin 0 = "0"
showBin n = reverse $ showBin' n
where showBin' 0 = ""
showBin' m = let (q, r) = quotRem m 2
in (['0','1'] !! r) : showBin' q
```
%% Cell type:markdown id: tags:
## 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`.
%% Cell type:code id: tags:
``` haskell
import Data.List
iterate' f = unfoldr (\x -> Just (x, f x))
```
%% Cell type:code id: tags:
``` haskell
-- The recursion pattern above is abstracted by
-- unfoldr :: (a -> Maybe (b, a)) -> a -> [b]
-- So a nicer way to write the instances is this:
import Data.List
import Data.Tuple
toRadix rad 0 = [0]
toRadix rad n = reverse . unfoldr (\m -> if m == 0 then Nothing else Just (swap $ quotRem m rad)) $ n
toDigit = ((['0'..'9'] ++ ['a'..'z']) !!)
instance ShowHex Int where
showHex = ("0x" ++) . map toDigit . toRadix 16
instance ShowBin Int where
showBin = ("0x" ++) . map toDigit . toRadix 2
```
%% Cell type:markdown id: tags:
## problem 7
Converting between metric and imperial units: Write a function `convertUnit :: (Double, String) -> (Double, String)` that behaves like
```haskell
convertUnit (1, "m") == (1.09361, "yd")
convertUnit (1, "kg") == (2.20462, "lb")
```
etc...
Is there a more type-safe way of doing this?
%% Cell type:code id: tags:
``` haskell
convertUnit :: (Double, String) -> (Double, String)
convertUnit (x, l)
| l == "m" = (1.09361 * x, "yd")
| l == "l" = (0.264172 * x, "gal")
| l == "kg" = (2.20462 * x, "lb")
| l == "yd" = (x / 1.09361, "m")
| l == "gal" = (x / 0.264172, "l")
| l == "lb" = (x / 2.20462, "kg")
| otherwise = error "Invalid input"
```
%% Cell type:code id: tags:
``` haskell
-- Using types (via http://shuklan.com/haskell/lec05.html):
data MetricUnit = Meter
| Liter
| KiloGram
deriving (Show, Eq)
```
%% Cell type:code id: tags:
``` haskell
data ImperialUnit = Yard
| Gallon
| Pound
deriving (Show, Eq)
```
%% Cell type:code id: tags:
``` haskell
data Measurement = MetricMeasurement Double MetricUnit
| ImperialMeasurement Double ImperialUnit
deriving (Show, Eq)
```
%% Cell type:code id: tags:
``` haskell
convertUnit :: Measurement -> Measurement
convertUnit (MetricMeasurement x u)
| u == Meter = ImperialMeasurement (1.0936*x) Yard
| u == Liter = ImperialMeasurement (0.2642*x) Gallon
| u == KiloGram = ImperialMeasurement (2.2046*x) Pound
convertUnit (ImperialMeasurement x u)
| u == Yard = MetricMeasurement (0.9144*x) Meter
| u == Gallon = MetricMeasurement (3.7854*x) Liter
| u == Pound = MetricMeasurement (0.4536*x) KiloGram
```
%% Cell type:markdown id: tags:
## problem 8
Prove the second functor law for lists:
```haskell
fmap (f . g) == fmap f . fmap g
```
%% Cell type:code id: tags:
``` haskell
-- Induction start:
fmap (f . g