changeset 214:709fba377099 matrix_opaque_immutable

Update matrix
author Chris Cannam
date Sat, 11 May 2013 11:39:09 +0100
parents d841bfc143dd
children c4f4e8def0aa
files yetilab/block/vector.yeti yetilab/matrix/matrix.yeti yetilab/matrix/matrixtype.yeti yetilab/stream/channels.yeti
diffstat 4 files changed, 68 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/yetilab/block/vector.yeti	Sat May 11 11:27:34 2013 +0100
+++ b/yetilab/block/vector.yeti	Sat May 11 11:39:09 2013 +0100
@@ -40,6 +40,9 @@
 empty?' =
     empty? . list';
 
+at' n v is number -> ~double[] -> number =
+    v[n];
+
 floats a is ~double[] -> ~float[] =
    (len = length' a;
     f = new float[len];
@@ -92,6 +95,7 @@
     array = array',
     length = length',
     empty? = empty?',
+    at = at',
     equal,
     rangeOf,
     resizedTo,
@@ -109,6 +113,7 @@
     array is vector -> array<number>,
     length is vector -> number,
     empty? is vector -> boolean,
+    at is number -> vector -> number,
     equal is vector -> vector -> boolean,
     rangeOf is number -> number -> vector -> vector, //!!! not well-named now vector arg is at the end
     resizedTo is number -> vector -> vector,
--- a/yetilab/matrix/matrix.yeti	Sat May 11 11:27:34 2013 +0100
+++ b/yetilab/matrix/matrix.yeti	Sat May 11 11:39:09 2013 +0100
@@ -1,7 +1,7 @@
 
 module yetilab.matrix.matrix;
 
-// A matrix is an array of blocks.
+// A matrix is an array of vectors.
 
 // A matrix can be stored in either column-major (the default) or
 // row-major format. Storage order is an efficiency concern only:
@@ -9,10 +9,12 @@
 // result regardless of storage order.  (The transpose function just
 // switches the row/column order without moving the elements.)
 
-bl = load yetilab.block.block;
+//!!! check that we are not unnecessarily copying in the transform functions
+
+vec = load yetilab.block.vector;
 bf = load yetilab.block.blockfuncs;
 
-load yetilab.block.blocktype;
+load yetilab.block.vectortype;
 load yetilab.matrix.matrixtype;
 
 size m =
@@ -21,12 +23,12 @@
         major = length r;
         { 
             rows = major, 
-            columns = if major > 0 then bl.length r[0] else 0 fi,
+            columns = if major > 0 then vec.length r[0] else 0 fi,
         };
     ColM c:
         major = length c;
         { 
-            rows = if major > 0 then bl.length c[0] else 0 fi,
+            rows = if major > 0 then vec.length c[0] else 0 fi,
             columns = major, 
         };
     esac;
@@ -36,27 +38,29 @@
 
 getAt row col m =
     case m of
-    RowM rows: r = rows[row]; (bl.data r)[col];
-    ColM cols: c = cols[col]; (bl.data c)[row];
+    RowM rows: r = rows[row]; vec.at col r;
+    ColM cols: c = cols[col]; vec.at row c;
     esac;
 
 getColumn j m =
     case m of
-    RowM rows: bl.fromList (map do i: getAt i j m done [0..length rows-1]);
+    RowM rows: vec.fromList (map do i: getAt i j m done [0..length rows-1]);
     ColM cols: cols[j];
     esac;
 
 getRow i m =
     case m of
     RowM rows: rows[i];
-    ColM cols: bl.fromList (map do j: getAt i j m done [0..length cols-1]);
+    ColM cols: vec.fromList (map do j: getAt i j m done [0..length cols-1]);
     esac;
 
+/*
 setAt row col n m = //!!! dangerous, could modify copies -- should it be allowed?
     case m of
-    RowM rows: r = rows[row]; (bl.data r)[col] := n;
-    ColM cols: c = cols[col]; (bl.data c)[row] := n;
+    RowM rows: r = rows[row]; (vec.data r)[col] := n;
+    ColM cols: c = cols[col]; (vec.data c)[row] := n;
     esac;
+*/
 
 isRowMajor? m =
     case m of
@@ -66,7 +70,7 @@
 
 newColMajorStorage { rows, columns } = 
     if rows < 1 then array []
-    else array (map \(bl.zeros rows) [1..columns])
+    else array (map \(vec.zeros rows) [1..columns])
     fi;
 
 zeroMatrix { rows, columns } = 
@@ -79,19 +83,23 @@
         ColM (newColMajorStorage { rows, columns });
     fi;
 
+zeroSizeMatrix () = zeroMatrix { rows = 0, columns = 0 };
+
 generate f { rows, columns } =
-   (m = newColMajorStorage { rows, columns };
-    for [0..columns-1] do col:
-        for [0..rows-1] do row:
-            (bl.data m[col])[row] := f row col;
+    if rows < 1 or columns < 1 then zeroSizeMatrix ()
+    else
+        m = array (map \(new double[rows]) [1..columns]);
+        for [0..columns-1] do col:
+            for [0..rows-1] do row:
+                m[col][row] := f row col;
+            done;
         done;
-    done;
-    ColM m);
+        ColM (array (map vec.vector m))
+    fi;
 
 constMatrix n = generate do row col: n done;
 randomMatrix = generate do row col: Math#random() done;
 identityMatrix = constMatrix 1;
-zeroSizeMatrix () = zeroMatrix { rows = 0, columns = 0 };
 
 transposed m =
     case m of
@@ -120,23 +128,25 @@
     if size m1 != size m2 then false
     elif isRowMajor? m1 != isRowMajor? m2 then equal (flipped m1) m2;
     else
-        compare d1 d2 = all id (map2 bl.equal d1 d2);
+        compare d1 d2 = all id (map2 vec.equal d1 d2);
         case m1 of
         RowM d1: case m2 of RowM d2: compare d1 d2; _: false; esac;
         ColM d1: case m2 of ColM d2: compare d1 d2; _: false; esac;
         esac
     fi;
 
+/*!!! not needed now it's immutable?
 copyOf m =
-   (copyOfData d = (array (map bl.copyOf d));
+   (copyOfData d = (array (map vec.copyOf d));
     case m of
     RowM d: RowM (copyOfData d);
     ColM d: ColM (copyOfData d);
     esac);
+*/
 
 newMatrix type data = //!!! NB does not copy data
    (tagger = case type of RowMajor (): RowM; ColumnMajor (): ColM esac;
-    if empty? data or bl.empty? (head data)
+    if empty? data or vec.empty? (head data)
     then zeroSizeMatrix ()
     else tagger (array data)
     fi);
@@ -176,7 +186,7 @@
    (n = counter (size (head mm));
     tagger (array
        (map do i:
-           bl.concat (map (getter i) mm)
+           vec.concat (map (getter i) mm)
            done [0..n-1])));
 
 concatWithGrain tagger getter counter mm =
@@ -222,14 +232,14 @@
     if isRowMajor? m then
         RowM (array (map ((flip getRow) m) [start .. start + count - 1]))
     else 
-        ColM (array (map (bl.rangeOf start count) (asColumns m)))
+        ColM (array (map (vec.rangeOf start count) (asColumns m)))
     fi;
 
 columnSlice start count m = //!!! doc: storage order same as input
     if not isRowMajor? m then
         ColM (array (map ((flip getColumn) m) [start .. start + count - 1]))
     else 
-        RowM (array (map (bl.rangeOf start count) (asRows m)))
+        RowM (array (map (vec.rangeOf start count) (asRows m)))
     fi;
 
 resizedTo newsize m =
@@ -268,7 +278,7 @@
     getAt,
     getColumn,
     getRow,
-    setAt,
+//    setAt,
     isRowMajor?,
     generate,
     constMatrix,
@@ -277,7 +287,7 @@
     identityMatrix,
     zeroSizeMatrix,
     equal,
-    copyOf,
+//    copyOf,
     transposed,
     flipped,
     toRowMajor,
@@ -303,9 +313,9 @@
     width is matrix -> number,
     height is matrix -> number,
     getAt is number -> number -> matrix -> number,
-    getColumn is number -> matrix -> block,
-    getRow is number -> matrix -> block,
-    setAt is number -> number -> number -> matrix -> (), //!!! lose?
+    getColumn is number -> matrix -> vector,
+    getRow is number -> matrix -> vector,
+//    setAt is number -> number -> number -> matrix -> (), //!!! lose?
     isRowMajor? is matrix -> boolean,
     generate is (number -> number -> number) -> { .rows is number, .columns is number } -> matrix,
     constMatrix is number -> { .rows is number, .columns is number } -> matrix,
@@ -314,22 +324,22 @@
     identityMatrix is { .rows is number, .columns is number } -> matrix, 
     zeroSizeMatrix is () -> matrix,
     equal is matrix -> matrix -> boolean,
-    copyOf is matrix -> matrix,
+//    copyOf is matrix -> matrix,
     transposed is matrix -> matrix,
     flipped is matrix -> matrix, 
     toRowMajor is matrix -> matrix, 
     toColumnMajor is matrix -> matrix,
     scaled is number -> matrix -> matrix,
     resizedTo is { .rows is number, .columns is number } -> matrix -> matrix,
-    asRows is matrix -> list<block>, 
-    asColumns is matrix -> list<block>,
+    asRows is matrix -> list<vector>, 
+    asColumns is matrix -> list<vector>,
     sum is matrix -> matrix -> matrix,
     product is matrix -> matrix -> matrix,
     concat is (Horizontal () | Vertical ()) -> list<matrix> -> matrix,
     rowSlice is number -> number -> matrix -> matrix, 
     columnSlice is number -> number -> matrix -> matrix,
-    newMatrix is (ColumnMajor () | RowMajor ()) -> list<block> -> matrix, 
-    newRowVector is block -> matrix, 
-    newColumnVector is block -> matrix,
+    newMatrix is (ColumnMajor () | RowMajor ()) -> list<vector> -> matrix, 
+    newRowVector is vector -> matrix, 
+    newColumnVector is vector -> matrix,
 }
 
--- a/yetilab/matrix/matrixtype.yeti	Sat May 11 11:27:34 2013 +0100
+++ b/yetilab/matrix/matrixtype.yeti	Sat May 11 11:39:09 2013 +0100
@@ -1,9 +1,9 @@
 
 module yetilab.matrix.matrixtype;
 
-load yetilab.block.blocktype;
+load yetilab.block.vectortype;
 
-typedef opaque matrix = RowM. array<block> | ColM. array<block>;
+typedef opaque matrix = RowM. array<vector> | ColM. array<vector>;
 
 ();
 
--- a/yetilab/stream/channels.yeti	Sat May 11 11:27:34 2013 +0100
+++ b/yetilab/stream/channels.yeti	Sat May 11 11:39:09 2013 +0100
@@ -1,8 +1,7 @@
 
 module yetilab.stream.channels;
 
-vec = load yetilab.block.fvector;
-block = load yetilab.block.block;
+vec = load yetilab.block.vector;
 mat = load yetilab.matrix.matrix;
         
 interleaved m = 
@@ -10,53 +9,53 @@
     if rows == 1 then
         mat.getRow 0 m
     else
-        v = vec.zeros (columns * rows);
+        v = new double[columns * rows];
         for [0..rows-1] do row:
             for [0..columns-1] do col:
                 v[col * rows + row] := mat.getAt row col m;
             done;
         done;
-        block.block v;
+        vec.vector v;
     fi);
 
 deinterleaved channels b =
     if channels == 1 then
         mat.newRowVector b
     else
-        rows = (block.length b) / channels;
-        vv = array (map \(vec.zeros rows) [0..channels-1]);
-        v = block.data b;
+        rows = (vec.length b) / channels;
+        vv = array (map \(new double[rows]) [0..channels-1]);
+        v = vec.data b;
         for [0..rows-1] do row:
             for [0..channels-1] do col:
                 vv[col][row] := v[channels * row + col];
             done
         done;
-        mat.newMatrix (RowMajor ()) (map block.block vv);
+        mat.newMatrix (RowMajor ()) (map vec.vector vv);
     fi;
 
 mixedDown m =  //!!! sum or average? at the moment we sum
    ({ columns, rows } = (mat.size m);
-    v = vec.zeros columns;
+    v = new double[columns];
     for [0..rows-1] do row:
         for [0..columns-1] do col:
             v[col] := v[col] + mat.getAt row col m;
         done;
     done;
-    block.block v);
+    vec.vector v);
 
 mixedDownFromInterleaved channels b =
     if channels == 1 then
         b;
     else
-        v = block.data b;
+        v = vec.data b;
         columns = ((vec.length v) / channels);
-        v' = vec.zeros columns;
+        v' = new double[columns];
         for [0..channels-1] do row:
             for [0..columns-1] do col:
                 v'[col] := v'[col] + v[col * channels + row];
             done;
         done;
-        block.block v';
+        vec.vector v';
     fi;
 
 mixedFromInterleavedTo targetChannels channels b = 
@@ -65,9 +64,9 @@
     elif targetChannels == 1 then
         mixedDownFromInterleaved channels b;
     else
-        v = block.data b;
+        v = vec.data b;
         columns = ((vec.length v) / channels);
-        v' = vec.zeros (columns * targetChannels);
+        v' = new double[columns * targetChannels];
         for [0..targetChannels-1] do target:
             for [0..columns-1] do col:
                 if target < channels then
@@ -77,7 +76,7 @@
                 fi
             done
         done;
-        block.block v';
+        vec.vector v';
     fi;
 
 mixedTo targetChannels m =