Commit 5a64e0b4 by Christoph Ruegge

### Moved solution from exercises/ to solutions/

parent e326e3b1
 %% Cell type:markdown id: tags: # Exercises 26 # problem 1 Implement Newton's method for functions from $\mathbb{R}^n$ to $\mathbb{R}^n$ given as a function of the form haskell newton :: (Vector Double -> Vector Double) -> (Vector Double -> Matrix Double) -> Vector Double -> Vector Double newton f df initial = [...]  Here, f is the function whose root should be found, and df is its derivative (i.e. Jacobian). initial is an initial guess, and should return the first iterate for which the norm of the function value is smaller than some fixed bound. %% Cell type:code id: tags:  haskell import Numeric.Container newton :: (Vector Double -> Vector Double) -> (Vector Double -> Matrix Double) -> Vector Double -> Vector Double newton f df initial = fst . head . filter stoprule $iterate step (initial, f initial) where step (x, y) = let x' = x - df x <\> y in (x', f x') stoprule :: (Vector Double, Vector Double) -> Bool stoprule (_, y) = norm2 y < 1e-6  %% Cell type:code id: tags:  haskell f :: Vector Double -> Vector Double f x = fromList [ x0^2 + x1^2 , x0^2 - x1^2] where x0 = x @> 0 x1 = x @> 1 df :: Vector Double -> Matrix Double df x = fromLists [ [ 2*x0, 2*x1 ] , [ 2*x0, -2*x1 ] ] where x0 = x @> 0 x1 = x @> 1 newton f df (fromList [10, 20])  %%%% Output: display_data %% Cell type:markdown id: tags: # problem 2 (This is problem 4 of the SIAM 100-digit challenge.) Consider the function $$f(x, y) = e^{\sin(50x)} + \sin(60 e^y) + \sin(70\sin(x)) + \sin(\sin(80y)) - \sin(10(x+y)) + \frac{x^2 + y^2}{4}.$$ 1. Plot the function using the vis.py script from the source repository. 2. Try to find the global minimum of the function by solving the equation $$\nabla f(x, y) = 0$$ using Newton's method from problem 1. Since the function oscillates very quickly and therefore has multiple local extrema, you should solve the equation for a sufficiently large number of initial values. Use a grid of$10 \times 10$points in the square$(-0.5,\, 0.5)^2 \subset \mathbb{R}^2$and run Newton's method on each of these points. 3. It may also be useful to try to refine the set of initial points until some heuristic criterion is fulfilled. Try to formulate such a criterion. For reference, the global minimum is -3.306868647. The function, its gradient and is Hessian are are implemented by the following Haskell functions: haskell f :: Double -> Double -> Double f x y = exp (sin (50*x)) + sin (60 * exp y) + sin (70 * sin x) + sin (sin (80*y)) - sin (10 * (x+y)) + (x^2 + y^2)/4 gradf :: Double -> Double -> [Double] gradf x y = [dfx, dfy] where dfx = 50 * cos (50*x) * exp (sin (50*x)) + 70 * cos x * cos (70 * sin x) - 10 * cos (10 * (x+y)) + x/2 dfy = 60 * exp y * cos (60 * exp y) + 80 * cos (80*y) * cos (sin (80*y)) - 10 * cos (10 * (x+y)) + y/2 hessf :: Double -> Double -> [[Double]] hessf x y = [[hfxx, hfxy], [hfxy, hfyy]] where hfxx = 2500 * cos (50*x) ^ 2 * exp (sin (50*x)) - 2500 * sin (50*x) * exp (sin (50*x)) - 70 * sin x * cos (70 * sin x) - 4900 * cos x ^ 2 * sin (70 * sin x) + 100 * sin (10 * (x+y)) + 1/2 hfyy = 60 * exp y * cos (60 * exp y) - 3600 * exp y ^ 2 * sin (60 * exp y) - 6400 * sin (80*y) * cos (sin (80*y)) - 6400 * cos (80*y) ^ 2 * sin (sin (80*y)) + 100 * sin(10 * (x+y)) + 1/2 hfxy = 100 * sin (10 * (x+y))  ... ...  %% Cell type:markdown id: tags: # Exercises 26 # problem 1 Implement Newton's method for functions from$\mathbb{R}^n$to$\mathbb{R}^n$given as a function of the form haskell newton :: (Vector Double -> Vector Double) -> (Vector Double -> Matrix Double) -> Vector Double -> Vector Double newton f df initial = [...]  Here, f is the function whose root should be found, and df is its derivative (i.e. Jacobian). initial is an initial guess, and should return the first iterate for which the norm of the function value is smaller than some fixed bound. %% Cell type:code id: tags:  haskell import Numeric.Container newton :: (Vector Double -> Vector Double) -> (Vector Double -> Matrix Double) -> Vector Double -> Vector Double newton f df initial = fst . head . filter stoprule$ iterate step (initial, f initial) where step (x, y) = let x' = x - df x <\> y in (x', f x') stoprule :: (Vector Double, Vector Double) -> Bool stoprule (_, y) = norm2 y < 1e-6  %% Cell type:code id: tags:  haskell f :: Vector Double -> Vector Double f x = fromList [ x0^2 + x1^2 , x0^2 - x1^2] where x0 = x @> 0 x1 = x @> 1 df :: Vector Double -> Matrix Double df x = fromLists [ [ 2*x0, 2*x1 ] , [ 2*x0, -2*x1 ] ] where x0 = x @> 0 x1 = x @> 1 newton f df (fromList [10, 20])  %%%% Output: display_data %% Cell type:markdown id: tags: # problem 2 (This is problem 4 of the SIAM 100-digit challenge.) Consider the function $$f(x, y) = e^{\sin(50x)} + \sin(60 e^y) + \sin(70\sin(x)) + \sin(\sin(80y)) - \sin(10(x+y)) + \frac{x^2 + y^2}{4}.$$ 1. Plot the function using the vis.py script from the source repository. 2. Try to find the global minimum of the function by solving the equation $$\nabla f(x, y) = 0$$ using Newton's method from problem 1. Since the function oscillates very quickly and therefore has multiple local extrema, you should solve the equation for a sufficiently large number of initial values. Use a grid of $10 \times 10$ points in the square $(-0.5,\, 0.5)^2 \subset \mathbb{R}^2$ and run Newton's method on each of these points. 3. It may also be useful to try to refine the set of initial points until some heuristic criterion is fulfilled. Try to formulate such a criterion. For reference, the global minimum is -3.306868647. The function, its gradient and is Hessian are are implemented by the following Haskell functions: haskell f :: Double -> Double -> Double f x y = exp (sin (50*x)) + sin (60 * exp y) + sin (70 * sin x) + sin (sin (80*y)) - sin (10 * (x+y)) + (x^2 + y^2)/4 gradf :: Double -> Double -> [Double] gradf x y = [dfx, dfy] where dfx = 50 * cos (50*x) * exp (sin (50*x)) + 70 * cos x * cos (70 * sin x) - 10 * cos (10 * (x+y)) + x/2 dfy = 60 * exp y * cos (60 * exp y) + 80 * cos (80*y) * cos (sin (80*y)) - 10 * cos (10 * (x+y)) + y/2 hessf :: Double -> Double -> [[Double]] hessf x y = [[hfxx, hfxy], [hfxy, hfyy]] where hfxx = 2500 * cos (50*x) ^ 2 * exp (sin (50*x)) - 2500 * sin (50*x) * exp (sin (50*x)) - 70 * sin x * cos (70 * sin x) - 4900 * cos x ^ 2 * sin (70 * sin x) + 100 * sin (10 * (x+y)) + 1/2 hfyy = 60 * exp y * cos (60 * exp y) - 3600 * exp y ^ 2 * sin (60 * exp y) - 6400 * sin (80*y) * cos (sin (80*y)) - 6400 * cos (80*y) ^ 2 * sin (sin (80*y)) + 100 * sin(10 * (x+y)) + 1/2 hfxy = 100 * sin (10 * (x+y))  ... ...
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!