Mercurial > hg > may
diff yetilab/matrix/matrix.yeti @ 259:fae62dca8048
Make concat also return sparse when all its inputs are sparse
author | Chris Cannam |
---|---|
date | Wed, 22 May 2013 09:22:10 +0100 |
parents | f3b7b5d20f88 |
children | de770971a628 |
line wrap: on
line diff
--- a/yetilab/matrix/matrix.yeti Wed May 22 08:56:51 2013 +0100 +++ b/yetilab/matrix/matrix.yeti Wed May 22 09:22:10 2013 +0100 @@ -9,8 +9,6 @@ // result regardless of storage order. (The transpose function just // switches the row/column order without moving the elements.) -//!!! check that we are not unnecessarily copying in the transform functions - vec = load yetilab.vector.vector; bf = load yetilab.vector.blockfuncs; @@ -536,6 +534,27 @@ map do i: getter i m done [0..n-1] done mm))); +sparseConcat direction first mm = + (dimension d f = if direction == d then sum (map f mm) else f first fi; + rows = dimension (Vertical ()) height; + columns = dimension (Horizontal ()) width; + entries ioff joff ui uj mm = + case mm of + m::rest: + (map do { i, j, v }: { i = i + ioff, j = j + joff, v } + done (enumerate m)) ++ + (entries + (ioff + ui * height m) + (joff + uj * width m) + ui uj rest); + _: [] + esac; + makeSparse + if isRowMajor? first then (RowMajor ()) else (ColumnMajor ()) fi + { rows, columns } + if direction == Vertical () then entries 0 0 1 0 mm + else entries 0 0 0 1 mm fi); + checkDimensionsFor direction first mm = (counter = if direction == Horizontal () then (.rows) else (.columns) fi; n = counter (size first); @@ -545,26 +564,31 @@ concat direction mm = //!!! doc: storage order is taken from first matrix in sequence //!!! would this be better as separate concatHorizontal/concatVertical functions? - case mm of - first::rest: + case length mm of + 0: zeroSizeMatrix (); + 1: head mm; + _: + first = head mm; checkDimensionsFor direction first mm; - row = isRowMajor? first; - // 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 DenseRows getRow (.rows) mm; - else concatWithGrain DenseCols getColumn (.columns) mm; - fi; - Vertical (): - if row then concatWithGrain DenseRows getRow (.rows) mm; - else concatAgainstGrain DenseCols getColumn (.columns) mm; - fi; - esac; - [single]: single; - _: zeroSizeMatrix (); + if all isSparse? mm then + sparseConcat direction first mm + else + row = isRowMajor? first; + // 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 DenseRows getRow (.rows) mm; + else concatWithGrain DenseCols getColumn (.columns) mm; + fi; + Vertical (): + if row then concatWithGrain DenseRows getRow (.rows) mm; + else concatAgainstGrain DenseCols getColumn (.columns) mm; + fi; + esac; + fi; esac; //!!! inconsistent with std.slice which has start..end not start+count (see also vec.slice/rangeOf)