changeset 255:8043f7405eae

Add general enumerate, ensure zeros fed in to makeSparse are not retained in non-zero lists; test
author Chris Cannam
date Tue, 21 May 2013 21:58:34 +0100
parents efdb1aee9d21
children 97e97a2e6a4e
files Makefile yetilab/matrix/matrix.yeti yetilab/matrix/test/test_matrix.yeti
diffstat 3 files changed, 73 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Tue May 21 14:29:22 2013 +0100
+++ b/Makefile	Tue May 21 21:58:34 2013 +0100
@@ -1,5 +1,6 @@
+ALL_SOURCES := $(wildcard yetilab/*.yeti yetilab/*/*.yeti yetilab/*/*/*.yeti)
 TEST_SOURCES := $(wildcard yetilab/test/*.yeti yetilab/*/test/*.yeti yetilab/*/*/test/*.yeti)
-SOURCES := $(filter-out $(TESTS), $(wildcard yetilab/*.yeti yetilab/*/*.yeti yetilab/*/*/*.yeti))
+SOURCES := $(filter-out $(TEST_SOURCES), $(ALL_SOURCES))
 
 bin/.testrun:	yetilab.jar $(TEST_SOURCES)
 	./bin/yc yetilab/test/all.yeti | tee $@.out
--- a/yetilab/matrix/matrix.yeti	Tue May 21 14:29:22 2013 +0100
+++ b/yetilab/matrix/matrix.yeti	Tue May 21 21:58:34 2013 +0100
@@ -166,6 +166,9 @@
         DenseCols (array (map vec.vector m))
     fi;
 
+swapij =
+    map do { i, j, v }: { i = j, j = i, v } done;
+
 enumerateSparse m =
    (enumerate { values, indices, pointers } =
         concat
@@ -177,13 +180,29 @@
                     (vec.list (vec.slice values start end))
                 done [0..length pointers - 2]);
     case m of
-    SparseCSC d: 
-        map do { i, j, v }: { i = j, j = i, v } done (enumerate d);
-    SparseCSR d:
-        enumerate d;
+    SparseCSC d: swapij (enumerate d);
+    SparseCSR d: enumerate d;
      _: [];
     esac);
 
+enumerateDense m =
+   (enumerate d =
+        concat
+           (map do i:
+                vv = d[i];
+                map2 do j v: { i, j, v } done
+                    [0..vec.length vv - 1]
+                    (vec.list vv);
+                done [0..length d - 1]);
+    case m of
+    DenseCols c: swapij (enumerate c);
+    DenseRows r: enumerate r;
+     _: [];
+    esac);
+
+enumerate m =
+    if isSparse? m then enumerateSparse m else enumerateDense m fi;
+
 makeSparse type size data =
    (isRow = case type of RowMajor (): true; ColumnMajor (): false esac;
     ordered = 
@@ -196,7 +215,7 @@
                 else
                     do { i, j, v }: { maj = j, min = i, v } done;
                 fi
-                data);
+               (filter do d: d.v != 0 done data));
     tagger = if isRow then SparseCSR else SparseCSC fi;
     majorSize = if isRow then size.rows else size.columns fi;
     minorSize = if isRow then size.columns else size.rows fi;
@@ -223,24 +242,10 @@
 toSparse m =
     if isSparse? m then m
     else
-        { rows, columns } = size m;
-        enumerate m ii jj =
-            case ii of
-            i::irest:
-                case jj of
-                j::rest:
-                    v = getAt i j m;
-                    if v != 0 then { i, j, v } :. \(enumerate m ii rest)
-                    else enumerate m ii rest
-                    fi;
-                 _: enumerate m irest [0..columns-1];
-                esac;
-             _: [];
-            esac;
         makeSparse 
             if isRowMajor? m then RowMajor () else ColumnMajor () fi
                (size m)
-               (enumerate m [0..rows-1] [0..columns-1]);
+               (enumerateDense m);
     fi;
 
 toDense m =
@@ -582,7 +587,8 @@
     newMatrix,
     newRowVector,
     newColumnVector,
-    newSparseMatrix = makeSparse
+    newSparseMatrix = makeSparse,
+    enumerate
 }
 as
 {
@@ -627,6 +633,7 @@
     newMatrix is (ColumnMajor () | RowMajor ()) -> list<vector> -> matrix, 
     newRowVector is vector -> matrix, 
     newColumnVector is vector -> matrix,
-    newSparseMatrix is (ColumnMajor () | RowMajor ()) -> { .rows is number, .columns is number } -> list<{ .i is number, .j is number, .v is number }> -> matrix
+    newSparseMatrix is (ColumnMajor () | RowMajor ()) -> { .rows is number, .columns is number } -> list<{ .i is number, .j is number, .v is number }> -> matrix,
+    enumerate is matrix -> list<{ .i is number, .j is number, .v is number }>
 }
 
--- a/yetilab/matrix/test/test_matrix.yeti	Tue May 21 14:29:22 2013 +0100
+++ b/yetilab/matrix/test/test_matrix.yeti	Tue May 21 21:58:34 2013 +0100
@@ -405,6 +405,48 @@
         compare (mat.density (mat.thresholded 2 m)) (3/9)
 ),
 
+"newSparseMatrix-\(name)": \(
+    s = mat.newSparseMatrix (ColumnMajor ()) { rows = 2, columns = 3 } [
+        { i = 0, j = 0, v = 1 },
+        { i = 0, j = 2, v = 2 },
+        { i = 1, j = 1, v = 4 },
+    ];
+    // If there are zeros in the entries list, they should not end up
+    // in the sparse data
+    t = mat.newSparseMatrix (ColumnMajor ()) { rows = 2, columns = 3 } [
+        { i = 0, j = 0, v = 1 },
+        { i = 0, j = 2, v = 0 },
+        { i = 1, j = 1, v = 4 },
+    ];
+    compare (mat.density s) (3/6) and
+        compare (mat.density t) (2/6) and
+        compareMatrices s (newMatrix (RowMajor ()) [[1,0,2],[0,4,0]]) and
+        compareMatrices t (newMatrix (RowMajor ()) [[1,0,0],[0,4,0]])
+),
+
+"enumerate-\(name)": \(
+    m = newMatrix (ColumnMajor ()) [[1,2,0],[-1,-4,6],[0,0,3]];
+    all = [
+        { i = 0, j = 0, v = 1 },
+        { i = 1, j = 0, v = 2 },
+        { i = 2, j = 0, v = 0 },
+        { i = 0, j = 1, v = -1 },
+        { i = 1, j = 1, v = -4 },
+        { i = 2, j = 1, v = 6 },
+        { i = 0, j = 2, v = 0 },
+        { i = 1, j = 2, v = 0 },
+        { i = 2, j = 2, v = 3 },
+    ];
+    sortEntries = 
+        sortBy do a b:
+            if a.i == b.i then a.j < b.j else a.i < b.i fi
+        done;
+    compare
+       (sortEntries (mat.enumerate m))
+       (sortEntries 
+           (if mat.isSparse? m then filter do d: d.v != 0 done all else all fi));
+),
+
 ]);
 
 colhash = makeTests "column-dense" id;