changeset 236:ccca84efa36a sparse

Extract values and slices (rows, columns) from sparse matrices
author Chris Cannam
date Sun, 19 May 2013 22:16:02 +0100
parents 619061a34099
children 601dbfcf949d
files yetilab/matrix/matrix.yeti yetilab/matrix/matrixtype.yeti yetilab/vector/vector.yeti
diffstat 3 files changed, 57 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/yetilab/matrix/matrix.yeti	Sun May 19 21:13:48 2013 +0100
+++ b/yetilab/matrix/matrix.yeti	Sun May 19 22:16:02 2013 +0100
@@ -31,37 +31,67 @@
             rows = if major > 0 then vec.length c[0] else 0 fi,
             columns = major, 
         };
-    SparseCSR { values, coli, rowp, cols }:
+    SparseCSR { values, indices, pointers, cols }:
         {
-            rows = (length rowp) - 1,
+            rows = (length pointers) - 1,
             columns = cols
         };
-    SparseCSC { values, rowi, colp, rows }:
+    SparseCSC { values, indices, pointers, rows }:
         {
             rows,
-            columns = (length colp) - 1
+            columns = (length pointers) - 1
         };
     esac;
 
 width m = (size m).columns;
 height m = (size m).rows;
 
+sparseSlice n d =
+   (start = d.pointers[n];
+    end = d.pointers[n+1];
+    { 
+        values = vec.slice d.values start end,
+        indices = slice d.indices start d.pointers[n+1],
+    });
+
+fromSlice n m d =
+   (slice = sparseSlice n d;
+    var v = 0;
+    for [0..length slice.indices - 1] do i:
+        if slice.indices[i] == m then
+            v := vec.at i slice.values;
+        fi
+    done;
+    v);
+
+filledSlice n d =
+   (slice = sparseSlice n d;
+    dslice = new double[d.extent];
+    \() (map2 do v i:
+             dslice[i] := v
+         done (vec.list slice.values) (list slice.indices));
+    vec.vector dslice);
+
 getAt row col m =
     case m of
     DenseRows rows: r = rows[row]; vec.at col r;
     DenseCols cols: c = cols[col]; vec.at row c;
+    SparseCSR data: fromSlice row col data;
+    SparseCSC data: fromSlice col row data;
     esac;
 
 getColumn j m =
     case m of
-    DenseRows rows: vec.fromList (map do i: getAt i j m done [0..length rows-1]);
     DenseCols cols: cols[j];
+    SparseCSC data: filledSlice j data;
+    _: vec.fromList (map do i: getAt i j m done [0..height m - 1]);
     esac;
 
 getRow i m =
     case m of
     DenseRows rows: rows[i];
-    DenseCols cols: vec.fromList (map do j: getAt i j m done [0..length cols-1]);
+    SparseCSR data: filledSlice i data; 
+    _: vec.fromList (map do j: getAt i j m done [0..width m - 1]);
     esac;
 
 isRowMajor? m =
@@ -121,19 +151,19 @@
          _: [];
         esac;
     case m of
-    SparseCSC { values, rowi, colp, rows }: 
-        enumerate (list values) rowi (list colp) 0 0;
-    SparseCSR { values, coli, rowp, rows }:
+    SparseCSC { values, indices, pointers, rows }: 
+        enumerate (vec.list values) indices (list pointers) 0 0;
+    SparseCSR { values, indices, pointers, rows }:
         map do { i, j, v }: { i = j, j = i, v } done 
-           (enumerate (list values) coli (list rowp) 0 0);
+           (enumerate (vec.list values) indices (list pointers) 0 0);
     esac);
 
 makeSparse type data =
     case type of
     RowMajor (): 
-        SparseCSR { values = vec.zeros 0, coli = array [], rowp = array [] };
+        SparseCSR { values = vec.zeros 0, indices = array [], pointers = array [] };
     ColMajor (): 
-        SparseCSC { values = vec.zeros 0, rowi = array [], colp = array [] };
+        SparseCSC { values = vec.zeros 0, indices = array [], pointers = array [] };
     esac;
 
 constMatrix n = generate do row col: n done;
@@ -144,10 +174,8 @@
     case m of
     DenseRows d: DenseCols d;
     DenseCols d: DenseRows d;
-    SparseCSR { values, coli, rowp, cols }:
-        SparseCSC { values, rowi = coli, colp = rowp, rows = cols };
-    SparseCSC { values, rowi, colp, rows }:
-        SparseCSR { values, coli = rowi, rowp = colp, cols = rows };
+    SparseCSR d: SparseCSC d;
+    SparseCSC d: SparseCSR d;
     esac;
 
 flipped m =
--- a/yetilab/matrix/matrixtype.yeti	Sun May 19 21:13:48 2013 +0100
+++ b/yetilab/matrix/matrixtype.yeti	Sun May 19 22:16:02 2013 +0100
@@ -4,19 +4,19 @@
 load yetilab.vector.vectortype;
 
 typedef opaque matrix =
-    DenseRows. array<vector> | 
-    DenseCols. array<vector> |
+    DenseRows. array<vector> | // array of rows
+    DenseCols. array<vector> | // array of columns
     SparseCSR. {
         .values is vector,
-        .coli is array<number>,
-        .rowp is array<number>,
-        .cols is number
+        .indices is array<number>, // column index of each value
+        .pointers is array<number>, // offset of first value in each row
+        .extent is number // max possible index + 1, i.e. number of columns
         } |
     SparseCSC. {
         .values is vector,
-        .rowi is array<number>,
-        .colp is array<number>,
-        .rows is number
+        .indices is array<number>, // row index of each value
+        .pointers is array<number>, // offset of first value in each column
+        .extent is number // max pointers index + 1, i.e. number of rows
         };
 
 ();
--- a/yetilab/vector/vector.yeti	Sun May 19 21:13:48 2013 +0100
+++ b/yetilab/vector/vector.yeti	Sun May 19 22:16:02 2013 +0100
@@ -72,6 +72,9 @@
 rangeOf start len v is number -> number -> ~double[] -> ~double[] =
     Arrays#copyOfRange(v, start, start + len);
 
+slice v start end is ~double[] -> number -> number -> ~double[] =
+    rangeOf start (end - start) v;
+
 resizedTo n v is number -> ~double[] -> ~double[] =
     Arrays#copyOf(v, n);
 
@@ -103,6 +106,7 @@
     equal,
     equalUnder,
     rangeOf,
+    slice,
     resizedTo,
     concat,
 } as {
@@ -122,6 +126,7 @@
     equal is vector -> vector -> boolean,
     equalUnder is (number -> number -> boolean) -> vector -> vector -> boolean,
     rangeOf is number -> number -> vector -> vector, //!!! not well-named now vector arg is at the end
+    slice is vector -> number -> number -> vector, //!!! duplication with rangeOf (std module function on arrays is called slice though)
     resizedTo is number -> vector -> vector,
     concat is list?<vector> -> vector,
 }