annotate yetilab/matrix/matrix.yeti @ 96:a5b4d0f68ca8

Matrix details
author Chris Cannam
date Wed, 20 Mar 2013 21:57:17 +0000
parents 5eee42ec5677
children d5fc902dcc3f
rev   line source
Chris@5 1
Chris@94 2 module yetilab.matrix.matrix;
Chris@94 3
Chris@94 4 // A matrix is an array of fvectors (i.e. primitive double[]s).
Chris@94 5
Chris@94 6 // A matrix can be either RowMajor, akin to a C multidimensional array
Chris@96 7 // in which each row is a separate fvector, or ColumnMajor, akin to a
Chris@94 8 // FORTAN multidimensional array in which each column is a separate
Chris@96 9 // fvector. The default is ColumnMajor. Storage order is an efficiency
Chris@94 10 // concern only, all operations behave identically regardless. (The
Chris@94 11 // transpose function just switches the row/column order without
Chris@94 12 // moving the elements.)
Chris@18 13
Chris@93 14 vec = load yetilab.block.fvector;
Chris@96 15 block = load yetilab.block.block;
Chris@9 16
Chris@96 17 make d = {
Chris@96 18 get data () = d,
Chris@96 19 get size () =
Chris@96 20 case d of
Chris@96 21 RowM r:
Chris@96 22 major = length r;
Chris@96 23 {
Chris@96 24 rows = major,
Chris@96 25 columns = if major > 0 then vec.length r[0] else 0 fi,
Chris@96 26 };
Chris@96 27 ColM c:
Chris@96 28 major = length c;
Chris@96 29 {
Chris@96 30 rows = if major > 0 then vec.length c[0] else 0 fi,
Chris@96 31 columns = major,
Chris@96 32 };
Chris@94 33 esac,
Chris@96 34 getColumn j =
Chris@96 35 case d of
Chris@96 36 RowM rows: block.fromList (map do i: getAt i j done [0..length rows-1]);
Chris@96 37 ColM cols: block.block cols[j];
Chris@94 38 esac,
Chris@96 39 getRow i =
Chris@96 40 case d of
Chris@96 41 RowM rows: block.block rows[i];
Chris@96 42 ColM cols: block.fromList (map do j: getAt i j done [0..length cols-1]);
Chris@94 43 esac,
Chris@96 44 getAt row col =
Chris@96 45 case d of
Chris@96 46 RowM rows: r = rows[row]; (r is ~double[])[col];
Chris@96 47 ColM cols: c = cols[col]; (c is ~double[])[row];
Chris@94 48 esac,
Chris@96 49 setAt row col n =
Chris@96 50 case d of
Chris@96 51 RowM rows: r = rows[row]; (r is ~double[])[col] := n;
Chris@96 52 ColM cols: c = cols[col]; (c is ~double[])[row] := n;
Chris@95 53 esac,
Chris@95 54 get isRowMajor? () =
Chris@96 55 case d of
Chris@96 56 RowM _: true;
Chris@96 57 ColM _: false;
Chris@95 58 esac,
Chris@94 59 };
Chris@94 60
Chris@94 61 newStorage rows cols =
Chris@95 62 array (map \(vec.zeros rows) [1..cols]);
Chris@94 63
Chris@94 64 zeroMatrix rows cols =
Chris@96 65 make (ColM (newStorage rows cols));
Chris@5 66
Chris@20 67 generate f rows cols =
Chris@94 68 (m = newStorage rows cols;
Chris@94 69 for [0..cols-1] do col:
Chris@94 70 for [0..rows-1] do row:
Chris@94 71 m[col][row] := f row col;
Chris@5 72 done;
Chris@5 73 done;
Chris@96 74 make (ColM m));
Chris@5 75
Chris@20 76 constMatrix n = generate do row col: n done;
Chris@20 77 randomMatrix = generate do row col: Math#random() done;
Chris@5 78 identityMatrix = constMatrix 1;
Chris@5 79
Chris@96 80 width m = m.size.columns;
Chris@96 81 height m = m.size.rows;
Chris@6 82
Chris@95 83 copyOf m =
Chris@95 84 (copyOfData d = (array (map vec.copyOf d));
Chris@96 85 make
Chris@95 86 (case m.data of
Chris@96 87 RowM d: RowM (copyOfData d);
Chris@96 88 ColM d: ColM (copyOfData d);
Chris@95 89 esac));
Chris@6 90
Chris@95 91 transposed m =
Chris@96 92 make
Chris@95 93 (case m.data of
Chris@96 94 RowM d: ColM d;
Chris@96 95 ColM d: RowM d;
Chris@95 96 esac);
Chris@5 97
Chris@96 98 //!!! Change storage from column to row major order (or back
Chris@96 99 //again). Is there a word for this?
Chris@96 100 flipped m =
Chris@96 101 if m.isRowMajor? then id else transposed fi
Chris@96 102 (generate do row col: m.getAt col row done m.size.columns m.size.rows);
Chris@96 103
Chris@96 104 newMatrix type data is RowMajor () | ColumnMajor () -> list?<list?<number>> -> 'a =
Chris@96 105 (tagger = case type of RowMajor (): RowM; ColumnMajor (): ColM esac;
Chris@96 106 if empty? data
Chris@96 107 then zeroMatrix 0 0
Chris@96 108 else make (tagger (array (map vec.vector data)))
Chris@96 109 fi);
Chris@96 110
Chris@96 111 newRowVector data =
Chris@96 112 newMatrix (RowMajor ()) [data];
Chris@96 113
Chris@96 114 newColumnVector data =
Chris@96 115 newMatrix (ColumnMajor ()) [data];
Chris@8 116
Chris@5 117 {
Chris@96 118 generate,
Chris@96 119 constMatrix, randomMatrix, zeroMatrix, identityMatrix,
Chris@96 120 width, height,
Chris@20 121 copyOf,
Chris@15 122 transposed,
Chris@96 123 flipped,
Chris@96 124 newMatrix, newRowVector, newColumnVector
Chris@5 125 }
Chris@5 126