Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
pp:l04 [2020/03/12 13:58]
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. ​
 Hence, the matrix Hence, 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} ​& 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} ​& 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 & \\ 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 & \\ 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:+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>​
  
 +===== 4. More matrices =====
  
 +4.1. Implement a function which places zeros **above** 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.
 +
 +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>​
 +
 +<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>​
 +
 +
 +