This is an old revision of the document!
Working with matrices and images using higher-order functions
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.
Hence, the matrix
$ \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:
type Matrix = [[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'.
- (Hint: You need to perform two types of very similar splitting operations: one into lines, and another into column values, for each line)
parsem :: String -> Matrix parsem =
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)
toString :: Matrix -> String toString =
3. Add the following to your code. Test the function displaymat
.
displaymat = putStrLn . toString
Matrix operations
4. Write a function that computes the scalar product with an integer:
$ \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)$
vprod :: Integer -> Matrix -> Matrix vprod v =
5. Write a function which adjoins two matrices by extending rows:
$ \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) $
hjoin :: Matrix -> Matrix -> Matrix hjoin =
6. Write a function which adjoins two matrices by adding new rows:
$ \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) $
vjoin :: Matrix -> Matrix -> Matrix vjoin =
7. Write a function which adds two matrices.
msum :: Matrix -> Matrix -> Matrix msum =
8. Write a function which computes the transposition of a matrix:
$ 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) $
tr :: [[a]] -> [[a]] tr ([]:_) = tr m =
9. Write a function which computes the vectorial product of two matrices.
- (Hint: start by writing a function which computes $ a_{ij}$ for a given line $ i$ and column $ 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)
mprod :: Matrix -> Matrix -> Matrix mprod m1 m2 =
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).
type Image = [String]
For instance, a rectangle could be represented as:
******** * * ********
more precisely, as the string:
"********\n* *\n********\n"
10. Implement an image-displaying function:
toStringImg :: Image -> String toStringImg =
Add the following function in order to view images in a nicer format:
displaym = putStrLn . toStringImg
11. Implement a function which flips an image horizontally:
flipH :: Image -> Image flipH =
12. Implement a function which flips an image vertically:
flipV :: Image -> Image flipV =
13. Implement a function which rotates an image 90grd clockwise
rotate90r :: Image -> Image rotate90r =
14. Implement a function which rotates an image -90grd clockwise
rotate90l :: Image -> Image rotate90l =
15. Implement a function which returns a diamond of a specified height. Example:
* *** diamond 3 = ***** *** * * diamond 2 = *** *
diamond :: Integer -> Image
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:
****** **** **** ** ** 0111verlay0032 ****** ** ** ** ** **** * * ****** ** **
overlay :: Image -> Image -> Image
Appendix
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]