Kraxorax / elm-matrix-a / Matrix

Matrix (a) datastructure of certain width and height, containing elements of type (a) on x and y indexes.

Exposes Matrix creation, traversal, and some manipulation functions.

Definition

Matrix


type Matrix a

A type representing a matrix. Internally, a matrix is just nested array with a constraint that all sub-arrays must be of same length

Creation

Use repeat and generate to create your matrices.

repeat : Basics.Int -> Basics.Int -> a -> Matrix a

Creates Matrix of given width and height by repeating single given value.

Call repeat with width and height, and a value to be repeated.

myFourByThreeMatrixOfZeros =
    repeat 4 3 0

-- 0 0 0 0
-- 0 0 0 0
-- 0 0 0 0

generate : Basics.Int -> Basics.Int -> (Basics.Int -> Basics.Int -> a) -> Matrix a

Creates Matrix of given width and height by calling a generator function.

Call generate with width and height, and a generator function : Int -> Int -> a. Generator function will be called for every element of matrix and will receive x and y of that element as params to return a value to be put into matrix.

generate : Int -> Int -> (Int -> Int -> a) -> Matrix a

multiplicationTable =
    generate 10 10 (\x y -> (x + 1) * (y + 1))

--  1   2   3   4   5   6   7   8   9   10
--  2   4   6   8   10  12  14  16  18  20
--  3   6   9   12  15  18  21  24  27  30
--  4   8   12  16  20  24  28  32  36  40
--  5   10  15  20  25  30  35  40  45  50
--  6   12  18  24  30  36  42  48  54  60
--  7   14  21  28  35  42  49  56  63  70
--  8   16  24  32  40  48  56  64  72  80
--  9   18  27  36  45  54  63  72  81  90
--  10  20  30  40  50  60  70  80  90  100

Traversal

These are just standard traversal functions.

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

Jup, it's a map

myMatrix = repeat 3 3 0
-- 0 0 0
-- 0 0 0
-- 0 0 0
map (String.fromInt) myMatrix
--  "0" "0" "0"
--  "0" "0" "0"
--  "0" "0" "0"

indexedMap : (Basics.Int -> Basics.Int -> a -> b) -> Matrix a -> Matrix b

indexedMap will call your function with x, y and a as params

myMatrix = repeat 3 3 2
-- 2 2 2
-- 2 2 2
-- 2 2 2
indexedMap (\x y element ->
    (x + y) * element |> String.fromInt)
    myMatrix
--  "0" "2" "4"
--  "2" "4" "6"
--  "4" "6" "8"

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

Folding right

myMatrix = generate 4 4 (\x y -> (String.fromInt x) ++ (String.fromInt y))
--  "00"    "10"    "20"    "30"
--  "01"    "11"    "21"    "31"
--  "02"    "12"    "22"    "32"
--  "03"    "13"    "23"    "33"
foldr (++) "" myMatrix
--  "00102030011121310212223203132333"

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

Folding left

myMatrix = generate 4 4 (\x y -> (String.fromInt x) ++ (String.fromInt y))
--  "00"    "10"    "20"    "30"
--  "01"    "11"    "21"    "31"
--  "02"    "12"    "22"    "32"
--  "03"    "13"    "23"    "33"
foldl (++) "" myMatrix
--  "33231303322212023121110130201000"

Manipulation

concatHorizontal : Matrix a -> Matrix a -> Result String (Matrix a)

Concatinates two matrices horizontally. Will return Result Err if matrices are not of same height.

matrixOne = repeat 2 2 1
-- 1 1
-- 1 1
matrixTwo = repeat 2 2 2
-- 2 2
-- 2 2
concatHorizontal matrixOne matrixTwo
-- 1 1 2 2
-- 1 1 2 2

concatVertical : Matrix a -> Matrix a -> Result String (Matrix a)

Concatinates two matrices vertically. Will return Result Err if matrices are not of same width.

matrixOne = repeat 2 2 1
-- 1 1
-- 1 1
matrixTwo = repeat 2 2 2
-- 2 2
-- 2 2
concatVertical matrixOne matrixTwo
-- 1 1
-- 1 1
-- 2 2
-- 2 2

Utility

width : Matrix a -> Basics.Int

Returns width of given Matrix

myMatrix = repeat 2 3 0
-- 0 0
-- 0 0
-- 0 0
width myMatrix
-- 2

height : Matrix a -> Basics.Int

Returns height of given Matrix

myMatrix = repeat 2 3 0
-- 0 0
-- 0 0
-- 0 0
height myMatrix
-- 3

get : Basics.Int -> Basics.Int -> Matrix a -> Result String a

Returns element at given x and y from matrix. Nothing of indexes are out of bounds.

myMatrix = generate 4 4 (\x y -> (String.fromInt x) ++ (String.fromInt y))
--  "00"    "10"    "20"    "30"
--  "01"    "11"    "21"    "31"
--  "02"    "12"    "22"    "32"
--  "03"    "13"    "23"    "33"
get 1 2 myMatrix
-- "12"

getRow : Basics.Int -> Matrix a -> Result String (Array a)

Returns a row at given index as a list. Result Err if index is out of bounds.

myMatrix = generate 4 4 (\x y -> (String.fromInt x) ++ (String.fromInt y))
--  "00"    "10"    "20"    "30"
--  "01"    "11"    "21"    "31"
--  "02"    "12"    "22"    "32"
--  "03"    "13"    "23"    "33"
getRow 1 myMatrix
--  Array.fromList ["01","11","21","31"]

getColumn : Basics.Int -> Matrix a -> Result String (Array a)

Returns a column at given index as an array. Result Err if index is out of bounds.

myMatrix =
    generate 4 4 (\x y -> String.fromInt x ++ String.fromInt y)

--  "00"    "10"    "20"    "30"
--  "01"    "11"    "21"    "31"
--  "02"    "12"    "22"    "32"
--  "03"    "13"    "23"    "33"
getColumn 1 myMatrix
--  Array.fromList ["10", "11", "12", "13"]

set : Basics.Int -> Basics.Int -> a -> Matrix a -> Matrix a

Set the element at a particular index. Returns an updated array. If the index is out of range, the matrix is unaltered.

myMatrix =
    generate 4 4 (\x y -> String.fromInt x ++ String.fromInt y)
        |> set 1 2 "**"

--  "00"    "10"    "20"    "30"
--  "01"    "11"    "21"    "31"
--  "02"    "**"    "22"    "32"
--  "03"    "13"    "23"    "33"

toArray : Matrix a -> Array a

Returns all elements of matrix in a single array.

myMatrix =
    generate 4 4 (\x y -> String.fromInt x ++ String.fromInt y)

--  "00"    "10"    "20"    "30"
--  "01"    "11"    "21"    "31"
--  "02"    "12"    "22"    "32"
--  "03"    "13"    "23"    "33"
toArray myMatrix
--  Array.fromList ["00", "10", "20", "30", "01", "11", "21", "31", "02", "12", "22", "32", "03", "13", "23", "33"]