Edit this page Backlinks This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. ====== 4. Working with matrices and images using higher-order functions ====== ===== Introduction - displaying a matrix ===== We shall represent matrices as //lists of lists//, i.e. values of type ''[ [Integer ] ]''. Each element in the outer list represents a line of the matrix. Hence, the matrix $math[ \displaystyle \left(\begin{array}{ccc} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \\ \end{array}\right)] will be represented by the list ''[ [1,2,3],[4,5,6],[7,8,9] ]''. To make signatures more legible, add the //type alias// to your code: <code haskell> type Matrix = [[Integer]] </code> which makes the type-name ''Matrix'' stand for ''[ [Integer] ]''. 1. Write a function ''parsem'' which takes a string and parses it to a ''Matrix''. In the string, the columns are separated by whitespace and lines - by '\n'. * (Hint: You need to perform two types of very similar splitting operations: one into lines, and another into column values, for each line) <code haskell> parsem :: String -> Matrix parsem = </code> 2. Write a function that converts a matrix to a string encoded as illustrated in the previous exercise. * (Hint: use folds) * (Hint: test the function ''show'' on several different values) <code haskell> toString :: Matrix -> String toString = </code> 3. Add the following to your code. Test the function ''displaymat''. <code haskell> displaymat = putStrLn . toString </cod e> ===== Matrix operations ===== 4. Write a function that computes the scalar product with an integer: $math[ \displaystyle 2 * \left(\begin{array}{ccc} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \\ \end{array}\right) = \left(\begin{array}{ccc} 1 & 4 & 6 \\ 8 & 10 & 12 \\ 14 & 16 & 18 \\ \end{array}\right)] <code haskell> vprod :: Integer -> Matrix -> Matrix vprod v = </code> 5. Write a function which adjoins two matrices by extending rows: $math[ \displaystyle \left(\begin{array}{cc} 1 & 2 \\ 3 & 4\\\end{array}\right) hjoin \left(\begin{array}{cc} 5 & 6 \\ 7 & 8\\\end{array}\right) = \left(\begin{array}{cc} 1 & 2 & 5 & 6 \\ 3 & 4 & 7 & 8\\\end{array}\right) ] <code haskell> hjoin :: Matrix -> Matrix -> Matrix hjoin = </code> 6. Write a function which adjoins two matrices by adding new rows: $math[ \displaystyle \left(\begin{array}{cc} 1 & 2 \\ 3 & 4\\\end{array}\right) vjoin \left(\begin{array}{cc} 5 & 6 \\ 7 & 8\\\end{array}\right) = \left(\begin{array}{cc} 1 & 2 \\ 3 & 4 \\ 5 & 6\\ 7 & 8\\ \end{array}\right) ] <code haskell> vjoin :: Matrix -> Matrix -> Matrix vjoin = </code> 7. Write a function which adds two matrices. <code haskell> msum :: Matrix -> Matrix -> Matrix msum = </code> 8. Write a function which computes the transposition of a matrix: $math[ tr \left(\begin{array}{ccc} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \\ \end{array}\right) = \left(\begin{array}{ccc} 1 & 4 & 6 \\ 2 & 5 & 8 \\ 3 & 6 & 9 \\ \end{array}\right) ] <code haskell> tr :: [[a]] -> [[a]] tr ([]:_) = tr m = </code> 9. Write a function which computes the vectorial product of two matrices. * (Hint: start by writing a function which computes $math[a_{ij}] for a given line $math[i] and column $math[j] (both represented as lists)) * (Hint: write a function which takes a line of matrix m1 and the matrix m2 and computes the respective line from the product) <code haskell> mprod :: Matrix -> Matrix -> Matrix mprod m1 m2 = </code> ===== Image operations ===== We can represent images as matrices of pixels. In our example a pixel will be represented as a ''Char'', which can take the values: '*' (signifying that the respective pixel is //on//) and ' ' (the pixel is off). <code haskell> type Image = [String] </code> For instance, a rectangle could be represented as: <code> ******** * * ******** </code> more precisely, as the string: <code haskell> "********\n* *\n********\n" </code> 10. Implement an image-displaying function. Use the image from the Appendix as a test. <code haskell> toStringImg :: Image -> String toStringImg = </code> Add the following function in order to view images in a nicer format: <code haskell> displaym = putStrLn . toStringImg </code> 11. Implement a function which flips an image horizontally: <code haskell> flipH :: Image -> Image flipH = </code> 12. Implement a function which flips an image vertically: <code haskell> flipV :: Image -> Image flipV = </code> 13. Implement a function which rotates an image 90grd clockwise <code haskell> rotate90r :: Image -> Image rotate90r = </code> 14. Implement a function which rotates an image -90grd clockwise <code haskell> rotate90l :: Image -> Image rotate90l = </code> 15. Implement a function which returns a diamond of a specified //height//. Example: <code> * *** diamond 3 = ***** *** * * diamond 2 = *** * </code> <code haskell> diamond :: Integer -> Image </code> 16. Implement a function with takes two images with the same dimensions. The second image is a mask. The output will be another image in which all pixels from the first image overlaying with a '*'-pixel from the mask will be displayed. All others will be deleted (made equal to ' '). Example: <code> ****** **** **** ** ** overlay ****** = ** ** ** ** **** * * ****** ** ** </code> <code haskell> overlay :: Image -> Image -> Image </code> ===== More matrices ===== 17. Implement a function which places zeros **above** the diagonal of a square matrix. Use folds. 18. Implement a function which places zeros **below** the diagonal of a square matrix. Use folds. 19. Implement either of 17 or 18 using the function(s) ''take'' and ''drop''. Check the types of these and test them. 20. Implement a function which computes the **diagonal** matrix of a square matrix. 21. Implement a function which computes **recursively** the determinant of a matrix. What additional functions would be necessary? ===== Appendix ===== <code haskell> l1=" ***** ** ***** ** " l2=" ****** **** ****** **** " l3=" ** * * *** ** * * *** " l4=" * * * *** * * * *** " l5=" * * ** * * ** " l6=" ** ** ** ** ** ** " l7=" ** ** ** ** ** ** " l8=" **** ** * **** ** * " l9=" * *** ** * * *** ** * " l10=" ** ******* ** ******* " l11=" ** ****** ** ****** " l12=" ** ** ** ** " l13=" ** ** ** ** " l14=" ** ** ** ** " l15=" ** ** ** ** ** ** " l16="*** * * *** * * " l17=" *** * *** * " l18=" ****** ****** " l19=" *** *** " logo = [l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12,l13,l14,l15,l16,l17,l18,l19] </code>