forsyde-shallow-3.4.0.0: ForSyDe's Haskell-embedded Domain Specific Language.

Copyright(c) ForSyDe Group KTH 2019
LicenseBSD-style (see the file LICENSE)
Maintainerforsyde-dev@kth.se
Stabilityexperimental
Portabilityportable
Safe HaskellSafe
LanguageHaskell98

ForSyDe.Shallow.Utility.Matrix

Contents

Description

This module defines the data type Matrix and corresponding functions. It is a shallow interpretation of 2D arrays and is used for quick prototyping of array algorithms and skeletons, although itself is a type synonym for a Vector of Vectors. Therefore this module is simply a collection of utility functions on 2D vectors used mainly for convenience. For a type-checked fixed-size data type for representing matrices, see the matrix or REPA packages.

OBS: The lengths in the API documentation for function arguments are not type-safe, but rather suggestions for usage in designing matrix algorithms or skeletons.

Synopsis

Documentation

type Matrix a = Vector (Vector a) Source #

Matrix is simply a type synonym for vector of vectors. This means that any function on Vector works also on Matrix.

prettyMat Source #

Arguments

:: Show a 
=> String

separator string

-> Matrix a

input matrix

-> IO () 

Prints out to the terminal a matrix in a readable format, where all elements are right-aligned and separated by a custom separator.

>>> let m = matrix 3 3 [1,2,3,3,100,4,12,32,67]
>>> prettyMat "|" m
 1|  2| 3
 3|100| 4
12| 32|67

Queries

nullMat :: Matrix a -> Bool Source #

Checks if a matrix is null. <> and <> are both null matrices.

sizeMat :: Matrix a -> (Int, Int) Source #

Returns the X and Y dimensions of matrix and checks if it is well formed.

wellFormedMat :: Matrix a -> Matrix a Source #

Checks if a matrix is well-formed, meaning that all its rows are of equal length. Returns the same matrix in case it is well-formed or throws an exception if it is ill-formed.

Generators

matrix Source #

Arguments

:: Int

number of columns (X dimension) = x

-> Int

number of rows (Y dimension) = y

-> [a]

list of values; length = x * y

-> Matrix a

Matrix of values; size = (x,y)

Converts a list into a Matrix. See example from prettyMat.

fromMatrix Source #

Arguments

:: Matrix a

size = (x,y)

-> [a]

length = x * y

Converts a matrix back to a list.

unitMat Source #

Arguments

:: a 
-> Matrix a

size = (1,1)

Creates a unit (i.e. singleton) matrix, which is a matrix with only one element.

indexMat :: Matrix (Int, Int) Source #

Returns an infinite matrix with (X,Y) index pairs. You need to zip it against another (finite) matrix or to extract a finite subset in order to be useful (see example below).

>>> prettyMat " " $ takeMat 3 4 indexMat
(0,0) (1,0) (2,0)
(0,1) (1,1) (2,1)
(0,2) (1,2) (2,2)
(0,3) (1,3) (2,3)

Functional skeletons

mapMat Source #

Arguments

:: (a -> b) 
-> Matrix a

size = (xa,ya)

-> Matrix b

size = (xa,ya)

Maps a function on every value of a matrix.

OBS: this function does not check if the output matrix is well-formed.

zipWithMat Source #

Arguments

:: (a -> b -> c) 
-> Matrix a

size = (xa,ya)

-> Matrix b

size = (xb,yb)

-> Matrix c

size = (minimum [xa,xb], minimum [ya,yb])

Applies a binary function pair-wise on each element in two matrices.

OBS: this function does not check if the output matrix is well-formed.

zipWith3Mat Source #

Arguments

:: (a -> b -> c -> d) 
-> Matrix a

size = (xa,ya)

-> Matrix b

size = (xb,yb)

-> Matrix c

size = (xc,yc)

-> Matrix d

size = (minimum [xa,xb,xc], minimum [ya,yb,yc])

Applies a function 3-tuple-wise on each element in three matrices.

OBS: this function does not check if the output matrix is well-formed.

reduceMat :: (a -> a -> a) -> Matrix a -> a Source #

Reduces all the elements of a matrix to one element based on a binary function.

>>> let m = matrix 3 3 [1,2,3,11,12,13,21,22,23]
>>> reduceMat (+) m
108

dotVecMat Source #

Arguments

:: (a -> a -> a)

kernel function for a row/column reduction, e.g. (+) for dot product

-> (b -> a -> a)

binary operation for pair-wise elements, e.g. (*) for dot product

-> Matrix b

size = (xa,ya)

-> Vector a

length = xa

-> Vector a

length = xa

Pattern implementing the template for a dot operation between a vector and a matrix.

>>> let mA = matrix 4 4 [1,-1,1,1,  1,-1,-1,-1,  1,1,-1,1,  1,1,1,-1]
>>> let y  = vector[1,0,0,0]
>>> dotVecMat (+) (*) mA y
<1,1,1,1>

dotMatMat Source #

Arguments

:: (a -> a -> a)

kernel function for a row/column reduction, e.g. (+) for dot product

-> (b -> a -> a)

binary operation for pair-wise elements, e.g. (*) for dot product

-> Matrix b

size = (xa,ya)

-> Matrix a

size = (ya,xa)

-> Matrix a

size = (xa,xa)

Pattern implementing the template for a dot operation between two matrices.

>>> let mA = matrix 4 4 [1,-1,1,1,  1,-1,-1,-1,  1,1,-1,1,  1,1,1,-1]
>>> prettyMat " " $ dotMatMat (+) (*) mA mA
2 -2  2  2
2 -2 -2 -2
2  2  2 -2
2  2 -2  2

Selectors

atMat Source #

Arguments

:: Int

X index starting from zero

-> Int

Y index starting from zero

-> Matrix a 
-> a 

Returns the element of a matrix at a certain position.

>>> let m = matrix 3 3 [1,2,3,11,12,13,21,22,23]
>>> atMat 2 1 m
13

takeMat Source #

Arguments

:: Int

X index starting from zero

-> Int

Y index starting from zero

-> Matrix a 
-> Matrix a 

Returns the upper-left part of a matrix until a specific position.

>>> let m = matrix 4 4 [1,2,3,4,11,12,13,14,21,22,23,24,31,32,33,34]
>>> prettyMat " " $ takeMat 2 2 m
 1  2
11 12

dropMat Source #

Arguments

:: Int

X index starting from zero

-> Int

Y index starting from zero

-> Matrix a 
-> Matrix a 

Returns the upper-left part of a matrix until a specific position.

>>> let m = matrix 4 4 [1,2,3,4,11,12,13,14,21,22,23,24,31,32,33,34]
>>> prettyMat " " $ dropMat 2 2 m
23 24
33 34

cropMat Source #

Arguments

:: Int

crop width = w

-> Int

crop height = h

-> Int

X start position = x0

-> Int

Y start position = y0

-> Matrix a

size = (xa,ya)

-> Matrix a

size = (minimum [w,xa-x0], minimum [h,xa-x0])

Crops a section of a matrix.

>>> let m = matrix 4 4 [1,2,3,4,11,12,13,14,21,22,23,24,31,32,33,34]
>>> prettyMat " " m
 1  2  3  4
11 12 13 14
21 22 23 24
31 32 33 34
>>> prettyMat " " $ cropMat 2 3 1 1 m
12 13
22 23
32 33

groupMat Source #

Arguments

:: Int

width of groups = w

-> Int

height of groups = h

-> Matrix a

size = (xa,ya)

-> Matrix (Matrix a)

size = (xa div w,ya div h)

Groups a matrix into smaller equallly-shaped matrices.

>>> let m = matrix 4 4 [1,2,3,4,11,12,13,14,21,22,23,24,31,32,33,34]
>>> prettyMat " " $ groupMat 2 2 m
  <<1,2>,<11,12>>   <<3,4>,<13,14>>
<<21,22>,<31,32>> <<23,24>,<33,34>>

stencilMat :: Int -> Int -> Matrix a -> Matrix (Matrix a) Source #

Returns a stencil of neighboring elements for each possible element in a vector.

>>> let m = matrix 4 4 [1,2,3,4,11,12,13,14,21,22,23,24,31,32,33,34]
>>> prettyMat " " $ stencilMat 2 2 m
  <<1,2>,<11,12>>   <<2,3>,<12,13>>   <<3,4>,<13,14>>
<<11,12>,<21,22>> <<12,13>,<22,23>> <<13,14>,<23,24>>
<<21,22>,<31,32>> <<22,23>,<32,33>> <<23,24>,<33,34>>

Permutators

zipMat Source #

Arguments

:: Matrix a

size = (xa,ya)

-> Matrix b

size = (xb,yb)

-> Matrix (a, b)

size = (minimum [xa,xb], minimum [ya,yb])

unzipMat Source #

Arguments

:: Matrix (a, b)

size = (x,y)

-> (Matrix a, Matrix b)

size = (x,y) and (x,y)

rotateMat Source #

Arguments

:: Int

index on X axis

-> Int

index on Y axis

-> Vector (Vector a) 
-> Vector (Vector a) 

Pattern which "rotates" a matrix. The rotation is controled with the x and y index arguments as following:

  • (> 0) : rotates the matrix right/down with the corresponding number of positions.
  • (= 0) : does not modify the position for that axis.
  • (< 0) : rotates the matrix left/up with the corresponding number of positions.
>>> let m = matrix 4 4 [1,2,3,4,11,12,13,14,21,22,23,24,31,32,33,34]
>>> prettyMat " " $ rotateMat (-1) 1 m
32 33 34 31
 2  3  4  1
12 13 14 11
22 23 24 21

reverseMat :: Matrix a -> Matrix a Source #

Reverses the order of elements in a matrix

transposeMat Source #

Arguments

:: Matrix a

size = (x,y)

-> Matrix a

size = (y,x)

Transposes a matrx.

replaceMat :: Int -> Int -> Matrix a -> Matrix a -> Matrix a Source #

Replaces a part of matrix with another (smaller) part, starting from an arbitrary position.

>>> let m  = matrix 4 4 [1,2,3,4,11,12,13,14,21,22,23,24,31,32,33,34]
>>> let m1 = matrix 2 2 [101,202,303,404]
>>> prettyMat " " $ replaceMat 1 1 m1 m
 1   2   3  4
11 101 202 14
21 303 404 24
31  32  33 34