Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
pp:l04 [2020/03/17 10:41] pdmatei |
pp:l04 [2023/03/22 18:54] (current) mihai.udubasa old revision restored (2021/03/28 20:51) |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== 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: | + | |
- | $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)] | + | 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} 2 & 4 & 6 \\ 8 & 10 & 12 \\ 14 & 16 & 18 \\ \end{array}\right)] | ||
<code haskell> | <code haskell> | ||
Line 46: | 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 55: | 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 64: | 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 71: | 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 81: | 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 90: | 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 109: | 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 118: | 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 127: | 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 133: | 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 139: | 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 145: | 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. | + | |
- | 19. Implement either of 17 or 18 using the function(s) ''take'' and ''drop''. Check the types of these and test them. | + | 4.2. Implement a function which places zeros **below** the diagonal of a square matrix. Use folds. |
- | 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? | + | 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. |
+ | |||
+ | 4.4. Implement a function which computes the **diagonal** matrix of a square matrix. | ||
+ | |||
+ | 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> | ||