changeset 178:032c4986b6b0

Implement and test matrix concat
author Chris Cannam
date Thu, 02 May 2013 21:58:58 +0100
parents 370d9350495c
children a1069ed26740
files yetilab/matrix/matrix.yeti yetilab/matrix/test/test_matrix.yeti
diffstat 2 files changed, 61 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/yetilab/matrix/matrix.yeti	Thu May 02 21:05:10 2013 +0100
+++ b/yetilab/matrix/matrix.yeti	Thu May 02 21:58:58 2013 +0100
@@ -173,29 +173,48 @@
 asColumns m =
     map m.getColumn [0 .. m.size.columns - 1];
 
-concatAgainstGrain tagger getter n mm =
+concatAgainstGrain tagger getter counter mm =
+   (n = counter (head mm).size;
     make (tagger (array
        (map do i:
            block.data (block.concat (map do m: getter m i done mm))
-           done [0..n-1])));
+           done [0..n-1]))));
 
-concatWithGrain tagger getter n mm =
+concatWithGrain tagger getter counter mm =
     make (tagger (array
        (concat
            (map do m:
-               map do i: getter m i done [0..n-1]
+               n = counter m.size;
+               map do i: block.data (getter m i) done [0..n-1]
                done mm))));
 
+checkDimensionsFor direction first mm =
+   (counter = if direction == Horizontal () then (.rows) else (.columns) fi;
+    n = counter first.size;
+    if not (all id (map do m: counter m.size == n done mm)) then
+        failWith "Matrix dimensions incompatible for concat (found \(map do m: counter m.size done mm) not all of which are \(n))";
+    fi);
+
 concat direction mm = //!!! storage order is taken from first matrix in sequence
     if empty? mm then zeroSizeMatrix ()
     else
-        nrows = (head mm).size.rows;
-        tagger = if (head mm).isRowMajor? then RowM else ColM fi;
-        if not (all id (map do m: m.size.rows == nrows done mm)) then
-            failWith "Matrix dimensions incompatible: not all have \(nrows) rows"
-        else
-            concatWithGrain tagger (.getRow) nrows mm;
-        fi
+        first = head mm;
+        checkDimensionsFor direction first mm;
+        row = first.isRowMajor?;
+        // horizontal, row-major: against grain with rows
+        // horizontal, col-major: with grain with cols
+        // vertical, row-major: with grain with rows
+        // vertical, col-major: against grain with cols
+        case direction of
+        Horizontal ():
+            if row then concatAgainstGrain RowM (.getRow) (.rows) mm;
+            else concatWithGrain ColM (.getColumn) (.columns) mm;
+            fi;
+        Vertical ():
+            if row then concatWithGrain RowM (.getRow) (.rows) mm;
+            else concatAgainstGrain ColM (.getColumn) (.columns) mm;
+            fi;
+        esac;
     fi;
 
 {
--- a/yetilab/matrix/test/test_matrix.yeti	Thu May 02 21:05:10 2013 +0100
+++ b/yetilab/matrix/test/test_matrix.yeti	Thu May 02 21:58:58 2013 +0100
@@ -278,7 +278,7 @@
         [[1,4],[2,5],[3,6]];
 ),
 
-"concat-lr-\(name)": \(
+"concat-horiz-\(name)": \(
     compareMatrices
        (mat.concat (Horizontal ()) 
           [(newMatrix (ColumnMajor ()) [[1,4],[2,5]]),
@@ -286,6 +286,36 @@
        (newMatrix (ColumnMajor ()) [[1,4],[2,5],[3,6]])
 ),
 
+"concatFail-horiz-\(name)": \(
+    try
+        \() (mat.concat (Horizontal ()) 
+          [(newMatrix (ColumnMajor ()) [[1,4],[2,5]]),
+           (newMatrix (ColumnMajor ()) [[3],[6]])]);
+        false
+    catch FailureException e:
+        true
+    yrt
+),
+
+"concat-vert-\(name)": \(
+    compareMatrices
+       (mat.concat (Vertical ()) 
+          [(newMatrix (ColumnMajor ()) [[1,4],[2,5]]),
+           (newMatrix (RowMajor ()) [[3,6]])])
+       (newMatrix (ColumnMajor ()) [[1,4,3],[2,5,6]])
+),
+
+"concatFail-vert-\(name)": \(
+    try
+        \() (mat.concat (Vertical ()) 
+          [(newMatrix (ColumnMajor ()) [[1,4],[2,5]]),
+           (newMatrix (RowMajor ()) [[3],[6]])]);
+        false
+    catch FailureException e:
+        true
+    yrt
+),
+
 ]);
 
 colhash = makeTests "column-major" id;