Add submatrix_set and block_matrix and tests

This commit is contained in:
Adrian Mariano 2020-09-01 16:42:47 -04:00
parent 0a5af2f710
commit 8f6c2e8538
2 changed files with 61 additions and 0 deletions

View File

@ -1199,6 +1199,42 @@ function zip(vecs, v2, v3, fit=false, fill=undef) =
: [for(i=[0:1:minlen-1]) [for(v=vecs) for(x=v[i]) x] ];
// Function: block_matrix()
// Usage:
// block_matrix([[M11, M12,...],[M21, M22,...], ... ])
// Description:
// Create a block matrix by supplying a matrix of matrices, which will
// be combined into one unified matrix. Every matrix in one row
// must have the same height, and the combined width of the matrices
// in each row must be equal.
function block_matrix(M) =
let(
bigM = [for(bigrow = M) each zip(bigrow)],
len0=len(bigM[0]),
badrows = [for(row=bigM) if (len(row)!=len0) 1]
)
assert(badrows==[], "Inconsistent or invalid input")
bigM;
// Function: submatrix_set()
// Usage: submatrix_set(M,A,[m],[n])
// Description:
// Sets a submatrix of M equal to the matrix A. By default the top left corner of M is set to A, but
// you can specify offset coordinates m and n. If A (as adjusted by m and n) extends beyond the bounds
// of M then the extra entries are ignored. You can pass in A=[[]], a null matrix, and M will be
// returned unchanged. Note that the input M need not be rectangular in shape.
function submatrix_set(M,A,m=0,n=0) =
assert(is_list(M))
assert(is_list(A))
let( badrows = [for(i=idx(A)) if (!is_list(A[i])) i])
assert(badrows==[], str("Input submatrix malformed rows: ",badrows))
[for(i=[0:1:len(M)-1])
assert(is_list(M[i]), str("Row ",i," of input matrix is not a list"))
[for(j=[0:1:len(M[i])-1])
i>=m && i <len(A)+m && j>=n && j<len(A[0])+n ? A[i-m][j-n] : M[i][j]]];
// Function: array_group()
// Description:
// Takes a flat array of values, and groups items in sets of `cnt` length.

View File

@ -470,6 +470,31 @@ module test_zip() {
}
test_zip();
module test_block_matrix() {
A = [[1,2],[3,4]];
B = ident(2);
assert_equal(block_matrix([[A,B],[B,A],[A,B]]), [[1,2,1,0],[3,4,0,1],[1,0,1,2],[0,1,3,4],[1,2,1,0],[3,4,0,1]]);
assert_equal(block_matrix([[A,B],ident(4)]), [[1,2,1,0],[3,4,0,1],[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]);
text = [["a","b"],["c","d"]];
assert_equal(block_matrix([[text,B]]), [["a","b",1,0],["c","d",0,1]]);
}
test_block_matrix();
module test_submatrix_set() {
test = [[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15], [16,17,18,19,20]];
ragged = [[1,2,3,4,5],[6,7,8,9,10],[11,12], [16,17]];
assert_equal(submatrix_set(test,[[9,8],[7,6]]), [[9,8,3,4,5],[7,6,8,9,10],[11,12,13,14,15], [16,17,18,19,20]]);
assert_equal(submatrix_set(test,[[9,7],[8,6]],1),[[1,2,3,4,5],[9,7,8,9,10],[8,6,13,14,15], [16,17,18,19,20]]);
assert_equal(submatrix_set(test,[[9,8],[7,6]],n=1), [[1,9,8,4,5],[6,7,6,9,10],[11,12,13,14,15], [16,17,18,19,20]]);
assert_equal(submatrix_set(test,[[9,8],[7,6]],1,2), [[1,2,3,4,5],[6,7,9,8,10],[11,12,7,6,15], [16,17,18,19,20]]);
assert_equal(submatrix_set(test,[[9,8],[7,6]],-1,-1), [[6,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15], [16,17,18,19,20]]);
assert_equal(submatrix_set(test,[[9,8],[7,6]],n=4), [[1,2,3,4,9],[6,7,8,9,7],[11,12,13,14,15], [16,17,18,19,20]]);
assert_equal(submatrix_set(test,[[9,8],[7,6]],7,7), [[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15], [16,17,18,19,20]]);
assert_equal(submatrix_set(ragged, [["a","b"],["c","d"]], 1, 1), [[1,2,3,4,5],[6,"a","b",9,10],[11,"c"], [16,17]]);
}
test_submatrix_set();
module test_array_group() {
v = [1,2,3,4,5,6];