view yetilab/matrix/test/test_matrix.yeti @ 254:5eb57c649de0 sparse

Using hashes is simpler, but turns out to be mostly no faster and sometimes much slower. Not one to merge back.
author Chris Cannam
date Tue, 21 May 2013 17:40:33 +0100
parents 9fe3192cce38
children 8043f7405eae
line wrap: on
line source

module yetilab.matrix.test.test_matrix;

mat = load yetilab.matrix.matrix;
vec = load yetilab.vector.vector;

load yetilab.vector.vectortype;
load yetilab.matrix.matrixtype;

import yeti.lang: FailureException;

{ compare, compareUsing } = load yetilab.test.test;

compareMatrices = compareUsing mat.equal;

makeTests name flipper =
   (constMatrix n s = flipper (mat.constMatrix n s);
    zeroMatrix s = flipper (mat.zeroMatrix s);
    randomMatrix s = flipper (mat.randomMatrix s);
    identityMatrix s = flipper (mat.identityMatrix s);
    generate f s = flipper (mat.generate f s);
    newMatrix t d = flipper (mat.newMatrix t (map vec.fromList d));
[

"constMatrixEmpty-\(name)": \(
    m = constMatrix 2 { rows = 0, columns = 0 };
    compare (mat.size m) { columns = 0, rows = 0 }
),

"constMatrixEmpty2-\(name)": \(
    compare (mat.size (constMatrix 2 { rows = 0, columns = 4 })) { columns = 0, rows = 0 } and
        compare (mat.size (constMatrix 2 { rows = 4, columns = 0 })) { columns = 0, rows = 0 }
),

"constMatrix-\(name)": \(
    m = constMatrix 2 { rows = 3, columns = 4 };
    compare (mat.size m) { columns = 4, rows = 3 } and
        all id (map do row: compare (vec.list (mat.getRow row m)) [2,2,2,2] done [0..2]) and
        all id (map do col: compare (vec.list (mat.getColumn col m)) [2,2,2] done [0..3])
),

"randomMatrixEmpty-\(name)": \(
    m = randomMatrix { rows = 0, columns = 0 };
    compare (mat.size m) { columns = 0, rows = 0 }
),

"randomMatrix-\(name)": \(
    m = randomMatrix { rows = 3, columns = 4 };
    compare (mat.size m) { columns = 4, rows = 3 }
),

"zeroMatrixEmpty-\(name)": \(
    m = zeroMatrix { rows = 0, columns = 0 };
    compare (mat.size m) { columns = 0, rows = 0 }
),

"zeroMatrix-\(name)": \(
    m = zeroMatrix { rows = 3, columns = 4 };
    compare (mat.size m) { columns = 4, rows = 3 } and
        all id (map do row: compare (vec.list (mat.getRow row m)) [0,0,0,0] done [0..2]) and
        all id (map do col: compare (vec.list (mat.getColumn col m)) [0,0,0] done [0..3])
),

"identityMatrixEmpty-\(name)": \(
    m = identityMatrix { rows = 0, columns = 0 };
    compare (mat.size m) { columns = 0, rows = 0 }
),

"identityMatrix-\(name)": \(
    m = identityMatrix { rows = 3, columns = 4 };
    compare (mat.size m) { columns = 4, rows = 3 } and
        all id (map do row: compare (vec.list (mat.getRow row m)) [1,1,1,1] done [0..2]) and
        all id (map do col: compare (vec.list (mat.getColumn col m)) [1,1,1] done [0..3])
),

"generateEmpty-\(name)": \(
    m = generate do row col: 0 done { rows = 0, columns = 0 };
    compare (mat.size m) { columns = 0, rows = 0 }
),

"generate-\(name)": \(
    m = generate do row col: row * 10 + col done { rows = 2, columns = 3 };
    compare (vec.list (mat.getRow 0 m)) [0,1,2] and
        compare (vec.list (mat.getRow 1 m)) [10,11,12]
),

"widthAndHeight-\(name)": \(
    m = constMatrix 2 { rows = 3, columns = 4 };
    compare (mat.size m) { columns = mat.width m, rows = mat.height m }
),

"equal-\(name)": \(
    m = newMatrix (ColumnMajor ()) [[1,4],[0,5],[3,6]];
    n = m;
    p = newMatrix (RowMajor ()) [[1,0,3],[4,5,6]];
    q = newMatrix (ColumnMajor ()) [[1,0,3],[4,5,6]];
    r = newMatrix (ColumnMajor ()) [[1,4],[0,5]];
    compareMatrices m n and
        compareMatrices m p and
        compareMatrices n p and
        not mat.equal m q and
        not mat.equal m r
),

"equalUnder-\(name)": \(
    p = newMatrix (ColumnMajor ()) [[1,2,3],[4,5,6]];
    q = newMatrix (ColumnMajor ()) [[1,2,3],[4,5,6]];
    r = newMatrix (ColumnMajor ()) [[4,3,1],[3,1,2]];
    s = newMatrix (ColumnMajor ()) [[1,4,5],[6,7,8]];
    t = newMatrix (ColumnMajor ()) [[1,4,5],[6,7,9]];
    mat.equalUnder (==) p p and
        mat.equalUnder (==) p q and
        mat.equalUnder (!=) p r and
        mat.equalUnder do a b: a % 2 == b % 2 done p s and
        not mat.equalUnder do a b: a % 2 == b % 2 done p t
),

"getAt-\(name)": \(
    generator row col = row * 10 + col;
    m = generate generator { rows = 2, columns = 3 };
    all id
       (map do row: all id
           (map do col: mat.getAt row col m == generator row col done [0..2])
            done [0..1])
),

"transposedEmpty-\(name)": \(
    compare (mat.size (mat.transposed (constMatrix 2 { rows = 0, columns = 0 }))) { columns = 0, rows = 0 } and
        compare (mat.size (mat.transposed (constMatrix 2 { rows = 0, columns = 4 }))) { columns = 0, rows = 0 } and
        compare (mat.size (mat.transposed (constMatrix 2 { rows = 4, columns = 0 }))) { columns = 0, rows = 0 }
),

"transposedSize-\(name)": \(
    compare (mat.size (mat.transposed (constMatrix 2 { rows = 3, columns = 4 }))) { columns = 3, rows = 4 }
),

"transposed-\(name)": \(
    generator row col = row * 10 + col;
    m = generate generator { rows = 2, columns = 3 };
    m' = mat.transposed m;
    all id
       (map do row: all id
           // like getAt test, but with col/row flipped
           (map do col: mat.getAt col row m' == generator row col done [0..2])
            done [0..1])
),

"transposed-back-\(name)": \(
    m = newMatrix (ColumnMajor ()) [[1,4],[2,5],[3,6]];
    compareMatrices m (mat.transposed (mat.transposed m)) and
        not mat.equal m (mat.transposed m);
),

"flipped-\(name)": \(
    m = newMatrix (ColumnMajor ()) [[1,4],[0,5],[3,6]];
    m' = mat.flipped m;
    m'' = newMatrix (RowMajor ()) [[1,0,3],[4,5,6]];
    compareMatrices m m' and compareMatrices m m'' and compareMatrices m' m'';
),

"flipped-back-\(name)": \(
    m = newMatrix (ColumnMajor ()) [[1,4],[0,5],[3,6]];
    compareMatrices m (mat.flipped (mat.flipped m));
),

"flipped-empty-\(name)": \(
    m = constMatrix 2 { rows = 0, columns = 4 };
    compareMatrices (mat.flipped m) (mat.flipped (constMatrix 0 { rows = 0, columns = 0 }));
),

"toRowMajor-\(name)": \(
    m = newMatrix (ColumnMajor ()) [[1,4],[0,5],[3,6]];
    m' = mat.toRowMajor m;
    m'' = newMatrix (RowMajor ()) [[1,0,3],[4,5,6]];
    m''' = mat.toRowMajor m'';
    compareMatrices m m' and compareMatrices m m'' and compareMatrices m' m''
        and compareMatrices m m''';
),

"toColumnMajor-\(name)": \(
    m = newMatrix (RowMajor ()) [[1,4],[0,5],[3,6]];
    m' = mat.toColumnMajor m;
    m'' = newMatrix (ColumnMajor ()) [[1,0,3],[4,5,6]];
    m''' = mat.toColumnMajor m'';
    compareMatrices m m' and compareMatrices m m'' and compareMatrices m' m''
        and compareMatrices m m''';
),

"scaled-\(name)": \(
    compareMatrices
       (mat.scaled 0.5 (constMatrix 2 { rows = 3, columns = 4 }))
       (constMatrix 1 { rows = 3, columns = 4 }) and
       compareMatrices
          (mat.scaled 0.5 (constMatrix (-3) { rows = 3, columns = 4 }))
          (constMatrix (-1.5) { rows = 3, columns = 4 }) and
       compareMatrices
          (mat.scaled 0.5 (constMatrix 2 { rows = 0, columns = 2 }))
          (constMatrix 5 { rows = 0, columns = 0 })
),

"sum-\(name)": \(
    compareMatrices
       (mat.sum (constMatrix 2 { rows = 3, columns = 4 })
                (constMatrix 1 { rows = 3, columns = 4 }))
       (constMatrix 3 { rows = 3, columns = 4 })
),

"sumFail-\(name)": \(
    try 
      \() (mat.sum (constMatrix 2 { rows = 3, columns = 4 })
                   (constMatrix 1 { rows = 3, columns = 5 }));
        false;
    catch FailureException e:
        true
    yrt
),

"difference-\(name)": \(
    compareMatrices
       (mat.difference (constMatrix 2 { rows = 3, columns = 4 })
                       (constMatrix 1 { rows = 3, columns = 4 }))
       (constMatrix 1 { rows = 3, columns = 4 })
),

"differenceFail-\(name)": \(
    try 
      \() (mat.difference (constMatrix 2 { rows = 3, columns = 4 })
                          (constMatrix 1 { rows = 3, columns = 5 }));
        false;
    catch FailureException e:
        true
    yrt
),

"abs-\(name)": \(
    compareMatrices
       (mat.abs (newMatrix (ColumnMajor ()) [[-1,4],[2,-5],[-3,0]]))
       (newMatrix (ColumnMajor ()) [[1,4],[2,5],[3,0]])
),

"product-\(name)": \(
    compareMatrices
       (mat.product (constMatrix 2 { rows = 4, columns = 2 })
                    (constMatrix 3 { rows = 2, columns = 3 }))
       (constMatrix 12 { rows = 4, columns = 3 }) and
        compareMatrices
           (mat.product (newMatrix (ColumnMajor ()) [[1,4],[2,5],[3,6]])
                        (newMatrix (ColumnMajor ()) [[7,9,11],[8,10,12]]))
           (newMatrix (ColumnMajor ()) [[58,139],[64,154]])
),

"sparseProduct-\(name)": \(
    s = mat.newSparseMatrix (ColumnMajor ()) { rows = 2, columns = 3 } [
        { i = 0, j = 0, v = 1 },
        { i = 0, j = 2, v = 2 },
        { i = 1, j = 1, v = 4 },
    ];
    t = mat.newSparseMatrix (ColumnMajor ()) { rows = 3, columns = 2 } [
        { i = 0, j = 1, v = 7 },
        { i = 1, j = 0, v = 5 },
        { i = 2, j = 0, v = 6 },
    ];
    prod = mat.product s t;
    mat.isSparse? prod and
        compareMatrices prod (mat.product (mat.toDense s) t) and
        compareMatrices prod (mat.product (mat.toDense s) (mat.toDense t)) and
        compareMatrices prod (mat.product s (mat.toDense t)) and
        compareMatrices prod 
           (mat.newSparseMatrix (RowMajor ()) { rows = 2, columns = 2 } [
               { i = 0, j = 0, v = 12 },
               { i = 0, j = 1, v = 7 },
               { i = 1, j = 0, v = 20 },
            ])
),

"productFail-\(name)": \(
    try
      \() (mat.product (constMatrix 2 { rows = 4, columns = 2 })
                       (constMatrix 3 { rows = 3, columns = 2 }));
        false;
    catch FailureException e:
        true
    yrt
),

"resizedTo-\(name)": \(
    compareMatrices
       (mat.resizedTo { rows = 2, columns = 2 }
           (newMatrix (ColumnMajor ()) [[1,4],[2,5],[3,6]]))
       (newMatrix (ColumnMajor ()) [[1,4],[2,5]]) and
        compareMatrices
           (mat.resizedTo { rows = 3, columns = 4 }
               (newMatrix (ColumnMajor ()) [[1,4],[2,5],[3,6]]))
           (newMatrix (ColumnMajor ()) [[1,4,0],[2,5,0],[3,6,0],[0,0,0]]) and
        compareMatrices
           (mat.resizedTo { rows = 1, columns = 1 }
               (newMatrix (ColumnMajor ()) [[1,4],[2,5],[3,6]]))
           (newMatrix (RowMajor ()) [[1]]) and
        compareMatrices
           (mat.resizedTo { rows = 2, columns = 3 }
               (mat.zeroSizeMatrix ()))
           (newMatrix (RowMajor ()) [[0,0,0],[0,0,0]])
),

"zeroSizeMatrix-\(name)": \(
    compareMatrices
       (mat.zeroSizeMatrix ())
       (newMatrix (ColumnMajor ()) [])
),

"asRows-\(name)": \(
    compare
       (map vec.list
           (mat.asRows (newMatrix (ColumnMajor ()) [[1,4],[0,5],[3,6]])))
        [[1,0,3],[4,5,6]];
),

"asColumns-\(name)": \(
    compare
       (map vec.list
           (mat.asColumns (newMatrix (ColumnMajor ()) [[1,4],[0,5],[3,6]])))
        [[1,4],[0,5],[3,6]];
),

"concat-horiz-\(name)": \(
    compareMatrices
       (mat.concat (Horizontal ()) 
          [(newMatrix (ColumnMajor ()) [[1,4],[0,5]]),
           (newMatrix (RowMajor ()) [[3],[6]])])
       (newMatrix (ColumnMajor ()) [[1,4],[0,5],[3,6]])
),

"concatFail-horiz-\(name)": \(
    try
        \() (mat.concat (Horizontal ()) 
          [(newMatrix (ColumnMajor ()) [[1,4],[0,5]]),
           (newMatrix (ColumnMajor ()) [[3],[6]])]);
        false
    catch FailureException e:
        true
    yrt
),

"concat-vert-\(name)": \(
    compareMatrices
       (mat.concat (Vertical ()) 
          [(newMatrix (ColumnMajor ()) [[1,4],[0,5]]),
           (newMatrix (RowMajor ()) [[3,6]])])
       (newMatrix (ColumnMajor ()) [[1,4,3],[0,5,6]])
),

"concatFail-vert-\(name)": \(
    try
        \() (mat.concat (Vertical ()) 
          [(newMatrix (ColumnMajor ()) [[1,4],[0,5]]),
           (newMatrix (RowMajor ()) [[3],[6]])]);
        false
    catch FailureException e:
        true
    yrt
),

"rowSlice-\(name)": \(
    compareMatrices
       (mat.rowSlice 1 2 (newMatrix (RowMajor ()) [[1,0],[3,4],[0,6],[7,8]]))
       (newMatrix (RowMajor ()) [[3,4],[0,6]])
),

"columnSlice-\(name)": \(
    compareMatrices
       (mat.columnSlice 1 2 (newMatrix (RowMajor ()) [[1,0,3,4],[0,6,7,8]]))
       (newMatrix (RowMajor ()) [[0,3],[6,7]])
),

"density-\(name)": \(
    compare (mat.density (newMatrix (ColumnMajor ()) [[1,2,0],[0,5,0]])) (3/6) and
        compare (mat.density (newMatrix (ColumnMajor ()) [[1,2,3],[4,5,6]])) (6/6) and
        compare (mat.density (newMatrix (ColumnMajor ()) [[0,0,0],[0,0,0]])) 0
),

"nonZeroValues-\(name)": \(
    compare (mat.nonZeroValues (newMatrix (ColumnMajor ()) [[1,2,0],[0,5,0]])) 3 and
        compare (mat.nonZeroValues (newMatrix (ColumnMajor ()) [[1,2,3],[4,5,6]])) 6 and
        compare (mat.nonZeroValues (newMatrix (ColumnMajor ()) [[0,0,0],[0,0,0]])) 0
),

"toSparse-\(name)": \(
    m = newMatrix (ColumnMajor ()) [[1,2,0],[-1,-4,6],[0,0,3]];
    compareMatrices (mat.toSparse m) m and
        compareMatrices (mat.toDense (mat.toSparse m)) m and
        compare (mat.density (mat.toSparse m)) (6/9)
),

"toDense-\(name)": \(
    m = newMatrix (ColumnMajor ()) [[1,2,0],[-1,-4,6],[0,0,3]];
    compareMatrices (mat.toDense m) m and
        compareMatrices (mat.toSparse (mat.toDense m)) m
),

"thresholded-\(name)": \(
    m = newMatrix (ColumnMajor ()) [[1,2,0],[-1,-4,6],[0,0,3]];
    compareMatrices
       (mat.thresholded 2 m)
       (newMatrix (ColumnMajor ()) [[0,0,0],[0,-4,6],[0,0,3]]) and
        compare (mat.density (mat.thresholded 2 m)) (3/9)
),

]);

colhash = makeTests "column-dense" id;
rowhash = makeTests "row-dense" mat.flipped;
sparsecolhash = makeTests "column-sparse" mat.toSparse;

// there are two possible orders for constructing a sparse row-major
// matrix from a dense col-major one, so test them both:
sparserowhash1 = makeTests "row-sparse-a" (mat.toSparse . mat.flipped);
sparserowhash2 = makeTests "row-sparse-b" (mat.flipped . mat.toSparse);

all = [:];
for [ colhash, rowhash, sparsecolhash, sparserowhash1, sparserowhash2 ] do h:
    for (keys h) do k: all[k] := h[k] done;
done;

all is hash<string, () -> boolean>;