Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
pp:l04 [2021/03/27 10:32] aghiculescu [Introduction] |
pp:l04 [2023/03/22 18:54] (current) mihai.udubasa old revision restored (2021/03/28 20:51) |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== 4. Working with matrices and images using higher-order functions ====== | ====== 4. Working with matrices and images using higher-order functions ====== | ||
| - | ===== Introduction ===== | + | ===== 1. Introduction ===== |
| 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. | 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. | ||
| Line 14: | Line 14: | ||
| which makes the type-name ''Matrix'' stand for ''[ [Integer] ]''. | 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'. | + | 1.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) | * (Hint: You need to perform two types of very similar splitting operations: one into lines, and another into column values, for each line) | ||
| Line 22: | Line 22: | ||
| </code> | </code> | ||
| - | 2. Write a function that converts a matrix to a string encoded as illustrated in the previous exercise. | + | 1.2. Write a function that converts a matrix to a string encoded as illustrated in the previous exercise. |
| * (Hint: use folds) | * (Hint: use folds) | ||
| * (Hint: test the function ''show'' on several different values) | * (Hint: test the function ''show'' on several different values) | ||
| + | * (Hint: first make a function to display one line) | ||
| <code haskell> | <code haskell> | ||
| - | toString :: Matrix -> String | + | toString:: Matrix -> String |
| - | toString = | + | toString= |
| </code> | </code> | ||
| - | 3. Add the following to your code. Test the function ''displaymat''. | + | 1.3. Add the following to your code. Test the function ''displayMatrix''. |
| <code haskell> | <code haskell> | ||
| - | displaymat = putStrLn . toString | + | displayMatrix = putStrLn . toString |
| </code> | </code> | ||
| - | ===== Matrix operations ===== | + | ===== 2. Matrix operations ===== |
| - | 4. Write a function that computes the scalar product with an integer: | + | 2.1. 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)] | + | $math[ \displaystyle 2 * \left(\begin{array}{ccc} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \\ \end{array}\right) = \left(\begin{array}{ccc} 2 & 4 & 6 \\ 8 & 10 & 12 \\ 14 & 16 & 18 \\ \end{array}\right)] |
| <code haskell> | <code haskell> | ||
| Line 47: | Line 48: | ||
| </code> | </code> | ||
| - | 5. Write a function which adjoins two matrices by extending rows: | + | 2.2. 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) ] | $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) ] | ||
| Line 56: | Line 57: | ||
| </code> | </code> | ||
| - | 6. Write a function which adjoins two matrices by adding new rows: | + | 2.3. 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) ] | $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) ] | ||
| Line 65: | Line 66: | ||
| </code> | </code> | ||
| - | 7. Write a function which adds two matrices. | + | 2.4. Write a function which adds two matrices. |
| <code haskell> | <code haskell> | ||
| Line 72: | Line 73: | ||
| </code> | </code> | ||
| - | 8. Write a function which computes the transposition of a matrix: | + | 2.5. 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) ] | + | $math[ tr \left(\begin{array}{ccc} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \\ \end{array}\right) = \left(\begin{array}{ccc} 1 & 4 & 7 \\ 2 & 5 & 8 \\ 3 & 6 & 9 \\ \end{array}\right) ] |
| <code haskell> | <code haskell> | ||
| Line 82: | Line 83: | ||
| </code> | </code> | ||
| - | 9. Write a function which computes the vectorial product of two matrices. | + | 2.6. 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: 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) | * (Hint: write a function which takes a line of matrix m1 and the matrix m2 and computes the respective line from the product) | ||
| Line 91: | Line 92: | ||
| </code> | </code> | ||
| - | ===== Image operations ===== | + | ===== 3. 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). | 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). | ||
| Line 110: | Line 111: | ||
| </code> | </code> | ||
| - | 10. Implement an image-displaying function. Use the image from the Appendix as a test. | + | 3.1. Implement an image-displaying function. Use the image from the Appendix as a test. |
| <code haskell> | <code haskell> | ||
| toStringImg :: Image -> String | toStringImg :: Image -> String | ||
| Line 119: | Line 120: | ||
| Add the following function in order to view images in a nicer format: | Add the following function in order to view images in a nicer format: | ||
| <code haskell> | <code haskell> | ||
| - | displaym = putStrLn . toStringImg | + | displayImg = putStrLn . toStringImg |
| </code> | </code> | ||
| - | 11. Implement a function which flips an image horizontally: | + | 3.2. Implement a function which flips an image horizontally: |
| <code haskell> | <code haskell> | ||
| flipH :: Image -> Image | flipH :: Image -> Image | ||
| Line 128: | Line 129: | ||
| </code> | </code> | ||
| - | 12. Implement a function which flips an image vertically: | + | 3.3. Implement a function which flips an image vertically: |
| <code haskell> | <code haskell> | ||
| flipV :: Image -> Image | flipV :: Image -> Image | ||
| Line 134: | Line 135: | ||
| </code> | </code> | ||
| - | 13. Implement a function which rotates an image 90grd clockwise | + | 3.4. Implement a function which rotates an image 90grd clockwise |
| <code haskell> | <code haskell> | ||
| rotate90r :: Image -> Image | rotate90r :: Image -> Image | ||
| Line 140: | Line 141: | ||
| </code> | </code> | ||
| - | 14. Implement a function which rotates an image -90grd clockwise | + | 3.5. Implement a function which rotates an image -90grd clockwise |
| <code haskell> | <code haskell> | ||
| rotate90l :: Image -> Image | rotate90l :: Image -> Image | ||
| Line 146: | Line 147: | ||
| </code> | </code> | ||
| - | 15. Implement a function which returns a diamond of a specified //height//. Example: | + | 3.6. Implement a function which inverts an image: ' ' becomes * and * becomes ' ': |
| - | <code> | + | <code haskell> |
| - | * | + | invert :: Image -> Image |
| - | *** | + | invert = |
| - | diamond 3 = ***** | + | |
| - | *** | + | |
| - | * | + | |
| - | + | ||
| - | * | + | |
| - | diamond 2 = *** | + | |
| - | * | + | |
| </code> | </code> | ||
| - | + | ||
| + | 3.7. Implement a function ''maskKeep'' which takes a mask and some image and only keeps the part of image which overlays the mask. Use the mask and the logo from Appendix to test it. | ||
| <code haskell> | <code haskell> | ||
| - | diamond :: Integer -> Image | + | maskKeep :: Image -> Image -> Image |
| + | maskKeep = | ||
| </code> | </code> | ||
| + | $math[ maskKeep \left(\begin{array}{ccc} & & * \\ & & * \\ & & * \\ \end{array}\right) \left(\begin{array}{ccc} * & & * \\ * & & \\ * & & * \\ \end{array}\right) = \left(\begin{array}{ccc} & & * \\ & & \\ & & * \\ \end{array}\right) ] | ||
| - | 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: | + | 3.8. Implement a function ''maskDiscard'' which takes a mask and some image and discards the part of the mask which overlays the image. |
| - | <code> | + | $math[ maskDiscard\left(\begin{array}{ccc} & & * \\ & & * \\ & & * \\ \end{array}\right) \left(\begin{array}{ccc} * & & * \\ * & & \\ * & & * \\ \end{array}\right) = \left(\begin{array}{ccc} & & \\ & & * \\ & & \\ \end{array}\right) ] |
| - | + | ||
| - | ****** **** **** | + | 3.9. Implement the ''union''' of two images. |
| - | ** ** overlay ****** = ** ** | + | <code haskell> |
| - | ** ** **** * * | + | union' :: Image -> Image -> Image |
| - | ****** ** ** | + | union' = |
| </code> | </code> | ||
| + | $math[ union \left(\begin{array}{ccc} & & * \\ & & * \\ & & * \\ \end{array}\right) \left(\begin{array}{ccc} * & & * \\ * & & \\ * & & * \\ \end{array}\right) = \left(\begin{array}{ccc} * & & * \\ * & & * \\ * & & * \\ \end{array}\right) ] | ||
| + | 3.10. Implement a function which takes a list of transformation and an image and applies all those transformations. | ||
| <code haskell> | <code haskell> | ||
| - | overlay :: Image -> Image -> Image | + | transformationSequence :: [Image -> Image] -> Image -> Image |
| + | </code> | ||
| + | Test it with the following sequence | ||
| + | <code haskell> | ||
| + | seq1 = transformationSequence [invert, union' mask, rotate90r] | ||
| </code> | </code> | ||
| - | ===== More matrices ===== | + | ===== 4. More matrices ===== |
| - | 17. Implement a function which places zeros **above** the diagonal of a square matrix. Use folds. | + | 4.1. 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. | + | 4.2. 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. | + | 4.3. Implement either of 4.1 or 4.2 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. | + | 4.4. 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? | + | 4.5. Implement a function which computes **recursively** the determinant of a matrix. What additional functions would be necessary? |
| ===== Appendix ===== | ===== Appendix ===== | ||
| <code haskell> | <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] | logo = [l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12,l13,l14,l15,l16,l17,l18,l19] | ||
| + | where l1 =" ***** ** ***** ** " | ||
| + | l2 =" ****** **** ****** **** " | ||
| + | l3 =" ** * * *** ** * * *** " | ||
| + | l4 =" * * * *** * * * *** " | ||
| + | l5 =" * * ** * * ** " | ||
| + | l6 =" ** ** ** ** ** ** " | ||
| + | l7 =" ** ** ** ** ** ** " | ||
| + | l8 =" **** ** * **** ** * " | ||
| + | l9 =" * *** ** * * *** ** * " | ||
| + | l10=" ** ******* ** ******* " | ||
| + | l11=" ** ****** ** ****** " | ||
| + | l12=" ** ** ** ** " | ||
| + | l13=" ** ** ** ** " | ||
| + | l14=" ** ** ** ** " | ||
| + | l15=" ** ** ** ** ** ** " | ||
| + | l16="*** * * *** * * " | ||
| + | l17=" *** * *** * " | ||
| + | l18=" ****** ****** " | ||
| + | l19=" *** *** " | ||
| + | </code> | ||
| + | |||
| + | <code haskell> | ||
| + | mask = [l1,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12,l13,l14,l15,l16,l17,l18,l19] | ||
| + | where l1 =" *****************" | ||
| + | l2 =" *****************" | ||
| + | l3 =" *****************" | ||
| + | l4 =" *****************" | ||
| + | l5 =" *****************" | ||
| + | l6 =" *****************" | ||
| + | l7 =" *****************" | ||
| + | l8 =" *****************" | ||
| + | l9 =" *****************" | ||
| + | l10=" *****************" | ||
| + | l11=" *****************" | ||
| + | l12=" *****************" | ||
| + | l13=" *****************" | ||
| + | l14=" *****************" | ||
| + | l15=" *****************" | ||
| + | l16=" *****************" | ||
| + | l17=" *****************" | ||
| + | l18=" *****************" | ||
| + | l19=" *****************" | ||
| </code> | </code> | ||