changeset 201:71a09107ee3e

more "scalable" resizedTo
author Chris Cannam
date Mon, 06 May 2013 17:57:43 +0100
parents 12818af285cc
children 9bc6070c041c
files yetilab/matrix/matrix.yeti
diffstat 1 files changed, 38 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/yetilab/matrix/matrix.yeti	Mon May 06 16:56:13 2013 +0100
+++ b/yetilab/matrix/matrix.yeti	Mon May 06 17:57:43 2013 +0100
@@ -60,16 +60,23 @@
         esac,
     };
 
-newStorage { rows, columns } = 
+newColMajorStorage { rows, columns } = 
     if rows < 1 then array []
     else array (map \(vec.zeros rows) [1..columns])
     fi;
 
 zeroMatrix { rows, columns } = 
-    make (ColM (newStorage { rows, columns }));
+    make (ColM (newColMajorStorage { rows, columns }));
+
+zeroMatrixWithTypeOf m { rows, columns } = 
+    if m.isRowMajor? then
+        make (RowM (newColMajorStorage { rows = columns, columns = rows }));
+    else
+        make (ColM (newColMajorStorage { rows, columns }));
+    fi;
 
 generate f { rows, columns } =
-   (m = newStorage { rows, columns };
+   (m = newColMajorStorage { rows, columns };
     for [0..columns-1] do col:
         for [0..rows-1] do row:
             m[col][row] := f row col;
@@ -131,7 +138,7 @@
 newMatrix type data = //!!! NB does not copy data
    (tagger = case type of RowMajor (): RowM; ColumnMajor (): ColM esac;
     if empty? data or block.empty? (head data)
-    then zeroMatrix { rows = 0, columns = 0 }
+    then zeroSizeMatrix ()
     else make (tagger (array (map block.data data)))
     fi);
 
@@ -144,16 +151,6 @@
 scaled factor m = //!!! v inefficient
     generate do row col: factor * m.getAt row col done m.size;
 
-resizedTo newsize m = //!!! also v inefficient
-   (oldsize = m.size;
-    if newsize == oldsize then m
-    else 
-        generate do row col:
-            if row < oldsize.rows and col < oldsize.columns
-            then m.getAt row col else 0 fi
-            done newsize;
-    fi);
-
 sum' m1 m2 =
     if m1.size != m2.size
     then failWith "Matrices are not the same size: \(m1.size), \(m2.size)";
@@ -236,6 +233,33 @@
         make (RowM (array (map (block.data . (block.rangeOf start count)) (asRows m))))
     fi;
 
+resizedTo newsize m =
+    if newsize == m.size then
+        m
+    else
+        growrows = newsize.rows - m.size.rows;
+        growcols = newsize.columns - m.size.columns;
+        rowm = m.isRowMajor?;
+        resizedTo newsize
+            if rowm and growrows < 0 then
+                rowSlice 0 newsize.rows m
+            elif (not rowm) and growcols < 0 then 
+                columnSlice 0 newsize.columns m
+            elif growrows < 0 then 
+                rowSlice 0 newsize.rows m
+            elif growcols < 0 then 
+                columnSlice 0 newsize.columns m
+            else
+                if growrows > 0 then
+                    concat (Vertical ())
+                       [m, zeroMatrixWithTypeOf m (m.size with { rows = growrows })]
+                else
+                    concat (Horizontal ())
+                       [m, zeroMatrixWithTypeOf m (m.size with { columns = growcols })]
+                fi
+            fi
+    fi;
+
 {
     generate is (number -> number -> number) -> { .rows is number, .columns is number } -> matrix,
     constMatrix is number -> { .rows is number, .columns is number } -> matrix,