Mercurial > hg > may
changeset 234:51c5ce72832e sparse
Embark on sparse-matrix support
author | Chris Cannam |
---|---|
date | Sun, 19 May 2013 19:16:18 +0100 |
parents | 545a32830886 |
children | 619061a34099 |
files | yetilab/matrix/matrix.yeti yetilab/matrix/matrixtype.yeti |
diffstat | 2 files changed, 72 insertions(+), 44 deletions(-) [+] |
line wrap: on
line diff
--- a/yetilab/matrix/matrix.yeti Sun May 19 18:42:10 2013 +0100 +++ b/yetilab/matrix/matrix.yeti Sun May 19 19:16:18 2013 +0100 @@ -19,18 +19,28 @@ size m = case m of - RowM r: + DenseRows r: major = length r; { rows = major, columns = if major > 0 then vec.length r[0] else 0 fi, }; - ColM c: + DenseCols c: major = length c; { rows = if major > 0 then vec.length c[0] else 0 fi, columns = major, }; + SparseCSR { values, coli, rowp, cols }: + { + rows = (length rowp) - 1, + columns = cols + }; + SparseCSC { values, rowi, colp, rows }: + { + rows, + columns = (length colp) - 1 + }; esac; width m = (size m).columns; @@ -38,34 +48,36 @@ getAt row col m = case m of - RowM rows: r = rows[row]; vec.at col r; - ColM cols: c = cols[col]; vec.at row c; + DenseRows rows: r = rows[row]; vec.at col r; + DenseCols cols: c = cols[col]; vec.at row c; esac; getColumn j m = case m of - RowM rows: vec.fromList (map do i: getAt i j m done [0..length rows-1]); - ColM cols: cols[j]; + DenseRows rows: vec.fromList (map do i: getAt i j m done [0..length rows-1]); + DenseCols cols: cols[j]; esac; getRow i m = case m of - RowM rows: rows[i]; - ColM cols: vec.fromList (map do j: getAt i j m done [0..length cols-1]); + DenseRows rows: rows[i]; + DenseCols cols: vec.fromList (map do j: getAt i j m done [0..length cols-1]); esac; -/* -setAt row col n m = //!!! dangerous, could modify copies -- should it be allowed? - case m of - RowM rows: r = rows[row]; (vec.data r)[col] := n; - ColM cols: c = cols[col]; (vec.data c)[row] := n; - esac; -*/ - isRowMajor? m = case m of - RowM _: true; - ColM _: false; + DenseRows _: true; + DenseCols _: false; + SparseCSR _: true; + SparseCSC _: false; + esac; + +isSparse? m = + case m of + DenseRows _: false; + DenseCols _: false; + SparseCSR _: true; + SparseCSC _: true; esac; newColMajorStorage { rows, columns } = @@ -74,13 +86,13 @@ fi; zeroMatrix { rows, columns } = - ColM (newColMajorStorage { rows, columns }); + DenseCols (newColMajorStorage { rows, columns }); zeroMatrixWithTypeOf m { rows, columns } = if isRowMajor? m then - RowM (newColMajorStorage { rows = columns, columns = rows }); + DenseRows (newColMajorStorage { rows = columns, columns = rows }); else - ColM (newColMajorStorage { rows, columns }); + DenseCols (newColMajorStorage { rows, columns }); fi; zeroSizeMatrix () = zeroMatrix { rows = 0, columns = 0 }; @@ -94,7 +106,7 @@ m[col][row] := f row col; done; done; - ColM (array (map vec.vector m)) + DenseCols (array (map vec.vector m)) fi; constMatrix n = generate do row col: n done; @@ -103,8 +115,12 @@ transposed m = case m of - RowM d: ColM d; - ColM d: RowM d; + 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 }; esac; flipped m = @@ -130,8 +146,8 @@ else compare d1 d2 = all id (map2 vecComparator d1 d2); case m1 of - RowM d1: case m2 of RowM d2: compare d1 d2; _: false; esac; - ColM d1: case m2 of ColM d2: compare d1 d2; _: false; esac; + DenseRows d1: case m2 of DenseRows d2: compare d1 d2; _: false; esac; + DenseCols d1: case m2 of DenseCols d2: compare d1 d2; _: false; esac; esac fi; @@ -148,23 +164,23 @@ copyOf m = (copyOfData d = (array (map vec.copyOf d)); case m of - RowM d: RowM (copyOfData d); - ColM d: ColM (copyOfData d); + DenseRows d: DenseRows (copyOfData d); + DenseCols d: DenseCols (copyOfData d); esac); */ newMatrix type data = //!!! NB does not copy data - (tagger = case type of RowMajor (): RowM; ColumnMajor (): ColM esac; + (tagger = case type of RowMajor (): RowM; ColumnMajor (): DenseCols esac; if empty? data or vec.empty? (head data) then zeroSizeMatrix () else tagger (array data) fi); newRowVector data = //!!! NB does not copy data - RowM (array [data]); + DenseRows (array [data]); newColumnVector data = //!!! NB does not copy data - ColM (array [data]); + DenseCols (array [data]); scaled factor m = //!!! v inefficient generate do row col: factor * (getAt row col m) done (size m); @@ -235,12 +251,12 @@ // 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; + if row then concatAgainstGrain DenseRows getRow (.rows) mm; + else concatWithGrain DenseCols getColumn (.columns) mm; fi; Vertical (): - if row then concatWithGrain RowM getRow (.rows) mm; - else concatAgainstGrain ColM getColumn (.columns) mm; + if row then concatWithGrain DenseRows getRow (.rows) mm; + else concatAgainstGrain DenseCols getColumn (.columns) mm; fi; esac; [single]: single; @@ -249,16 +265,16 @@ rowSlice start count m = //!!! doc: storage order same as input if isRowMajor? m then - RowM (array (map ((flip getRow) m) [start .. start + count - 1])) + DenseRows (array (map ((flip getRow) m) [start .. start + count - 1])) else - ColM (array (map (vec.rangeOf start count) (asColumns m))) + DenseCols (array (map (vec.rangeOf start count) (asColumns m))) fi; columnSlice start count m = //!!! doc: storage order same as input if not isRowMajor? m then - ColM (array (map ((flip getColumn) m) [start .. start + count - 1])) + DenseCols (array (map ((flip getColumn) m) [start .. start + count - 1])) else - RowM (array (map (vec.rangeOf start count) (asRows m))) + DenseRows (array (map (vec.rangeOf start count) (asRows m))) fi; resizedTo newsize m = @@ -297,8 +313,8 @@ getAt, getColumn, getRow, -// setAt, isRowMajor?, + isSparse?, generate, constMatrix, randomMatrix, @@ -307,7 +323,6 @@ zeroSizeMatrix, equal, equalUnder, -// copyOf, transposed, flipped, toRowMajor, @@ -337,8 +352,8 @@ getAt is number -> number -> matrix -> number, getColumn is number -> matrix -> vector, getRow is number -> matrix -> vector, -// setAt is number -> number -> number -> matrix -> (), //!!! lose? isRowMajor? is matrix -> boolean, + isSparse? is matrix -> boolean, generate is (number -> number -> number) -> { .rows is number, .columns is number } -> matrix, constMatrix is number -> { .rows is number, .columns is number } -> matrix, randomMatrix is { .rows is number, .columns is number } -> matrix, @@ -347,7 +362,6 @@ zeroSizeMatrix is () -> matrix, equal is matrix -> matrix -> boolean, equalUnder is (number -> number -> boolean) -> matrix -> matrix -> boolean, -// copyOf is matrix -> matrix, transposed is matrix -> matrix, flipped is matrix -> matrix, toRowMajor is matrix -> matrix,
--- a/yetilab/matrix/matrixtype.yeti Sun May 19 18:42:10 2013 +0100 +++ b/yetilab/matrix/matrixtype.yeti Sun May 19 19:16:18 2013 +0100 @@ -3,7 +3,21 @@ load yetilab.vector.vectortype; -typedef opaque matrix = RowM. array<vector> | ColM. array<vector>; +typedef opaque matrix = + DenseRows. array<vector> | + DenseCols. array<vector> | + SparseCSR. { + .values is vector, + .coli is array<number>, + .rowp is array<number>, + .cols is number + } | + SparseCSC. { + .values is vector, + .rowi is array<number>, + .colp is array<number>, + .rows is number + }; ();