From 4dcca8743cdf71aceefd1ba3b332bca43eb7759a Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Tue, 21 Jan 2020 16:18:36 -0800 Subject: [PATCH 01/23] Homology progress so far (including SNF computation). --- example/homology.chpl | 399 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 399 insertions(+) create mode 100644 example/homology.chpl diff --git a/example/homology.chpl b/example/homology.chpl new file mode 100644 index 0000000..e184728 --- /dev/null +++ b/example/homology.chpl @@ -0,0 +1,399 @@ +use CHGL; // Includes all core and utility components of CHGL +use Time; // For Timer +use Set; +use Map; +use List; +use Sort; +use Search; +/* + Part 1: Global-View Distributed Data Structures +*/ +// Question: How do we create a toy hypergraph? +// Answer: Generate it! +/* config const numVertices = 4; */ +/* config const numEdges = 10; */ +/* config const edgeProbability = 1; */ +/* var hypergraph = new AdjListHyperGraph(numVertices, numEdges, new unmanaged Cyclic(startIdx=0)); */ +/* var timer = new Timer(); */ +/* timer.start(); */ +/* generateErdosRenyi(hypergraph, edgeProbability); */ +/* timer.stop(); */ +/* writeln("Generated ErdosRenyi with |V|=", numVertices, */ +/* ", |E|=", numEdges, ", P_E=", edgeProbability, " in ", timer.elapsed(), " seconds"); */ + + +/* writeln("Removing duplicates: ", hypergraph.removeDuplicates()); */ +/* hypergraph.removeDuplicates(); */ + +var hypergraph = new AdjListHyperGraph(4, 1, new unmanaged Cyclic(startIdx=0)); +for v in hypergraph.getVertices() do hypergraph.addInclusion(v, 0); + + +// writeln(e : string + " vertices:" + vertices :string); +// writeln("-----"); + /* for currentsize in 1..#vertices.size by -1 { */ + /* writeln("Strings: "); */ + +// writeln(elmInSubset : string); + +// var vertices = graph.incidence(graph.toEdge(eIdx)); + +var _vtxSubsetSet = new set(string); + +iter processVtxSubset(vtxSubset) { + for i in 1..#vtxSubset.size { + var tmp : [1..#vtxSubset.size - 1] int; + tmp[1..i - 1] = vtxSubset[1..i - 1]; + tmp[i..] = vtxSubset[i + 1..]; + yield tmp; + } +} + +/* Generate the permutation */ +proc doProcessVertices (verticesSet) { + if (verticesSet.size == 0) { + return; + } else if (verticesSet.size == 1) { + var verticesStr = stringify(verticesSet); + if !_vtxSubsetSet.contains(verticesStr) { + _vtxSubsetSet.add(verticesStr); + } + } else { + var verticesStr = stringify(verticesSet); + if !_vtxSubsetSet.contains(verticesStr) { + _vtxSubsetSet.add(verticesStr); + for _vtxSubset in processVtxSubset(verticesSet) { + doProcessVertices(_vtxSubset); + } + } + } +} + +/*For each of the hyperedge, do the permutation of all the vertices.*/ +for e in hypergraph.getEdges() { + var vertices = hypergraph.incidence(e); // ABCD + // writeln(vertices.domain); + ref tmp = vertices[1..#vertices.size]; + var verticesInEdge : [1..#vertices.size] int; + verticesInEdge[1..#vertices.size] = tmp.id; // ABCD vertices.low + doProcessVertices(verticesInEdge); +} + +writeln("Printing all generated combination"); +/*Verify the set by printing*/ +var setContent = _vtxSubsetSet.toArray(); +for c in setContent do + writeln(c); + +writeln("-----"); +var _sz = 0; +writeln("Printing bins"); +/*bin k-cells, with key as the length of the list and value is a list with all the k-cells*/ +var kCellMap = new map(int, list(string, true)); +for vtxSet in _vtxSubsetSet { + //var _vtxSet = vtxSet.split(" "); + var sz = + reduce [ch in vtxSet] ch == ' '; + writeln(sz : string + " " + vtxSet : string); + kCellMap[sz].append(vtxSet); + _sz = sz; +} + +class kCellsArray{ + var numKCells : int; + var D = {1..numKCells}; + var A : [D] string; + proc init(_N: int) { + numKCells = _N; + } +} + +var numBins = kCellMap.size - 1; +var kCellsArrayMap : [0..numBins] owned kCellsArray?; +var kCellKeys = kCellMap.keysToArray(); +sort(kCellKeys); + +// Empty record serves as comparator +record Comparator { } +// compare method defines how 2 elements are compared +// Simplified comparator since we know that the strings are of the same size +proc Comparator.compare(a :string, b :string) : int { + var retVal : int = 0; + for (c1, c2) in zip (a , b) { + if (c1 == c2) {continue;} + if (c1 < c2) {retVal = -1; break;} + else {retVal = 1; break;} + } + return retVal; +} + +var absComparator: Comparator; + + +// sort(Array, comparator=absComparator); + +writeln("%%%%%%%%%%%%%"); +// Leader-follower iterator +// Create the new KcellMaps for convenience of sorting +for (_kCellsArray, kCellKey) in zip(kCellsArrayMap, kCellKeys) { + writeln("listsize: " + kCellMap[kCellKey].size : string); + _kCellsArray = new owned kCellsArray(kCellMap[kCellKey].size); + _kCellsArray.A = kCellMap[kCellKey].toArray(); + compilerWarning(kCellMap[kCellKey].toArray().type : string); + sort(_kCellsArray.A, comparator=absComparator); + /* for c in kCellMap[kCellKey].toArray() { */ + /* writeln(c); */ + /* compilerWarning(c.type: string); */ + /* } */ +} +writeln("%%%%%%%%%%%%%"); + +writeln("Printing after sorting"); +writeln("^^^^^^^^^^^^^^^^^^^^^^^"); +for _kCellsArray in kCellsArrayMap { + writeln(_kCellsArray.A : string); +} +writeln("^^^^^^^^^^^^^^^^^^^^^^^"); + +/*Start of the construction of boundary matrices.*/ +class Matrix { + var N : int; + var M : int; + var matrix : [1..N, 1..M] int; + proc init(_N: int, _M:int) { + N = _N; + M = _M; + } +} + +var K = kCellMap.size - 1; +var boundaryMaps : [1..K] owned Matrix?; +var i : int = 1; + +// Leader-follower iterator +// Create the boundary Maps +for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { + writeln("dimensions: " + kCellsArrayMap[dimension_k_1].numKCells: string + " " + kCellsArrayMap[dimension_k].numKCells : string); + boundaryMap = new owned Matrix(kCellsArrayMap[dimension_k_1].numKCells, kCellsArrayMap[dimension_k].numKCells); +} + +/* forall (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { */ +/* writeln("dimensions: " + kCellMap[dimension_k_1].size: string + " " + kCellMap[dimension_k].size : string); */ +/* boundaryMap = new owned Matrix(kCellMap[dimension_k_1].size, kCellMap[dimension_k].size); */ +/* } */ + + +writeln("####"); +// Compute values for each entries in each of the boundary map +for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { + var arrayOfKCells = kCellsArrayMap[dimension_k].A; + var arrayOfK_1Cells = kCellsArrayMap[dimension_k_1].A; + writeln("$$$$$$$$$$$"); + writeln(arrayOfKCells); + writeln(arrayOfK_1Cells); + writeln("$$$$$$$$$$$"); + for SkCell in arrayOfKCells { + var kCell = SkCell.split(" "); + /* for kk in kCell { */ + /* compilerWarning(kk.type :string); */ + /* writeln("kk:" + kk :string); */ + /* } */ + /* compilerWarning(kCell.type : string); */ + for Sk_1Cell in arrayOfK_1Cells { + var k_1Cell = Sk_1Cell.split(" "); + for kk in k_1Cell { + var (found, Pos) = binarySearch(kCell, kk, comparator=absComparator); + if (found) { + writeln(kk : string + " was found in: " + kCell); + } + } + writeln("Considering combination: " , kCell : string + " and " + k_1Cell :string); + /* var position = kCell.find(k_1Cell); */ + /* if (position != 0) { */ + /* writeln(k_1Cell: string + " Occurs at position: " + position : string); */ + /* } */ + } + } + writeln("$$$$$$$$$$$"); +} + + + +/* forall (_kCellsArray, kCellList) in zip(kCellsArrayMap, kCellMap) { */ +/* // writeln("listsize: " + kCellMap[kCellList].size : string); */ +/* } */ + +// compilerWarning(kCellMap[_sz].type : string); + + +// for kCell in kCellMap { + // compilerWarning(kCellMap[kCell].type : string); + // kCellMap[kCell].sort(comparator=absComparator); +// } + +// Verify k-cells +/* for kCell in kCellMap { */ + +/* writeln(kCellMap(kCell)); */ +/* } */ +// writeln("-----"); + + + /* var sz_a = a.size; */ + /* var sz_b = b.size; */ + /* // var c: string; */ + /* var sz = 0; */ + /* if (sz_a <= sz_b) { */ + /* sz = sz_a; */ + /* // c = a; */ + /* } else { */ + /* // c = b */ + /* sz = sz_b; */ + /* } */ + /* /\* for l in c { *\/ */ + /* /\* if *\/ */ + /* /\* } *\/ */ + /* var i = 0; */ + /* while (i < sz) { */ + /* if (a[i] == b[i]) {i += 1;}//continue; */ + /* if (a[i] < b[i]) { */ + /* // i += 1; */ + /* return -1; */ + /* } else { */ + /* // i += 1; */ + /* return 1; */ + /* } */ + /* } */ + + +// Both of the following methods work for allocating the array. +//var boundaryMaps: owned Matrix? = new owned Matrix[1..10]; +// var boundaryMaps : [1..K] owned Matrix?; +// var i : int = 1; +/* for boundaryMap in boundaryMaps { */ +/* var dimension_k_1 = kCellMap[i - 1].size; */ +/* var dimension_k = kCellMap[i].size; */ +/* i += 1; */ +/* writeln("dimensions: " + dimension_k_1: string + " " + dimension_k: string); */ +/* boundaryMap = new owned Matrix(dimension_k_1, dimension_k); */ +/* } */ + + + // var splitlistOfKCells = listOfKCells.split(","); + // compilerWarning(splitlistOfKCells.type : string); + // writeln(splitlistOfKCells); + /* var listOfK_1Cells = kcellMap[dimension_k_1].split(" "); // got all (k-1)-cells */ + /* var lstIndex = 1; */ + /* for column in 1..#boundaryMap.M { */ + /* var _kcell = listOfKCells(lstIndex); // no way to index with [] operator? */ + /* for row in 1..#boundaryMap.N { */ + /* var _k_1Cell = listOfK_1Cells(lstIndex); */ + /* var position = _kcell.find(_k_1Cell); */ + /* if (position != 0 ) {//store the location where the match occurs. if the location is odd , store -1, else store 1} */ + /* boundaryMap[row, column] = ((position % 2) == 0 ? 1 : -1); */ + /* } else { */ + /* boundaryMap[row, column] = 0; */ + /* } */ + /* lstIndex += 1; */ + /* } */ + +// compilerWarning(listOfKCells.type : string); // list of strings ["0 1 2", "1 2 3"] +// writeln(listOfKCells); //.split(" "); // get all k-cells + /* writeln(kcell); */ + /* compilerWarning(kcell.type :string); */ + /* writeln("---->"); */ + + /* compilerWarning(sp.type : string); */ + /* writeln(sp); */ + /* writeln(sp.size); */ + /* writeln("---->"); */ + + +// For each k +// Allocate the matrix of size |k-1|X |k| +// Compute the entries of the matrix using the formula: + +// +// + /* for subset in processEdge(hypergraph, e) { */ + /* // writeln(e : string + "subset of vertices:" + subset : string); */ + /* } */ + // doProcessEdge(e); // Ensure we run every edge in parallel/distributed + + +/* var newEdgeIdx : atomic int; */ +/* forall e in hypergraph.getEdges() { */ +/* for subset in processEdge(e) { */ +/* var subsetStr = stringify(subset); */ +/* // Needs to be atomic... transactional */ +/* if !set.contains(subsetStr) { */ +/* var ix = newEdgeIdx.fetchAdd(1); // New index for this edge... */ +/* set[subsetStr] = ix; */ +/* // Recursively process 'subset' via 'processEdge'... */ +/* } */ +/* // Else we prune by not doing anything */ +/* } */ +/* } */ + +/* var newHypergraph = new AdjListHyperGraph(numVertices, newEdgeIdx.read()); */ +/* forall (subsetStr, eIdx) in set { */ +/* var subset = unstringify(subsetStr); */ +/* for x in subset do newHypergraph.addInclusion(x, eIdx); // Aggregated if distributed */ +/* } */ + + +/* for e in hypergraph.getEdges() { */ +/* compilerWarning(hypergraph.degree(e).type : string); */ +/* } */ + +/* var degree : int; */ +/* forall e in hypergraph.getEdges() with (max reduce degree) { */ +/* degree = max(hypergraph.degree(e), degree); */ +/* } */ +/* writeln(degree); */ + +/* forall e in hypergraph.getEdges() { */ +/* compilerWarning(e.type : string); */ +/* } */ + +/* // writeln(max reduce [e in hypergraph.getEdges()] compilerWarning(e.type : string)); */ +/* // writeln(max reduce [e in hypergraph.getEdges()] hypergraph.degree(e)); */ +/* writeln([e in hypergraph.getEdges()] hypergraph.degree(e)); */ + +/* forall e in hypergraph.getEdges() { */ +/* // for v in hypergraph.incidence(e) { */ +/* writeln(e : string + " = " + hypergraph.incidence(e) : string); */ +/* // } */ +/* } */ + + + +var M : [1..10, 1..10] int; +for (i,j) in M.domain do M[i,j] = i + j; +for s in 1..10 { + ref M_ = M[.., s..]; + var val, loc = minloc reduce zip(M_, M_.domain); + writeln("Minimum value for s = ", s, " is ", val, " and location is ", loc); +} + +proc IdentityMatrix(n) { + var A : [1..n, 1..n] int = 1; + return A; +} + +proc swap_rows(M, i, j) { M[i, ..] <=> M[j, ..]; } +proc swap_cols(M, i, j) { M[.., i] <=> M[.., j]; } + +proc change_sign_row(M) { M[x, ..] = -M[x, ..]; } +proc change_sign_col(M) {M[.., x] = -M[.., x];} + +proc is_lone(M,s) { + return (&& reduce (M[s,s+1..] != 0)) && (&& reduce (M[s+1.., s] != 0)); +} + +proc get_nextentry(M,s) { + const val = M[s,s]; + for ((i,j), m) in zip(M.domain, M) { + if m % val != 0 then return (i,j); + } + throw CustomError(..); +} \ No newline at end of file From 7b84c4305c0ad6b9bf18459241666fb2733ea62a Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Sat, 25 Jan 2020 14:11:43 -0800 Subject: [PATCH 02/23] Smith Normal form computation implementation so far. --- example/snf.chpl | 225 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 example/snf.chpl diff --git a/example/snf.chpl b/example/snf.chpl new file mode 100644 index 0000000..2fc051e --- /dev/null +++ b/example/snf.chpl @@ -0,0 +1,225 @@ +var b: [1..6, 1..11] int; +b(1,1) = 1; +b(1,2) = 1; +b(1,3) = 1; +b(1,4) = 1; +b(1,5) = 1; +b(2,1) = 1; +b(2,6) = 1; +b(2,7) = 1; +b(3,2) = 1; +b[3,6] = 1; +b[4,3] = 1; +b[4,7] = 1; +b[4,8] = 1; +b[4,9] = 1; +b[5,4] = 1; +b[5,8] = 1; +b[5,10] = 1; +b[5, 11] = 1; +b[6,5] = 1; +b[6,9] = 1; +b[6,11] = 1; +/*var b1 = + [[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0], + [1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0], + [0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], + [0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1], + [0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1]];*/ + +compilerWarning(b.type :string); + + +for i in {1..6} { + for j in {1..11} { + write(b(i,j):string + " "); + } + writeln(); +} + +proc IdentityMatrix(n) { + var A : [1..n, 1..n] int = 1; + return A; +} + +use List; +class Matrix2D { + var N : int; + var M : int; + var _arr : [1..N, 1..M] int; + proc init (row : int, col : int) { + N = row; + M = col; + } +} + +proc _get_next_pivot(M,s) { + var dims = M.domain.high; + var dimR = dims(1); + var dimC = dims(2); + for c in s..dimC { + for r in s..dimR { + if (M(r,c) != 0) { + return (r,c); + } + } + } + return (-1,-1); // TODO: return +} + +var dims = b.domain.high; +var dimL = dims(1); +var dimR = dims(2); +var minDim = if dimL <= dimR then dimL else dimR; + +writeln(dimL : string ); // dims give me the index set but I need the max value of the index set +writeln(minDim); + + +var S = b; +var IL = IdentityMatrix(dimL); +var IR = IdentityMatrix(dimR); + +var Linv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation +var Rinv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation + +var L = IL; +var R = IR; + +var rc = _get_next_pivot(b, 3); +writeln(rc : string); + +proc swap_rows(i, j, M) { + var N = M; + N[i, ..] <=> N[j, ..]; + return N; +} + +proc swap_columns(i, j, M) { + var N = M; + N[.., i] <=> N[.., j]; + return N; +} + +// Replaces row i (of M) with sum ri multiple of ith row and rj multiple of jth row +proc add_to_row(M,i,j,ri = 1, rj = 1, mod = 2) { + var N = M; + N[i, ..] = (ri * N[i, ..] + rj * N[j, ..]) % 2; + return N; +} + + +proc add_to_column(M,i,j,ci = 1, cj = 1, mod = 2) { + var N = M; + N[.., i] = (ci * N[.., i] + cj * N[..,j]) % 2; + return N; +} + +proc matmultmod (M, N, mod =2) { + var nr = M.domain.high(1); + var nc = N.domain.high(2); + var m = M.domain.high(2); + var C = [1..nr, 1..nc] int; + + forall i in 1..nr { + for j in 1..nc { + C[i,j] = (+ reduce A[i, 1..m] * B[1..m, j]) % 2 ; + } + } + +} + +proc matmultmod2 (M, N, mod =2) { + var C : [M.dim(1), N.dim(2)] int; + forall (i,j) in C.domain { + C[i,j] = (+ reduce A[i, M.dim(2)] * B[M.dim(2), j]) % 2 ; + } +} + +/*proc modmult(M, N, mod =2 ) { + return matmultmod(M, N, mod); + }*/ + +type listType = list(unmanaged Matrix2D?, true); +proc matmulreduce(arr : listType, reverse = false, mod = 2) { + var P = arr(0); + if (reverse) { + for i in arr.size..1 by -1 { + P = matmultmod(P, arr(i)._arr); + } + } else { + for i in 1..arr.size { + P = matmultmod(P, arr(i)._arr); + } + } + return P; + +} + +writeln("########"); +for s in 1..minDim { + writeln(s : string); + var pivot = _get_next_pivot(S,s); + var rdx : int, cdx : int; + if (pivot(1) == -1 && pivot(2) == -1) { + break; + } + else { + (rdx, cdx) = pivot; + } + + // Swap rows and columns as needed so the 1 is in the s,s position + if (rdx > s) { + S = swap_rows(s, rdx, S); + L = swap_rows(s, rdx, L); + var tmp = swap_rows(s, rdx, IL); + var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + LM._arr = tmp; + Linv.append(LM); + } + if (cdx > s) { + S = swap_columns(s, cdx, S); + R = swap_columns(s, cdx, R); + var tmp = swap_columns(s, cdx, IR); + var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + RM._arr = tmp; + Linv.append(RM); + } + + // add sth row to every nonzero row & sth column to every nonzero column + // zip(S[.., s], S.dim(1)) gives you (S[i,j], 1..N) + // row_indices = [idx for idx in range(dimL) if idx != s and S[idx][s] == 1] + // var RD: domain(2) = {1..dimL, 1..dimL}; + // var row_indices = [(x,(i,j)) in zip(S, 1..dimL)] if x == 1 && j != s then (i,j); + // var row_indices = [(s,idx) in zip(S, {1..dimL})] if s == 1 then idx; + + var row_indices = [idx in 1..dimL] if (idx != s && S(idx,s) == 1) then idx; + // compilerWarning(row_indices.type : string); + + for rdx in row_indices { + // writeln("rdx: " + rdx : string); + S = add_to_row(S, rdx, s); + L = add_to_row(L, rdx, s); + var tmp = add_to_row(IL, rdx, s); + var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + LM._arr = tmp; + Linv.append(LM); + } + + var column_indices = [jdx in 1..dimR] if (jdx != s && S(s,jdx) == 1) then jdx; + + for (jdx,cdx) in zip(1..,column_indices) {// TODO: check + // writeln("rdx: " + rdx : string); + S = add_to_row(S, cdx, s); + R = add_to_row(R, cdx, s); + var tmp = add_to_column(IR, cdx, s); + var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + RM._arr = tmp; + Linv.append(RM); + } + + Linv = matmulreduce(Linv,mod=mod); + Rinv = matmulreduce(Rinv,reverse=True,mod=mod); +} \ No newline at end of file From b8eab6ad8d8aa86d90bf1ccec90c5d2cee56c382 Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Sat, 25 Jan 2020 15:20:05 -0800 Subject: [PATCH 03/23] Compiled version --- example/snf.chpl | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/example/snf.chpl b/example/snf.chpl index 2fc051e..46667b3 100644 --- a/example/snf.chpl +++ b/example/snf.chpl @@ -117,34 +117,39 @@ proc add_to_column(M,i,j,ci = 1, cj = 1, mod = 2) { return N; } -proc matmultmod (M, N, mod =2) { +proc matmultmod2 (M, N, mod = 2) { var nr = M.domain.high(1); var nc = N.domain.high(2); var m = M.domain.high(2); - var C = [1..nr, 1..nc] int; + var C : [1..nr, 1..nc] atomic int; forall i in 1..nr { for j in 1..nc { - C[i,j] = (+ reduce A[i, 1..m] * B[1..m, j]) % 2 ; + C[i,j].write((+ reduce M[i, 1..m] * N[1..m, j]) % 2) ; } } - + return C.read(); } -proc matmultmod2 (M, N, mod =2) { - var C : [M.dim(1), N.dim(2)] int; +proc matmultmod3 (M, N, mod = 2) { + var C : [M.domain.dim(1), N.domain.dim(2)] atomic int; forall (i,j) in C.domain { - C[i,j] = (+ reduce A[i, M.dim(2)] * B[M.dim(2), j]) % 2 ; + C[i,j].write((+ reduce M[i, M.domain.dim(2)] * N[M.domain.dim(2), j]) % 2); } + return C.read(); } -/*proc modmult(M, N, mod =2 ) { - return matmultmod(M, N, mod); - }*/ +proc matmultmod (M, N, mod =2) { + var C : [M.domain.dim(1), N.domain.dim(2)] int; + forall (i,j) in C.domain { + C[i,j] = (+ reduce (M[i, M.domain.dim(2)] * N[M.domain.dim(2), j])) % 2; + } + return C; +} type listType = list(unmanaged Matrix2D?, true); proc matmulreduce(arr : listType, reverse = false, mod = 2) { - var P = arr(0); + var P = arr(0)._arr; if (reverse) { for i in arr.size..1 by -1 { P = matmultmod(P, arr(i)._arr); @@ -220,6 +225,6 @@ for s in 1..minDim { Linv.append(RM); } - Linv = matmulreduce(Linv,mod=mod); - Rinv = matmulreduce(Rinv,reverse=True,mod=mod); + var LinvF = matmulreduce(Linv); + var RinvF = matmulreduce(Rinv, true, 2); } \ No newline at end of file From c418eb0ff32ee6ece2c46cd1823fde2185bcc626 Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Sun, 26 Jan 2020 12:43:15 -0800 Subject: [PATCH 04/23] SNF calculation with L, R and S verified. Trying to verify Linv and Rinv --- example/snf.chpl | 134 ++++++++++++++++++++++++++++++----------------- 1 file changed, 86 insertions(+), 48 deletions(-) diff --git a/example/snf.chpl b/example/snf.chpl index 46667b3..8ecf682 100644 --- a/example/snf.chpl +++ b/example/snf.chpl @@ -1,4 +1,4 @@ -var b: [1..6, 1..11] int; +var b: [1..7, 1..11] int; b(1,1) = 1; b(1,2) = 1; b(1,3) = 1; @@ -13,13 +13,14 @@ b[4,3] = 1; b[4,7] = 1; b[4,8] = 1; b[4,9] = 1; -b[5,4] = 1; -b[5,8] = 1; b[5,10] = 1; -b[5, 11] = 1; -b[6,5] = 1; -b[6,9] = 1; +b[6,4] = 1; +b[6,8] = 1; +b[6,10] = 1; b[6,11] = 1; +b[7,5] = 1; +b[7,9] = 1; +b[7,11] = 1; /*var b1 = [[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0], @@ -29,18 +30,21 @@ b[6,11] = 1; [0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1], [0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1]];*/ -compilerWarning(b.type :string); +// compilerWarning(b.type :string); - -for i in {1..6} { - for j in {1..11} { - write(b(i,j):string + " "); +proc printmatrix(M) { + for i in {1..M.domain.high(1)} { + for j in {1..M.domain.high(2)} { + write(M(i,j):string + " "); + } + writeln(); } - writeln(); } + proc IdentityMatrix(n) { - var A : [1..n, 1..n] int = 1; + var A : [1..n, 1..n] int; + [i in A.domain.dim(1)] A[i,i] = 1; return A; } @@ -69,27 +73,6 @@ proc _get_next_pivot(M,s) { return (-1,-1); // TODO: return } -var dims = b.domain.high; -var dimL = dims(1); -var dimR = dims(2); -var minDim = if dimL <= dimR then dimL else dimR; - -writeln(dimL : string ); // dims give me the index set but I need the max value of the index set -writeln(minDim); - - -var S = b; -var IL = IdentityMatrix(dimL); -var IR = IdentityMatrix(dimR); - -var Linv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation -var Rinv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation - -var L = IL; -var R = IR; - -var rc = _get_next_pivot(b, 3); -writeln(rc : string); proc swap_rows(i, j, M) { var N = M; @@ -104,16 +87,16 @@ proc swap_columns(i, j, M) { } // Replaces row i (of M) with sum ri multiple of ith row and rj multiple of jth row -proc add_to_row(M,i,j,ri = 1, rj = 1, mod = 2) { +proc add_to_row(M, i, j, ri = 1, rj = 1, mod = 2) { var N = M; - N[i, ..] = (ri * N[i, ..] + rj * N[j, ..]) % 2; + N[i, ..] = (ri * N[i, ..] + rj * N[j, ..]) % mod; return N; } -proc add_to_column(M,i,j,ci = 1, cj = 1, mod = 2) { +proc add_to_column(M, i, j, ci = 1, cj = 1, mod = 2) { var N = M; - N[.., i] = (ci * N[.., i] + cj * N[..,j]) % 2; + N[.., i] = (ci * N[.., i] + cj * N[..,j]) % mod; return N; } @@ -149,7 +132,7 @@ proc matmultmod (M, N, mod =2) { type listType = list(unmanaged Matrix2D?, true); proc matmulreduce(arr : listType, reverse = false, mod = 2) { - var P = arr(0)._arr; + var P = arr(1)._arr; if (reverse) { for i in arr.size..1 by -1 { P = matmultmod(P, arr(i)._arr); @@ -161,11 +144,49 @@ proc matmulreduce(arr : listType, reverse = false, mod = 2) { } return P; -} +} + +printmatrix(b); + +var dims = b.domain.high; +var dimL = dims(1); +var dimR = dims(2); +var minDim = if dimL <= dimR then dimL else dimR; + +// writeln(dimL : string ); // dims give me the index set but I need the max value of the index set +// writeln(minDim); + +var S = b; +var IL = IdentityMatrix(dimL); +var IR = IdentityMatrix(dimR); + +var Linv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation +var Rinv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation + +var Linit = new unmanaged Matrix2D(IL.domain.high(1), IL.domain.high(2)); +Linit._arr = IL; +Linv.append(Linit); +var Rinit = new unmanaged Matrix2D(IR.domain.high(1), IR.domain.high(2)); +Rinit._arr = IR; +Rinv.append(Rinit); + +var L = IL; +var R = IR; + +/* writeln("###############"); */ +/* writeln("L:"); */ +/* printmatrix(L); */ +/* writeln("###############"); */ +/* writeln("R:"); */ +/* printmatrix(R); */ + +// var rc = _get_next_pivot(b, 3); +// writeln(rc : string); + writeln("########"); for s in 1..minDim { - writeln(s : string); + writeln("Iteration: " + s : string); var pivot = _get_next_pivot(S,s); var rdx : int, cdx : int; if (pivot(1) == -1 && pivot(2) == -1) { @@ -190,7 +211,7 @@ for s in 1..minDim { var tmp = swap_columns(s, cdx, IR); var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); RM._arr = tmp; - Linv.append(RM); + Rinv.append(RM); } // add sth row to every nonzero row & sth column to every nonzero column @@ -217,14 +238,31 @@ for s in 1..minDim { for (jdx,cdx) in zip(1..,column_indices) {// TODO: check // writeln("rdx: " + rdx : string); - S = add_to_row(S, cdx, s); - R = add_to_row(R, cdx, s); + S = add_to_column(S, cdx, s); + R = add_to_column(R, cdx, s); var tmp = add_to_column(IR, cdx, s); var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); RM._arr = tmp; - Linv.append(RM); + Rinv.append(RM); } +} + +writeln("###############"); +writeln("L:"); +printmatrix(L); +writeln("###############"); +writeln("R:"); +printmatrix(R); +writeln("###############"); +writeln("S:"); +printmatrix(S); + +var LinvF = matmulreduce(Linv); +var RinvF = matmulreduce(Rinv, true, 2); +writeln("###############"); +writeln("Linv:"); +printmatrix(LinvF); +writeln("###############"); +writeln("Rinv:"); +printmatrix(RinvF); - var LinvF = matmulreduce(Linv); - var RinvF = matmulreduce(Rinv, true, 2); -} \ No newline at end of file From 8436f5651aab1c83b18f3f44c81c02c1ab6dcf58 Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Sun, 26 Jan 2020 13:49:28 -0800 Subject: [PATCH 05/23] Working version of snf. --- example/homology.chpl | 2 ++ example/snf.chpl | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/example/homology.chpl b/example/homology.chpl index e184728..f520867 100644 --- a/example/homology.chpl +++ b/example/homology.chpl @@ -382,6 +382,8 @@ proc IdentityMatrix(n) { proc swap_rows(M, i, j) { M[i, ..] <=> M[j, ..]; } proc swap_cols(M, i, j) { M[.., i] <=> M[.., j]; } +proc add_to_row(M,x,k,s) {M[x, ..] += k * M[s, ..]; M[x, ..] = M[x, ..] % 2; } +proc add_to_column(M,x,k,s){M[.., x] += k * M[.., s]; M[.., x] = M[.., x] % 2;} proc change_sign_row(M) { M[x, ..] = -M[x, ..]; } proc change_sign_col(M) {M[.., x] = -M[.., x];} diff --git a/example/snf.chpl b/example/snf.chpl index 8ecf682..1360349 100644 --- a/example/snf.chpl +++ b/example/snf.chpl @@ -132,13 +132,15 @@ proc matmultmod (M, N, mod =2) { type listType = list(unmanaged Matrix2D?, true); proc matmulreduce(arr : listType, reverse = false, mod = 2) { - var P = arr(1)._arr; + var P : [arr(1)._arr._dom] int; if (reverse) { - for i in arr.size..1 by -1 { + P = arr(arr.size)._arr; + for i in 1..#arr.size - 1 by -1 { P = matmultmod(P, arr(i)._arr); } } else { - for i in 1..arr.size { + P = arr(1)._arr; + for i in 2..arr.size { P = matmultmod(P, arr(i)._arr); } } From 7de1c9da106f372dda9362fd1b634cb053afaaa5 Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Wed, 29 Jan 2020 12:01:23 -0800 Subject: [PATCH 06/23] Homology computation and snf progress so far. --- example/homology.chpl | 271 +++++++++++------------------------------- example/snf.chpl | 250 +++++++++++++++++++++++--------------- 2 files changed, 228 insertions(+), 293 deletions(-) diff --git a/example/homology.chpl b/example/homology.chpl index f520867..8eb5b23 100644 --- a/example/homology.chpl +++ b/example/homology.chpl @@ -76,6 +76,7 @@ for e in hypergraph.getEdges() { ref tmp = vertices[1..#vertices.size]; var verticesInEdge : [1..#vertices.size] int; verticesInEdge[1..#vertices.size] = tmp.id; // ABCD vertices.low + compilerWarning(verticesInEdge.type :string ); doProcessVertices(verticesInEdge); } @@ -138,7 +139,7 @@ for (_kCellsArray, kCellKey) in zip(kCellsArrayMap, kCellKeys) { writeln("listsize: " + kCellMap[kCellKey].size : string); _kCellsArray = new owned kCellsArray(kCellMap[kCellKey].size); _kCellsArray.A = kCellMap[kCellKey].toArray(); - compilerWarning(kCellMap[kCellKey].toArray().type : string); + // compilerWarning(kCellMap[kCellKey].toArray().type : string); sort(_kCellsArray.A, comparator=absComparator); /* for c in kCellMap[kCellKey].toArray() { */ /* writeln(c); */ @@ -182,220 +183,92 @@ for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { /* } */ +var vs = new set(string); + +iter processVtxSubset2(vtxSubset) { + for i in 1..#vtxSubset.size { + var tmp : [1..#vtxSubset.size - 1] int; + tmp[1..i - 1] = vtxSubset[1..i - 1]; + tmp[i..] = vtxSubset[i + 1..]; + yield tmp; + } +} + +/* Generate the permutation */ +proc doProcessVertices2 (verticesSet) { + if (verticesSet.size == 0) { + return; + } else if (verticesSet.size == 1) { + var verticesStr = stringify(verticesSet); + if !vs.contains(verticesStr) { + vs.add(verticesStr); + } + } else { + var verticesStr = stringify(verticesSet); + if !vs.contains(verticesStr) { + vs.add(verticesStr); + for _vtxSubset in processVtxSubset2(verticesSet) { + doProcessVertices2(_vtxSubset); + } + } + } +} + + writeln("####"); // Compute values for each entries in each of the boundary map for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { - var arrayOfKCells = kCellsArrayMap[dimension_k].A; + var arrayOfKCells = kCellsArrayMap[dimension_k].A; // Arrays of strings, each string being 1 kcell var arrayOfK_1Cells = kCellsArrayMap[dimension_k_1].A; writeln("$$$$$$$$$$$"); writeln(arrayOfKCells); writeln(arrayOfK_1Cells); writeln("$$$$$$$$$$$"); - for SkCell in arrayOfKCells { - var kCell = SkCell.split(" "); - /* for kk in kCell { */ - /* compilerWarning(kk.type :string); */ - /* writeln("kk:" + kk :string); */ - /* } */ - /* compilerWarning(kCell.type : string); */ + for SkCell in arrayOfKCells { // iterate through all the k-cells + /* Generate permutation of the current k-Cell*/ + compilerWarning(SkCell.type : string); + var kCell = SkCell.split(" ") : int; + compilerWarning(kCell.type : string); + writeln("#kcell: " + kCell :string); + vs.clear(); + doProcessVertices2(kCell); + var _setContent = vs.toArray(); + writeln("Combinations generated ": string); + for c in _setContent do + writeln(c); for Sk_1Cell in arrayOfK_1Cells { var k_1Cell = Sk_1Cell.split(" "); - for kk in k_1Cell { - var (found, Pos) = binarySearch(kCell, kk, comparator=absComparator); - if (found) { - writeln(kk : string + " was found in: " + kCell); + for c in _setContent { + for k_1 in k_1Cell { + if (k_1 == c) { + + } } } - writeln("Considering combination: " , kCell : string + " and " + k_1Cell :string); - /* var position = kCell.find(k_1Cell); */ - /* if (position != 0) { */ - /* writeln(k_1Cell: string + " Occurs at position: " + position : string); */ - /* } */ } + // doProcessVertices() + /* for kk in kCell { */ + /* compilerWarning(kk.type :string); */ + /* writeln("kk:" + kk :string); */ + /* } */ + /* compilerWarning(kCell.type : string); */ + /* for Sk_1Cell in arrayOfK_1Cells { */ + /* var k_1Cell = Sk_1Cell.split(" "); */ + /* for kk in k_1Cell { */ + /* var (found, Pos) = binarySearch(kCell, kk, comparator=absComparator); */ + /* if (found) { */ + /* writeln(kk : string + " was found in: " + kCell); */ + /* } */ + /* } */ + /* writeln("Considering combination: " , kCell : string + " and " + k_1Cell :string); */ + /* /\* var position = kCell.find(k_1Cell); *\/ */ + /* /\* if (position != 0) { *\/ */ + /* /\* writeln(k_1Cell: string + " Occurs at position: " + position : string); *\/ */ + /* /\* } *\/ */ + /* } */ } writeln("$$$$$$$$$$$"); } -/* forall (_kCellsArray, kCellList) in zip(kCellsArrayMap, kCellMap) { */ -/* // writeln("listsize: " + kCellMap[kCellList].size : string); */ -/* } */ - -// compilerWarning(kCellMap[_sz].type : string); - - -// for kCell in kCellMap { - // compilerWarning(kCellMap[kCell].type : string); - // kCellMap[kCell].sort(comparator=absComparator); -// } - -// Verify k-cells -/* for kCell in kCellMap { */ - -/* writeln(kCellMap(kCell)); */ -/* } */ -// writeln("-----"); - - - /* var sz_a = a.size; */ - /* var sz_b = b.size; */ - /* // var c: string; */ - /* var sz = 0; */ - /* if (sz_a <= sz_b) { */ - /* sz = sz_a; */ - /* // c = a; */ - /* } else { */ - /* // c = b */ - /* sz = sz_b; */ - /* } */ - /* /\* for l in c { *\/ */ - /* /\* if *\/ */ - /* /\* } *\/ */ - /* var i = 0; */ - /* while (i < sz) { */ - /* if (a[i] == b[i]) {i += 1;}//continue; */ - /* if (a[i] < b[i]) { */ - /* // i += 1; */ - /* return -1; */ - /* } else { */ - /* // i += 1; */ - /* return 1; */ - /* } */ - /* } */ - - -// Both of the following methods work for allocating the array. -//var boundaryMaps: owned Matrix? = new owned Matrix[1..10]; -// var boundaryMaps : [1..K] owned Matrix?; -// var i : int = 1; -/* for boundaryMap in boundaryMaps { */ -/* var dimension_k_1 = kCellMap[i - 1].size; */ -/* var dimension_k = kCellMap[i].size; */ -/* i += 1; */ -/* writeln("dimensions: " + dimension_k_1: string + " " + dimension_k: string); */ -/* boundaryMap = new owned Matrix(dimension_k_1, dimension_k); */ -/* } */ - - - // var splitlistOfKCells = listOfKCells.split(","); - // compilerWarning(splitlistOfKCells.type : string); - // writeln(splitlistOfKCells); - /* var listOfK_1Cells = kcellMap[dimension_k_1].split(" "); // got all (k-1)-cells */ - /* var lstIndex = 1; */ - /* for column in 1..#boundaryMap.M { */ - /* var _kcell = listOfKCells(lstIndex); // no way to index with [] operator? */ - /* for row in 1..#boundaryMap.N { */ - /* var _k_1Cell = listOfK_1Cells(lstIndex); */ - /* var position = _kcell.find(_k_1Cell); */ - /* if (position != 0 ) {//store the location where the match occurs. if the location is odd , store -1, else store 1} */ - /* boundaryMap[row, column] = ((position % 2) == 0 ? 1 : -1); */ - /* } else { */ - /* boundaryMap[row, column] = 0; */ - /* } */ - /* lstIndex += 1; */ - /* } */ - -// compilerWarning(listOfKCells.type : string); // list of strings ["0 1 2", "1 2 3"] -// writeln(listOfKCells); //.split(" "); // get all k-cells - /* writeln(kcell); */ - /* compilerWarning(kcell.type :string); */ - /* writeln("---->"); */ - - /* compilerWarning(sp.type : string); */ - /* writeln(sp); */ - /* writeln(sp.size); */ - /* writeln("---->"); */ - - -// For each k -// Allocate the matrix of size |k-1|X |k| -// Compute the entries of the matrix using the formula: - -// -// - /* for subset in processEdge(hypergraph, e) { */ - /* // writeln(e : string + "subset of vertices:" + subset : string); */ - /* } */ - // doProcessEdge(e); // Ensure we run every edge in parallel/distributed - - -/* var newEdgeIdx : atomic int; */ -/* forall e in hypergraph.getEdges() { */ -/* for subset in processEdge(e) { */ -/* var subsetStr = stringify(subset); */ -/* // Needs to be atomic... transactional */ -/* if !set.contains(subsetStr) { */ -/* var ix = newEdgeIdx.fetchAdd(1); // New index for this edge... */ -/* set[subsetStr] = ix; */ -/* // Recursively process 'subset' via 'processEdge'... */ -/* } */ -/* // Else we prune by not doing anything */ -/* } */ -/* } */ - -/* var newHypergraph = new AdjListHyperGraph(numVertices, newEdgeIdx.read()); */ -/* forall (subsetStr, eIdx) in set { */ -/* var subset = unstringify(subsetStr); */ -/* for x in subset do newHypergraph.addInclusion(x, eIdx); // Aggregated if distributed */ -/* } */ - - -/* for e in hypergraph.getEdges() { */ -/* compilerWarning(hypergraph.degree(e).type : string); */ -/* } */ - -/* var degree : int; */ -/* forall e in hypergraph.getEdges() with (max reduce degree) { */ -/* degree = max(hypergraph.degree(e), degree); */ -/* } */ -/* writeln(degree); */ - -/* forall e in hypergraph.getEdges() { */ -/* compilerWarning(e.type : string); */ -/* } */ - -/* // writeln(max reduce [e in hypergraph.getEdges()] compilerWarning(e.type : string)); */ -/* // writeln(max reduce [e in hypergraph.getEdges()] hypergraph.degree(e)); */ -/* writeln([e in hypergraph.getEdges()] hypergraph.degree(e)); */ - -/* forall e in hypergraph.getEdges() { */ -/* // for v in hypergraph.incidence(e) { */ -/* writeln(e : string + " = " + hypergraph.incidence(e) : string); */ -/* // } */ -/* } */ - - - -var M : [1..10, 1..10] int; -for (i,j) in M.domain do M[i,j] = i + j; -for s in 1..10 { - ref M_ = M[.., s..]; - var val, loc = minloc reduce zip(M_, M_.domain); - writeln("Minimum value for s = ", s, " is ", val, " and location is ", loc); -} - -proc IdentityMatrix(n) { - var A : [1..n, 1..n] int = 1; - return A; -} - -proc swap_rows(M, i, j) { M[i, ..] <=> M[j, ..]; } -proc swap_cols(M, i, j) { M[.., i] <=> M[.., j]; } -proc add_to_row(M,x,k,s) {M[x, ..] += k * M[s, ..]; M[x, ..] = M[x, ..] % 2; } -proc add_to_column(M,x,k,s){M[.., x] += k * M[.., s]; M[.., x] = M[.., x] % 2;} - -proc change_sign_row(M) { M[x, ..] = -M[x, ..]; } -proc change_sign_col(M) {M[.., x] = -M[.., x];} - -proc is_lone(M,s) { - return (&& reduce (M[s,s+1..] != 0)) && (&& reduce (M[s+1.., s] != 0)); -} - -proc get_nextentry(M,s) { - const val = M[s,s]; - for ((i,j), m) in zip(M.domain, M) { - if m % val != 0 then return (i,j); - } - throw CustomError(..); -} \ No newline at end of file diff --git a/example/snf.chpl b/example/snf.chpl index 1360349..7ebba96 100644 --- a/example/snf.chpl +++ b/example/snf.chpl @@ -1,3 +1,4 @@ +/*Test matrix 1*/ var b: [1..7, 1..11] int; b(1,1) = 1; b(1,2) = 1; @@ -21,6 +22,25 @@ b[6,11] = 1; b[7,5] = 1; b[7,9] = 1; b[7,11] = 1; + +/*Test matrix 2*/ +var c : [1..11, 1..5] int; +c(1,1) = 1; +c(3,1) = 1; +c(3,2) = 1; +c(3,3) = 1; +c(4,2) = 1; +c(4,4) = 1; +c(5,3) = 1; +c(5,4) = 1; +c(7,1) = 1; +c(8,2) = 1; +c(8,5) = 1; +c(9,3) = 1; +c(9,5) = 1; +c(11,4) = 1; +c(11,5) = 1; + /*var b1 = [[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0], @@ -148,107 +168,130 @@ proc matmulreduce(arr : listType, reverse = false, mod = 2) { } +// rank calculation: +proc calculateRank(M) { + var rank = + reduce [i in M.domain.dim(2)] (max reduce M[.., i]); + return rank; +} + + printmatrix(b); -var dims = b.domain.high; -var dimL = dims(1); -var dimR = dims(2); -var minDim = if dimL <= dimR then dimL else dimR; +proc smithNormalForm(b) { + var dims = b.domain.high; + var dimL = dims(1); + var dimR = dims(2); + var minDim = if dimL <= dimR then dimL else dimR; -// writeln(dimL : string ); // dims give me the index set but I need the max value of the index set -// writeln(minDim); - -var S = b; -var IL = IdentityMatrix(dimL); -var IR = IdentityMatrix(dimR); - -var Linv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation -var Rinv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation - -var Linit = new unmanaged Matrix2D(IL.domain.high(1), IL.domain.high(2)); -Linit._arr = IL; -Linv.append(Linit); -var Rinit = new unmanaged Matrix2D(IR.domain.high(1), IR.domain.high(2)); -Rinit._arr = IR; -Rinv.append(Rinit); - -var L = IL; -var R = IR; - -/* writeln("###############"); */ -/* writeln("L:"); */ -/* printmatrix(L); */ -/* writeln("###############"); */ -/* writeln("R:"); */ -/* printmatrix(R); */ - -// var rc = _get_next_pivot(b, 3); -// writeln(rc : string); - - -writeln("########"); -for s in 1..minDim { - writeln("Iteration: " + s : string); - var pivot = _get_next_pivot(S,s); - var rdx : int, cdx : int; - if (pivot(1) == -1 && pivot(2) == -1) { - break; - } - else { - (rdx, cdx) = pivot; - } + // writeln(dimL : string ); // dims give me the index set but I need the max value of the index set + // writeln(minDim); + + + var S = b; + var IL = IdentityMatrix(dimL); + var IR = IdentityMatrix(dimR); + + var Linv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation + var Rinv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation + + var Linit = new unmanaged Matrix2D(IL.domain.high(1), IL.domain.high(2)); + Linit._arr = IL; + Linv.append(Linit); + var Rinit = new unmanaged Matrix2D(IR.domain.high(1), IR.domain.high(2)); + Rinit._arr = IR; + Rinv.append(Rinit); + + var L = IL; + var R = IR; + + /* writeln("###############"); */ + /* writeln("L:"); */ + /* printmatrix(L); */ + /* writeln("###############"); */ + /* writeln("R:"); */ + /* printmatrix(R); */ + + // var rc = _get_next_pivot(b, 3); + // writeln(rc : string); + + + writeln("########"); + for s in 1..minDim { + writeln("Iteration: " + s : string); + var pivot = _get_next_pivot(S,s); + var rdx : int, cdx : int; + if (pivot(1) == -1 && pivot(2) == -1) { + break; + } + else { + (rdx, cdx) = pivot; + } - // Swap rows and columns as needed so the 1 is in the s,s position - if (rdx > s) { - S = swap_rows(s, rdx, S); - L = swap_rows(s, rdx, L); - var tmp = swap_rows(s, rdx, IL); - var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); - LM._arr = tmp; - Linv.append(LM); - } - if (cdx > s) { - S = swap_columns(s, cdx, S); - R = swap_columns(s, cdx, R); - var tmp = swap_columns(s, cdx, IR); - var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); - RM._arr = tmp; - Rinv.append(RM); - } + // Swap rows and columns as needed so the 1 is in the s,s position + if (rdx > s) { + S = swap_rows(s, rdx, S); + L = swap_rows(s, rdx, L); + var tmp = swap_rows(s, rdx, IL); + var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + LM._arr = tmp; + Linv.append(LM); + } + if (cdx > s) { + S = swap_columns(s, cdx, S); + R = swap_columns(s, cdx, R); + var tmp = swap_columns(s, cdx, IR); + var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + RM._arr = tmp; + Rinv.append(RM); + } - // add sth row to every nonzero row & sth column to every nonzero column - // zip(S[.., s], S.dim(1)) gives you (S[i,j], 1..N) - // row_indices = [idx for idx in range(dimL) if idx != s and S[idx][s] == 1] - // var RD: domain(2) = {1..dimL, 1..dimL}; - // var row_indices = [(x,(i,j)) in zip(S, 1..dimL)] if x == 1 && j != s then (i,j); - // var row_indices = [(s,idx) in zip(S, {1..dimL})] if s == 1 then idx; - - var row_indices = [idx in 1..dimL] if (idx != s && S(idx,s) == 1) then idx; - // compilerWarning(row_indices.type : string); - - for rdx in row_indices { - // writeln("rdx: " + rdx : string); - S = add_to_row(S, rdx, s); - L = add_to_row(L, rdx, s); - var tmp = add_to_row(IL, rdx, s); - var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); - LM._arr = tmp; - Linv.append(LM); - } + // add sth row to every nonzero row & sth column to every nonzero column + // zip(S[.., s], S.dim(1)) gives you (S[i,j], 1..N) + // row_indices = [idx for idx in range(dimL) if idx != s and S[idx][s] == 1] + // var RD: domain(2) = {1..dimL, 1..dimL}; + // var row_indices = [(x,(i,j)) in zip(S, 1..dimL)] if x == 1 && j != s then (i,j); + // var row_indices = [(s,idx) in zip(S, {1..dimL})] if s == 1 then idx; + + var row_indices = [idx in 1..dimL] if (idx != s && S(idx,s) == 1) then idx; + // compilerWarning(row_indices.type : string); + + for rdx in row_indices { + // writeln("rdx: " + rdx : string); + S = add_to_row(S, rdx, s); + L = add_to_row(L, rdx, s); + var tmp = add_to_row(IL, rdx, s); + var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + LM._arr = tmp; + Linv.append(LM); + } - var column_indices = [jdx in 1..dimR] if (jdx != s && S(s,jdx) == 1) then jdx; + var column_indices = [jdx in 1..dimR] if (jdx != s && S(s,jdx) == 1) then jdx; - for (jdx,cdx) in zip(1..,column_indices) {// TODO: check - // writeln("rdx: " + rdx : string); - S = add_to_column(S, cdx, s); - R = add_to_column(R, cdx, s); - var tmp = add_to_column(IR, cdx, s); - var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); - RM._arr = tmp; - Rinv.append(RM); + for (jdx,cdx) in zip(1..,column_indices) {// TODO: check + // writeln("rdx: " + rdx : string); + S = add_to_column(S, cdx, s); + R = add_to_column(R, cdx, s); + var tmp = add_to_column(IR, cdx, s); + var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + RM._arr = tmp; + Rinv.append(RM); + } } + + + var LinvF = matmulreduce(Linv); + var RinvF = matmulreduce(Rinv, true, 2); + return (L,R,S,LinvF,RinvF); } +var computedMatrices = smithNormalForm(b); +var computedMatrices2 = smithNormalForm(c); +var L2 = computedMatrices2(1); +var L = computedMatrices(1); +var R = computedMatrices(2); +var S = computedMatrices(3); +var LinvF = computedMatrices(4); +var RinvF = computedMatrices(5); writeln("###############"); writeln("L:"); printmatrix(L); @@ -258,9 +301,6 @@ printmatrix(R); writeln("###############"); writeln("S:"); printmatrix(S); - -var LinvF = matmulreduce(Linv); -var RinvF = matmulreduce(Rinv, true, 2); writeln("###############"); writeln("Linv:"); printmatrix(LinvF); @@ -268,3 +308,25 @@ writeln("###############"); writeln("Rinv:"); printmatrix(RinvF); +var r = calculateRank(S); +writeln("Rank of S: " + r : string); +var nr = R.domain.high(2) - r; +var ker1 :[1..R.domain.high(1), 1..nr] int = R[..,r+1..]; +writeln("###############"); +writeln("ker1:"); +printmatrix(ker1); + +var LKernel = new list(unmanaged Matrix2D?, true); + +var _L2 = new unmanaged Matrix2D(L2.domain.high(1), L2.domain.high(2)); +_L2._arr = L2; +LKernel.append(_L2); + +var _ker1 = new unmanaged Matrix2D(ker1.domain.high(1), ker1.domain.high(2)); +_ker1._arr = ker1; +LKernel.append(_ker1); + +var result = matmulreduce(LKernel); +writeln("###############"); +writeln("Product:"); +printmatrix(result); \ No newline at end of file From 658e69d9874049acca34681f39dd3abc4e613597 Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Wed, 29 Jan 2020 15:07:53 -0800 Subject: [PATCH 07/23] Boundary map calculation progress so far. --- example/homology.chpl | 69 +++++++++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 16 deletions(-) diff --git a/example/homology.chpl b/example/homology.chpl index 8eb5b23..ab0f19d 100644 --- a/example/homology.chpl +++ b/example/homology.chpl @@ -25,6 +25,8 @@ use Search; /* writeln("Removing duplicates: ", hypergraph.removeDuplicates()); */ /* hypergraph.removeDuplicates(); */ +/*TODO: move all constants to the top of your file and all declarations of types as well. */ + var hypergraph = new AdjListHyperGraph(4, 1, new unmanaged Cyclic(startIdx=0)); for v in hypergraph.getVertices() do hypergraph.addInclusion(v, 0); @@ -55,7 +57,7 @@ proc doProcessVertices (verticesSet) { return; } else if (verticesSet.size == 1) { var verticesStr = stringify(verticesSet); - if !_vtxSubsetSet.contains(verticesStr) { + if !_vtxSubsetSet.contains(verticesStr) { // TODO: redundant? _vtxSubsetSet.add(verticesStr); } } else { @@ -106,6 +108,11 @@ class kCellsArray{ proc init(_N: int) { numKCells = _N; } + proc findCellIndex(s :string) { + for k in A { + + } + } } var numBins = kCellMap.size - 1; @@ -131,6 +138,12 @@ var absComparator: Comparator; // sort(Array, comparator=absComparator); +/*TODO: change the following loop as follows:*/ +/*forall k in 0..K { + kCellsArrayMap[k] = new owned kCellsArray(k + 1); + kCellsArrayMap[k].A = kCellMap[k + 1].toArray(); + sort(kCellsArrayMap[k].A, comparator=absComparator); +}*/ writeln("%%%%%%%%%%%%%"); // Leader-follower iterator @@ -148,8 +161,17 @@ for (_kCellsArray, kCellKey) in zip(kCellsArrayMap, kCellKeys) { } writeln("%%%%%%%%%%%%%"); +// TODO: change the following: +/* +for (_kCellsArray, idx) in (kCellsArrayMap, 1..K) { + writeln((_kCellsArray.A, idx) : string); +} +*/ writeln("Printing after sorting"); writeln("^^^^^^^^^^^^^^^^^^^^^^^"); +/* for (_kCellsArray, idx) in zip(kCellsArrayMap, 1..numBins) { */ +/* writeln((_kCellsArray.A, idx) : string); */ +/* } */ for _kCellsArray in kCellsArrayMap { writeln(_kCellsArray.A : string); } @@ -220,32 +242,47 @@ writeln("####"); for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { var arrayOfKCells = kCellsArrayMap[dimension_k].A; // Arrays of strings, each string being 1 kcell var arrayOfK_1Cells = kCellsArrayMap[dimension_k_1].A; + compilerWarning(arrayOfK_1Cells.type : string); writeln("$$$$$$$$$$$"); writeln(arrayOfKCells); writeln(arrayOfK_1Cells); writeln("$$$$$$$$$$$"); + var i : int = 0; + var j : int = 0; for SkCell in arrayOfKCells { // iterate through all the k-cells + i = i + 1; /* Generate permutation of the current k-Cell*/ - compilerWarning(SkCell.type : string); + // compilerWarning(SkCell.type : string); var kCell = SkCell.split(" ") : int; - compilerWarning(kCell.type : string); + // compilerWarning(kCell.type : string); writeln("#kcell: " + kCell :string); - vs.clear(); - doProcessVertices2(kCell); - var _setContent = vs.toArray(); - writeln("Combinations generated ": string); - for c in _setContent do - writeln(c); - for Sk_1Cell in arrayOfK_1Cells { - var k_1Cell = Sk_1Cell.split(" "); - for c in _setContent { - for k_1 in k_1Cell { - if (k_1 == c) { - - } + /* writeln("Combinations generated ": string); */ + for sc in processVtxSubset(kCell) { + compilerWarning(sc.type : string); + writeln(sc); + var st = stringify(sc); + j = 0; + for Sk_1Cell in arrayOfK_1Cells { + j = j + 1; + if (st == Sk_1Cell) { + writeln(st :string + "matches"); + boundaryMap[i, j] = 1; + break; } } } + /* for c in _setContent do */ + /* writeln(c); */ + /* for Sk_1Cell in arrayOfK_1Cells { */ + /* var k_1Cell = Sk_1Cell.split(" "); */ + /* for c in _setContent { */ + /* for k_1 in k_1Cell { */ + /* if (k_1 == c) { */ + /* boundaryMap[] */ + /* } */ + /* } */ + /* } */ + /* } */ // doProcessVertices() /* for kk in kCell { */ /* compilerWarning(kk.type :string); */ From 491eca10a4b6931af7e379e3c98573be4ec8ca5c Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Wed, 29 Jan 2020 15:11:13 -0800 Subject: [PATCH 08/23] Fixing a compiler error --- example/homology.chpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/homology.chpl b/example/homology.chpl index ab0f19d..26979e8 100644 --- a/example/homology.chpl +++ b/example/homology.chpl @@ -266,7 +266,7 @@ for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { j = j + 1; if (st == Sk_1Cell) { writeln(st :string + "matches"); - boundaryMap[i, j] = 1; + boundaryMap.matrix[i, j] = 1; break; } } From e931fbc487406cf365b238a075498e270a61c602 Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Wed, 29 Jan 2020 15:50:05 -0800 Subject: [PATCH 09/23] Boundary matrix computation done hopefully. --- example/homology.chpl | 49 +++++++++++++------------------------------ 1 file changed, 15 insertions(+), 34 deletions(-) diff --git a/example/homology.chpl b/example/homology.chpl index 26979e8..941cb5b 100644 --- a/example/homology.chpl +++ b/example/homology.chpl @@ -266,46 +266,27 @@ for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { j = j + 1; if (st == Sk_1Cell) { writeln(st :string + "matches"); - boundaryMap.matrix[i, j] = 1; + boundaryMap.matrix[j, i] = 1; break; } } } - /* for c in _setContent do */ - /* writeln(c); */ - /* for Sk_1Cell in arrayOfK_1Cells { */ - /* var k_1Cell = Sk_1Cell.split(" "); */ - /* for c in _setContent { */ - /* for k_1 in k_1Cell { */ - /* if (k_1 == c) { */ - /* boundaryMap[] */ - /* } */ - /* } */ - /* } */ - /* } */ - // doProcessVertices() - /* for kk in kCell { */ - /* compilerWarning(kk.type :string); */ - /* writeln("kk:" + kk :string); */ - /* } */ - /* compilerWarning(kCell.type : string); */ - /* for Sk_1Cell in arrayOfK_1Cells { */ - /* var k_1Cell = Sk_1Cell.split(" "); */ - /* for kk in k_1Cell { */ - /* var (found, Pos) = binarySearch(kCell, kk, comparator=absComparator); */ - /* if (found) { */ - /* writeln(kk : string + " was found in: " + kCell); */ - /* } */ - /* } */ - /* writeln("Considering combination: " , kCell : string + " and " + k_1Cell :string); */ - /* /\* var position = kCell.find(k_1Cell); *\/ */ - /* /\* if (position != 0) { *\/ */ - /* /\* writeln(k_1Cell: string + " Occurs at position: " + position : string); *\/ */ - /* /\* } *\/ */ - /* } */ } writeln("$$$$$$$$$$$"); } +proc printBoundaryMap(boundaryMap) { + var row : int = boundaryMap.matrix.domain.high(1); + var col : int = boundaryMap.matrix.domain.high(2); + for i in 1..row { + for j in 1..col { + write(boundaryMap.matrix[i, j] : string + " "); + } + writeln(); + } +} - +for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { + writeln("Printing boundary map for: " : string + dimension_k_1 : string + " " :string + dimension_k : string); + printBoundaryMap(boundaryMap); +} From 21cefb922f16ad00071f5cdc9d34773f86df89ee Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Tue, 4 Feb 2020 13:31:57 -0800 Subject: [PATCH 10/23] Fixed a bug when multiplying bunch of matrices. --- example/snf.chpl | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/example/snf.chpl b/example/snf.chpl index 7ebba96..438a01e 100644 --- a/example/snf.chpl +++ b/example/snf.chpl @@ -152,20 +152,29 @@ proc matmultmod (M, N, mod =2) { type listType = list(unmanaged Matrix2D?, true); proc matmulreduce(arr : listType, reverse = false, mod = 2) { - var P : [arr(1)._arr._dom] int; + var PD: domain(2) = {1..arr(1)._arr.domain.high(1), 1..arr(1)._arr.domain.high(2)}; + var P : [PD] int; if (reverse) { + PD = {1..arr(arr.size)._arr.domain.high(1), 1..arr(arr.size)._arr.domain.high(2)}; P = arr(arr.size)._arr; for i in 1..#arr.size - 1 by -1 { - P = matmultmod(P, arr(i)._arr); + var tempD : domain(2) = {1..P.domain.high(1), 1..arr(i)._arr.domain.high(2)}; + var temp : [tempD] int; + temp = matmultmod(P, arr(i)._arr); + PD = tempD; + P = temp; } } else { P = arr(1)._arr; for i in 2..arr.size { - P = matmultmod(P, arr(i)._arr); + var tempD : domain(2) = {1..P.domain.high(1), 1..arr(i)._arr.domain.high(2)}; + var temp : [tempD] int; + temp = matmultmod(P, arr(i)._arr); + PD = tempD; + P = temp; } } return P; - } // rank calculation: @@ -316,6 +325,10 @@ writeln("###############"); writeln("ker1:"); printmatrix(ker1); +writeln("###############"); +writeln("L2:"); +printmatrix(L2); + var LKernel = new list(unmanaged Matrix2D?, true); var _L2 = new unmanaged Matrix2D(L2.domain.high(1), L2.domain.high(2)); @@ -326,6 +339,9 @@ var _ker1 = new unmanaged Matrix2D(ker1.domain.high(1), ker1.domain.high(2)); _ker1._arr = ker1; LKernel.append(_ker1); +writeln("L2 dimension: " + L2.domain.high(1) :string + "X" + L2.domain.high(2):string); +writeln("ker1 dimension: " + ker1.domain.high(1) :string + "X" + ker1.domain.high(2):string); + var result = matmulreduce(LKernel); writeln("###############"); writeln("Product:"); From 27353ab9072bbd1778e453acef044eb03e0385ec Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Tue, 4 Feb 2020 19:19:20 -0800 Subject: [PATCH 11/23] 1. Added full-pipeline from boundary matrix computation to calculating the Smith Normal form. 2. Added proc for computing reduced Row Echelon Form. --- example/boundary_matrix.chpl | 292 ++++++++++++++++++++ example/homology.chpl | 505 ++++++++++++++++++++++++++++++----- example/snf.chpl | 63 +++-- 3 files changed, 764 insertions(+), 96 deletions(-) create mode 100644 example/boundary_matrix.chpl diff --git a/example/boundary_matrix.chpl b/example/boundary_matrix.chpl new file mode 100644 index 0000000..941cb5b --- /dev/null +++ b/example/boundary_matrix.chpl @@ -0,0 +1,292 @@ +use CHGL; // Includes all core and utility components of CHGL +use Time; // For Timer +use Set; +use Map; +use List; +use Sort; +use Search; +/* + Part 1: Global-View Distributed Data Structures +*/ +// Question: How do we create a toy hypergraph? +// Answer: Generate it! +/* config const numVertices = 4; */ +/* config const numEdges = 10; */ +/* config const edgeProbability = 1; */ +/* var hypergraph = new AdjListHyperGraph(numVertices, numEdges, new unmanaged Cyclic(startIdx=0)); */ +/* var timer = new Timer(); */ +/* timer.start(); */ +/* generateErdosRenyi(hypergraph, edgeProbability); */ +/* timer.stop(); */ +/* writeln("Generated ErdosRenyi with |V|=", numVertices, */ +/* ", |E|=", numEdges, ", P_E=", edgeProbability, " in ", timer.elapsed(), " seconds"); */ + + +/* writeln("Removing duplicates: ", hypergraph.removeDuplicates()); */ +/* hypergraph.removeDuplicates(); */ + +/*TODO: move all constants to the top of your file and all declarations of types as well. */ + +var hypergraph = new AdjListHyperGraph(4, 1, new unmanaged Cyclic(startIdx=0)); +for v in hypergraph.getVertices() do hypergraph.addInclusion(v, 0); + + +// writeln(e : string + " vertices:" + vertices :string); +// writeln("-----"); + /* for currentsize in 1..#vertices.size by -1 { */ + /* writeln("Strings: "); */ + +// writeln(elmInSubset : string); + +// var vertices = graph.incidence(graph.toEdge(eIdx)); + +var _vtxSubsetSet = new set(string); + +iter processVtxSubset(vtxSubset) { + for i in 1..#vtxSubset.size { + var tmp : [1..#vtxSubset.size - 1] int; + tmp[1..i - 1] = vtxSubset[1..i - 1]; + tmp[i..] = vtxSubset[i + 1..]; + yield tmp; + } +} + +/* Generate the permutation */ +proc doProcessVertices (verticesSet) { + if (verticesSet.size == 0) { + return; + } else if (verticesSet.size == 1) { + var verticesStr = stringify(verticesSet); + if !_vtxSubsetSet.contains(verticesStr) { // TODO: redundant? + _vtxSubsetSet.add(verticesStr); + } + } else { + var verticesStr = stringify(verticesSet); + if !_vtxSubsetSet.contains(verticesStr) { + _vtxSubsetSet.add(verticesStr); + for _vtxSubset in processVtxSubset(verticesSet) { + doProcessVertices(_vtxSubset); + } + } + } +} + +/*For each of the hyperedge, do the permutation of all the vertices.*/ +for e in hypergraph.getEdges() { + var vertices = hypergraph.incidence(e); // ABCD + // writeln(vertices.domain); + ref tmp = vertices[1..#vertices.size]; + var verticesInEdge : [1..#vertices.size] int; + verticesInEdge[1..#vertices.size] = tmp.id; // ABCD vertices.low + compilerWarning(verticesInEdge.type :string ); + doProcessVertices(verticesInEdge); +} + +writeln("Printing all generated combination"); +/*Verify the set by printing*/ +var setContent = _vtxSubsetSet.toArray(); +for c in setContent do + writeln(c); + +writeln("-----"); +var _sz = 0; +writeln("Printing bins"); +/*bin k-cells, with key as the length of the list and value is a list with all the k-cells*/ +var kCellMap = new map(int, list(string, true)); +for vtxSet in _vtxSubsetSet { + //var _vtxSet = vtxSet.split(" "); + var sz = + reduce [ch in vtxSet] ch == ' '; + writeln(sz : string + " " + vtxSet : string); + kCellMap[sz].append(vtxSet); + _sz = sz; +} + +class kCellsArray{ + var numKCells : int; + var D = {1..numKCells}; + var A : [D] string; + proc init(_N: int) { + numKCells = _N; + } + proc findCellIndex(s :string) { + for k in A { + + } + } +} + +var numBins = kCellMap.size - 1; +var kCellsArrayMap : [0..numBins] owned kCellsArray?; +var kCellKeys = kCellMap.keysToArray(); +sort(kCellKeys); + +// Empty record serves as comparator +record Comparator { } +// compare method defines how 2 elements are compared +// Simplified comparator since we know that the strings are of the same size +proc Comparator.compare(a :string, b :string) : int { + var retVal : int = 0; + for (c1, c2) in zip (a , b) { + if (c1 == c2) {continue;} + if (c1 < c2) {retVal = -1; break;} + else {retVal = 1; break;} + } + return retVal; +} + +var absComparator: Comparator; + + +// sort(Array, comparator=absComparator); +/*TODO: change the following loop as follows:*/ +/*forall k in 0..K { + kCellsArrayMap[k] = new owned kCellsArray(k + 1); + kCellsArrayMap[k].A = kCellMap[k + 1].toArray(); + sort(kCellsArrayMap[k].A, comparator=absComparator); +}*/ + +writeln("%%%%%%%%%%%%%"); +// Leader-follower iterator +// Create the new KcellMaps for convenience of sorting +for (_kCellsArray, kCellKey) in zip(kCellsArrayMap, kCellKeys) { + writeln("listsize: " + kCellMap[kCellKey].size : string); + _kCellsArray = new owned kCellsArray(kCellMap[kCellKey].size); + _kCellsArray.A = kCellMap[kCellKey].toArray(); + // compilerWarning(kCellMap[kCellKey].toArray().type : string); + sort(_kCellsArray.A, comparator=absComparator); + /* for c in kCellMap[kCellKey].toArray() { */ + /* writeln(c); */ + /* compilerWarning(c.type: string); */ + /* } */ +} +writeln("%%%%%%%%%%%%%"); + +// TODO: change the following: +/* +for (_kCellsArray, idx) in (kCellsArrayMap, 1..K) { + writeln((_kCellsArray.A, idx) : string); +} +*/ +writeln("Printing after sorting"); +writeln("^^^^^^^^^^^^^^^^^^^^^^^"); +/* for (_kCellsArray, idx) in zip(kCellsArrayMap, 1..numBins) { */ +/* writeln((_kCellsArray.A, idx) : string); */ +/* } */ +for _kCellsArray in kCellsArrayMap { + writeln(_kCellsArray.A : string); +} +writeln("^^^^^^^^^^^^^^^^^^^^^^^"); + +/*Start of the construction of boundary matrices.*/ +class Matrix { + var N : int; + var M : int; + var matrix : [1..N, 1..M] int; + proc init(_N: int, _M:int) { + N = _N; + M = _M; + } +} + +var K = kCellMap.size - 1; +var boundaryMaps : [1..K] owned Matrix?; +var i : int = 1; + +// Leader-follower iterator +// Create the boundary Maps +for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { + writeln("dimensions: " + kCellsArrayMap[dimension_k_1].numKCells: string + " " + kCellsArrayMap[dimension_k].numKCells : string); + boundaryMap = new owned Matrix(kCellsArrayMap[dimension_k_1].numKCells, kCellsArrayMap[dimension_k].numKCells); +} + +/* forall (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { */ +/* writeln("dimensions: " + kCellMap[dimension_k_1].size: string + " " + kCellMap[dimension_k].size : string); */ +/* boundaryMap = new owned Matrix(kCellMap[dimension_k_1].size, kCellMap[dimension_k].size); */ +/* } */ + + +var vs = new set(string); + +iter processVtxSubset2(vtxSubset) { + for i in 1..#vtxSubset.size { + var tmp : [1..#vtxSubset.size - 1] int; + tmp[1..i - 1] = vtxSubset[1..i - 1]; + tmp[i..] = vtxSubset[i + 1..]; + yield tmp; + } +} + +/* Generate the permutation */ +proc doProcessVertices2 (verticesSet) { + if (verticesSet.size == 0) { + return; + } else if (verticesSet.size == 1) { + var verticesStr = stringify(verticesSet); + if !vs.contains(verticesStr) { + vs.add(verticesStr); + } + } else { + var verticesStr = stringify(verticesSet); + if !vs.contains(verticesStr) { + vs.add(verticesStr); + for _vtxSubset in processVtxSubset2(verticesSet) { + doProcessVertices2(_vtxSubset); + } + } + } +} + + +writeln("####"); +// Compute values for each entries in each of the boundary map +for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { + var arrayOfKCells = kCellsArrayMap[dimension_k].A; // Arrays of strings, each string being 1 kcell + var arrayOfK_1Cells = kCellsArrayMap[dimension_k_1].A; + compilerWarning(arrayOfK_1Cells.type : string); + writeln("$$$$$$$$$$$"); + writeln(arrayOfKCells); + writeln(arrayOfK_1Cells); + writeln("$$$$$$$$$$$"); + var i : int = 0; + var j : int = 0; + for SkCell in arrayOfKCells { // iterate through all the k-cells + i = i + 1; + /* Generate permutation of the current k-Cell*/ + // compilerWarning(SkCell.type : string); + var kCell = SkCell.split(" ") : int; + // compilerWarning(kCell.type : string); + writeln("#kcell: " + kCell :string); + /* writeln("Combinations generated ": string); */ + for sc in processVtxSubset(kCell) { + compilerWarning(sc.type : string); + writeln(sc); + var st = stringify(sc); + j = 0; + for Sk_1Cell in arrayOfK_1Cells { + j = j + 1; + if (st == Sk_1Cell) { + writeln(st :string + "matches"); + boundaryMap.matrix[j, i] = 1; + break; + } + } + } + } + writeln("$$$$$$$$$$$"); +} + +proc printBoundaryMap(boundaryMap) { + var row : int = boundaryMap.matrix.domain.high(1); + var col : int = boundaryMap.matrix.domain.high(2); + for i in 1..row { + for j in 1..col { + write(boundaryMap.matrix[i, j] : string + " "); + } + writeln(); + } +} + +for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { + writeln("Printing boundary map for: " : string + dimension_k_1 : string + " " :string + dimension_k : string); + printBoundaryMap(boundaryMap); +} diff --git a/example/homology.chpl b/example/homology.chpl index 941cb5b..5463cee 100644 --- a/example/homology.chpl +++ b/example/homology.chpl @@ -5,40 +5,17 @@ use Map; use List; use Sort; use Search; -/* - Part 1: Global-View Distributed Data Structures -*/ -// Question: How do we create a toy hypergraph? -// Answer: Generate it! -/* config const numVertices = 4; */ -/* config const numEdges = 10; */ -/* config const edgeProbability = 1; */ -/* var hypergraph = new AdjListHyperGraph(numVertices, numEdges, new unmanaged Cyclic(startIdx=0)); */ -/* var timer = new Timer(); */ -/* timer.start(); */ -/* generateErdosRenyi(hypergraph, edgeProbability); */ -/* timer.stop(); */ -/* writeln("Generated ErdosRenyi with |V|=", numVertices, */ -/* ", |E|=", numEdges, ", P_E=", edgeProbability, " in ", timer.elapsed(), " seconds"); */ - -/* writeln("Removing duplicates: ", hypergraph.removeDuplicates()); */ -/* hypergraph.removeDuplicates(); */ - -/*TODO: move all constants to the top of your file and all declarations of types as well. */ - -var hypergraph = new AdjListHyperGraph(4, 1, new unmanaged Cyclic(startIdx=0)); -for v in hypergraph.getVertices() do hypergraph.addInclusion(v, 0); - - -// writeln(e : string + " vertices:" + vertices :string); -// writeln("-----"); - /* for currentsize in 1..#vertices.size by -1 { */ - /* writeln("Strings: "); */ - -// writeln(elmInSubset : string); - -// var vertices = graph.incidence(graph.toEdge(eIdx)); +var hypergraph = new AdjListHyperGraph(4, 3, new unmanaged Cyclic(startIdx=0)); +// V = ['A','B','C','D']; +// E = ['AB','BC','ACD']; +hypergraph.addInclusion(0, 0); +hypergraph.addInclusion(1,0); +hypergraph.addInclusion(1,1); +hypergraph.addInclusion(2,1); +hypergraph.addInclusion(0,2); +hypergraph.addInclusion(2,2); +hypergraph.addInclusion(3,2); var _vtxSubsetSet = new set(string); @@ -74,11 +51,9 @@ proc doProcessVertices (verticesSet) { /*For each of the hyperedge, do the permutation of all the vertices.*/ for e in hypergraph.getEdges() { var vertices = hypergraph.incidence(e); // ABCD - // writeln(vertices.domain); ref tmp = vertices[1..#vertices.size]; var verticesInEdge : [1..#vertices.size] int; verticesInEdge[1..#vertices.size] = tmp.id; // ABCD vertices.low - compilerWarning(verticesInEdge.type :string ); doProcessVertices(verticesInEdge); } @@ -136,15 +111,6 @@ proc Comparator.compare(a :string, b :string) : int { var absComparator: Comparator; - -// sort(Array, comparator=absComparator); -/*TODO: change the following loop as follows:*/ -/*forall k in 0..K { - kCellsArrayMap[k] = new owned kCellsArray(k + 1); - kCellsArrayMap[k].A = kCellMap[k + 1].toArray(); - sort(kCellsArrayMap[k].A, comparator=absComparator); -}*/ - writeln("%%%%%%%%%%%%%"); // Leader-follower iterator // Create the new KcellMaps for convenience of sorting @@ -152,26 +118,12 @@ for (_kCellsArray, kCellKey) in zip(kCellsArrayMap, kCellKeys) { writeln("listsize: " + kCellMap[kCellKey].size : string); _kCellsArray = new owned kCellsArray(kCellMap[kCellKey].size); _kCellsArray.A = kCellMap[kCellKey].toArray(); - // compilerWarning(kCellMap[kCellKey].toArray().type : string); sort(_kCellsArray.A, comparator=absComparator); - /* for c in kCellMap[kCellKey].toArray() { */ - /* writeln(c); */ - /* compilerWarning(c.type: string); */ - /* } */ } writeln("%%%%%%%%%%%%%"); -// TODO: change the following: -/* -for (_kCellsArray, idx) in (kCellsArrayMap, 1..K) { - writeln((_kCellsArray.A, idx) : string); -} -*/ writeln("Printing after sorting"); writeln("^^^^^^^^^^^^^^^^^^^^^^^"); -/* for (_kCellsArray, idx) in zip(kCellsArrayMap, 1..numBins) { */ -/* writeln((_kCellsArray.A, idx) : string); */ -/* } */ for _kCellsArray in kCellsArrayMap { writeln(_kCellsArray.A : string); } @@ -199,12 +151,6 @@ for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { boundaryMap = new owned Matrix(kCellsArrayMap[dimension_k_1].numKCells, kCellsArrayMap[dimension_k].numKCells); } -/* forall (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { */ -/* writeln("dimensions: " + kCellMap[dimension_k_1].size: string + " " + kCellMap[dimension_k].size : string); */ -/* boundaryMap = new owned Matrix(kCellMap[dimension_k_1].size, kCellMap[dimension_k].size); */ -/* } */ - - var vs = new set(string); iter processVtxSubset2(vtxSubset) { @@ -239,10 +185,9 @@ proc doProcessVertices2 (verticesSet) { writeln("####"); // Compute values for each entries in each of the boundary map -for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { +for (dimension_k_1, dimension_k) in zip(0..1, 1..2) { var arrayOfKCells = kCellsArrayMap[dimension_k].A; // Arrays of strings, each string being 1 kcell var arrayOfK_1Cells = kCellsArrayMap[dimension_k_1].A; - compilerWarning(arrayOfK_1Cells.type : string); writeln("$$$$$$$$$$$"); writeln(arrayOfKCells); writeln(arrayOfK_1Cells); @@ -252,21 +197,17 @@ for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { for SkCell in arrayOfKCells { // iterate through all the k-cells i = i + 1; /* Generate permutation of the current k-Cell*/ - // compilerWarning(SkCell.type : string); var kCell = SkCell.split(" ") : int; - // compilerWarning(kCell.type : string); writeln("#kcell: " + kCell :string); /* writeln("Combinations generated ": string); */ for sc in processVtxSubset(kCell) { - compilerWarning(sc.type : string); - writeln(sc); var st = stringify(sc); j = 0; for Sk_1Cell in arrayOfK_1Cells { j = j + 1; if (st == Sk_1Cell) { - writeln(st :string + "matches"); - boundaryMap.matrix[j, i] = 1; + // writeln(st :string + "matches"); + boundaryMaps[dimension_k].matrix[j, i] = 1; break; } } @@ -286,7 +227,423 @@ proc printBoundaryMap(boundaryMap) { } } -for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { +for (dimension_k_1, dimension_k) in zip(0..1, 1..2) { writeln("Printing boundary map for: " : string + dimension_k_1 : string + " " :string + dimension_k : string); - printBoundaryMap(boundaryMap); + printBoundaryMap(boundaryMaps[dimension_k]); +} + + +proc printmatrix(M) { + for i in {1..M.domain.high(1)} { + for j in {1..M.domain.high(2)} { + write(M(i,j):string + " "); + } + writeln(); + } +} + + +proc IdentityMatrix(n) { + var A : [1..n, 1..n] int; + [i in A.domain.dim(1)] A[i,i] = 1; + return A; +} + +use List; +class Matrix2D { + var N : int; + var M : int; + var _arr : [1..N, 1..M] int; + proc init (row : int, col : int) { + N = row; + M = col; + } +} + +proc _get_next_pivot(M, s1, in s2 : int = 0) { + var dims = M.domain.high; + var dimR = dims(1); + var dimC = dims(2); + if (s2 == 0) { + s2 = s1; + } + for c in s2..dimC { + for r in s1..dimR { + if (M(r,c) != 0) { + return (r,c); + } + } + } + return (-1,-1); // TODO: return +} + + +proc swap_rows(i, j, M) { + var N = M; + N[i, ..] <=> N[j, ..]; + return N; +} + +proc swap_columns(i, j, M) { + var N = M; + N[.., i] <=> N[.., j]; + return N; +} + +// Replaces row i (of M) with sum ri multiple of ith row and rj multiple of jth row +proc add_to_row(M, i, j, ri = 1, rj = 1, mod = 2) { + var N = M; + N[i, ..] = (ri * N[i, ..] + rj * N[j, ..]) % mod; + return N; +} + + +proc add_to_column(M, i, j, ci = 1, cj = 1, mod = 2) { + var N = M; + N[.., i] = (ci * N[.., i] + cj * N[..,j]) % mod; + return N; +} + +proc matmultmod2 (M, N, mod = 2) { + var nr = M.domain.high(1); + var nc = N.domain.high(2); + var m = M.domain.high(2); + var C : [1..nr, 1..nc] atomic int; + + forall i in 1..nr { + for j in 1..nc { + C[i,j].write((+ reduce M[i, 1..m] * N[1..m, j]) % 2) ; + } + } + return C.read(); +} + +proc matmultmod3 (M, N, mod = 2) { + var C : [M.domain.dim(1), N.domain.dim(2)] atomic int; + forall (i,j) in C.domain { + C[i,j].write((+ reduce M[i, M.domain.dim(2)] * N[M.domain.dim(2), j]) % 2); + } + return C.read(); +} + +proc matmultmod (M, N, mod =2) { + var C : [M.domain.dim(1), N.domain.dim(2)] int; + forall (i,j) in C.domain { + C[i,j] = (+ reduce (M[i, M.domain.dim(2)] * N[M.domain.dim(2), j])) % 2; + } + return C; +} + +type listType = list(unmanaged Matrix2D?, true); +proc matmulreduce(arr : listType, reverse = false, mod = 2) { + var PD: domain(2) = {1..arr(1)._arr.domain.high(1), 1..arr(1)._arr.domain.high(2)}; + var P : [PD] int; + if (reverse) { + PD = {1..arr(arr.size)._arr.domain.high(1), 1..arr(arr.size)._arr.domain.high(2)}; + P = arr(arr.size)._arr; + for i in 1..#arr.size - 1 by -1 { + var tempD : domain(2) = {1..P.domain.high(1), 1..arr(i)._arr.domain.high(2)}; + var temp : [tempD] int; + temp = matmultmod(P, arr(i)._arr); + PD = tempD; + P = temp; + } + } else { + P = arr(1)._arr; + for i in 2..arr.size { + var tempD : domain(2) = {1..P.domain.high(1), 1..arr(i)._arr.domain.high(2)}; + var temp : [tempD] int; + temp = matmultmod(P, arr(i)._arr); + PD = tempD; + P = temp; + } + } + return P; +} + +// rank calculation: +proc calculateRank(M) { + var rank = + reduce [i in M.domain.dim(2)] (max reduce M[.., i]); + return rank; +} + + +// printmatrix(b); + +proc smithNormalForm(b) { + var dims = b.domain.high; + var dimL = dims(1); + var dimR = dims(2); + var minDim = if dimL <= dimR then dimL else dimR; + + // writeln(dimL : string ); // dims give me the index set but I need the max value of the index set + // writeln(minDim); + + + var S = b; + var IL = IdentityMatrix(dimL); + var IR = IdentityMatrix(dimR); + + var Linv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation + var Rinv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation + + var Linit = new unmanaged Matrix2D(IL.domain.high(1), IL.domain.high(2)); + Linit._arr = IL; + Linv.append(Linit); + var Rinit = new unmanaged Matrix2D(IR.domain.high(1), IR.domain.high(2)); + Rinit._arr = IR; + Rinv.append(Rinit); + + var L = IL; + var R = IR; + + /* writeln("###############"); */ + /* writeln("L:"); */ + /* printmatrix(L); */ + /* writeln("###############"); */ + /* writeln("R:"); */ + /* printmatrix(R); */ + + // var rc = _get_next_pivot(b, 3); + // writeln(rc : string); + + + writeln("########"); + for s in 1..minDim { + writeln("Iteration: " + s : string); + var pivot = _get_next_pivot(S,s); + var rdx : int, cdx : int; + if (pivot(1) == -1 && pivot(2) == -1) { + break; + } + else { + (rdx, cdx) = pivot; + } + + // Swap rows and columns as needed so the 1 is in the s,s position + if (rdx > s) { + S = swap_rows(s, rdx, S); + L = swap_rows(s, rdx, L); + var tmp = swap_rows(s, rdx, IL); + var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + LM._arr = tmp; + Linv.append(LM); + } + if (cdx > s) { + S = swap_columns(s, cdx, S); + R = swap_columns(s, cdx, R); + var tmp = swap_columns(s, cdx, IR); + var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + RM._arr = tmp; + Rinv.append(RM); + } + + // add sth row to every nonzero row & sth column to every nonzero column + // zip(S[.., s], S.dim(1)) gives you (S[i,j], 1..N) + // row_indices = [idx for idx in range(dimL) if idx != s and S[idx][s] == 1] + // var RD: domain(2) = {1..dimL, 1..dimL}; + // var row_indices = [(x,(i,j)) in zip(S, 1..dimL)] if x == 1 && j != s then (i,j); + // var row_indices = [(s,idx) in zip(S, {1..dimL})] if s == 1 then idx; + + var row_indices = [idx in 1..dimL] if (idx != s && S(idx,s) == 1) then idx; + // compilerWarning(row_indices.type : string); + + for rdx in row_indices { + // writeln("rdx: " + rdx : string); + S = add_to_row(S, rdx, s); + L = add_to_row(L, rdx, s); + var tmp = add_to_row(IL, rdx, s); + var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + LM._arr = tmp; + Linv.append(LM); + } + + var column_indices = [jdx in 1..dimR] if (jdx != s && S(s,jdx) == 1) then jdx; + + for (jdx,cdx) in zip(1..,column_indices) {// TODO: check + // writeln("rdx: " + rdx : string); + S = add_to_column(S, cdx, s); + R = add_to_column(R, cdx, s); + var tmp = add_to_column(IR, cdx, s); + var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + RM._arr = tmp; + Rinv.append(RM); + } + } + + + var LinvF = matmulreduce(Linv); + var RinvF = matmulreduce(Rinv, true, 2); + return (L,R,S,LinvF,RinvF); } + +var computedMatrices = smithNormalForm(boundaryMaps[1].matrix); +var computedMatrices2 = smithNormalForm(boundaryMaps[2].matrix); +var L1 = computedMatrices(1); +var R1 = computedMatrices(2); +var S1 = computedMatrices(3); +var L1invF = computedMatrices(4); +var R1invF = computedMatrices(5); +var L2 = computedMatrices2(1); +var R2 = computedMatrices2(2); +var S2 = computedMatrices2(3); +var L2invF = computedMatrices2(4); +var R2invF = computedMatrices2(5); +writeln("###############"); +writeln("L1:"); +printmatrix(L1); +writeln("###############"); +writeln("R1:"); +printmatrix(R1); +writeln("###############"); +writeln("S1:"); +printmatrix(S1); +writeln("###############"); +writeln("L1inv:"); +printmatrix(L1invF); +writeln("###############"); +writeln("R1inv:"); +printmatrix(R1invF); +writeln("###############"); +writeln("L2inv:"); +printmatrix(L2invF); + +var rank1 = calculateRank(S1); +writeln("Rank of S1: " + rank1 : string); +var rank2 = calculateRank(S2); +writeln("Rank of S2: " + rank2 : string); +var nullity1 = S1.domain.high(2) - rank1; +var betti1 = S1.domain.high(2) - rank1 - rank2; +var cokernel2_dim = S1.domain.high(2) - rank2; + +var nr1 = R1.domain.high(2) - rank1; +var ker1 : [1..R1.domain.high(1), 1..nr1] int = R1[..,rank1+1..]; +writeln("###############"); +writeln("ker1:"); +printmatrix(ker1); + +// im2 = L2inv[:,:rank2] +var im2 : [1..L2invF.domain.high(1), 1..rank2] int = L2invF[..,1..rank2]; +var nr2 = L2invF.domain.high(2) - rank2; +var cokernel2 : [1..L2invF.domain.high(1), 1..nr2] int = L2invF[..,rank2 + 1..]; + +writeln("###############"); +writeln("Cokernel:"); +printmatrix(cokernel2); + +writeln("###############"); +writeln("L2:"); +printmatrix(L2); + +var LKernel = new list(unmanaged Matrix2D?, true); + +var _L2 = new unmanaged Matrix2D(L2.domain.high(1), L2.domain.high(2)); +_L2._arr = L2; +LKernel.append(_L2); + +var _ker1 = new unmanaged Matrix2D(ker1.domain.high(1), ker1.domain.high(2)); +_ker1._arr = ker1; +LKernel.append(_ker1); + +writeln("L2 dimension: " + L2.domain.high(1) :string + "X" + L2.domain.high(2):string); +writeln("ker1 dimension: " + ker1.domain.high(1) :string + "X" + ker1.domain.high(2):string); + +var result = matmulreduce(LKernel); +var slc = result.domain.high(1) - rank2; +var proj : [1..slc, 1..result.domain.high(2)] int = result[rank2 + 1..,..]; +writeln("###############"); +writeln("Projection1:"); +printmatrix(proj); + +// proj = matmulreduce([L2,ker1])[rank2:,:] +// proj = matmulreduce([L2inv[:,rank2:],proj]).transpose() + +var L2invKernel = new list(unmanaged Matrix2D?, true); + +// var nr2 = L2invF.domain.high(2) - rank2; +var _L2inv = new unmanaged Matrix2D(L2invF.domain.high(1), nr2); +_L2inv._arr = L2invF[..,rank2 + 1..]; +L2invKernel.append(_L2inv); + +var _proj = new unmanaged Matrix2D(proj.domain.high(1), proj.domain.high(2)); +_proj._arr = proj; +L2invKernel.append(_proj); + +var proj2 = matmulreduce(L2invKernel); + +writeln("###############"); +writeln("Projection2:"); +printmatrix(proj2); + + +proc reducedRowEchelonForm(b) { + var dims = b.domain.high; + var dimL = dims(1); + var dimR = dims(2); + var minDim = if dimL <= dimR then dimL else dimR; + + // writeln(dimL : string ); // dims give me the index set but I need the max value of the index set + // writeln(minDim); + + + var S = b; + var IL = IdentityMatrix(dimL); + + var Linv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation + + var Linit = new unmanaged Matrix2D(IL.domain.high(1), IL.domain.high(2)); + Linit._arr = IL; + Linv.append(Linit); + + var L = IL; + + /* writeln("###############"); */ + /* writeln("L:"); */ + /* printmatrix(L); */ + /* writeln("###############"); */ + /* writeln("R:"); */ + /* printmatrix(R); */ + + // var rc = _get_next_pivot(b, 3); + // writeln(rc : string); + + var s2 : int = 1; + writeln("########"); + for s1 in 1..dimL { + writeln("Iteration: " + s1 : string); + var rdx : int, cdx : int; + for s2 in s2..dimR { + var pivot = _get_next_pivot(S,s1, s2); + if (pivot(1) != -1 && pivot(2) != -1) { + (rdx, cdx) = pivot; + s2 = cdx; + break; + } + } + // Swap rows + if (rdx > s1) { + S = swap_rows(s1, rdx, S); + L = swap_rows(s1, rdx, L); + var tmp = swap_rows(s1, rdx, IL); + var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + LM._arr = tmp; + Linv.append(LM); + } + + var row_indices = [idx in 1..dimL] if (idx != s1 && S(idx,cdx) == 1) then idx; + // compilerWarning(row_indices.type : string); + + for idx in row_indices { + // writeln("rdx: " + rdx : string); + S = add_to_row(S, idx, s1); + L = add_to_row(L, idx, s1); + var tmp = add_to_row(IL, idx, s1); + var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + LM._arr = tmp; + Linv.append(LM); + } + } + + var LinvF = matmulreduce(Linv); + return (L,S,LinvF); +} \ No newline at end of file diff --git a/example/snf.chpl b/example/snf.chpl index 438a01e..702a59a 100644 --- a/example/snf.chpl +++ b/example/snf.chpl @@ -295,36 +295,53 @@ proc smithNormalForm(b) { var computedMatrices = smithNormalForm(b); var computedMatrices2 = smithNormalForm(c); +var L1 = computedMatrices(1); +var R1 = computedMatrices(2); +var S1 = computedMatrices(3); +var L1invF = computedMatrices(4); +var R1invF = computedMatrices(5); var L2 = computedMatrices2(1); -var L = computedMatrices(1); -var R = computedMatrices(2); -var S = computedMatrices(3); -var LinvF = computedMatrices(4); -var RinvF = computedMatrices(5); +var R2 = computedMatrices2(2); +var S2 = computedMatrices2(3); +var L2invF = computedMatrices2(4); +var R2invF = computedMatrices2(5); writeln("###############"); -writeln("L:"); -printmatrix(L); +writeln("L1:"); +printmatrix(L1); writeln("###############"); -writeln("R:"); -printmatrix(R); +writeln("R1:"); +printmatrix(R1); writeln("###############"); -writeln("S:"); -printmatrix(S); +writeln("S1:"); +printmatrix(S1); writeln("###############"); -writeln("Linv:"); -printmatrix(LinvF); +writeln("L1inv:"); +printmatrix(L1invF); writeln("###############"); -writeln("Rinv:"); -printmatrix(RinvF); - -var r = calculateRank(S); -writeln("Rank of S: " + r : string); -var nr = R.domain.high(2) - r; -var ker1 :[1..R.domain.high(1), 1..nr] int = R[..,r+1..]; +writeln("R1inv:"); +printmatrix(R1invF); + +var rank1 = calculateRank(S1); +writeln("Rank of S1: " + rank1 : string); +var rank2 = calculateRank(S2); +writeln("Rank of S2: " + rank2 : string); +var nullity1 = S1.domain.high(2) - rank1; +var betti1 = S1.domain.high(2) - rank1 - rank2; +var cokernel2_dim = S1.domain.high(2) - rank2; + +var nr1 = R1.domain.high(2) - rank1; +var ker1 : [1..R1.domain.high(1), 1..nr1] int = R1[..,rank1+1..]; writeln("###############"); writeln("ker1:"); printmatrix(ker1); +// im2 = L2inv[:,:rank2] +var im2 : [1..L2invF.domain.high(1), 1..rank2] int = L2invF[..,1..rank2]; +var nr2 = L2invF.domain.high(2) - rank2; +var cokernel2 : [1..L2invF.domain.high(1), 1..nr2] int = L2invF[..,rank2 + 1..]; + + + writeln("###############"); writeln("L2:"); printmatrix(L2); @@ -343,6 +360,8 @@ writeln("L2 dimension: " + L2.domain.high(1) :string + "X" + L2.domain.high(2):s writeln("ker1 dimension: " + ker1.domain.high(1) :string + "X" + ker1.domain.high(2):string); var result = matmulreduce(LKernel); +var slc = result.domain.high(1) - rank2; +var proj : [1..slc, 1..result.domain.high(2)] int = result[rank2 + 1..,..]; writeln("###############"); -writeln("Product:"); -printmatrix(result); \ No newline at end of file +writeln("Projection1:"); +printmatrix(proj); \ No newline at end of file From 7c3038062e6155b194f2a2cd035a0c2d97c36246 Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Wed, 5 Feb 2020 16:36:51 -0800 Subject: [PATCH 12/23] Fixed errors in ActiveDNS code due to upgrade. --- example/activeDNS.chpl | 2 +- src/AdjListHyperGraph.chpl | 40 +++++++++++++++++++++----------------- src/PropertyMaps.chpl | 4 ++-- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/example/activeDNS.chpl b/example/activeDNS.chpl index 4af0583..0beb682 100644 --- a/example/activeDNS.chpl +++ b/example/activeDNS.chpl @@ -378,7 +378,7 @@ wq.flush(); // Aggregate fetches to properties into another work queue; when we flush // each of the property maps, their individual PropertyHandle will be finished. // Also send the 'String' so that it can be reclaimed. -var handleWQ = new WorkQueue((unmanaged PropertyHandle, unmanaged PropertyHandle), 64 * 1024); +var handleWQ = new WorkQueue((unmanaged PropertyHandle?, unmanaged PropertyHandle?), 64 * 1024); var handleTD = new TerminationDetector(); forall fileName in doWorkLoop(wq, td) { for line in getLines(fileName) { diff --git a/src/AdjListHyperGraph.chpl b/src/AdjListHyperGraph.chpl index 0335d2e..2a33696 100644 --- a/src/AdjListHyperGraph.chpl +++ b/src/AdjListHyperGraph.chpl @@ -1392,6 +1392,7 @@ prototype module AdjListHyperGraph { [dup in duplicateVertices] dup.write(-1); var newVerticesDomain = __verticesDomain; var vertexMappings : [__verticesDomain] int = -1; + var dummyNode = new unmanaged NodeData(eDescType, _vPropType); //writeln("Collapsing Vertices..."); // Pass 1: Locate duplicates by performing an s-walk where s is the size of current vertex @@ -1438,7 +1439,7 @@ prototype module AdjListHyperGraph { numUnique += 1; for follower in eqclass.getCandidates(leader) { delete _vertices[follower]; - _vertices[follower] = nil; + _vertices[follower] = dummyNode; duplicateVertices[follower].write(leader); } } @@ -1461,7 +1462,7 @@ prototype module AdjListHyperGraph { if Debug.ALHG_DEBUG { forall v in _verticesDomain { var vv = v; - while _vertices[vv] == nil { + while _vertices[vv] == dummyNode { vv = duplicateVertices[vv].read(); assert(vv != -1, "A vertex is nil without a duplicate mapping..."); } @@ -1478,7 +1479,7 @@ prototype module AdjListHyperGraph { writeln("Broken Dual!"); var vvv = v; write("Link: ", toVertex(v)); - while _vertices[vvv] == nil { + while _vertices[vvv] == dummyNode { vvv = duplicateVertices[vvv].read(); write(" -> ", toVertex(vvv)); } @@ -1513,7 +1514,7 @@ prototype module AdjListHyperGraph { // array; hence, try to first claim indices that are local in _both_ new and old arrays. var idx : atomic int; forall v in oldVertices.domain { - if oldVertices[v] != nil { + if oldVertices[v] != dummyNode { // TODO // When no RDMA atomics are supported, this will have _massive_ communication costs // Possibly want to perform explicit `coforall` and create explicit tasks on each @@ -1531,7 +1532,7 @@ prototype module AdjListHyperGraph { delete oldVertices[v]; } - oldVertices[v] = nil; + oldVertices[v] = dummyNode; vertexMappings[v] = ix; } } @@ -1602,7 +1603,7 @@ prototype module AdjListHyperGraph { [dup in duplicateEdges] dup.write(-1); var newEdgesDomain = __edgesDomain; var edgeMappings : [__edgesDomain] int = -1; - + var dummyEdge = new unmanaged NodeData(vDescType, _ePropType); //writeln("Collapsing Edges..."); @@ -1640,7 +1641,7 @@ prototype module AdjListHyperGraph { numUnique += 1; for follower in eqclass.getCandidates(leader) { delete _edges[follower]; - _edges[follower] = nil; + _edges[follower] = dummyEdge; duplicateEdges[follower].write(leader); } } @@ -1662,7 +1663,7 @@ prototype module AdjListHyperGraph { if Debug.ALHG_DEBUG { forall e in _edgesDomain { var ee = e; - while _edges[ee] == nil { + while _edges[ee] == dummyEdge { ee = duplicateEdges[ee].read(); assert(ee != -1, "An edge is nil without a duplicate mapping..."); } @@ -1680,7 +1681,7 @@ prototype module AdjListHyperGraph { writeln("Broken Dual!"); var eee = e; write("Link: ", toEdge(e)); - while _edges[eee] == nil { + while _edges[eee] == dummyEdge { eee = duplicateEdges[eee].read(); write(" -> ", toEdge(eee)); } @@ -1707,7 +1708,7 @@ prototype module AdjListHyperGraph { { var idx : atomic int; forall e in oldEdges.domain { - if oldEdges[e] != nil { + if oldEdges[e] != dummyEdge { var ix = idx.fetchAdd(1); if oldEdges[e].locale == _edges[ix].locale { @@ -1717,7 +1718,7 @@ prototype module AdjListHyperGraph { delete oldEdges[e]; } - oldEdges[e] = nil; + oldEdges[e] = dummyEdge; edgeMappings[e] = ix; } } @@ -1786,6 +1787,7 @@ prototype module AdjListHyperGraph { [toplex in toplexEdges] toplex.write(-1); var newEdgesDomain = __edgesDomain; var edgeMappings : [__edgesDomain] int = -1; + var dummyEdge = new unmanaged NodeData(vDescType, _ePropType); writeln("Collapsing Subset..."); { @@ -1830,7 +1832,7 @@ prototype module AdjListHyperGraph { forall e in _edgesDomain with (+ reduce numToplex) { if toplexEdges[e].read() != -1 { delete _edges[e]; - _edges[e] = nil; + _edges[e] = dummyEdge; } else { numToplex += 1; } @@ -1856,7 +1858,7 @@ prototype module AdjListHyperGraph { { var idx : atomic int; forall e in oldEdges.domain { - if oldEdges[e] != nil { + if oldEdges[e] != dummyEdge { var ix = idx.fetchAdd(1); if oldEdges[e].locale == _edges[ix].locale { @@ -1866,7 +1868,7 @@ prototype module AdjListHyperGraph { delete oldEdges[e]; } - oldEdges[e] = nil; + oldEdges[e] = dummyEdge; edgeMappings[e] = ix; } } @@ -2023,6 +2025,8 @@ prototype module AdjListHyperGraph { hyperedges. Returns the number of isolated components. */ proc removeIsolatedComponents() : int { + var dummyNode = new unmanaged NodeData(eDescType, _vPropType); + var dummyEdge = new unmanaged NodeData(vDescType, _ePropType); // Enforce on Locale 0 (presumed master locale...) if here != Locales[0] { // Cannot jump and return as return type is inferred by compiler. @@ -2046,11 +2050,11 @@ prototype module AdjListHyperGraph { if nn == 1 { if _this._ePropMap.isInitialized then _this._ePropMap.setProperty(_this.getEdge(e).property, -1); delete _this.getEdge(e); - _this.getEdge(e) = nil; + _this.getEdge(e) = dummyEdge; if _this._vPropMap.isInitialized then _this._vPropMap.setProperty(_this.getVertex(v).property, -1); delete _this.getVertex(v); - _this.getVertex(v) = nil; + _this.getVertex(v) = dummyNode; numIsolatedComponents += 1; } @@ -2095,7 +2099,7 @@ prototype module AdjListHyperGraph { delete oldVertices[v]; } - oldVertices[v] = nil; + oldVertices[v] = dummyNode; vertexMappings[v] = ix; } } @@ -2116,7 +2120,7 @@ prototype module AdjListHyperGraph { delete oldEdges[e]; } - oldEdges[e] = nil; + oldEdges[e] = dummyEdge; edgeMappings[e] = ix; } } diff --git a/src/PropertyMaps.chpl b/src/PropertyMaps.chpl index 03401a7..ae5fd2f 100644 --- a/src/PropertyMaps.chpl +++ b/src/PropertyMaps.chpl @@ -287,7 +287,7 @@ prototype module PropertyMaps { } } - proc _flushGetAggregatorBuffer(buf : Buffer, loc : locale, param acquireLock = true) { + proc _flushGetAggregatorBuffer(buf : Buffer?, loc : locale, param acquireLock = true) { // Obtain separate array of properties and handles; we need to isolate properties // so we can do a bulk-transfer on the other locales. var arr = buf.getArray(); @@ -295,7 +295,7 @@ prototype module PropertyMaps { const arrSz = arr.size; var properties : [0..#arrSz] propertyType; var keys : [0..#arrSz] int; - var handles : [0..#arrSz] unmanaged PropertyHandle; + var handles : [0..#arrSz] unmanaged PropertyHandle?; forall ((prop, hndle), _prop, _hndle) in zip(arr, properties, handles) { _prop = prop; _hndle = hndle; From 9cfcc8b7dac73c60bb82fb0a97d32f3625001b32 Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Wed, 5 Feb 2020 19:27:15 -0800 Subject: [PATCH 13/23] Updating Jenkins script --- jenkins-build.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/jenkins-build.sh b/jenkins-build.sh index 484f056..fc0d695 100644 --- a/jenkins-build.sh +++ b/jenkins-build.sh @@ -6,12 +6,11 @@ WORKSPACE=/lustre/jenkins/chgl-workspace # Load required modules -export MODULEPATH=/home/zale916/software/modules:$MODULEPATH +export MODULEPATH=/home/firo017/softwares/modules:$MODULEPATH module load gcc/8.2.0 module load openmpi/3.1.3 -module load hdf5/1.10.5 -module load zmq/4.3.1 -module load chapel/1.19.0 +module load clang/8.0.1 +module load chapel/1.20.0 # Execute peformance tests export CHPL_TEST_LAUNCHCMD="$CHPL_HOME/util/test/chpl_launchcmd.py --CHPL_LAUNCHCMD_DEBUG" From e0d04f27d3ad59ef5dd17e175d706b364f108b42 Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Thu, 6 Feb 2020 13:37:19 -0800 Subject: [PATCH 14/23] Updating rest of the tests for performance regression. --- src/AdjListHyperGraph.chpl | 10 +++++----- src/Metrics.chpl | 2 +- test_performance/BTER.chpl | 2 +- test_performance/ChungLu.chpl | 2 +- test_performance/Privatized.chpl | 1 + test_performance/activeDNS.chpl | 2 +- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/AdjListHyperGraph.chpl b/src/AdjListHyperGraph.chpl index 2a33696..9446bd1 100644 --- a/src/AdjListHyperGraph.chpl +++ b/src/AdjListHyperGraph.chpl @@ -268,7 +268,7 @@ prototype module AdjListHyperGraph { ) { instance = new unmanaged AdjListHyperGraphImpl( numVertices, numEdges, verticesMappings, edgesMappings, distributeVertices, distributeEdges - ); + )?; pid = instance.pid; } @@ -284,7 +284,7 @@ prototype module AdjListHyperGraph { proc init(vPropMap : PropertyMap(?vPropType), vertexMappings, numEdges, edgeMappings) { instance = new unmanaged AdjListHyperGraphImpl( vPropMap, vertexMappings, numEdges, edgeMappings - ); + )?; pid = instance.pid; } @@ -301,7 +301,7 @@ prototype module AdjListHyperGraph { proc init(numVertices, vertexMappings, ePropMap : PropertyMap(?ePropType), edgeMappings) { instance = new unmanaged AdjListHyperGraphImpl( numVertices, vertexMappings, ePropMap, edgeMappings - ); + )?; pid = instance.pid; } @@ -318,7 +318,7 @@ prototype module AdjListHyperGraph { proc init(vPropMap : PropertyMap(?vPropType), vertexMappings, ePropMap : PropertyMap(?ePropType), edgeMappings) { instance = new unmanaged AdjListHyperGraphImpl( vPropMap, vertexMappings, ePropMap, edgeMappings - ); + )?; pid = instance.pid; } @@ -336,7 +336,7 @@ prototype module AdjListHyperGraph { // Code that causes it: init(other.numVertices, other.numEdges, other.verticesDist) pragma "no doc" proc clone(other : this.type) { - instance = new unmanaged AdjListHyperGraphImpl(other._value); + instance = new unmanaged AdjListHyperGraphImpl(other._value)?; pid = instance.pid; } diff --git a/src/Metrics.chpl b/src/Metrics.chpl index 84b1ac7..0b27d9e 100644 --- a/src/Metrics.chpl +++ b/src/Metrics.chpl @@ -1,7 +1,7 @@ /* Compilation of common metrics to be performed on hypergraphs or graphs. */ -module Metrics { +prototype module Metrics { use CHGL; use Vectors; use Utilities; diff --git a/test_performance/BTER.chpl b/test_performance/BTER.chpl index 5f79d89..c48e60f 100644 --- a/test_performance/BTER.chpl +++ b/test_performance/BTER.chpl @@ -1,7 +1,7 @@ use AdjListHyperGraph; use CommDiagnostics; use VisualDebug; -use Generation; +use CHGL; use Time; /* Performance Test for BTER algorithm */ diff --git a/test_performance/ChungLu.chpl b/test_performance/ChungLu.chpl index 2503cb9..4719b6e 100644 --- a/test_performance/ChungLu.chpl +++ b/test_performance/ChungLu.chpl @@ -1,7 +1,7 @@ use AdjListHyperGraph; use CommDiagnostics; use VisualDebug; -use Generation; +use CHGL; use Time; /* Performance Test for ChungLu algorithm */ diff --git a/test_performance/Privatized.chpl b/test_performance/Privatized.chpl index 623459b..2324e82 100644 --- a/test_performance/Privatized.chpl +++ b/test_performance/Privatized.chpl @@ -1,5 +1,6 @@ use CHGL; use ReplicatedDist; +use ReplicatedVar; use Time; config const N = 1024 * 1024; diff --git a/test_performance/activeDNS.chpl b/test_performance/activeDNS.chpl index 907b49c..39d05f9 100644 --- a/test_performance/activeDNS.chpl +++ b/test_performance/activeDNS.chpl @@ -81,7 +81,7 @@ t.clear(); t.start(); graph.startAggregation(); // Aggregate fetching of keys -var handles = new owned Vector((unmanaged PropertyHandle, unmanaged PropertyHandle)); +var handles = new owned Vector((unmanaged PropertyHandle?, unmanaged PropertyHandle?)); for line in getLines(dataset) { var attrs = line.split(","); var qname = attrs[1]; From 980cb88e331351b06c45fdf89eba16501541782d Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Thu, 6 Feb 2020 13:56:20 -0800 Subject: [PATCH 15/23] Updating the jenkins script. --- jenkins-build.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jenkins-build.sh b/jenkins-build.sh index fc0d695..1a5d8f5 100644 --- a/jenkins-build.sh +++ b/jenkins-build.sh @@ -7,6 +7,9 @@ WORKSPACE=/lustre/jenkins/chgl-workspace # Load required modules export MODULEPATH=/home/firo017/softwares/modules:$MODULEPATH +export CHPL_COMM=gasnet +export CHPL_COMM_SUBSTRATE=ibv +source util/setchplenv.bash module load gcc/8.2.0 module load openmpi/3.1.3 module load clang/8.0.1 From 568a0d03cb6967b87e17b14c4d8ce2502a8ca192 Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Thu, 6 Feb 2020 13:59:53 -0800 Subject: [PATCH 16/23] Updating the jenkins script. --- jenkins-build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/jenkins-build.sh b/jenkins-build.sh index 1a5d8f5..7ce1f54 100644 --- a/jenkins-build.sh +++ b/jenkins-build.sh @@ -9,6 +9,7 @@ WORKSPACE=/lustre/jenkins/chgl-workspace export MODULEPATH=/home/firo017/softwares/modules:$MODULEPATH export CHPL_COMM=gasnet export CHPL_COMM_SUBSTRATE=ibv +export CHPL_LAUNCHER=slurm-gasnetrun_ibv source util/setchplenv.bash module load gcc/8.2.0 module load openmpi/3.1.3 From d9a0c5e5b193e70fe01be011e1f6674eb5ed15f0 Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Thu, 6 Feb 2020 14:23:57 -0800 Subject: [PATCH 17/23] Making Butterfly module a prototype module. --- src/Butterfly.chpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Butterfly.chpl b/src/Butterfly.chpl index 3ec441b..350eb23 100755 --- a/src/Butterfly.chpl +++ b/src/Butterfly.chpl @@ -1,4 +1,4 @@ -module Butterfly { +prototype module Butterfly { use AdjListHyperGraph; /* Calculates the maximum number of inclusions that the AdjListHyperGraph object can contain without duplicates From c54b870050743124459775590e4f88a0268113bf Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Thu, 6 Feb 2020 19:30:20 -0800 Subject: [PATCH 18/23] 1. Added code to compute homology computation on DNS data. 2. Fixed the comparator. --- example/boundary_matrix.chpl | 35 +- example/homology.chpl | 14 +- example/homology_dns.chpl | 800 +++++++++++++++++++++++++++++++++++ 3 files changed, 818 insertions(+), 31 deletions(-) create mode 100644 example/homology_dns.chpl diff --git a/example/boundary_matrix.chpl b/example/boundary_matrix.chpl index 941cb5b..a6ea248 100644 --- a/example/boundary_matrix.chpl +++ b/example/boundary_matrix.chpl @@ -5,27 +5,6 @@ use Map; use List; use Sort; use Search; -/* - Part 1: Global-View Distributed Data Structures -*/ -// Question: How do we create a toy hypergraph? -// Answer: Generate it! -/* config const numVertices = 4; */ -/* config const numEdges = 10; */ -/* config const edgeProbability = 1; */ -/* var hypergraph = new AdjListHyperGraph(numVertices, numEdges, new unmanaged Cyclic(startIdx=0)); */ -/* var timer = new Timer(); */ -/* timer.start(); */ -/* generateErdosRenyi(hypergraph, edgeProbability); */ -/* timer.stop(); */ -/* writeln("Generated ErdosRenyi with |V|=", numVertices, */ -/* ", |E|=", numEdges, ", P_E=", edgeProbability, " in ", timer.elapsed(), " seconds"); */ - - -/* writeln("Removing duplicates: ", hypergraph.removeDuplicates()); */ -/* hypergraph.removeDuplicates(); */ - -/*TODO: move all constants to the top of your file and all declarations of types as well. */ var hypergraph = new AdjListHyperGraph(4, 1, new unmanaged Cyclic(startIdx=0)); for v in hypergraph.getVertices() do hypergraph.addInclusion(v, 0); @@ -123,13 +102,17 @@ sort(kCellKeys); // Empty record serves as comparator record Comparator { } // compare method defines how 2 elements are compared -// Simplified comparator since we know that the strings are of the same size proc Comparator.compare(a :string, b :string) : int { var retVal : int = 0; - for (c1, c2) in zip (a , b) { - if (c1 == c2) {continue;} - if (c1 < c2) {retVal = -1; break;} - else {retVal = 1; break;} + var aa = a.split(" ") : int; + var bb = b.split(" ") : int; + var done : bool = false; + for aaa in aa { + for bbb in bb { + if (aaa < bbb) {retVal = -1; done = true; break;} + if (aaa > bbb) {retVal = 1; done = true; break;} + } + if (done) {break;} } return retVal; } diff --git a/example/homology.chpl b/example/homology.chpl index 5463cee..366ea90 100644 --- a/example/homology.chpl +++ b/example/homology.chpl @@ -98,13 +98,17 @@ sort(kCellKeys); // Empty record serves as comparator record Comparator { } // compare method defines how 2 elements are compared -// Simplified comparator since we know that the strings are of the same size proc Comparator.compare(a :string, b :string) : int { var retVal : int = 0; - for (c1, c2) in zip (a , b) { - if (c1 == c2) {continue;} - if (c1 < c2) {retVal = -1; break;} - else {retVal = 1; break;} + var aa = a.split(" ") : int; + var bb = b.split(" ") : int; + var done : bool = false; + for aaa in aa { + for bbb in bb { + if (aaa < bbb) {retVal = -1; done = true; break;} + if (aaa > bbb) {retVal = 1; done = true; break;} + } + if (done) {break;} } return retVal; } diff --git a/example/homology_dns.chpl b/example/homology_dns.chpl new file mode 100644 index 0000000..7e5ba2e --- /dev/null +++ b/example/homology_dns.chpl @@ -0,0 +1,800 @@ +use CHGL; // Includes all core and utility components of CHGL +use Time; // For Timer +use Set; +use Map; +use List; +use Sort; +use Search; +use Regexp; +use FileSystem; +use BigInteger; + +/* + Directory containing the DNS dataset in CSV format. Each file is parsed + individually, in parallel, and distributed. This is liable to change to be + more flexible, I.E to consider binary format (preprocessed), but for now + it must be a directory containing files ending in ".csv". +*/ +config const datasetDirectory = "../homology_data/"; +/* + Output directory. +*/ +config const outputDirectory = "tmp/"; +// Maximum number of files to process. +config const numMaxFiles = max(int(64)); + +var files : [0..-1] string; +var vPropMap = new PropertyMap(string); +var ePropMap = new PropertyMap(string); +var wq = new WorkQueue(string, 1024); +var td = new TerminationDetector(); +var t = new Timer(); + +proc printPropertyDistribution(propMap) : void { + var localNumProperties : [LocaleSpace] int; + coforall loc in Locales do on loc do localNumProperties[here.id] = propMap.numProperties(); + var globalNumProperties = + reduce localNumProperties; + for locid in LocaleSpace { + writeln("Locale#", locid, " has ", localNumProperties[locid], "(", localNumProperties[locid] : real / globalNumProperties * 100, "%)"); + } +} + +//Need to create outputDirectory prior to opening files +if !exists(outputDirectory) { + try { + mkdir(outputDirectory); + } + catch { + halt("*Unable to create directory ", outputDirectory); + } +} +// Fill work queue with files to load up +var currLoc : int; +var nFiles : int; +var fileNames : [0..-1] string; +for fileName in listdir(datasetDirectory, dirs=false) { + if !fileName.endsWith(".csv") then continue; + if nFiles == numMaxFiles then break; + files.push_back(fileName); + fileNames.push_back(datasetDirectory + fileName); + currLoc += 1; + nFiles += 1; +} + +// Spread out the work across multiple locales. +var _currLoc : atomic int; +forall fileName in fileNames { + td.started(1); + wq.addWork(fileName, _currLoc.fetchAdd(1) % numLocales); +} +wq.flush(); + + +// Initialize property maps; aggregation is used as properties can be remote to current locale. +forall fileName in doWorkLoop(wq, td) { + for line in getLines(fileName) { + var attrs = line.split(","); + var qname = attrs[1].strip(); + var rdata = attrs[2].strip(); + + vPropMap.create(rdata, aggregated=true); + ePropMap.create(qname, aggregated=true); + } + td.finished(); +} +vPropMap.flushGlobal(); +ePropMap.flushGlobal(); +// t.stop(); +writeln("Constructed Property Map with ", vPropMap.numPropertiesGlobal(), + " vertex properties and ", ePropMap.numPropertiesGlobal(), + " edge properties in ", t.elapsed(), "s"); +t.clear(); + +writeln("Vertex Property Map"); +printPropertyDistribution(vPropMap); +writeln("Edge Property Map"); +printPropertyDistribution(ePropMap); + +writeln("Constructing HyperGraph..."); +t.start(); +var hypergraph = new AdjListHyperGraph(vPropMap, ePropMap, new unmanaged Cyclic(startIdx=0)); +t.stop(); +writeln("Constructed HyperGraph in ", t.elapsed(), "s"); +t.clear(); +writeln("Populating HyperGraph..."); + +t.start(); +// Spread out the work across multiple locales. +_currLoc.write(0); +forall fileName in fileNames { + td.started(1); + wq.addWork(fileName, _currLoc.fetchAdd(1) % numLocales); +} +wq.flush(); + +// Aggregate fetches to properties into another work queue; when we flush +// each of the property maps, their individual PropertyHandle will be finished. +// Also send the 'String' so that it can be reclaimed. +var handleWQ = new WorkQueue((unmanaged PropertyHandle?, unmanaged PropertyHandle?), 64 * 1024); +var handleTD = new TerminationDetector(); +forall fileName in doWorkLoop(wq, td) { + for line in getLines(fileName) { + var attrs = line.split(","); + var qname = attrs[1].strip(); + var rdata = attrs[2].strip(); + handleTD.started(1); + handleWQ.addWork((vPropMap.getPropertyAsync(rdata), ePropMap.getPropertyAsync(qname))); + } + td.finished(); +} +vPropMap.flushGlobal(); +ePropMap.flushGlobal(); + +// Finally aggregate inclusions for the hypergraph. +hypergraph.startAggregation(); +forall (vHandle, eHandle) in doWorkLoop(handleWQ, handleTD) { + hypergraph.addInclusion(vHandle.get(), eHandle.get()); + delete vHandle; + delete eHandle; + handleTD.finished(1); +} +hypergraph.stopAggregation(); +hypergraph.flushBuffers(); + +t.stop(); +writeln("Populated HyperGraph in ", t.elapsed(), "s"); +t.clear(); +writeln("Number of Inclusions: ", hypergraph.getInclusions()); +writeln("Deleting Duplicate edges: ", hypergraph.removeDuplicates()); +writeln("Number of Inclusions: ", hypergraph.getInclusions()); + + +/* var hypergraph = new AdjListHyperGraph(4, 3, new unmanaged Cyclic(startIdx=0)); */ +/* // V = ['A','B','C','D']; */ +/* // E = ['AB','BC','ACD']; */ +/* hypergraph.addInclusion(0, 0); */ +/* hypergraph.addInclusion(1,0); */ +/* hypergraph.addInclusion(1,1); */ +/* hypergraph.addInclusion(2,1); */ +/* hypergraph.addInclusion(0,2); */ +/* hypergraph.addInclusion(2,2); */ +/* hypergraph.addInclusion(3,2); */ + +t.start(); +var _vtxSubsetSet = new set(string); + +iter processVtxSubset(vtxSubset) { + for i in 1..#vtxSubset.size { + var tmp : [1..#vtxSubset.size - 1] int; + tmp[1..i - 1] = vtxSubset[1..i - 1]; + tmp[i..] = vtxSubset[i + 1..]; + yield tmp; + } +} + +/* Generate the permutation */ +proc doProcessVertices (verticesSet) { + if (verticesSet.size == 0) { + return; + } else if (verticesSet.size == 1) { + var verticesStr = stringify(verticesSet); + if !_vtxSubsetSet.contains(verticesStr) { // TODO: redundant? + _vtxSubsetSet.add(verticesStr); + } + } else { + var verticesStr = stringify(verticesSet); + if !_vtxSubsetSet.contains(verticesStr) { + _vtxSubsetSet.add(verticesStr); + for _vtxSubset in processVtxSubset(verticesSet) { + doProcessVertices(_vtxSubset); + } + } + } +} + +/*For each of the hyperedge, do the permutation of all the vertices.*/ +for e in hypergraph.getEdges() { + var vertices = hypergraph.incidence(e); // ABCD + ref tmp = vertices[1..#vertices.size]; + var verticesInEdge : [1..#vertices.size] int; + verticesInEdge[1..#vertices.size] = tmp.id; // ABCD vertices.low + doProcessVertices(verticesInEdge); +} + +writeln("Printing all generated combination"); +/*Verify the set by printing*/ +var setContent = _vtxSubsetSet.toArray(); +for c in setContent do + writeln(c); + +writeln("-----"); +var _sz = 0; +writeln("Printing bins"); +/*bin k-cells, with key as the length of the list and value is a list with all the k-cells*/ +var kCellMap = new map(int, list(string, true)); +for vtxSet in _vtxSubsetSet { + //var _vtxSet = vtxSet.split(" "); + var sz = + reduce [ch in vtxSet] ch == ' '; + writeln(sz : string + " " + vtxSet : string); + kCellMap[sz].append(vtxSet); + _sz = sz; +} + +class kCellsArray{ + var numKCells : int; + var D = {1..numKCells}; + var A : [D] string; + proc init(_N: int) { + numKCells = _N; + } + proc findCellIndex(s :string) { + for k in A { + + } + } +} + +var numBins = kCellMap.size - 1; +var kCellsArrayMap : [0..numBins] owned kCellsArray?; +var kCellKeys = kCellMap.keysToArray(); +sort(kCellKeys); + +// Empty record serves as comparator +record Comparator { } +// compare method defines how 2 elements are compared +proc Comparator.compare(a :string, b :string) : int { + var retVal : int = 0; + var aa = a.split(" ") : int; + var bb = b.split(" ") : int; + var done : bool = false; + for aaa in aa { + for bbb in bb { + if (aaa < bbb) {retVal = -1; done = true; break;} + if (aaa > bbb) {retVal = 1; done = true; break;} + } + if (done) {break;} + } + return retVal; +} + +var absComparator: Comparator; + +writeln("%%%%%%%%%%%%%"); +// Leader-follower iterator +// Create the new KcellMaps for convenience of sorting +for (_kCellsArray, kCellKey) in zip(kCellsArrayMap, kCellKeys) { + writeln("listsize: " + kCellMap[kCellKey].size : string); + _kCellsArray = new owned kCellsArray(kCellMap[kCellKey].size); + _kCellsArray.A = kCellMap[kCellKey].toArray(); + sort(_kCellsArray.A, comparator=absComparator); +} +writeln("%%%%%%%%%%%%%"); + +writeln("Printing after sorting"); +writeln("^^^^^^^^^^^^^^^^^^^^^^^"); +for _kCellsArray in kCellsArrayMap { + writeln(_kCellsArray.A : string); +} +writeln("^^^^^^^^^^^^^^^^^^^^^^^"); + +/*Start of the construction of boundary matrices.*/ +class Matrix { + var N : int; + var M : int; + var matrix : [1..N, 1..M] int; + proc init(_N: int, _M:int) { + N = _N; + M = _M; + } +} + +var K = kCellMap.size - 1; +var boundaryMaps : [1..K] owned Matrix?; +var i : int = 1; + +// Leader-follower iterator +// Create the boundary Maps +for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { + writeln("dimensions: " + kCellsArrayMap[dimension_k_1].numKCells: string + " " + kCellsArrayMap[dimension_k].numKCells : string); + boundaryMap = new owned Matrix(kCellsArrayMap[dimension_k_1].numKCells, kCellsArrayMap[dimension_k].numKCells); +} + +var vs = new set(string); + +iter processVtxSubset2(vtxSubset) { + for i in 1..#vtxSubset.size { + var tmp : [1..#vtxSubset.size - 1] int; + tmp[1..i - 1] = vtxSubset[1..i - 1]; + tmp[i..] = vtxSubset[i + 1..]; + yield tmp; + } +} + +/* Generate the permutation */ +proc doProcessVertices2 (verticesSet) { + if (verticesSet.size == 0) { + return; + } else if (verticesSet.size == 1) { + var verticesStr = stringify(verticesSet); + if !vs.contains(verticesStr) { + vs.add(verticesStr); + } + } else { + var verticesStr = stringify(verticesSet); + if !vs.contains(verticesStr) { + vs.add(verticesStr); + for _vtxSubset in processVtxSubset2(verticesSet) { + doProcessVertices2(_vtxSubset); + } + } + } +} + + +writeln("####"); +// Compute values for each entries in each of the boundary map +for (dimension_k_1, dimension_k) in zip(0..1, 1..2) { + var arrayOfKCells = kCellsArrayMap[dimension_k].A; // Arrays of strings, each string being 1 kcell + var arrayOfK_1Cells = kCellsArrayMap[dimension_k_1].A; + writeln("$$$$$$$$$$$"); + writeln(arrayOfKCells); + writeln(arrayOfK_1Cells); + writeln("$$$$$$$$$$$"); + var i : int = 0; + var j : int = 0; + for SkCell in arrayOfKCells { // iterate through all the k-cells + i = i + 1; + /* Generate permutation of the current k-Cell*/ + var kCell = SkCell.split(" ") : int; + writeln("#kcell: " + kCell :string); + /* writeln("Combinations generated ": string); */ + for sc in processVtxSubset(kCell) { + var st = stringify(sc); + j = 0; + for Sk_1Cell in arrayOfK_1Cells { + j = j + 1; + if (st == Sk_1Cell) { + // writeln(st :string + "matches"); + boundaryMaps[dimension_k].matrix[j, i] = 1; + break; + } + } + } + } + writeln("$$$$$$$$$$$"); +} + +proc printBoundaryMap(boundaryMap) { + var row : int = boundaryMap.matrix.domain.high(1); + var col : int = boundaryMap.matrix.domain.high(2); + for i in 1..row { + for j in 1..col { + write(boundaryMap.matrix[i, j] : string + " "); + } + writeln(); + } +} + +for (dimension_k_1, dimension_k) in zip(0..1, 1..2) { + writeln("Printing boundary map for: " : string + dimension_k_1 : string + " " :string + dimension_k : string); + printBoundaryMap(boundaryMaps[dimension_k]); +} + + +proc printmatrix(M) { + for i in {1..M.domain.high(1)} { + for j in {1..M.domain.high(2)} { + write(M(i,j):string + " "); + } + writeln(); + } +} + + +proc IdentityMatrix(n) { + var A : [1..n, 1..n] int; + [i in A.domain.dim(1)] A[i,i] = 1; + return A; +} + +use List; +class Matrix2D { + var N : int; + var M : int; + var _arr : [1..N, 1..M] int; + proc init (row : int, col : int) { + N = row; + M = col; + } +} + +proc _get_next_pivot(M, s1, in s2 : int = 0) { + var dims = M.domain.high; + var dimR = dims(1); + var dimC = dims(2); + if (s2 == 0) { + s2 = s1; + } + for c in s2..dimC { + for r in s1..dimR { + if (M(r,c) != 0) { + return (r,c); + } + } + } + return (-1,-1); // TODO: return +} + + +proc swap_rows(i, j, M) { + var N = M; + N[i, ..] <=> N[j, ..]; + return N; +} + +proc swap_columns(i, j, M) { + var N = M; + N[.., i] <=> N[.., j]; + return N; +} + +// Replaces row i (of M) with sum ri multiple of ith row and rj multiple of jth row +proc add_to_row(M, i, j, ri = 1, rj = 1, mod = 2) { + var N = M; + N[i, ..] = (ri * N[i, ..] + rj * N[j, ..]) % mod; + return N; +} + + +proc add_to_column(M, i, j, ci = 1, cj = 1, mod = 2) { + var N = M; + N[.., i] = (ci * N[.., i] + cj * N[..,j]) % mod; + return N; +} + +proc matmultmod2 (M, N, mod = 2) { + var nr = M.domain.high(1); + var nc = N.domain.high(2); + var m = M.domain.high(2); + var C : [1..nr, 1..nc] atomic int; + + forall i in 1..nr { + for j in 1..nc { + C[i,j].write((+ reduce M[i, 1..m] * N[1..m, j]) % 2) ; + } + } + return C.read(); +} + +proc matmultmod3 (M, N, mod = 2) { + var C : [M.domain.dim(1), N.domain.dim(2)] atomic int; + forall (i,j) in C.domain { + C[i,j].write((+ reduce M[i, M.domain.dim(2)] * N[M.domain.dim(2), j]) % 2); + } + return C.read(); +} + +proc matmultmod (M, N, mod =2) { + var C : [M.domain.dim(1), N.domain.dim(2)] int; + forall (i,j) in C.domain { + C[i,j] = (+ reduce (M[i, M.domain.dim(2)] * N[M.domain.dim(2), j])) % 2; + } + return C; +} + +type listType = list(unmanaged Matrix2D?, true); +proc matmulreduce(arr : listType, reverse = false, mod = 2) { + var PD: domain(2) = {1..arr(1)._arr.domain.high(1), 1..arr(1)._arr.domain.high(2)}; + var P : [PD] int; + if (reverse) { + PD = {1..arr(arr.size)._arr.domain.high(1), 1..arr(arr.size)._arr.domain.high(2)}; + P = arr(arr.size)._arr; + for i in 1..#arr.size - 1 by -1 { + var tempD : domain(2) = {1..P.domain.high(1), 1..arr(i)._arr.domain.high(2)}; + var temp : [tempD] int; + temp = matmultmod(P, arr(i)._arr); + PD = tempD; + P = temp; + } + } else { + P = arr(1)._arr; + for i in 2..arr.size { + var tempD : domain(2) = {1..P.domain.high(1), 1..arr(i)._arr.domain.high(2)}; + var temp : [tempD] int; + temp = matmultmod(P, arr(i)._arr); + PD = tempD; + P = temp; + } + } + return P; +} + +// rank calculation: +proc calculateRank(M) { + var rank = + reduce [i in M.domain.dim(2)] (max reduce M[.., i]); + return rank; +} + + +// printmatrix(b); + +proc smithNormalForm(b) { + var dims = b.domain.high; + var dimL = dims(1); + var dimR = dims(2); + var minDim = if dimL <= dimR then dimL else dimR; + + // writeln(dimL : string ); // dims give me the index set but I need the max value of the index set + // writeln(minDim); + + + var S = b; + var IL = IdentityMatrix(dimL); + var IR = IdentityMatrix(dimR); + + var Linv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation + var Rinv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation + + var Linit = new unmanaged Matrix2D(IL.domain.high(1), IL.domain.high(2)); + Linit._arr = IL; + Linv.append(Linit); + var Rinit = new unmanaged Matrix2D(IR.domain.high(1), IR.domain.high(2)); + Rinit._arr = IR; + Rinv.append(Rinit); + + var L = IL; + var R = IR; + + /* writeln("###############"); */ + /* writeln("L:"); */ + /* printmatrix(L); */ + /* writeln("###############"); */ + /* writeln("R:"); */ + /* printmatrix(R); */ + + // var rc = _get_next_pivot(b, 3); + // writeln(rc : string); + + + writeln("########"); + for s in 1..minDim { + writeln("Iteration: " + s : string); + var pivot = _get_next_pivot(S,s); + var rdx : int, cdx : int; + if (pivot(1) == -1 && pivot(2) == -1) { + break; + } + else { + (rdx, cdx) = pivot; + } + + // Swap rows and columns as needed so the 1 is in the s,s position + if (rdx > s) { + S = swap_rows(s, rdx, S); + L = swap_rows(s, rdx, L); + var tmp = swap_rows(s, rdx, IL); + var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + LM._arr = tmp; + Linv.append(LM); + } + if (cdx > s) { + S = swap_columns(s, cdx, S); + R = swap_columns(s, cdx, R); + var tmp = swap_columns(s, cdx, IR); + var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + RM._arr = tmp; + Rinv.append(RM); + } + + // add sth row to every nonzero row & sth column to every nonzero column + // zip(S[.., s], S.dim(1)) gives you (S[i,j], 1..N) + // row_indices = [idx for idx in range(dimL) if idx != s and S[idx][s] == 1] + // var RD: domain(2) = {1..dimL, 1..dimL}; + // var row_indices = [(x,(i,j)) in zip(S, 1..dimL)] if x == 1 && j != s then (i,j); + // var row_indices = [(s,idx) in zip(S, {1..dimL})] if s == 1 then idx; + + var row_indices = [idx in 1..dimL] if (idx != s && S(idx,s) == 1) then idx; + // compilerWarning(row_indices.type : string); + + for rdx in row_indices { + // writeln("rdx: " + rdx : string); + S = add_to_row(S, rdx, s); + L = add_to_row(L, rdx, s); + var tmp = add_to_row(IL, rdx, s); + var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + LM._arr = tmp; + Linv.append(LM); + } + + var column_indices = [jdx in 1..dimR] if (jdx != s && S(s,jdx) == 1) then jdx; + + for (jdx,cdx) in zip(1..,column_indices) {// TODO: check + // writeln("rdx: " + rdx : string); + S = add_to_column(S, cdx, s); + R = add_to_column(R, cdx, s); + var tmp = add_to_column(IR, cdx, s); + var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + RM._arr = tmp; + Rinv.append(RM); + } + } + + + var LinvF = matmulreduce(Linv); + var RinvF = matmulreduce(Rinv, true, 2); + return (L,R,S,LinvF,RinvF); +} + +var computedMatrices = smithNormalForm(boundaryMaps[1].matrix); +var computedMatrices2 = smithNormalForm(boundaryMaps[2].matrix); +var L1 = computedMatrices(1); +var R1 = computedMatrices(2); +var S1 = computedMatrices(3); +var L1invF = computedMatrices(4); +var R1invF = computedMatrices(5); +var L2 = computedMatrices2(1); +var R2 = computedMatrices2(2); +var S2 = computedMatrices2(3); +var L2invF = computedMatrices2(4); +var R2invF = computedMatrices2(5); +writeln("###############"); +writeln("L1:"); +printmatrix(L1); +writeln("###############"); +writeln("R1:"); +printmatrix(R1); +writeln("###############"); +writeln("S1:"); +printmatrix(S1); +writeln("###############"); +writeln("L1inv:"); +printmatrix(L1invF); +writeln("###############"); +writeln("R1inv:"); +printmatrix(R1invF); +writeln("###############"); +writeln("L2inv:"); +printmatrix(L2invF); + +var rank1 = calculateRank(S1); +writeln("Rank of S1: " + rank1 : string); +var rank2 = calculateRank(S2); +writeln("Rank of S2: " + rank2 : string); +var nullity1 = S1.domain.high(2) - rank1; +var betti1 = S1.domain.high(2) - rank1 - rank2; +var cokernel2_dim = S1.domain.high(2) - rank2; + +var nr1 = R1.domain.high(2) - rank1; +var ker1 : [1..R1.domain.high(1), 1..nr1] int = R1[..,rank1+1..]; +writeln("###############"); +writeln("ker1:"); +printmatrix(ker1); + +// im2 = L2inv[:,:rank2] +var im2 : [1..L2invF.domain.high(1), 1..rank2] int = L2invF[..,1..rank2]; +var nr2 = L2invF.domain.high(2) - rank2; +var cokernel2 : [1..L2invF.domain.high(1), 1..nr2] int = L2invF[..,rank2 + 1..]; + +writeln("###############"); +writeln("Cokernel:"); +printmatrix(cokernel2); + +writeln("###############"); +writeln("L2:"); +printmatrix(L2); + +var LKernel = new list(unmanaged Matrix2D?, true); + +var _L2 = new unmanaged Matrix2D(L2.domain.high(1), L2.domain.high(2)); +_L2._arr = L2; +LKernel.append(_L2); + +var _ker1 = new unmanaged Matrix2D(ker1.domain.high(1), ker1.domain.high(2)); +_ker1._arr = ker1; +LKernel.append(_ker1); + +writeln("L2 dimension: " + L2.domain.high(1) :string + "X" + L2.domain.high(2):string); +writeln("ker1 dimension: " + ker1.domain.high(1) :string + "X" + ker1.domain.high(2):string); + +var result = matmulreduce(LKernel); +var slc = result.domain.high(1) - rank2; +var proj : [1..slc, 1..result.domain.high(2)] int = result[rank2 + 1..,..]; +writeln("###############"); +writeln("Projection1:"); +printmatrix(proj); + +// proj = matmulreduce([L2,ker1])[rank2:,:] +// proj = matmulreduce([L2inv[:,rank2:],proj]).transpose() + +var L2invKernel = new list(unmanaged Matrix2D?, true); + +// var nr2 = L2invF.domain.high(2) - rank2; +var _L2inv = new unmanaged Matrix2D(L2invF.domain.high(1), nr2); +_L2inv._arr = L2invF[..,rank2 + 1..]; +L2invKernel.append(_L2inv); + +var _proj = new unmanaged Matrix2D(proj.domain.high(1), proj.domain.high(2)); +_proj._arr = proj; +L2invKernel.append(_proj); + +var proj2 = matmulreduce(L2invKernel); + +writeln("###############"); +writeln("Projection2:"); +printmatrix(proj2); + +t.stop(); +writeln("Homology computed in ", t.elapsed(), "s"); + + +proc reducedRowEchelonForm(b) { + var dims = b.domain.high; + var dimL = dims(1); + var dimR = dims(2); + var minDim = if dimL <= dimR then dimL else dimR; + + // writeln(dimL : string ); // dims give me the index set but I need the max value of the index set + // writeln(minDim); + + + var S = b; + var IL = IdentityMatrix(dimL); + + var Linv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation + + var Linit = new unmanaged Matrix2D(IL.domain.high(1), IL.domain.high(2)); + Linit._arr = IL; + Linv.append(Linit); + + var L = IL; + + /* writeln("###############"); */ + /* writeln("L:"); */ + /* printmatrix(L); */ + /* writeln("###############"); */ + /* writeln("R:"); */ + /* printmatrix(R); */ + + // var rc = _get_next_pivot(b, 3); + // writeln(rc : string); + + var s2 : int = 1; + writeln("########"); + for s1 in 1..dimL { + writeln("Iteration: " + s1 : string); + var rdx : int, cdx : int; + for s2 in s2..dimR { + var pivot = _get_next_pivot(S,s1, s2); + if (pivot(1) != -1 && pivot(2) != -1) { + (rdx, cdx) = pivot; + s2 = cdx; + break; + } + } + // Swap rows + if (rdx > s1) { + S = swap_rows(s1, rdx, S); + L = swap_rows(s1, rdx, L); + var tmp = swap_rows(s1, rdx, IL); + var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + LM._arr = tmp; + Linv.append(LM); + } + + var row_indices = [idx in 1..dimL] if (idx != s1 && S(idx,cdx) == 1) then idx; + // compilerWarning(row_indices.type : string); + + for idx in row_indices { + // writeln("rdx: " + rdx : string); + S = add_to_row(S, idx, s1); + L = add_to_row(L, idx, s1); + var tmp = add_to_row(IL, idx, s1); + var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + LM._arr = tmp; + Linv.append(LM); + } + } + + var LinvF = matmulreduce(Linv); + return (L,S,LinvF); +} \ No newline at end of file From f12d9ee2d7debd13dc292006331044190440f0af Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Wed, 12 Feb 2020 20:24:49 -0800 Subject: [PATCH 19/23] Taking a snapshot that Chapel may still have bug for customized comparator for sorting. --- example/boundary_matrix.chpl | 1 + example/homology_dns.chpl | 1116 +++++++++++++++++----------------- 2 files changed, 555 insertions(+), 562 deletions(-) diff --git a/example/boundary_matrix.chpl b/example/boundary_matrix.chpl index a6ea248..960a504 100644 --- a/example/boundary_matrix.chpl +++ b/example/boundary_matrix.chpl @@ -1,3 +1,4 @@ +/*Boundary matrix computation with a toy example.*/ use CHGL; // Includes all core and utility components of CHGL use Time; // For Timer use Set; diff --git a/example/homology_dns.chpl b/example/homology_dns.chpl index 7e5ba2e..0a70a01 100644 --- a/example/homology_dns.chpl +++ b/example/homology_dns.chpl @@ -9,13 +9,7 @@ use Regexp; use FileSystem; use BigInteger; -/* - Directory containing the DNS dataset in CSV format. Each file is parsed - individually, in parallel, and distributed. This is liable to change to be - more flexible, I.E to consider binary format (preprocessed), but for now - it must be a directory containing files ending in ".csv". -*/ -config const datasetDirectory = "../homology_data/"; +config const datasetDirectory = "/lustre/firo017/chgl_upgrade/homology/chgl/homology_data_emilie/"; /* Output directory. */ @@ -149,17 +143,6 @@ writeln("Deleting Duplicate edges: ", hypergraph.removeDuplicates()); writeln("Number of Inclusions: ", hypergraph.getInclusions()); -/* var hypergraph = new AdjListHyperGraph(4, 3, new unmanaged Cyclic(startIdx=0)); */ -/* // V = ['A','B','C','D']; */ -/* // E = ['AB','BC','ACD']; */ -/* hypergraph.addInclusion(0, 0); */ -/* hypergraph.addInclusion(1,0); */ -/* hypergraph.addInclusion(1,1); */ -/* hypergraph.addInclusion(2,1); */ -/* hypergraph.addInclusion(0,2); */ -/* hypergraph.addInclusion(2,2); */ -/* hypergraph.addInclusion(3,2); */ - t.start(); var _vtxSubsetSet = new set(string); @@ -174,6 +157,7 @@ iter processVtxSubset(vtxSubset) { /* Generate the permutation */ proc doProcessVertices (verticesSet) { + /* writeln(stringify(verticesSet)); */ if (verticesSet.size == 0) { return; } else if (verticesSet.size == 1) { @@ -201,23 +185,20 @@ for e in hypergraph.getEdges() { doProcessVertices(verticesInEdge); } -writeln("Printing all generated combination"); -/*Verify the set by printing*/ -var setContent = _vtxSubsetSet.toArray(); -for c in setContent do - writeln(c); +/* writeln("Printing all generated combination"); */ +/* /\*Verify the set by printing*\/ */ +/* var setContent = _vtxSubsetSet.toArray(); */ +/* for c in setContent do */ +/* writeln(c); */ -writeln("-----"); -var _sz = 0; -writeln("Printing bins"); +/* writeln("-----"); */ +/* writeln("Printing bins"); */ /*bin k-cells, with key as the length of the list and value is a list with all the k-cells*/ var kCellMap = new map(int, list(string, true)); for vtxSet in _vtxSubsetSet { - //var _vtxSet = vtxSet.split(" "); var sz = + reduce [ch in vtxSet] ch == ' '; - writeln(sz : string + " " + vtxSet : string); + /* writeln(sz : string + " " + vtxSet : string); */ kCellMap[sz].append(vtxSet); - _sz = sz; } class kCellsArray{ @@ -227,11 +208,6 @@ class kCellsArray{ proc init(_N: int) { numKCells = _N; } - proc findCellIndex(s :string) { - for k in A { - - } - } } var numBins = kCellMap.size - 1; @@ -244,7 +220,12 @@ record Comparator { } // compare method defines how 2 elements are compared proc Comparator.compare(a :string, b :string) : int { var retVal : int = 0; - var aa = a.split(" ") : int; + if (b == "") { + writeln("a: " + a : string + " b: " + b : string); + retVal = -1; + return retVal; + } + var aa = a.split(" ") : int; var bb = b.split(" ") : int; var done : bool = false; for aaa in aa { @@ -259,542 +240,553 @@ proc Comparator.compare(a :string, b :string) : int { var absComparator: Comparator; -writeln("%%%%%%%%%%%%%"); -// Leader-follower iterator -// Create the new KcellMaps for convenience of sorting +/* /\* writeln("%%%%%%%%%%%%%"); *\/ */ +/* // Leader-follower iterator */ +/* // Create the new KcellMaps for convenience of sorting */ for (_kCellsArray, kCellKey) in zip(kCellsArrayMap, kCellKeys) { + writeln("kCellkey:" + kCellKey : string); writeln("listsize: " + kCellMap[kCellKey].size : string); _kCellsArray = new owned kCellsArray(kCellMap[kCellKey].size); _kCellsArray.A = kCellMap[kCellKey].toArray(); - sort(_kCellsArray.A, comparator=absComparator); -} -writeln("%%%%%%%%%%%%%"); - -writeln("Printing after sorting"); -writeln("^^^^^^^^^^^^^^^^^^^^^^^"); -for _kCellsArray in kCellsArrayMap { - writeln(_kCellsArray.A : string); -} -writeln("^^^^^^^^^^^^^^^^^^^^^^^"); - -/*Start of the construction of boundary matrices.*/ -class Matrix { - var N : int; - var M : int; - var matrix : [1..N, 1..M] int; - proc init(_N: int, _M:int) { - N = _N; - M = _M; - } -} - -var K = kCellMap.size - 1; -var boundaryMaps : [1..K] owned Matrix?; -var i : int = 1; - -// Leader-follower iterator -// Create the boundary Maps -for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { - writeln("dimensions: " + kCellsArrayMap[dimension_k_1].numKCells: string + " " + kCellsArrayMap[dimension_k].numKCells : string); - boundaryMap = new owned Matrix(kCellsArrayMap[dimension_k_1].numKCells, kCellsArrayMap[dimension_k].numKCells); -} - -var vs = new set(string); - -iter processVtxSubset2(vtxSubset) { - for i in 1..#vtxSubset.size { - var tmp : [1..#vtxSubset.size - 1] int; - tmp[1..i - 1] = vtxSubset[1..i - 1]; - tmp[i..] = vtxSubset[i + 1..]; - yield tmp; - } -} - -/* Generate the permutation */ -proc doProcessVertices2 (verticesSet) { - if (verticesSet.size == 0) { - return; - } else if (verticesSet.size == 1) { - var verticesStr = stringify(verticesSet); - if !vs.contains(verticesStr) { - vs.add(verticesStr); - } - } else { - var verticesStr = stringify(verticesSet); - if !vs.contains(verticesStr) { - vs.add(verticesStr); - for _vtxSubset in processVtxSubset2(verticesSet) { - doProcessVertices2(_vtxSubset); + if (kCellKey == 3) { + writeln("size: " + _kCellsArray.A.size); + for c in _kCellsArray.A { + if (c == "") { + writeln("Found an empty string!"); } + writeln(c); } } + sort(_kCellsArray.A, comparator=absComparator); } - - -writeln("####"); -// Compute values for each entries in each of the boundary map -for (dimension_k_1, dimension_k) in zip(0..1, 1..2) { - var arrayOfKCells = kCellsArrayMap[dimension_k].A; // Arrays of strings, each string being 1 kcell - var arrayOfK_1Cells = kCellsArrayMap[dimension_k_1].A; - writeln("$$$$$$$$$$$"); - writeln(arrayOfKCells); - writeln(arrayOfK_1Cells); - writeln("$$$$$$$$$$$"); - var i : int = 0; - var j : int = 0; - for SkCell in arrayOfKCells { // iterate through all the k-cells - i = i + 1; - /* Generate permutation of the current k-Cell*/ - var kCell = SkCell.split(" ") : int; - writeln("#kcell: " + kCell :string); - /* writeln("Combinations generated ": string); */ - for sc in processVtxSubset(kCell) { - var st = stringify(sc); - j = 0; - for Sk_1Cell in arrayOfK_1Cells { - j = j + 1; - if (st == Sk_1Cell) { - // writeln(st :string + "matches"); - boundaryMaps[dimension_k].matrix[j, i] = 1; - break; - } - } - } - } - writeln("$$$$$$$$$$$"); -} - -proc printBoundaryMap(boundaryMap) { - var row : int = boundaryMap.matrix.domain.high(1); - var col : int = boundaryMap.matrix.domain.high(2); - for i in 1..row { - for j in 1..col { - write(boundaryMap.matrix[i, j] : string + " "); - } - writeln(); - } -} - -for (dimension_k_1, dimension_k) in zip(0..1, 1..2) { - writeln("Printing boundary map for: " : string + dimension_k_1 : string + " " :string + dimension_k : string); - printBoundaryMap(boundaryMaps[dimension_k]); -} - - -proc printmatrix(M) { - for i in {1..M.domain.high(1)} { - for j in {1..M.domain.high(2)} { - write(M(i,j):string + " "); - } - writeln(); - } -} - - -proc IdentityMatrix(n) { - var A : [1..n, 1..n] int; - [i in A.domain.dim(1)] A[i,i] = 1; - return A; -} - -use List; -class Matrix2D { - var N : int; - var M : int; - var _arr : [1..N, 1..M] int; - proc init (row : int, col : int) { - N = row; - M = col; - } -} - -proc _get_next_pivot(M, s1, in s2 : int = 0) { - var dims = M.domain.high; - var dimR = dims(1); - var dimC = dims(2); - if (s2 == 0) { - s2 = s1; - } - for c in s2..dimC { - for r in s1..dimR { - if (M(r,c) != 0) { - return (r,c); - } - } - } - return (-1,-1); // TODO: return -} - - -proc swap_rows(i, j, M) { - var N = M; - N[i, ..] <=> N[j, ..]; - return N; -} - -proc swap_columns(i, j, M) { - var N = M; - N[.., i] <=> N[.., j]; - return N; -} - -// Replaces row i (of M) with sum ri multiple of ith row and rj multiple of jth row -proc add_to_row(M, i, j, ri = 1, rj = 1, mod = 2) { - var N = M; - N[i, ..] = (ri * N[i, ..] + rj * N[j, ..]) % mod; - return N; -} - - -proc add_to_column(M, i, j, ci = 1, cj = 1, mod = 2) { - var N = M; - N[.., i] = (ci * N[.., i] + cj * N[..,j]) % mod; - return N; -} - -proc matmultmod2 (M, N, mod = 2) { - var nr = M.domain.high(1); - var nc = N.domain.high(2); - var m = M.domain.high(2); - var C : [1..nr, 1..nc] atomic int; - - forall i in 1..nr { - for j in 1..nc { - C[i,j].write((+ reduce M[i, 1..m] * N[1..m, j]) % 2) ; - } - } - return C.read(); -} - -proc matmultmod3 (M, N, mod = 2) { - var C : [M.domain.dim(1), N.domain.dim(2)] atomic int; - forall (i,j) in C.domain { - C[i,j].write((+ reduce M[i, M.domain.dim(2)] * N[M.domain.dim(2), j]) % 2); - } - return C.read(); -} - -proc matmultmod (M, N, mod =2) { - var C : [M.domain.dim(1), N.domain.dim(2)] int; - forall (i,j) in C.domain { - C[i,j] = (+ reduce (M[i, M.domain.dim(2)] * N[M.domain.dim(2), j])) % 2; - } - return C; -} - -type listType = list(unmanaged Matrix2D?, true); -proc matmulreduce(arr : listType, reverse = false, mod = 2) { - var PD: domain(2) = {1..arr(1)._arr.domain.high(1), 1..arr(1)._arr.domain.high(2)}; - var P : [PD] int; - if (reverse) { - PD = {1..arr(arr.size)._arr.domain.high(1), 1..arr(arr.size)._arr.domain.high(2)}; - P = arr(arr.size)._arr; - for i in 1..#arr.size - 1 by -1 { - var tempD : domain(2) = {1..P.domain.high(1), 1..arr(i)._arr.domain.high(2)}; - var temp : [tempD] int; - temp = matmultmod(P, arr(i)._arr); - PD = tempD; - P = temp; - } - } else { - P = arr(1)._arr; - for i in 2..arr.size { - var tempD : domain(2) = {1..P.domain.high(1), 1..arr(i)._arr.domain.high(2)}; - var temp : [tempD] int; - temp = matmultmod(P, arr(i)._arr); - PD = tempD; - P = temp; - } - } - return P; -} - -// rank calculation: -proc calculateRank(M) { - var rank = + reduce [i in M.domain.dim(2)] (max reduce M[.., i]); - return rank; -} - - -// printmatrix(b); - -proc smithNormalForm(b) { - var dims = b.domain.high; - var dimL = dims(1); - var dimR = dims(2); - var minDim = if dimL <= dimR then dimL else dimR; +/* writeln("%%%%%%%%%%%%%"); */ + +/* /\* writeln("Printing after sorting"); *\/ */ +/* /\* writeln("^^^^^^^^^^^^^^^^^^^^^^^"); *\/ */ +/* /\* for _kCellsArray in kCellsArrayMap { *\/ */ +/* /\* writeln(_kCellsArray.A : string); *\/ */ +/* /\* } *\/ */ +/* /\* writeln("^^^^^^^^^^^^^^^^^^^^^^^"); *\/ */ + +/* /\*Start of the construction of boundary matrices.*\/ */ +/* class Matrix { */ +/* var N : int; */ +/* var M : int; */ +/* var matrix : [1..N, 1..M] int; */ +/* proc init(_N: int, _M:int) { */ +/* N = _N; */ +/* M = _M; */ +/* } */ +/* } */ + +/* var K = kCellMap.size - 1; */ +/* var boundaryMaps : [1..K] owned Matrix?; */ +/* var i : int = 1; */ + +/* // Leader-follower iterator */ +/* // Create the boundary Maps */ +/* for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { */ +/* /\* writeln("dimensions: " + kCellsArrayMap[dimension_k_1].numKCells: string + " " + kCellsArrayMap[dimension_k].numKCells : string); *\/ */ +/* boundaryMap = new owned Matrix(kCellsArrayMap[dimension_k_1].numKCells, kCellsArrayMap[dimension_k].numKCells); */ +/* } */ + +/* var vs = new set(string); */ + +/* iter processVtxSubset2(vtxSubset) { */ +/* for i in 1..#vtxSubset.size { */ +/* var tmp : [1..#vtxSubset.size - 1] int; */ +/* tmp[1..i - 1] = vtxSubset[1..i - 1]; */ +/* tmp[i..] = vtxSubset[i + 1..]; */ +/* yield tmp; */ +/* } */ +/* } */ + +/* /\* Generate the permutation *\/ */ +/* proc doProcessVertices2 (verticesSet) { */ +/* if (verticesSet.size == 0) { */ +/* return; */ +/* } else if (verticesSet.size == 1) { */ +/* var verticesStr = stringify(verticesSet); */ +/* if !vs.contains(verticesStr) { */ +/* vs.add(verticesStr); */ +/* } */ +/* } else { */ +/* var verticesStr = stringify(verticesSet); */ +/* if !vs.contains(verticesStr) { */ +/* vs.add(verticesStr); */ +/* for _vtxSubset in processVtxSubset2(verticesSet) { */ +/* doProcessVertices2(_vtxSubset); */ +/* } */ +/* } */ +/* } */ +/* } */ + + +/* /\* writeln("####"); *\/ */ +/* // Compute values for each entries in each of the boundary map */ +/* for (dimension_k_1, dimension_k) in zip(0..1, 1..2) { */ +/* var arrayOfKCells = kCellsArrayMap[dimension_k].A; // Arrays of strings, each string being 1 kcell */ +/* var arrayOfK_1Cells = kCellsArrayMap[dimension_k_1].A; */ +/* /\* writeln("$$$$$$$$$$$"); *\/ */ +/* /\* writeln(arrayOfKCells); *\/ */ +/* /\* writeln(arrayOfK_1Cells); *\/ */ +/* /\* writeln("$$$$$$$$$$$"); *\/ */ +/* var i : int = 0; */ +/* var j : int = 0; */ +/* for SkCell in arrayOfKCells { // iterate through all the k-cells */ +/* i = i + 1; */ +/* /\* Generate permutation of the current k-Cell*\/ */ +/* var kCell = SkCell.split(" ") : int; */ +/* /\* writeln("#kcell: " + kCell :string); *\/ */ +/* /\* writeln("Combinations generated ": string); *\/ */ +/* for sc in processVtxSubset(kCell) { */ +/* var st = stringify(sc); */ +/* j = 0; */ +/* for Sk_1Cell in arrayOfK_1Cells { */ +/* j = j + 1; */ +/* if (st == Sk_1Cell) { */ +/* // writeln(st :string + "matches"); */ +/* boundaryMaps[dimension_k].matrix[j, i] = 1; */ +/* break; */ +/* } */ +/* } */ +/* } */ +/* } */ +/* /\* writeln("$$$$$$$$$$$"); *\/ */ +/* } */ + +/* proc printBoundaryMap(boundaryMap) { */ +/* var row : int = boundaryMap.matrix.domain.high(1); */ +/* var col : int = boundaryMap.matrix.domain.high(2); */ +/* for i in 1..row { */ +/* for j in 1..col { */ +/* write(boundaryMap.matrix[i, j] : string + " "); */ +/* } */ +/* writeln(); */ +/* } */ +/* } */ + +/* /\* for (dimension_k_1, dimension_k) in zip(0..1, 1..2) { *\/ */ +/* /\* writeln("Printing boundary map for: " : string + dimension_k_1 : string + " " :string + dimension_k : string); *\/ */ +/* /\* printBoundaryMap(boundaryMaps[dimension_k]); *\/ */ +/* /\* } *\/ */ + + +/* proc printmatrix(M) { */ +/* for i in {1..M.domain.high(1)} { */ +/* for j in {1..M.domain.high(2)} { */ +/* write(M(i,j):string + " "); */ +/* } */ +/* writeln(); */ +/* } */ +/* } */ + + +/* proc IdentityMatrix(n) { */ +/* var A : [1..n, 1..n] int; */ +/* [i in A.domain.dim(1)] A[i,i] = 1; */ +/* return A; */ +/* } */ + +/* use List; */ +/* class Matrix2D { */ +/* var N : int; */ +/* var M : int; */ +/* var _arr : [1..N, 1..M] int; */ +/* proc init (row : int, col : int) { */ +/* N = row; */ +/* M = col; */ +/* } */ +/* } */ + +/* proc _get_next_pivot(M, s1, in s2 : int = 0) { */ +/* var dims = M.domain.high; */ +/* var dimR = dims(1); */ +/* var dimC = dims(2); */ +/* if (s2 == 0) { */ +/* s2 = s1; */ +/* } */ +/* for c in s2..dimC { */ +/* for r in s1..dimR { */ +/* if (M(r,c) != 0) { */ +/* return (r,c); */ +/* } */ +/* } */ +/* } */ +/* return (-1,-1); // TODO: return */ +/* } */ + + +/* proc swap_rows(i, j, M) { */ +/* var N = M; */ +/* N[i, ..] <=> N[j, ..]; */ +/* return N; */ +/* } */ + +/* proc swap_columns(i, j, M) { */ +/* var N = M; */ +/* N[.., i] <=> N[.., j]; */ +/* return N; */ +/* } */ + +/* // Replaces row i (of M) with sum ri multiple of ith row and rj multiple of jth row */ +/* proc add_to_row(M, i, j, ri = 1, rj = 1, mod = 2) { */ +/* var N = M; */ +/* N[i, ..] = (ri * N[i, ..] + rj * N[j, ..]) % mod; */ +/* return N; */ +/* } */ + + +/* proc add_to_column(M, i, j, ci = 1, cj = 1, mod = 2) { */ +/* var N = M; */ +/* N[.., i] = (ci * N[.., i] + cj * N[..,j]) % mod; */ +/* return N; */ +/* } */ + +/* proc matmultmod2 (M, N, mod = 2) { */ +/* var nr = M.domain.high(1); */ +/* var nc = N.domain.high(2); */ +/* var m = M.domain.high(2); */ +/* var C : [1..nr, 1..nc] atomic int; */ + +/* forall i in 1..nr { */ +/* for j in 1..nc { */ +/* C[i,j].write((+ reduce M[i, 1..m] * N[1..m, j]) % 2) ; */ +/* } */ +/* } */ +/* return C.read(); */ +/* } */ + +/* proc matmultmod3 (M, N, mod = 2) { */ +/* var C : [M.domain.dim(1), N.domain.dim(2)] atomic int; */ +/* forall (i,j) in C.domain { */ +/* C[i,j].write((+ reduce M[i, M.domain.dim(2)] * N[M.domain.dim(2), j]) % 2); */ +/* } */ +/* return C.read(); */ +/* } */ + +/* proc matmultmod (M, N, mod =2) { */ +/* var C : [M.domain.dim(1), N.domain.dim(2)] int; */ +/* forall (i,j) in C.domain { */ +/* C[i,j] = (+ reduce (M[i, M.domain.dim(2)] * N[M.domain.dim(2), j])) % 2; */ +/* } */ +/* return C; */ +/* } */ + +/* type listType = list(unmanaged Matrix2D?, true); */ +/* proc matmulreduce(arr : listType, reverse = false, mod = 2) { */ +/* var PD: domain(2) = {1..arr(1)._arr.domain.high(1), 1..arr(1)._arr.domain.high(2)}; */ +/* var P : [PD] int; */ +/* if (reverse) { */ +/* PD = {1..arr(arr.size)._arr.domain.high(1), 1..arr(arr.size)._arr.domain.high(2)}; */ +/* P = arr(arr.size)._arr; */ +/* for i in 1..#arr.size - 1 by -1 { */ +/* var tempD : domain(2) = {1..P.domain.high(1), 1..arr(i)._arr.domain.high(2)}; */ +/* var temp : [tempD] int; */ +/* temp = matmultmod(P, arr(i)._arr); */ +/* PD = tempD; */ +/* P = temp; */ +/* } */ +/* } else { */ +/* P = arr(1)._arr; */ +/* for i in 2..arr.size { */ +/* var tempD : domain(2) = {1..P.domain.high(1), 1..arr(i)._arr.domain.high(2)}; */ +/* var temp : [tempD] int; */ +/* temp = matmultmod(P, arr(i)._arr); */ +/* PD = tempD; */ +/* P = temp; */ +/* } */ +/* } */ +/* return P; */ +/* } */ + +/* // rank calculation: */ +/* proc calculateRank(M) { */ +/* var rank = + reduce [i in M.domain.dim(2)] (max reduce M[.., i]); */ +/* return rank; */ +/* } */ + + +/* // printmatrix(b); */ + +/* proc smithNormalForm(b) { */ +/* var dims = b.domain.high; */ +/* var dimL = dims(1); */ +/* var dimR = dims(2); */ +/* var minDim = if dimL <= dimR then dimL else dimR; */ - // writeln(dimL : string ); // dims give me the index set but I need the max value of the index set - // writeln(minDim); - - - var S = b; - var IL = IdentityMatrix(dimL); - var IR = IdentityMatrix(dimR); - - var Linv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation - var Rinv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation - - var Linit = new unmanaged Matrix2D(IL.domain.high(1), IL.domain.high(2)); - Linit._arr = IL; - Linv.append(Linit); - var Rinit = new unmanaged Matrix2D(IR.domain.high(1), IR.domain.high(2)); - Rinit._arr = IR; - Rinv.append(Rinit); - - var L = IL; - var R = IR; - - /* writeln("###############"); */ - /* writeln("L:"); */ - /* printmatrix(L); */ - /* writeln("###############"); */ - /* writeln("R:"); */ - /* printmatrix(R); */ - - // var rc = _get_next_pivot(b, 3); - // writeln(rc : string); - - - writeln("########"); - for s in 1..minDim { - writeln("Iteration: " + s : string); - var pivot = _get_next_pivot(S,s); - var rdx : int, cdx : int; - if (pivot(1) == -1 && pivot(2) == -1) { - break; - } - else { - (rdx, cdx) = pivot; - } +/* // writeln(dimL : string ); // dims give me the index set but I need the max value of the index set */ +/* // writeln(minDim); */ + + +/* var S = b; */ +/* var IL = IdentityMatrix(dimL); */ +/* var IR = IdentityMatrix(dimR); */ + +/* var Linv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation */ +/* var Rinv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation */ + +/* var Linit = new unmanaged Matrix2D(IL.domain.high(1), IL.domain.high(2)); */ +/* Linit._arr = IL; */ +/* Linv.append(Linit); */ +/* var Rinit = new unmanaged Matrix2D(IR.domain.high(1), IR.domain.high(2)); */ +/* Rinit._arr = IR; */ +/* Rinv.append(Rinit); */ + +/* var L = IL; */ +/* var R = IR; */ + +/* /\* writeln("###############"); *\/ */ +/* /\* writeln("L:"); *\/ */ +/* /\* printmatrix(L); *\/ */ +/* /\* writeln("###############"); *\/ */ +/* /\* writeln("R:"); *\/ */ +/* /\* printmatrix(R); *\/ */ + +/* // var rc = _get_next_pivot(b, 3); */ +/* // writeln(rc : string); */ + + +/* writeln("########"); */ +/* for s in 1..minDim { */ +/* /\* writeln("Iteration: " + s : string); *\/ */ +/* var pivot = _get_next_pivot(S,s); */ +/* var rdx : int, cdx : int; */ +/* if (pivot(1) == -1 && pivot(2) == -1) { */ +/* break; */ +/* } */ +/* else { */ +/* (rdx, cdx) = pivot; */ +/* } */ - // Swap rows and columns as needed so the 1 is in the s,s position - if (rdx > s) { - S = swap_rows(s, rdx, S); - L = swap_rows(s, rdx, L); - var tmp = swap_rows(s, rdx, IL); - var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); - LM._arr = tmp; - Linv.append(LM); - } - if (cdx > s) { - S = swap_columns(s, cdx, S); - R = swap_columns(s, cdx, R); - var tmp = swap_columns(s, cdx, IR); - var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); - RM._arr = tmp; - Rinv.append(RM); - } - - // add sth row to every nonzero row & sth column to every nonzero column - // zip(S[.., s], S.dim(1)) gives you (S[i,j], 1..N) - // row_indices = [idx for idx in range(dimL) if idx != s and S[idx][s] == 1] - // var RD: domain(2) = {1..dimL, 1..dimL}; - // var row_indices = [(x,(i,j)) in zip(S, 1..dimL)] if x == 1 && j != s then (i,j); - // var row_indices = [(s,idx) in zip(S, {1..dimL})] if s == 1 then idx; - - var row_indices = [idx in 1..dimL] if (idx != s && S(idx,s) == 1) then idx; - // compilerWarning(row_indices.type : string); - - for rdx in row_indices { - // writeln("rdx: " + rdx : string); - S = add_to_row(S, rdx, s); - L = add_to_row(L, rdx, s); - var tmp = add_to_row(IL, rdx, s); - var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); - LM._arr = tmp; - Linv.append(LM); - } - - var column_indices = [jdx in 1..dimR] if (jdx != s && S(s,jdx) == 1) then jdx; +/* // Swap rows and columns as needed so the 1 is in the s,s position */ +/* if (rdx > s) { */ +/* S = swap_rows(s, rdx, S); */ +/* L = swap_rows(s, rdx, L); */ +/* var tmp = swap_rows(s, rdx, IL); */ +/* var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); */ +/* LM._arr = tmp; */ +/* Linv.append(LM); */ +/* } */ +/* if (cdx > s) { */ +/* S = swap_columns(s, cdx, S); */ +/* R = swap_columns(s, cdx, R); */ +/* var tmp = swap_columns(s, cdx, IR); */ +/* var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); */ +/* RM._arr = tmp; */ +/* Rinv.append(RM); */ +/* } */ + +/* // add sth row to every nonzero row & sth column to every nonzero column */ +/* // zip(S[.., s], S.dim(1)) gives you (S[i,j], 1..N) */ +/* // row_indices = [idx for idx in range(dimL) if idx != s and S[idx][s] == 1] */ +/* // var RD: domain(2) = {1..dimL, 1..dimL}; */ +/* // var row_indices = [(x,(i,j)) in zip(S, 1..dimL)] if x == 1 && j != s then (i,j); */ +/* // var row_indices = [(s,idx) in zip(S, {1..dimL})] if s == 1 then idx; */ + +/* var row_indices = [idx in 1..dimL] if (idx != s && S(idx,s) == 1) then idx; */ +/* // compilerWarning(row_indices.type : string); */ + +/* for rdx in row_indices { */ +/* // writeln("rdx: " + rdx : string); */ +/* S = add_to_row(S, rdx, s); */ +/* L = add_to_row(L, rdx, s); */ +/* var tmp = add_to_row(IL, rdx, s); */ +/* var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); */ +/* LM._arr = tmp; */ +/* Linv.append(LM); */ +/* } */ + +/* var column_indices = [jdx in 1..dimR] if (jdx != s && S(s,jdx) == 1) then jdx; */ - for (jdx,cdx) in zip(1..,column_indices) {// TODO: check - // writeln("rdx: " + rdx : string); - S = add_to_column(S, cdx, s); - R = add_to_column(R, cdx, s); - var tmp = add_to_column(IR, cdx, s); - var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); - RM._arr = tmp; - Rinv.append(RM); - } - } - - - var LinvF = matmulreduce(Linv); - var RinvF = matmulreduce(Rinv, true, 2); - return (L,R,S,LinvF,RinvF); -} - -var computedMatrices = smithNormalForm(boundaryMaps[1].matrix); -var computedMatrices2 = smithNormalForm(boundaryMaps[2].matrix); -var L1 = computedMatrices(1); -var R1 = computedMatrices(2); -var S1 = computedMatrices(3); -var L1invF = computedMatrices(4); -var R1invF = computedMatrices(5); -var L2 = computedMatrices2(1); -var R2 = computedMatrices2(2); -var S2 = computedMatrices2(3); -var L2invF = computedMatrices2(4); -var R2invF = computedMatrices2(5); -writeln("###############"); -writeln("L1:"); -printmatrix(L1); -writeln("###############"); -writeln("R1:"); -printmatrix(R1); -writeln("###############"); -writeln("S1:"); -printmatrix(S1); -writeln("###############"); -writeln("L1inv:"); -printmatrix(L1invF); -writeln("###############"); -writeln("R1inv:"); -printmatrix(R1invF); -writeln("###############"); -writeln("L2inv:"); -printmatrix(L2invF); - -var rank1 = calculateRank(S1); -writeln("Rank of S1: " + rank1 : string); -var rank2 = calculateRank(S2); -writeln("Rank of S2: " + rank2 : string); -var nullity1 = S1.domain.high(2) - rank1; -var betti1 = S1.domain.high(2) - rank1 - rank2; -var cokernel2_dim = S1.domain.high(2) - rank2; - -var nr1 = R1.domain.high(2) - rank1; -var ker1 : [1..R1.domain.high(1), 1..nr1] int = R1[..,rank1+1..]; -writeln("###############"); -writeln("ker1:"); -printmatrix(ker1); - -// im2 = L2inv[:,:rank2] -var im2 : [1..L2invF.domain.high(1), 1..rank2] int = L2invF[..,1..rank2]; -var nr2 = L2invF.domain.high(2) - rank2; -var cokernel2 : [1..L2invF.domain.high(1), 1..nr2] int = L2invF[..,rank2 + 1..]; - -writeln("###############"); -writeln("Cokernel:"); -printmatrix(cokernel2); - -writeln("###############"); -writeln("L2:"); -printmatrix(L2); - -var LKernel = new list(unmanaged Matrix2D?, true); - -var _L2 = new unmanaged Matrix2D(L2.domain.high(1), L2.domain.high(2)); -_L2._arr = L2; -LKernel.append(_L2); - -var _ker1 = new unmanaged Matrix2D(ker1.domain.high(1), ker1.domain.high(2)); -_ker1._arr = ker1; -LKernel.append(_ker1); - -writeln("L2 dimension: " + L2.domain.high(1) :string + "X" + L2.domain.high(2):string); -writeln("ker1 dimension: " + ker1.domain.high(1) :string + "X" + ker1.domain.high(2):string); - -var result = matmulreduce(LKernel); -var slc = result.domain.high(1) - rank2; -var proj : [1..slc, 1..result.domain.high(2)] int = result[rank2 + 1..,..]; -writeln("###############"); -writeln("Projection1:"); -printmatrix(proj); - -// proj = matmulreduce([L2,ker1])[rank2:,:] -// proj = matmulreduce([L2inv[:,rank2:],proj]).transpose() - -var L2invKernel = new list(unmanaged Matrix2D?, true); - -// var nr2 = L2invF.domain.high(2) - rank2; -var _L2inv = new unmanaged Matrix2D(L2invF.domain.high(1), nr2); -_L2inv._arr = L2invF[..,rank2 + 1..]; -L2invKernel.append(_L2inv); - -var _proj = new unmanaged Matrix2D(proj.domain.high(1), proj.domain.high(2)); -_proj._arr = proj; -L2invKernel.append(_proj); - -var proj2 = matmulreduce(L2invKernel); - -writeln("###############"); -writeln("Projection2:"); -printmatrix(proj2); - -t.stop(); -writeln("Homology computed in ", t.elapsed(), "s"); - - -proc reducedRowEchelonForm(b) { - var dims = b.domain.high; - var dimL = dims(1); - var dimR = dims(2); - var minDim = if dimL <= dimR then dimL else dimR; +/* for (jdx,cdx) in zip(1..,column_indices) {// TODO: check */ +/* // writeln("rdx: " + rdx : string); */ +/* S = add_to_column(S, cdx, s); */ +/* R = add_to_column(R, cdx, s); */ +/* var tmp = add_to_column(IR, cdx, s); */ +/* var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); */ +/* RM._arr = tmp; */ +/* Rinv.append(RM); */ +/* } */ +/* } */ + + +/* var LinvF = matmulreduce(Linv); */ +/* var RinvF = matmulreduce(Rinv, true, 2); */ +/* return (L,R,S,LinvF,RinvF); */ +/* } */ + +/* var computedMatrices = smithNormalForm(boundaryMaps[1].matrix); */ +/* var computedMatrices2 = smithNormalForm(boundaryMaps[2].matrix); */ +/* var L1 = computedMatrices(1); */ +/* var R1 = computedMatrices(2); */ +/* var S1 = computedMatrices(3); */ +/* var L1invF = computedMatrices(4); */ +/* var R1invF = computedMatrices(5); */ +/* var L2 = computedMatrices2(1); */ +/* var R2 = computedMatrices2(2); */ +/* var S2 = computedMatrices2(3); */ +/* var L2invF = computedMatrices2(4); */ +/* var R2invF = computedMatrices2(5); */ +/* /\* writeln("###############"); *\/ */ +/* /\* writeln("L1:"); *\/ */ +/* /\* printmatrix(L1); *\/ */ +/* /\* writeln("###############"); *\/ */ +/* /\* writeln("R1:"); *\/ */ +/* /\* printmatrix(R1); *\/ */ +/* /\* writeln("###############"); *\/ */ +/* /\* writeln("S1:"); *\/ */ +/* /\* printmatrix(S1); *\/ */ +/* /\* writeln("###############"); *\/ */ +/* /\* writeln("L1inv:"); *\/ */ +/* /\* printmatrix(L1invF); *\/ */ +/* /\* writeln("###############"); *\/ */ +/* /\* writeln("R1inv:"); *\/ */ +/* /\* printmatrix(R1invF); *\/ */ +/* /\* writeln("###############"); *\/ */ +/* /\* writeln("L2inv:"); *\/ */ +/* /\* printmatrix(L2invF); *\/ */ + +/* var rank1 = calculateRank(S1); */ +/* writeln("Rank of S1: " + rank1 : string); */ +/* var rank2 = calculateRank(S2); */ +/* writeln("Rank of S2: " + rank2 : string); */ +/* var nullity1 = S1.domain.high(2) - rank1; */ +/* var betti1 = S1.domain.high(2) - rank1 - rank2; */ +/* writeln("Betti: " + betti1 : string); */ +/* /\* var cokernel2_dim = S1.domain.high(2) - rank2; *\/ */ + +/* /\* var nr1 = R1.domain.high(2) - rank1; *\/ */ +/* /\* var ker1 : [1..R1.domain.high(1), 1..nr1] int = R1[..,rank1+1..]; *\/ */ +/* /\* writeln("###############"); *\/ */ +/* /\* writeln("ker1:"); *\/ */ +/* /\* printmatrix(ker1); *\/ */ + +/* /\* // im2 = L2inv[:,:rank2] *\/ */ +/* /\* var im2 : [1..L2invF.domain.high(1), 1..rank2] int = L2invF[..,1..rank2]; *\/ */ +/* /\* var nr2 = L2invF.domain.high(2) - rank2; *\/ */ +/* /\* var cokernel2 : [1..L2invF.domain.high(1), 1..nr2] int = L2invF[..,rank2 + 1..]; *\/ */ + +/* /\* writeln("###############"); *\/ */ +/* /\* writeln("Cokernel:"); *\/ */ +/* /\* printmatrix(cokernel2); *\/ */ + +/* /\* writeln("###############"); *\/ */ +/* /\* writeln("L2:"); *\/ */ +/* /\* printmatrix(L2); *\/ */ + +/* /\* var LKernel = new list(unmanaged Matrix2D?, true); *\/ */ + +/* /\* var _L2 = new unmanaged Matrix2D(L2.domain.high(1), L2.domain.high(2)); *\/ */ +/* /\* _L2._arr = L2; *\/ */ +/* /\* LKernel.append(_L2); *\/ */ + +/* /\* var _ker1 = new unmanaged Matrix2D(ker1.domain.high(1), ker1.domain.high(2)); *\/ */ +/* /\* _ker1._arr = ker1; *\/ */ +/* /\* LKernel.append(_ker1); *\/ */ + +/* /\* writeln("L2 dimension: " + L2.domain.high(1) :string + "X" + L2.domain.high(2):string); *\/ */ +/* /\* writeln("ker1 dimension: " + ker1.domain.high(1) :string + "X" + ker1.domain.high(2):string); *\/ */ + +/* /\* var result = matmulreduce(LKernel); *\/ */ +/* /\* var slc = result.domain.high(1) - rank2; *\/ */ +/* /\* var proj : [1..slc, 1..result.domain.high(2)] int = result[rank2 + 1..,..]; *\/ */ +/* /\* writeln("###############"); *\/ */ +/* /\* writeln("Projection1:"); *\/ */ +/* /\* printmatrix(proj); *\/ */ + +/* /\* // proj = matmulreduce([L2,ker1])[rank2:,:] *\/ */ +/* /\* // proj = matmulreduce([L2inv[:,rank2:],proj]).transpose() *\/ */ + +/* /\* var L2invKernel = new list(unmanaged Matrix2D?, true); *\/ */ + +/* /\* // var nr2 = L2invF.domain.high(2) - rank2; *\/ */ +/* /\* var _L2inv = new unmanaged Matrix2D(L2invF.domain.high(1), nr2); *\/ */ +/* /\* _L2inv._arr = L2invF[..,rank2 + 1..]; *\/ */ +/* /\* L2invKernel.append(_L2inv); *\/ */ + +/* /\* var _proj = new unmanaged Matrix2D(proj.domain.high(1), proj.domain.high(2)); *\/ */ +/* /\* _proj._arr = proj; *\/ */ +/* /\* L2invKernel.append(_proj); *\/ */ + +/* /\* var proj2 = matmulreduce(L2invKernel); *\/ */ + +/* /\* writeln("###############"); *\/ */ +/* /\* writeln("Projection2:"); *\/ */ +/* /\* printmatrix(proj2); *\/ */ + +/* /\* t.stop(); *\/ */ +/* /\* writeln("Homology computed in ", t.elapsed(), "s"); *\/ */ + + +/* /\* proc reducedRowEchelonForm(b) { *\/ */ +/* /\* var dims = b.domain.high; *\/ */ +/* /\* var dimL = dims(1); *\/ */ +/* /\* var dimR = dims(2); *\/ */ +/* /\* var minDim = if dimL <= dimR then dimL else dimR; *\/ */ - // writeln(dimL : string ); // dims give me the index set but I need the max value of the index set - // writeln(minDim); - - - var S = b; - var IL = IdentityMatrix(dimL); - - var Linv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation - - var Linit = new unmanaged Matrix2D(IL.domain.high(1), IL.domain.high(2)); - Linit._arr = IL; - Linv.append(Linit); - - var L = IL; - - /* writeln("###############"); */ - /* writeln("L:"); */ - /* printmatrix(L); */ - /* writeln("###############"); */ - /* writeln("R:"); */ - /* printmatrix(R); */ - - // var rc = _get_next_pivot(b, 3); - // writeln(rc : string); - - var s2 : int = 1; - writeln("########"); - for s1 in 1..dimL { - writeln("Iteration: " + s1 : string); - var rdx : int, cdx : int; - for s2 in s2..dimR { - var pivot = _get_next_pivot(S,s1, s2); - if (pivot(1) != -1 && pivot(2) != -1) { - (rdx, cdx) = pivot; - s2 = cdx; - break; - } - } - // Swap rows - if (rdx > s1) { - S = swap_rows(s1, rdx, S); - L = swap_rows(s1, rdx, L); - var tmp = swap_rows(s1, rdx, IL); - var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); - LM._arr = tmp; - Linv.append(LM); - } - - var row_indices = [idx in 1..dimL] if (idx != s1 && S(idx,cdx) == 1) then idx; - // compilerWarning(row_indices.type : string); - - for idx in row_indices { - // writeln("rdx: " + rdx : string); - S = add_to_row(S, idx, s1); - L = add_to_row(L, idx, s1); - var tmp = add_to_row(IL, idx, s1); - var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); - LM._arr = tmp; - Linv.append(LM); - } - } - - var LinvF = matmulreduce(Linv); - return (L,S,LinvF); -} \ No newline at end of file +/* /\* // writeln(dimL : string ); // dims give me the index set but I need the max value of the index set *\/ */ +/* /\* // writeln(minDim); *\/ */ + + +/* /\* var S = b; *\/ */ +/* /\* var IL = IdentityMatrix(dimL); *\/ */ + +/* /\* var Linv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation *\/ */ + +/* /\* var Linit = new unmanaged Matrix2D(IL.domain.high(1), IL.domain.high(2)); *\/ */ +/* /\* Linit._arr = IL; *\/ */ +/* /\* Linv.append(Linit); *\/ */ + +/* /\* var L = IL; *\/ */ + +/* /\* /\\* writeln("###############"); *\\/ *\/ */ +/* /\* /\\* writeln("L:"); *\\/ *\/ */ +/* /\* /\\* printmatrix(L); *\\/ *\/ */ +/* /\* /\\* writeln("###############"); *\\/ *\/ */ +/* /\* /\\* writeln("R:"); *\\/ *\/ */ +/* /\* /\\* printmatrix(R); *\\/ *\/ */ + +/* /\* // var rc = _get_next_pivot(b, 3); *\/ */ +/* /\* // writeln(rc : string); *\/ */ + +/* /\* var s2 : int = 1; *\/ */ +/* /\* writeln("########"); *\/ */ +/* /\* for s1 in 1..dimL { *\/ */ +/* /\* writeln("Iteration: " + s1 : string); *\/ */ +/* /\* var rdx : int, cdx : int; *\/ */ +/* /\* for s2 in s2..dimR { *\/ */ +/* /\* var pivot = _get_next_pivot(S,s1, s2); *\/ */ +/* /\* if (pivot(1) != -1 && pivot(2) != -1) { *\/ */ +/* /\* (rdx, cdx) = pivot; *\/ */ +/* /\* s2 = cdx; *\/ */ +/* /\* break; *\/ */ +/* /\* } *\/ */ +/* /\* } *\/ */ +/* /\* // Swap rows *\/ */ +/* /\* if (rdx > s1) { *\/ */ +/* /\* S = swap_rows(s1, rdx, S); *\/ */ +/* /\* L = swap_rows(s1, rdx, L); *\/ */ +/* /\* var tmp = swap_rows(s1, rdx, IL); *\/ */ +/* /\* var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); *\/ */ +/* /\* LM._arr = tmp; *\/ */ +/* /\* Linv.append(LM); *\/ */ +/* /\* } *\/ */ + +/* /\* var row_indices = [idx in 1..dimL] if (idx != s1 && S(idx,cdx) == 1) then idx; *\/ */ +/* /\* // compilerWarning(row_indices.type : string); *\/ */ + +/* /\* for idx in row_indices { *\/ */ +/* /\* // writeln("rdx: " + rdx : string); *\/ */ +/* /\* S = add_to_row(S, idx, s1); *\/ */ +/* /\* L = add_to_row(L, idx, s1); *\/ */ +/* /\* var tmp = add_to_row(IL, idx, s1); *\/ */ +/* /\* var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); *\/ */ +/* /\* LM._arr = tmp; *\/ */ +/* /\* Linv.append(LM); *\/ */ +/* /\* } *\/ */ +/* /\* } *\/ */ + +/* /\* var LinvF = matmulreduce(Linv); *\/ */ +/* /\* return (L,S,LinvF); *\/ */ +/* /\* } *\/ */ \ No newline at end of file From b68ac6f7067e9c341e87f7753630ae780cedebb4 Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Wed, 12 Feb 2020 21:01:18 -0800 Subject: [PATCH 20/23] Fixing the comparator. --- example/boundary_matrix.chpl | 24 ++++++++++++++++++------ example/homology_dns.chpl | 28 ++++++++++++++++++---------- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/example/boundary_matrix.chpl b/example/boundary_matrix.chpl index 960a504..683742e 100644 --- a/example/boundary_matrix.chpl +++ b/example/boundary_matrix.chpl @@ -105,19 +105,31 @@ record Comparator { } // compare method defines how 2 elements are compared proc Comparator.compare(a :string, b :string) : int { var retVal : int = 0; - var aa = a.split(" ") : int; + if (b == "") { + writeln("a: " + a : string + " b: " + b : string); + retVal = -1; + return retVal; + } + var aa = a.split(" ") : int; var bb = b.split(" ") : int; var done : bool = false; - for aaa in aa { - for bbb in bb { - if (aaa < bbb) {retVal = -1; done = true; break;} - if (aaa > bbb) {retVal = 1; done = true; break;} + var ndone : bool = false; + for i in 1..#aa.size { + for j in i..#bb.size { + if (aa[i] == bb[j]) { + break; + } + if (aa[i] < bb[j]) { + retVal = -1; done = true; break; + } + if (aa[i] > bb[j]) { + retVal = 1; done = true; break; + } } if (done) {break;} } return retVal; } - var absComparator: Comparator; diff --git a/example/homology_dns.chpl b/example/homology_dns.chpl index 0a70a01..0624bc5 100644 --- a/example/homology_dns.chpl +++ b/example/homology_dns.chpl @@ -228,10 +228,18 @@ proc Comparator.compare(a :string, b :string) : int { var aa = a.split(" ") : int; var bb = b.split(" ") : int; var done : bool = false; - for aaa in aa { - for bbb in bb { - if (aaa < bbb) {retVal = -1; done = true; break;} - if (aaa > bbb) {retVal = 1; done = true; break;} + var ndone : bool = false; + for i in 1..#aa.size { + for j in i..#bb.size { + if (aa[i] == bb[j]) { + break; + } + if (aa[i] < bb[j]) { + retVal = -1; done = true; break; + } + if (aa[i] > bb[j]) { + retVal = 1; done = true; break; + } } if (done) {break;} } @@ -261,12 +269,12 @@ for (_kCellsArray, kCellKey) in zip(kCellsArrayMap, kCellKeys) { } /* writeln("%%%%%%%%%%%%%"); */ -/* /\* writeln("Printing after sorting"); *\/ */ -/* /\* writeln("^^^^^^^^^^^^^^^^^^^^^^^"); *\/ */ -/* /\* for _kCellsArray in kCellsArrayMap { *\/ */ -/* /\* writeln(_kCellsArray.A : string); *\/ */ -/* /\* } *\/ */ -/* /\* writeln("^^^^^^^^^^^^^^^^^^^^^^^"); *\/ */ +writeln("Printing after sorting"); +writeln("^^^^^^^^^^^^^^^^^^^^^^^"); +for _kCellsArray in kCellsArrayMap { + writeln(_kCellsArray.A : string); +} +writeln("^^^^^^^^^^^^^^^^^^^^^^^"); /* /\*Start of the construction of boundary matrices.*\/ */ /* class Matrix { */ From 307f02d18ba3740a9bf6114f0547759c2c31ccfb Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Thu, 13 Feb 2020 14:36:01 -0800 Subject: [PATCH 21/23] commenting out print statements. --- example/boundary_matrix.chpl | 64 ++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/example/boundary_matrix.chpl b/example/boundary_matrix.chpl index 683742e..d48aa2b 100644 --- a/example/boundary_matrix.chpl +++ b/example/boundary_matrix.chpl @@ -1,4 +1,4 @@ -/*Boundary matrix computation with a toy example.*/ +/*Example of Boundary matrix computation with a toy example.*/ use CHGL; // Includes all core and utility components of CHGL use Time; // For Timer use Set; @@ -62,21 +62,21 @@ for e in hypergraph.getEdges() { doProcessVertices(verticesInEdge); } -writeln("Printing all generated combination"); -/*Verify the set by printing*/ -var setContent = _vtxSubsetSet.toArray(); -for c in setContent do - writeln(c); +/* writeln("Printing all generated combination"); */ +/* /\*Verify the set by printing*\/ */ +/* var setContent = _vtxSubsetSet.toArray(); */ +/* for c in setContent do */ +/* writeln(c); */ -writeln("-----"); +/* writeln("-----"); */ var _sz = 0; -writeln("Printing bins"); +/* writeln("Printing bins"); */ /*bin k-cells, with key as the length of the list and value is a list with all the k-cells*/ var kCellMap = new map(int, list(string, true)); for vtxSet in _vtxSubsetSet { //var _vtxSet = vtxSet.split(" "); var sz = + reduce [ch in vtxSet] ch == ' '; - writeln(sz : string + " " + vtxSet : string); + /* writeln(sz : string + " " + vtxSet : string); */ kCellMap[sz].append(vtxSet); _sz = sz; } @@ -105,8 +105,8 @@ record Comparator { } // compare method defines how 2 elements are compared proc Comparator.compare(a :string, b :string) : int { var retVal : int = 0; - if (b == "") { - writeln("a: " + a : string + " b: " + b : string); + if (b == "" || a == "") { + /* writeln("a: " + a : string + " b: " + b : string); */ retVal = -1; return retVal; } @@ -141,11 +141,11 @@ var absComparator: Comparator; sort(kCellsArrayMap[k].A, comparator=absComparator); }*/ -writeln("%%%%%%%%%%%%%"); +/* writeln("%%%%%%%%%%%%%"); */ // Leader-follower iterator // Create the new KcellMaps for convenience of sorting for (_kCellsArray, kCellKey) in zip(kCellsArrayMap, kCellKeys) { - writeln("listsize: " + kCellMap[kCellKey].size : string); + /* writeln("listsize: " + kCellMap[kCellKey].size : string); */ _kCellsArray = new owned kCellsArray(kCellMap[kCellKey].size); _kCellsArray.A = kCellMap[kCellKey].toArray(); // compilerWarning(kCellMap[kCellKey].toArray().type : string); @@ -155,7 +155,7 @@ for (_kCellsArray, kCellKey) in zip(kCellsArrayMap, kCellKeys) { /* compilerWarning(c.type: string); */ /* } */ } -writeln("%%%%%%%%%%%%%"); +/* writeln("%%%%%%%%%%%%%"); */ // TODO: change the following: /* @@ -163,15 +163,15 @@ for (_kCellsArray, idx) in (kCellsArrayMap, 1..K) { writeln((_kCellsArray.A, idx) : string); } */ -writeln("Printing after sorting"); -writeln("^^^^^^^^^^^^^^^^^^^^^^^"); -/* for (_kCellsArray, idx) in zip(kCellsArrayMap, 1..numBins) { */ -/* writeln((_kCellsArray.A, idx) : string); */ +/* writeln("Printing after sorting"); */ +/* writeln("^^^^^^^^^^^^^^^^^^^^^^^"); */ +/* /\* for (_kCellsArray, idx) in zip(kCellsArrayMap, 1..numBins) { *\/ */ +/* /\* writeln((_kCellsArray.A, idx) : string); *\/ */ +/* /\* } *\/ */ +/* for _kCellsArray in kCellsArrayMap { */ +/* writeln(_kCellsArray.A : string); */ /* } */ -for _kCellsArray in kCellsArrayMap { - writeln(_kCellsArray.A : string); -} -writeln("^^^^^^^^^^^^^^^^^^^^^^^"); +/* writeln("^^^^^^^^^^^^^^^^^^^^^^^"); */ /*Start of the construction of boundary matrices.*/ class Matrix { @@ -191,7 +191,7 @@ var i : int = 1; // Leader-follower iterator // Create the boundary Maps for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { - writeln("dimensions: " + kCellsArrayMap[dimension_k_1].numKCells: string + " " + kCellsArrayMap[dimension_k].numKCells : string); + /* writeln("dimensions: " + kCellsArrayMap[dimension_k_1].numKCells: string + " " + kCellsArrayMap[dimension_k].numKCells : string); */ boundaryMap = new owned Matrix(kCellsArrayMap[dimension_k_1].numKCells, kCellsArrayMap[dimension_k].numKCells); } @@ -238,11 +238,11 @@ writeln("####"); for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { var arrayOfKCells = kCellsArrayMap[dimension_k].A; // Arrays of strings, each string being 1 kcell var arrayOfK_1Cells = kCellsArrayMap[dimension_k_1].A; - compilerWarning(arrayOfK_1Cells.type : string); - writeln("$$$$$$$$$$$"); - writeln(arrayOfKCells); - writeln(arrayOfK_1Cells); - writeln("$$$$$$$$$$$"); + /* compilerWarning(arrayOfK_1Cells.type : string); */ + /* writeln("$$$$$$$$$$$"); */ + /* writeln(arrayOfKCells); */ + /* writeln(arrayOfK_1Cells); */ + /* writeln("$$$$$$$$$$$"); */ var i : int = 0; var j : int = 0; for SkCell in arrayOfKCells { // iterate through all the k-cells @@ -251,24 +251,24 @@ for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { // compilerWarning(SkCell.type : string); var kCell = SkCell.split(" ") : int; // compilerWarning(kCell.type : string); - writeln("#kcell: " + kCell :string); + /* writeln("#kcell: " + kCell :string); */ /* writeln("Combinations generated ": string); */ for sc in processVtxSubset(kCell) { compilerWarning(sc.type : string); - writeln(sc); + /* writeln(sc); */ var st = stringify(sc); j = 0; for Sk_1Cell in arrayOfK_1Cells { j = j + 1; if (st == Sk_1Cell) { - writeln(st :string + "matches"); + /* writeln(st :string + "matches"); */ boundaryMap.matrix[j, i] = 1; break; } } } } - writeln("$$$$$$$$$$$"); + /* writeln("$$$$$$$$$$$"); */ } proc printBoundaryMap(boundaryMap) { From e5152faba8f048f9f9af8c0c03b70042ddf27dfb Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Thu, 13 Feb 2020 18:25:57 -0800 Subject: [PATCH 22/23] Restructuring the files. --- example/homology_dns.chpl | 800 ----------------- .../betti_number_calculator.chpl | 678 +++++++++++++++ .../bip_ER_V20_E20_p0.2_me8_t4.csv | 89 ++ .../boundary_matrix.chpl | 74 -- .../homology_experimental/homology_dns.chpl | 808 ++++++++++++++++++ .../homology_dns_data/dns1.csv | 37 + .../homology_dns_data/dns1.csv~ | 38 + example/{ => homology_experimental}/snf.chpl | 2 + 8 files changed, 1652 insertions(+), 874 deletions(-) delete mode 100644 example/homology_dns.chpl create mode 100644 example/homology_experimental/betti_number_calculator.chpl create mode 100644 example/homology_experimental/betti_test_data/bip_ER_V20_E20_p0.2_me8_t4.csv rename example/{ => homology_experimental}/boundary_matrix.chpl (68%) create mode 100644 example/homology_experimental/homology_dns.chpl create mode 100644 example/homology_experimental/homology_dns_data/dns1.csv create mode 100644 example/homology_experimental/homology_dns_data/dns1.csv~ rename example/{ => homology_experimental}/snf.chpl (99%) diff --git a/example/homology_dns.chpl b/example/homology_dns.chpl deleted file mode 100644 index 0624bc5..0000000 --- a/example/homology_dns.chpl +++ /dev/null @@ -1,800 +0,0 @@ -use CHGL; // Includes all core and utility components of CHGL -use Time; // For Timer -use Set; -use Map; -use List; -use Sort; -use Search; -use Regexp; -use FileSystem; -use BigInteger; - -config const datasetDirectory = "/lustre/firo017/chgl_upgrade/homology/chgl/homology_data_emilie/"; -/* - Output directory. -*/ -config const outputDirectory = "tmp/"; -// Maximum number of files to process. -config const numMaxFiles = max(int(64)); - -var files : [0..-1] string; -var vPropMap = new PropertyMap(string); -var ePropMap = new PropertyMap(string); -var wq = new WorkQueue(string, 1024); -var td = new TerminationDetector(); -var t = new Timer(); - -proc printPropertyDistribution(propMap) : void { - var localNumProperties : [LocaleSpace] int; - coforall loc in Locales do on loc do localNumProperties[here.id] = propMap.numProperties(); - var globalNumProperties = + reduce localNumProperties; - for locid in LocaleSpace { - writeln("Locale#", locid, " has ", localNumProperties[locid], "(", localNumProperties[locid] : real / globalNumProperties * 100, "%)"); - } -} - -//Need to create outputDirectory prior to opening files -if !exists(outputDirectory) { - try { - mkdir(outputDirectory); - } - catch { - halt("*Unable to create directory ", outputDirectory); - } -} -// Fill work queue with files to load up -var currLoc : int; -var nFiles : int; -var fileNames : [0..-1] string; -for fileName in listdir(datasetDirectory, dirs=false) { - if !fileName.endsWith(".csv") then continue; - if nFiles == numMaxFiles then break; - files.push_back(fileName); - fileNames.push_back(datasetDirectory + fileName); - currLoc += 1; - nFiles += 1; -} - -// Spread out the work across multiple locales. -var _currLoc : atomic int; -forall fileName in fileNames { - td.started(1); - wq.addWork(fileName, _currLoc.fetchAdd(1) % numLocales); -} -wq.flush(); - - -// Initialize property maps; aggregation is used as properties can be remote to current locale. -forall fileName in doWorkLoop(wq, td) { - for line in getLines(fileName) { - var attrs = line.split(","); - var qname = attrs[1].strip(); - var rdata = attrs[2].strip(); - - vPropMap.create(rdata, aggregated=true); - ePropMap.create(qname, aggregated=true); - } - td.finished(); -} -vPropMap.flushGlobal(); -ePropMap.flushGlobal(); -// t.stop(); -writeln("Constructed Property Map with ", vPropMap.numPropertiesGlobal(), - " vertex properties and ", ePropMap.numPropertiesGlobal(), - " edge properties in ", t.elapsed(), "s"); -t.clear(); - -writeln("Vertex Property Map"); -printPropertyDistribution(vPropMap); -writeln("Edge Property Map"); -printPropertyDistribution(ePropMap); - -writeln("Constructing HyperGraph..."); -t.start(); -var hypergraph = new AdjListHyperGraph(vPropMap, ePropMap, new unmanaged Cyclic(startIdx=0)); -t.stop(); -writeln("Constructed HyperGraph in ", t.elapsed(), "s"); -t.clear(); -writeln("Populating HyperGraph..."); - -t.start(); -// Spread out the work across multiple locales. -_currLoc.write(0); -forall fileName in fileNames { - td.started(1); - wq.addWork(fileName, _currLoc.fetchAdd(1) % numLocales); -} -wq.flush(); - -// Aggregate fetches to properties into another work queue; when we flush -// each of the property maps, their individual PropertyHandle will be finished. -// Also send the 'String' so that it can be reclaimed. -var handleWQ = new WorkQueue((unmanaged PropertyHandle?, unmanaged PropertyHandle?), 64 * 1024); -var handleTD = new TerminationDetector(); -forall fileName in doWorkLoop(wq, td) { - for line in getLines(fileName) { - var attrs = line.split(","); - var qname = attrs[1].strip(); - var rdata = attrs[2].strip(); - handleTD.started(1); - handleWQ.addWork((vPropMap.getPropertyAsync(rdata), ePropMap.getPropertyAsync(qname))); - } - td.finished(); -} -vPropMap.flushGlobal(); -ePropMap.flushGlobal(); - -// Finally aggregate inclusions for the hypergraph. -hypergraph.startAggregation(); -forall (vHandle, eHandle) in doWorkLoop(handleWQ, handleTD) { - hypergraph.addInclusion(vHandle.get(), eHandle.get()); - delete vHandle; - delete eHandle; - handleTD.finished(1); -} -hypergraph.stopAggregation(); -hypergraph.flushBuffers(); - -t.stop(); -writeln("Populated HyperGraph in ", t.elapsed(), "s"); -t.clear(); -writeln("Number of Inclusions: ", hypergraph.getInclusions()); -writeln("Deleting Duplicate edges: ", hypergraph.removeDuplicates()); -writeln("Number of Inclusions: ", hypergraph.getInclusions()); - - -t.start(); -var _vtxSubsetSet = new set(string); - -iter processVtxSubset(vtxSubset) { - for i in 1..#vtxSubset.size { - var tmp : [1..#vtxSubset.size - 1] int; - tmp[1..i - 1] = vtxSubset[1..i - 1]; - tmp[i..] = vtxSubset[i + 1..]; - yield tmp; - } -} - -/* Generate the permutation */ -proc doProcessVertices (verticesSet) { - /* writeln(stringify(verticesSet)); */ - if (verticesSet.size == 0) { - return; - } else if (verticesSet.size == 1) { - var verticesStr = stringify(verticesSet); - if !_vtxSubsetSet.contains(verticesStr) { // TODO: redundant? - _vtxSubsetSet.add(verticesStr); - } - } else { - var verticesStr = stringify(verticesSet); - if !_vtxSubsetSet.contains(verticesStr) { - _vtxSubsetSet.add(verticesStr); - for _vtxSubset in processVtxSubset(verticesSet) { - doProcessVertices(_vtxSubset); - } - } - } -} - -/*For each of the hyperedge, do the permutation of all the vertices.*/ -for e in hypergraph.getEdges() { - var vertices = hypergraph.incidence(e); // ABCD - ref tmp = vertices[1..#vertices.size]; - var verticesInEdge : [1..#vertices.size] int; - verticesInEdge[1..#vertices.size] = tmp.id; // ABCD vertices.low - doProcessVertices(verticesInEdge); -} - -/* writeln("Printing all generated combination"); */ -/* /\*Verify the set by printing*\/ */ -/* var setContent = _vtxSubsetSet.toArray(); */ -/* for c in setContent do */ -/* writeln(c); */ - -/* writeln("-----"); */ -/* writeln("Printing bins"); */ -/*bin k-cells, with key as the length of the list and value is a list with all the k-cells*/ -var kCellMap = new map(int, list(string, true)); -for vtxSet in _vtxSubsetSet { - var sz = + reduce [ch in vtxSet] ch == ' '; - /* writeln(sz : string + " " + vtxSet : string); */ - kCellMap[sz].append(vtxSet); -} - -class kCellsArray{ - var numKCells : int; - var D = {1..numKCells}; - var A : [D] string; - proc init(_N: int) { - numKCells = _N; - } -} - -var numBins = kCellMap.size - 1; -var kCellsArrayMap : [0..numBins] owned kCellsArray?; -var kCellKeys = kCellMap.keysToArray(); -sort(kCellKeys); - -// Empty record serves as comparator -record Comparator { } -// compare method defines how 2 elements are compared -proc Comparator.compare(a :string, b :string) : int { - var retVal : int = 0; - if (b == "") { - writeln("a: " + a : string + " b: " + b : string); - retVal = -1; - return retVal; - } - var aa = a.split(" ") : int; - var bb = b.split(" ") : int; - var done : bool = false; - var ndone : bool = false; - for i in 1..#aa.size { - for j in i..#bb.size { - if (aa[i] == bb[j]) { - break; - } - if (aa[i] < bb[j]) { - retVal = -1; done = true; break; - } - if (aa[i] > bb[j]) { - retVal = 1; done = true; break; - } - } - if (done) {break;} - } - return retVal; -} - -var absComparator: Comparator; - -/* /\* writeln("%%%%%%%%%%%%%"); *\/ */ -/* // Leader-follower iterator */ -/* // Create the new KcellMaps for convenience of sorting */ -for (_kCellsArray, kCellKey) in zip(kCellsArrayMap, kCellKeys) { - writeln("kCellkey:" + kCellKey : string); - writeln("listsize: " + kCellMap[kCellKey].size : string); - _kCellsArray = new owned kCellsArray(kCellMap[kCellKey].size); - _kCellsArray.A = kCellMap[kCellKey].toArray(); - if (kCellKey == 3) { - writeln("size: " + _kCellsArray.A.size); - for c in _kCellsArray.A { - if (c == "") { - writeln("Found an empty string!"); - } - writeln(c); - } - } - sort(_kCellsArray.A, comparator=absComparator); -} -/* writeln("%%%%%%%%%%%%%"); */ - -writeln("Printing after sorting"); -writeln("^^^^^^^^^^^^^^^^^^^^^^^"); -for _kCellsArray in kCellsArrayMap { - writeln(_kCellsArray.A : string); -} -writeln("^^^^^^^^^^^^^^^^^^^^^^^"); - -/* /\*Start of the construction of boundary matrices.*\/ */ -/* class Matrix { */ -/* var N : int; */ -/* var M : int; */ -/* var matrix : [1..N, 1..M] int; */ -/* proc init(_N: int, _M:int) { */ -/* N = _N; */ -/* M = _M; */ -/* } */ -/* } */ - -/* var K = kCellMap.size - 1; */ -/* var boundaryMaps : [1..K] owned Matrix?; */ -/* var i : int = 1; */ - -/* // Leader-follower iterator */ -/* // Create the boundary Maps */ -/* for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { */ -/* /\* writeln("dimensions: " + kCellsArrayMap[dimension_k_1].numKCells: string + " " + kCellsArrayMap[dimension_k].numKCells : string); *\/ */ -/* boundaryMap = new owned Matrix(kCellsArrayMap[dimension_k_1].numKCells, kCellsArrayMap[dimension_k].numKCells); */ -/* } */ - -/* var vs = new set(string); */ - -/* iter processVtxSubset2(vtxSubset) { */ -/* for i in 1..#vtxSubset.size { */ -/* var tmp : [1..#vtxSubset.size - 1] int; */ -/* tmp[1..i - 1] = vtxSubset[1..i - 1]; */ -/* tmp[i..] = vtxSubset[i + 1..]; */ -/* yield tmp; */ -/* } */ -/* } */ - -/* /\* Generate the permutation *\/ */ -/* proc doProcessVertices2 (verticesSet) { */ -/* if (verticesSet.size == 0) { */ -/* return; */ -/* } else if (verticesSet.size == 1) { */ -/* var verticesStr = stringify(verticesSet); */ -/* if !vs.contains(verticesStr) { */ -/* vs.add(verticesStr); */ -/* } */ -/* } else { */ -/* var verticesStr = stringify(verticesSet); */ -/* if !vs.contains(verticesStr) { */ -/* vs.add(verticesStr); */ -/* for _vtxSubset in processVtxSubset2(verticesSet) { */ -/* doProcessVertices2(_vtxSubset); */ -/* } */ -/* } */ -/* } */ -/* } */ - - -/* /\* writeln("####"); *\/ */ -/* // Compute values for each entries in each of the boundary map */ -/* for (dimension_k_1, dimension_k) in zip(0..1, 1..2) { */ -/* var arrayOfKCells = kCellsArrayMap[dimension_k].A; // Arrays of strings, each string being 1 kcell */ -/* var arrayOfK_1Cells = kCellsArrayMap[dimension_k_1].A; */ -/* /\* writeln("$$$$$$$$$$$"); *\/ */ -/* /\* writeln(arrayOfKCells); *\/ */ -/* /\* writeln(arrayOfK_1Cells); *\/ */ -/* /\* writeln("$$$$$$$$$$$"); *\/ */ -/* var i : int = 0; */ -/* var j : int = 0; */ -/* for SkCell in arrayOfKCells { // iterate through all the k-cells */ -/* i = i + 1; */ -/* /\* Generate permutation of the current k-Cell*\/ */ -/* var kCell = SkCell.split(" ") : int; */ -/* /\* writeln("#kcell: " + kCell :string); *\/ */ -/* /\* writeln("Combinations generated ": string); *\/ */ -/* for sc in processVtxSubset(kCell) { */ -/* var st = stringify(sc); */ -/* j = 0; */ -/* for Sk_1Cell in arrayOfK_1Cells { */ -/* j = j + 1; */ -/* if (st == Sk_1Cell) { */ -/* // writeln(st :string + "matches"); */ -/* boundaryMaps[dimension_k].matrix[j, i] = 1; */ -/* break; */ -/* } */ -/* } */ -/* } */ -/* } */ -/* /\* writeln("$$$$$$$$$$$"); *\/ */ -/* } */ - -/* proc printBoundaryMap(boundaryMap) { */ -/* var row : int = boundaryMap.matrix.domain.high(1); */ -/* var col : int = boundaryMap.matrix.domain.high(2); */ -/* for i in 1..row { */ -/* for j in 1..col { */ -/* write(boundaryMap.matrix[i, j] : string + " "); */ -/* } */ -/* writeln(); */ -/* } */ -/* } */ - -/* /\* for (dimension_k_1, dimension_k) in zip(0..1, 1..2) { *\/ */ -/* /\* writeln("Printing boundary map for: " : string + dimension_k_1 : string + " " :string + dimension_k : string); *\/ */ -/* /\* printBoundaryMap(boundaryMaps[dimension_k]); *\/ */ -/* /\* } *\/ */ - - -/* proc printmatrix(M) { */ -/* for i in {1..M.domain.high(1)} { */ -/* for j in {1..M.domain.high(2)} { */ -/* write(M(i,j):string + " "); */ -/* } */ -/* writeln(); */ -/* } */ -/* } */ - - -/* proc IdentityMatrix(n) { */ -/* var A : [1..n, 1..n] int; */ -/* [i in A.domain.dim(1)] A[i,i] = 1; */ -/* return A; */ -/* } */ - -/* use List; */ -/* class Matrix2D { */ -/* var N : int; */ -/* var M : int; */ -/* var _arr : [1..N, 1..M] int; */ -/* proc init (row : int, col : int) { */ -/* N = row; */ -/* M = col; */ -/* } */ -/* } */ - -/* proc _get_next_pivot(M, s1, in s2 : int = 0) { */ -/* var dims = M.domain.high; */ -/* var dimR = dims(1); */ -/* var dimC = dims(2); */ -/* if (s2 == 0) { */ -/* s2 = s1; */ -/* } */ -/* for c in s2..dimC { */ -/* for r in s1..dimR { */ -/* if (M(r,c) != 0) { */ -/* return (r,c); */ -/* } */ -/* } */ -/* } */ -/* return (-1,-1); // TODO: return */ -/* } */ - - -/* proc swap_rows(i, j, M) { */ -/* var N = M; */ -/* N[i, ..] <=> N[j, ..]; */ -/* return N; */ -/* } */ - -/* proc swap_columns(i, j, M) { */ -/* var N = M; */ -/* N[.., i] <=> N[.., j]; */ -/* return N; */ -/* } */ - -/* // Replaces row i (of M) with sum ri multiple of ith row and rj multiple of jth row */ -/* proc add_to_row(M, i, j, ri = 1, rj = 1, mod = 2) { */ -/* var N = M; */ -/* N[i, ..] = (ri * N[i, ..] + rj * N[j, ..]) % mod; */ -/* return N; */ -/* } */ - - -/* proc add_to_column(M, i, j, ci = 1, cj = 1, mod = 2) { */ -/* var N = M; */ -/* N[.., i] = (ci * N[.., i] + cj * N[..,j]) % mod; */ -/* return N; */ -/* } */ - -/* proc matmultmod2 (M, N, mod = 2) { */ -/* var nr = M.domain.high(1); */ -/* var nc = N.domain.high(2); */ -/* var m = M.domain.high(2); */ -/* var C : [1..nr, 1..nc] atomic int; */ - -/* forall i in 1..nr { */ -/* for j in 1..nc { */ -/* C[i,j].write((+ reduce M[i, 1..m] * N[1..m, j]) % 2) ; */ -/* } */ -/* } */ -/* return C.read(); */ -/* } */ - -/* proc matmultmod3 (M, N, mod = 2) { */ -/* var C : [M.domain.dim(1), N.domain.dim(2)] atomic int; */ -/* forall (i,j) in C.domain { */ -/* C[i,j].write((+ reduce M[i, M.domain.dim(2)] * N[M.domain.dim(2), j]) % 2); */ -/* } */ -/* return C.read(); */ -/* } */ - -/* proc matmultmod (M, N, mod =2) { */ -/* var C : [M.domain.dim(1), N.domain.dim(2)] int; */ -/* forall (i,j) in C.domain { */ -/* C[i,j] = (+ reduce (M[i, M.domain.dim(2)] * N[M.domain.dim(2), j])) % 2; */ -/* } */ -/* return C; */ -/* } */ - -/* type listType = list(unmanaged Matrix2D?, true); */ -/* proc matmulreduce(arr : listType, reverse = false, mod = 2) { */ -/* var PD: domain(2) = {1..arr(1)._arr.domain.high(1), 1..arr(1)._arr.domain.high(2)}; */ -/* var P : [PD] int; */ -/* if (reverse) { */ -/* PD = {1..arr(arr.size)._arr.domain.high(1), 1..arr(arr.size)._arr.domain.high(2)}; */ -/* P = arr(arr.size)._arr; */ -/* for i in 1..#arr.size - 1 by -1 { */ -/* var tempD : domain(2) = {1..P.domain.high(1), 1..arr(i)._arr.domain.high(2)}; */ -/* var temp : [tempD] int; */ -/* temp = matmultmod(P, arr(i)._arr); */ -/* PD = tempD; */ -/* P = temp; */ -/* } */ -/* } else { */ -/* P = arr(1)._arr; */ -/* for i in 2..arr.size { */ -/* var tempD : domain(2) = {1..P.domain.high(1), 1..arr(i)._arr.domain.high(2)}; */ -/* var temp : [tempD] int; */ -/* temp = matmultmod(P, arr(i)._arr); */ -/* PD = tempD; */ -/* P = temp; */ -/* } */ -/* } */ -/* return P; */ -/* } */ - -/* // rank calculation: */ -/* proc calculateRank(M) { */ -/* var rank = + reduce [i in M.domain.dim(2)] (max reduce M[.., i]); */ -/* return rank; */ -/* } */ - - -/* // printmatrix(b); */ - -/* proc smithNormalForm(b) { */ -/* var dims = b.domain.high; */ -/* var dimL = dims(1); */ -/* var dimR = dims(2); */ -/* var minDim = if dimL <= dimR then dimL else dimR; */ - -/* // writeln(dimL : string ); // dims give me the index set but I need the max value of the index set */ -/* // writeln(minDim); */ - - -/* var S = b; */ -/* var IL = IdentityMatrix(dimL); */ -/* var IR = IdentityMatrix(dimR); */ - -/* var Linv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation */ -/* var Rinv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation */ - -/* var Linit = new unmanaged Matrix2D(IL.domain.high(1), IL.domain.high(2)); */ -/* Linit._arr = IL; */ -/* Linv.append(Linit); */ -/* var Rinit = new unmanaged Matrix2D(IR.domain.high(1), IR.domain.high(2)); */ -/* Rinit._arr = IR; */ -/* Rinv.append(Rinit); */ - -/* var L = IL; */ -/* var R = IR; */ - -/* /\* writeln("###############"); *\/ */ -/* /\* writeln("L:"); *\/ */ -/* /\* printmatrix(L); *\/ */ -/* /\* writeln("###############"); *\/ */ -/* /\* writeln("R:"); *\/ */ -/* /\* printmatrix(R); *\/ */ - -/* // var rc = _get_next_pivot(b, 3); */ -/* // writeln(rc : string); */ - - -/* writeln("########"); */ -/* for s in 1..minDim { */ -/* /\* writeln("Iteration: " + s : string); *\/ */ -/* var pivot = _get_next_pivot(S,s); */ -/* var rdx : int, cdx : int; */ -/* if (pivot(1) == -1 && pivot(2) == -1) { */ -/* break; */ -/* } */ -/* else { */ -/* (rdx, cdx) = pivot; */ -/* } */ - -/* // Swap rows and columns as needed so the 1 is in the s,s position */ -/* if (rdx > s) { */ -/* S = swap_rows(s, rdx, S); */ -/* L = swap_rows(s, rdx, L); */ -/* var tmp = swap_rows(s, rdx, IL); */ -/* var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); */ -/* LM._arr = tmp; */ -/* Linv.append(LM); */ -/* } */ -/* if (cdx > s) { */ -/* S = swap_columns(s, cdx, S); */ -/* R = swap_columns(s, cdx, R); */ -/* var tmp = swap_columns(s, cdx, IR); */ -/* var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); */ -/* RM._arr = tmp; */ -/* Rinv.append(RM); */ -/* } */ - -/* // add sth row to every nonzero row & sth column to every nonzero column */ -/* // zip(S[.., s], S.dim(1)) gives you (S[i,j], 1..N) */ -/* // row_indices = [idx for idx in range(dimL) if idx != s and S[idx][s] == 1] */ -/* // var RD: domain(2) = {1..dimL, 1..dimL}; */ -/* // var row_indices = [(x,(i,j)) in zip(S, 1..dimL)] if x == 1 && j != s then (i,j); */ -/* // var row_indices = [(s,idx) in zip(S, {1..dimL})] if s == 1 then idx; */ - -/* var row_indices = [idx in 1..dimL] if (idx != s && S(idx,s) == 1) then idx; */ -/* // compilerWarning(row_indices.type : string); */ - -/* for rdx in row_indices { */ -/* // writeln("rdx: " + rdx : string); */ -/* S = add_to_row(S, rdx, s); */ -/* L = add_to_row(L, rdx, s); */ -/* var tmp = add_to_row(IL, rdx, s); */ -/* var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); */ -/* LM._arr = tmp; */ -/* Linv.append(LM); */ -/* } */ - -/* var column_indices = [jdx in 1..dimR] if (jdx != s && S(s,jdx) == 1) then jdx; */ - -/* for (jdx,cdx) in zip(1..,column_indices) {// TODO: check */ -/* // writeln("rdx: " + rdx : string); */ -/* S = add_to_column(S, cdx, s); */ -/* R = add_to_column(R, cdx, s); */ -/* var tmp = add_to_column(IR, cdx, s); */ -/* var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); */ -/* RM._arr = tmp; */ -/* Rinv.append(RM); */ -/* } */ -/* } */ - - -/* var LinvF = matmulreduce(Linv); */ -/* var RinvF = matmulreduce(Rinv, true, 2); */ -/* return (L,R,S,LinvF,RinvF); */ -/* } */ - -/* var computedMatrices = smithNormalForm(boundaryMaps[1].matrix); */ -/* var computedMatrices2 = smithNormalForm(boundaryMaps[2].matrix); */ -/* var L1 = computedMatrices(1); */ -/* var R1 = computedMatrices(2); */ -/* var S1 = computedMatrices(3); */ -/* var L1invF = computedMatrices(4); */ -/* var R1invF = computedMatrices(5); */ -/* var L2 = computedMatrices2(1); */ -/* var R2 = computedMatrices2(2); */ -/* var S2 = computedMatrices2(3); */ -/* var L2invF = computedMatrices2(4); */ -/* var R2invF = computedMatrices2(5); */ -/* /\* writeln("###############"); *\/ */ -/* /\* writeln("L1:"); *\/ */ -/* /\* printmatrix(L1); *\/ */ -/* /\* writeln("###############"); *\/ */ -/* /\* writeln("R1:"); *\/ */ -/* /\* printmatrix(R1); *\/ */ -/* /\* writeln("###############"); *\/ */ -/* /\* writeln("S1:"); *\/ */ -/* /\* printmatrix(S1); *\/ */ -/* /\* writeln("###############"); *\/ */ -/* /\* writeln("L1inv:"); *\/ */ -/* /\* printmatrix(L1invF); *\/ */ -/* /\* writeln("###############"); *\/ */ -/* /\* writeln("R1inv:"); *\/ */ -/* /\* printmatrix(R1invF); *\/ */ -/* /\* writeln("###############"); *\/ */ -/* /\* writeln("L2inv:"); *\/ */ -/* /\* printmatrix(L2invF); *\/ */ - -/* var rank1 = calculateRank(S1); */ -/* writeln("Rank of S1: " + rank1 : string); */ -/* var rank2 = calculateRank(S2); */ -/* writeln("Rank of S2: " + rank2 : string); */ -/* var nullity1 = S1.domain.high(2) - rank1; */ -/* var betti1 = S1.domain.high(2) - rank1 - rank2; */ -/* writeln("Betti: " + betti1 : string); */ -/* /\* var cokernel2_dim = S1.domain.high(2) - rank2; *\/ */ - -/* /\* var nr1 = R1.domain.high(2) - rank1; *\/ */ -/* /\* var ker1 : [1..R1.domain.high(1), 1..nr1] int = R1[..,rank1+1..]; *\/ */ -/* /\* writeln("###############"); *\/ */ -/* /\* writeln("ker1:"); *\/ */ -/* /\* printmatrix(ker1); *\/ */ - -/* /\* // im2 = L2inv[:,:rank2] *\/ */ -/* /\* var im2 : [1..L2invF.domain.high(1), 1..rank2] int = L2invF[..,1..rank2]; *\/ */ -/* /\* var nr2 = L2invF.domain.high(2) - rank2; *\/ */ -/* /\* var cokernel2 : [1..L2invF.domain.high(1), 1..nr2] int = L2invF[..,rank2 + 1..]; *\/ */ - -/* /\* writeln("###############"); *\/ */ -/* /\* writeln("Cokernel:"); *\/ */ -/* /\* printmatrix(cokernel2); *\/ */ - -/* /\* writeln("###############"); *\/ */ -/* /\* writeln("L2:"); *\/ */ -/* /\* printmatrix(L2); *\/ */ - -/* /\* var LKernel = new list(unmanaged Matrix2D?, true); *\/ */ - -/* /\* var _L2 = new unmanaged Matrix2D(L2.domain.high(1), L2.domain.high(2)); *\/ */ -/* /\* _L2._arr = L2; *\/ */ -/* /\* LKernel.append(_L2); *\/ */ - -/* /\* var _ker1 = new unmanaged Matrix2D(ker1.domain.high(1), ker1.domain.high(2)); *\/ */ -/* /\* _ker1._arr = ker1; *\/ */ -/* /\* LKernel.append(_ker1); *\/ */ - -/* /\* writeln("L2 dimension: " + L2.domain.high(1) :string + "X" + L2.domain.high(2):string); *\/ */ -/* /\* writeln("ker1 dimension: " + ker1.domain.high(1) :string + "X" + ker1.domain.high(2):string); *\/ */ - -/* /\* var result = matmulreduce(LKernel); *\/ */ -/* /\* var slc = result.domain.high(1) - rank2; *\/ */ -/* /\* var proj : [1..slc, 1..result.domain.high(2)] int = result[rank2 + 1..,..]; *\/ */ -/* /\* writeln("###############"); *\/ */ -/* /\* writeln("Projection1:"); *\/ */ -/* /\* printmatrix(proj); *\/ */ - -/* /\* // proj = matmulreduce([L2,ker1])[rank2:,:] *\/ */ -/* /\* // proj = matmulreduce([L2inv[:,rank2:],proj]).transpose() *\/ */ - -/* /\* var L2invKernel = new list(unmanaged Matrix2D?, true); *\/ */ - -/* /\* // var nr2 = L2invF.domain.high(2) - rank2; *\/ */ -/* /\* var _L2inv = new unmanaged Matrix2D(L2invF.domain.high(1), nr2); *\/ */ -/* /\* _L2inv._arr = L2invF[..,rank2 + 1..]; *\/ */ -/* /\* L2invKernel.append(_L2inv); *\/ */ - -/* /\* var _proj = new unmanaged Matrix2D(proj.domain.high(1), proj.domain.high(2)); *\/ */ -/* /\* _proj._arr = proj; *\/ */ -/* /\* L2invKernel.append(_proj); *\/ */ - -/* /\* var proj2 = matmulreduce(L2invKernel); *\/ */ - -/* /\* writeln("###############"); *\/ */ -/* /\* writeln("Projection2:"); *\/ */ -/* /\* printmatrix(proj2); *\/ */ - -/* /\* t.stop(); *\/ */ -/* /\* writeln("Homology computed in ", t.elapsed(), "s"); *\/ */ - - -/* /\* proc reducedRowEchelonForm(b) { *\/ */ -/* /\* var dims = b.domain.high; *\/ */ -/* /\* var dimL = dims(1); *\/ */ -/* /\* var dimR = dims(2); *\/ */ -/* /\* var minDim = if dimL <= dimR then dimL else dimR; *\/ */ - -/* /\* // writeln(dimL : string ); // dims give me the index set but I need the max value of the index set *\/ */ -/* /\* // writeln(minDim); *\/ */ - - -/* /\* var S = b; *\/ */ -/* /\* var IL = IdentityMatrix(dimL); *\/ */ - -/* /\* var Linv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation *\/ */ - -/* /\* var Linit = new unmanaged Matrix2D(IL.domain.high(1), IL.domain.high(2)); *\/ */ -/* /\* Linit._arr = IL; *\/ */ -/* /\* Linv.append(Linit); *\/ */ - -/* /\* var L = IL; *\/ */ - -/* /\* /\\* writeln("###############"); *\\/ *\/ */ -/* /\* /\\* writeln("L:"); *\\/ *\/ */ -/* /\* /\\* printmatrix(L); *\\/ *\/ */ -/* /\* /\\* writeln("###############"); *\\/ *\/ */ -/* /\* /\\* writeln("R:"); *\\/ *\/ */ -/* /\* /\\* printmatrix(R); *\\/ *\/ */ - -/* /\* // var rc = _get_next_pivot(b, 3); *\/ */ -/* /\* // writeln(rc : string); *\/ */ - -/* /\* var s2 : int = 1; *\/ */ -/* /\* writeln("########"); *\/ */ -/* /\* for s1 in 1..dimL { *\/ */ -/* /\* writeln("Iteration: " + s1 : string); *\/ */ -/* /\* var rdx : int, cdx : int; *\/ */ -/* /\* for s2 in s2..dimR { *\/ */ -/* /\* var pivot = _get_next_pivot(S,s1, s2); *\/ */ -/* /\* if (pivot(1) != -1 && pivot(2) != -1) { *\/ */ -/* /\* (rdx, cdx) = pivot; *\/ */ -/* /\* s2 = cdx; *\/ */ -/* /\* break; *\/ */ -/* /\* } *\/ */ -/* /\* } *\/ */ -/* /\* // Swap rows *\/ */ -/* /\* if (rdx > s1) { *\/ */ -/* /\* S = swap_rows(s1, rdx, S); *\/ */ -/* /\* L = swap_rows(s1, rdx, L); *\/ */ -/* /\* var tmp = swap_rows(s1, rdx, IL); *\/ */ -/* /\* var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); *\/ */ -/* /\* LM._arr = tmp; *\/ */ -/* /\* Linv.append(LM); *\/ */ -/* /\* } *\/ */ - -/* /\* var row_indices = [idx in 1..dimL] if (idx != s1 && S(idx,cdx) == 1) then idx; *\/ */ -/* /\* // compilerWarning(row_indices.type : string); *\/ */ - -/* /\* for idx in row_indices { *\/ */ -/* /\* // writeln("rdx: " + rdx : string); *\/ */ -/* /\* S = add_to_row(S, idx, s1); *\/ */ -/* /\* L = add_to_row(L, idx, s1); *\/ */ -/* /\* var tmp = add_to_row(IL, idx, s1); *\/ */ -/* /\* var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); *\/ */ -/* /\* LM._arr = tmp; *\/ */ -/* /\* Linv.append(LM); *\/ */ -/* /\* } *\/ */ -/* /\* } *\/ */ - -/* /\* var LinvF = matmulreduce(Linv); *\/ */ -/* /\* return (L,S,LinvF); *\/ */ -/* /\* } *\/ */ \ No newline at end of file diff --git a/example/homology_experimental/betti_number_calculator.chpl b/example/homology_experimental/betti_number_calculator.chpl new file mode 100644 index 0000000..625a72f --- /dev/null +++ b/example/homology_experimental/betti_number_calculator.chpl @@ -0,0 +1,678 @@ +/*Calculation of betti numbers for k = 1 and k =2 */ +/*To compile: chpl -o betti_number_calculator --fast --cc-warnings -M../../src --dynamic --no-lifetime-checking --no-warnings betti_number_calculator.chpl */ + +use CHGL; // Includes all core and utility components of CHGL +use Time; // For Timer +use Set; +use Map; +use List; +use Sort; +use Search; +use Regexp; +use FileSystem; +use BigInteger; + +config const datasetDir = "./betti_test_data/"; +/* + Output directory. +*/ +config const outputDirectory = "tmp/"; +// Maximum number of files to process. +config const numMaxFiles = max(int(64)); + +var files : [0..-1] string; +var vPropMap = new PropertyMap(string); +var ePropMap = new PropertyMap(string); +var wq = new WorkQueue(string, 1024); +var td = new TerminationDetector(); +var t = new Timer(); +var total_time = new Timer(); +total_time.start(); + +proc printPropertyDistribution(propMap) : void { + var localNumProperties : [LocaleSpace] int; + coforall loc in Locales do on loc do localNumProperties[here.id] = propMap.numProperties(); + var globalNumProperties = + reduce localNumProperties; + for locid in LocaleSpace { + writeln("Locale#", locid, " has ", localNumProperties[locid], "(", localNumProperties[locid] : real / globalNumProperties * 100, "%)"); + } +} + +//Need to create outputDirectory prior to opening files +if !exists(outputDirectory) { + try { + mkdir(outputDirectory); + } + catch { + halt("*Unable to create directory ", outputDirectory); + } +} +// Fill work queue with files to load up +var currLoc : int; +var nFiles : int; +var fileNames : [0..-1] string; +for fileName in listdir(datasetDir, dirs=false) { + if !fileName.endsWith(".csv") then continue; + if nFiles == numMaxFiles then break; + files.push_back(fileName); + fileNames.push_back(datasetDir + fileName); + currLoc += 1; + nFiles += 1; +} + +// Spread out the work across multiple locales. +var _currLoc : atomic int; +forall fileName in fileNames { + td.started(1); + wq.addWork(fileName, _currLoc.fetchAdd(1) % numLocales); +} +wq.flush(); + + +// Initialize property maps; aggregation is used as properties can be remote to current locale. +forall fileName in doWorkLoop(wq, td) { + for line in getLines(fileName) { + var attrs = line.split(","); + var qname = attrs[1].strip(); + var rdata = attrs[2].strip(); + + vPropMap.create(rdata, aggregated=true); + ePropMap.create(qname, aggregated=true); + } + td.finished(); +} +vPropMap.flushGlobal(); +ePropMap.flushGlobal(); +// t.stop(); +writeln("Constructed Property Map with ", vPropMap.numPropertiesGlobal(), + " vertex properties and ", ePropMap.numPropertiesGlobal(), + " edge properties in ", t.elapsed(), "s"); +t.clear(); + +writeln("Vertex Property Map"); +printPropertyDistribution(vPropMap); +writeln("Edge Property Map"); +printPropertyDistribution(ePropMap); + +writeln("Constructing HyperGraph..."); +t.start(); +var hypergraph = new AdjListHyperGraph(vPropMap, ePropMap, new unmanaged Cyclic(startIdx=0)); +t.stop(); +writeln("Constructed HyperGraph in ", t.elapsed(), "s"); +t.clear(); +writeln("Populating HyperGraph..."); + +t.start(); +// Spread out the work across multiple locales. +_currLoc.write(0); +forall fileName in fileNames { + td.started(1); + wq.addWork(fileName, _currLoc.fetchAdd(1) % numLocales); +} +wq.flush(); + +// Aggregate fetches to properties into another work queue; when we flush +// each of the property maps, their individual PropertyHandle will be finished. +// Also send the 'String' so that it can be reclaimed. +var handleWQ = new WorkQueue((unmanaged PropertyHandle?, unmanaged PropertyHandle?), 64 * 1024); +var handleTD = new TerminationDetector(); +forall fileName in doWorkLoop(wq, td) { + for line in getLines(fileName) { + var attrs = line.split(","); + var qname = attrs[1].strip(); + var rdata = attrs[2].strip(); + handleTD.started(1); + handleWQ.addWork((vPropMap.getPropertyAsync(rdata), ePropMap.getPropertyAsync(qname))); + } + td.finished(); +} +vPropMap.flushGlobal(); +ePropMap.flushGlobal(); + +// Finally aggregate inclusions for the hypergraph. +hypergraph.startAggregation(); +forall (vHandle, eHandle) in doWorkLoop(handleWQ, handleTD) { + hypergraph.addInclusion(vHandle.get(), eHandle.get()); + delete vHandle; + delete eHandle; + handleTD.finished(1); +} +hypergraph.stopAggregation(); +hypergraph.flushBuffers(); + +t.stop(); +writeln("Populated HyperGraph in ", t.elapsed(), "s"); +t.clear(); +writeln("Number of Inclusions: ", hypergraph.getInclusions()); +writeln("Deleting Duplicate edges: ", hypergraph.removeDuplicates()); +writeln("Number of Inclusions: ", hypergraph.getInclusions()); + + +t.start(); +var _vtxSubsetSet = new set(string); + +iter processVtxSubset(vtxSubset) { + for i in 1..#vtxSubset.size { + var tmp : [1..#vtxSubset.size - 1] int; + tmp[1..i - 1] = vtxSubset[1..i - 1]; + tmp[i..] = vtxSubset[i + 1..]; + yield tmp; + } +} + +/* Generate the permutation */ +proc doProcessVertices (verticesSet) { + /* writeln(stringify(verticesSet)); */ + if (verticesSet.size == 0) { + return; + } else if (verticesSet.size == 1) { + var verticesStr = stringify(verticesSet); + if !_vtxSubsetSet.contains(verticesStr) { // TODO: redundant? + _vtxSubsetSet.add(verticesStr); + } + } else { + var verticesStr = stringify(verticesSet); + if !_vtxSubsetSet.contains(verticesStr) { + _vtxSubsetSet.add(verticesStr); + for _vtxSubset in processVtxSubset(verticesSet) { + doProcessVertices(_vtxSubset); + } + } + } +} + +/*For each of the hyperedge, do the permutation of all the vertices.*/ +for e in hypergraph.getEdges() { + var vertices = hypergraph.incidence(e); // ABCD + ref tmp = vertices[1..#vertices.size]; + var verticesInEdge : [1..#vertices.size] int; + verticesInEdge[1..#vertices.size] = tmp.id; // ABCD vertices.low + doProcessVertices(verticesInEdge); +} + +/* writeln("Printing all generated combination"); */ +/* /\*Verify the set by printing*\/ */ +/* var setContent = _vtxSubsetSet.toArray(); */ +/* for c in setContent do */ +/* writeln(c); */ + +/* writeln("-----"); */ +/* writeln("Printing bins"); */ +/*bin k-cells, with key as the length of the list and value is a list with all the k-cells*/ +var kCellMap = new map(int, list(string, true)); +for vtxSet in _vtxSubsetSet { + var sz = + reduce [ch in vtxSet] ch == ' '; + /* writeln(sz : string + " " + vtxSet : string); */ + kCellMap[sz].append(vtxSet); +} + +class kCellsArray{ + var numKCells : int; + var D = {1..numKCells}; + var A : [D] string; + proc init(_N: int) { + numKCells = _N; + } +} + +var numBins = kCellMap.size - 1; +var kCellsArrayMap : [0..numBins] owned kCellsArray?; +var kCellKeys = kCellMap.keysToArray(); +sort(kCellKeys); + +// Empty record serves as comparator +record Comparator { } +// compare method defines how 2 elements are compared +proc Comparator.compare(a :string, b :string) : int { + var retVal : int = 0; + if (b == "" || a == "") { + /* writeln("a: " + a : string + " b: " + b : string); */ + retVal = -1; + return retVal; + } + var aa = a.split(" ") : int; + var bb = b.split(" ") : int; + var done : bool = false; + var ndone : bool = false; + for i in 1..#aa.size { + for j in i..#bb.size { + if (aa[i] == bb[j]) { + break; + } + if (aa[i] < bb[j]) { + retVal = -1; done = true; break; + } + if (aa[i] > bb[j]) { + retVal = 1; done = true; break; + } + } + if (done) {break;} + } + return retVal; +} + +var absComparator: Comparator; + +/* /\* writeln("%%%%%%%%%%%%%"); *\/ */ +/* // Leader-follower iterator */ +/* // Create the new KcellMaps for convenience of sorting */ +for (_kCellsArray, kCellKey) in zip(kCellsArrayMap, kCellKeys) { + /* writeln("kCellkey:" + kCellKey : string); */ + /* writeln("listsize: " + kCellMap[kCellKey].size : string); */ + _kCellsArray = new owned kCellsArray(kCellMap[kCellKey].size); + _kCellsArray.A = kCellMap[kCellKey].toArray(); + sort(_kCellsArray.A, comparator=absComparator); +} +/* writeln("%%%%%%%%%%%%%"); */ + +/* writeln("Printing after sorting"); */ +/* writeln("^^^^^^^^^^^^^^^^^^^^^^^"); */ +/* for _kCellsArray in kCellsArrayMap { */ +/* writeln(_kCellsArray.A : string); */ +/* } */ +/* writeln("^^^^^^^^^^^^^^^^^^^^^^^"); */ + +/*Start of the construction of boundary matrices.*/ +class Matrix { + var N : int; + var M : int; + var matrix : [1..N, 1..M] int; + proc init(_N: int, _M:int) { + N = _N; + M = _M; + } +} + +var K = kCellMap.size - 1; +// Only computing upto 3 +var boundaryMaps : [1..3] owned Matrix?; +var i : int = 1; + +// Leader-follower iterator +// Create the boundary Maps +for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { + /* writeln("dimensions: " + kCellsArrayMap[dimension_k_1].numKCells: string + " " + kCellsArrayMap[dimension_k].numKCells : string); */ + boundaryMap = new owned Matrix(kCellsArrayMap[dimension_k_1].numKCells, kCellsArrayMap[dimension_k].numKCells); +} + +var vs = new set(string); + +iter processVtxSubset2(vtxSubset) { + for i in 1..#vtxSubset.size { + var tmp : [1..#vtxSubset.size - 1] int; + tmp[1..i - 1] = vtxSubset[1..i - 1]; + tmp[i..] = vtxSubset[i + 1..]; + yield tmp; + } +} + +/* Generate the permutation */ +proc doProcessVertices2 (verticesSet) { + if (verticesSet.size == 0) { + return; + } else if (verticesSet.size == 1) { + var verticesStr = stringify(verticesSet); + if !vs.contains(verticesStr) { + vs.add(verticesStr); + } + } else { + var verticesStr = stringify(verticesSet); + if !vs.contains(verticesStr) { + vs.add(verticesStr); + for _vtxSubset in processVtxSubset2(verticesSet) { + doProcessVertices2(_vtxSubset); + } + } + } +} + + +/* writeln("####"); */ +// Compute values for each entries in each of the boundary map +for (dimension_k_1, dimension_k) in zip(0..2, 1..3) { + var arrayOfKCells = kCellsArrayMap[dimension_k].A; // Arrays of strings, each string being 1 kcell + var arrayOfK_1Cells = kCellsArrayMap[dimension_k_1].A; + /* writeln("$$$$$$$$$$$"); */ + /* writeln(arrayOfKCells); */ + /* writeln(arrayOfK_1Cells); */ + /* writeln("$$$$$$$$$$$"); */ + var i : int = 0; + var j : int = 0; + for SkCell in arrayOfKCells { // iterate through all the k-cells + i = i + 1; + /* Generate permutation of the current k-Cell*/ + var kCell = SkCell.split(" ") : int; + /* writeln("#kcell: " + kCell :string); */ + /* writeln("Combinations generated ": string); */ + for sc in processVtxSubset(kCell) { + var st = stringify(sc); + j = 0; + for Sk_1Cell in arrayOfK_1Cells { + j = j + 1; + if (st == Sk_1Cell) { + // writeln(st :string + "matches"); + boundaryMaps[dimension_k].matrix[j, i] = 1; + break; + } + } + } + } + /* writeln("$$$$$$$$$$$"); */ +} + +proc printBoundaryMap(boundaryMap) { + var row : int = boundaryMap.matrix.domain.high(1); + var col : int = boundaryMap.matrix.domain.high(2); + for i in 1..row { + for j in 1..col { + write(boundaryMap.matrix[i, j] : string + " "); + } + writeln(); + } +} + +/* for (dimension_k_1, dimension_k) in zip(0..1, 1..2) { */ +/* writeln("Printing boundary map for: " : string + dimension_k_1 : string + " " :string + dimension_k : string); */ +/* printBoundaryMap(boundaryMaps[dimension_k]); */ +/* } */ + + +proc printmatrix(M) { + for i in {1..M.domain.high(1)} { + for j in {1..M.domain.high(2)} { + write(M(i,j):string + " "); + } + writeln(); + } +} + + +proc IdentityMatrix(n) { + var A : [1..n, 1..n] int; + [i in A.domain.dim(1)] A[i,i] = 1; + return A; +} + +use List; +class Matrix2D { + var N : int; + var M : int; + var _arr : [1..N, 1..M] int; + proc init (row : int, col : int) { + N = row; + M = col; + } +} + +proc _get_next_pivot(M, s1, in s2 : int = 0) { + var dims = M.domain.high; + var dimR = dims(1); + var dimC = dims(2); + if (s2 == 0) { + s2 = s1; + } + for c in s2..dimC { + for r in s1..dimR { + if (M(r,c) != 0) { + return (r,c); + } + } + } + return (-1,-1); // TODO: return +} + + +proc swap_rows(i, j, M) { + var N = M; + N[i, ..] <=> N[j, ..]; + return N; +} + +proc swap_columns(i, j, M) { + var N = M; + N[.., i] <=> N[.., j]; + return N; +} + +// Replaces row i (of M) with sum ri multiple of ith row and rj multiple of jth row +proc add_to_row(M, i, j, ri = 1, rj = 1, mod = 2) { + var N = M; + N[i, ..] = (ri * N[i, ..] + rj * N[j, ..]) % mod; + return N; +} + + +proc add_to_column(M, i, j, ci = 1, cj = 1, mod = 2) { + var N = M; + N[.., i] = (ci * N[.., i] + cj * N[..,j]) % mod; + return N; +} + +proc matmultmod2 (M, N, mod = 2) { + var nr = M.domain.high(1); + var nc = N.domain.high(2); + var m = M.domain.high(2); + var C : [1..nr, 1..nc] atomic int; + + forall i in 1..nr { + for j in 1..nc { + C[i,j].write((+ reduce M[i, 1..m] * N[1..m, j]) % 2) ; + } + } + return C.read(); +} + +proc matmultmod3 (M, N, mod = 2) { + var C : [M.domain.dim(1), N.domain.dim(2)] atomic int; + forall (i,j) in C.domain { + C[i,j].write((+ reduce M[i, M.domain.dim(2)] * N[M.domain.dim(2), j]) % 2); + } + return C.read(); +} + +proc matmultmod (M, N, mod =2) { + var C : [M.domain.dim(1), N.domain.dim(2)] int; + forall (i,j) in C.domain { + C[i,j] = (+ reduce (M[i, M.domain.dim(2)] * N[M.domain.dim(2), j])) % 2; + } + return C; +} + +type listType = list(unmanaged Matrix2D?, true); +proc matmulreduce(arr : listType, reverse = false, mod = 2) { + var PD: domain(2) = {1..arr(1)._arr.domain.high(1), 1..arr(1)._arr.domain.high(2)}; + var P : [PD] int; + if (reverse) { + PD = {1..arr(arr.size)._arr.domain.high(1), 1..arr(arr.size)._arr.domain.high(2)}; + P = arr(arr.size)._arr; + for i in 1..#arr.size - 1 by -1 { + var tempD : domain(2) = {1..P.domain.high(1), 1..arr(i)._arr.domain.high(2)}; + var temp : [tempD] int; + temp = matmultmod(P, arr(i)._arr); + PD = tempD; + P = temp; + } + } else { + P = arr(1)._arr; + for i in 2..arr.size { + var tempD : domain(2) = {1..P.domain.high(1), 1..arr(i)._arr.domain.high(2)}; + var temp : [tempD] int; + temp = matmultmod(P, arr(i)._arr); + PD = tempD; + P = temp; + } + } + return P; +} + +// rank calculation: +proc calculateRank(M) { + var rank = + reduce [i in M.domain.dim(2)] (max reduce M[.., i]); + return rank; +} + + +// printmatrix(b); + +proc smithNormalForm(b) { + var dims = b.domain.high; + var dimL = dims(1); + var dimR = dims(2); + var minDim = if dimL <= dimR then dimL else dimR; + + // writeln(dimL : string ); // dims give me the index set but I need the max value of the index set + // writeln(minDim); + + + var S = b; + var IL = IdentityMatrix(dimL); + var IR = IdentityMatrix(dimR); + + var Linv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation + var Rinv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation + + var Linit = new unmanaged Matrix2D(IL.domain.high(1), IL.domain.high(2)); + Linit._arr = IL; + Linv.append(Linit); + var Rinit = new unmanaged Matrix2D(IR.domain.high(1), IR.domain.high(2)); + Rinit._arr = IR; + Rinv.append(Rinit); + + var L = IL; + var R = IR; + + /* writeln("###############"); */ + /* writeln("L:"); */ + /* printmatrix(L); */ + /* writeln("###############"); */ + /* writeln("R:"); */ + /* printmatrix(R); */ + + // var rc = _get_next_pivot(b, 3); + // writeln(rc : string); + + + writeln("########"); + for s in 1..minDim { + /* writeln("Iteration: " + s : string); */ + var pivot = _get_next_pivot(S,s); + var rdx : int, cdx : int; + if (pivot(1) == -1 && pivot(2) == -1) { + break; + } + else { + (rdx, cdx) = pivot; + } + + // Swap rows and columns as needed so the 1 is in the s,s position + if (rdx > s) { + S = swap_rows(s, rdx, S); + L = swap_rows(s, rdx, L); + var tmp = swap_rows(s, rdx, IL); + var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + LM._arr = tmp; + Linv.append(LM); + } + if (cdx > s) { + S = swap_columns(s, cdx, S); + R = swap_columns(s, cdx, R); + var tmp = swap_columns(s, cdx, IR); + var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + RM._arr = tmp; + Rinv.append(RM); + } + + // add sth row to every nonzero row & sth column to every nonzero column + // zip(S[.., s], S.dim(1)) gives you (S[i,j], 1..N) + // row_indices = [idx for idx in range(dimL) if idx != s and S[idx][s] == 1] + // var RD: domain(2) = {1..dimL, 1..dimL}; + // var row_indices = [(x,(i,j)) in zip(S, 1..dimL)] if x == 1 && j != s then (i,j); + // var row_indices = [(s,idx) in zip(S, {1..dimL})] if s == 1 then idx; + + var row_indices = [idx in 1..dimL] if (idx != s && S(idx,s) == 1) then idx; + // compilerWarning(row_indices.type : string); + + for rdx in row_indices { + // writeln("rdx: " + rdx : string); + S = add_to_row(S, rdx, s); + L = add_to_row(L, rdx, s); + var tmp = add_to_row(IL, rdx, s); + var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + LM._arr = tmp; + Linv.append(LM); + } + + var column_indices = [jdx in 1..dimR] if (jdx != s && S(s,jdx) == 1) then jdx; + + for (jdx,cdx) in zip(1..,column_indices) {// TODO: check + // writeln("rdx: " + rdx : string); + S = add_to_column(S, cdx, s); + R = add_to_column(R, cdx, s); + var tmp = add_to_column(IR, cdx, s); + var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + RM._arr = tmp; + Rinv.append(RM); + } + } + + + var LinvF = matmulreduce(Linv); + var RinvF = matmulreduce(Rinv, true, 2); + return (L,R,S,LinvF,RinvF); +} + +var computedMatrices = smithNormalForm(boundaryMaps[1].matrix); +var computedMatrices2 = smithNormalForm(boundaryMaps[2].matrix); +var computedMatrices3 = smithNormalForm(boundaryMaps[3].matrix); +var L1 = computedMatrices(1); +var R1 = computedMatrices(2); +var S1 = computedMatrices(3); +var L1invF = computedMatrices(4); +var R1invF = computedMatrices(5); +var L2 = computedMatrices2(1); +var R2 = computedMatrices2(2); +var S2 = computedMatrices2(3); +var L2invF = computedMatrices2(4); +var R2invF = computedMatrices2(5); +var L3 = computedMatrices3(1); +var R3 = computedMatrices3(2); +var S3 = computedMatrices3(3); +var L3invF = computedMatrices3(4); +var R3invF = computedMatrices3(5); +/* writeln("###############"); */ +/* writeln("L1:"); */ +/* printmatrix(L1); */ +/* writeln("###############"); */ +/* writeln("R1:"); */ +/* printmatrix(R1); */ +/* writeln("###############"); */ +/* writeln("S1:"); */ +/* printmatrix(S1); */ +/* writeln("###############"); */ +/* writeln("L1inv:"); */ +/* printmatrix(L1invF); */ +/* writeln("###############"); */ +/* writeln("R1inv:"); */ +/* printmatrix(R1invF); */ +/* writeln("###############"); */ +/* writeln("L2inv:"); */ +/* printmatrix(L2invF); */ + +var rank1 = calculateRank(S1); +writeln("Rank of S1: " + rank1 : string); +var rank2 = calculateRank(S2); +writeln("Rank of S2: " + rank2 : string); +var nullity1 = S1.domain.high(2) - rank1; +var betti1 = S1.domain.high(2) - rank1 - rank2; +writeln("Betti 1: " + betti1 : string); + +/* var rank3 = calculateRank(S2); */ +/* writeln("Rank of S2: " + rank1 : string); */ +var rank3 = calculateRank(S3); +writeln("Rank of S3: " + rank3 : string); +var betti2 = S2.domain.high(2) - rank2 - rank3; +writeln("Betti 2: " + betti2 : string); +writeln("Total execution time: " + total_time.elapsed() : string + " s"); + + + diff --git a/example/homology_experimental/betti_test_data/bip_ER_V20_E20_p0.2_me8_t4.csv b/example/homology_experimental/betti_test_data/bip_ER_V20_E20_p0.2_me8_t4.csv new file mode 100644 index 0000000..469c9b8 --- /dev/null +++ b/example/homology_experimental/betti_test_data/bip_ER_V20_E20_p0.2_me8_t4.csv @@ -0,0 +1,89 @@ +20,1 +20,2 +20,6 +20,9 +20,18 +21,4 +21,8 +21,13 +21,18 +22,1 +22,2 +22,7 +22,11 +22,16 +22,17 +23,6 +23,8 +24,3 +24,7 +24,15 +24,16 +25,0 +25,2 +25,5 +25,8 +25,11 +25,13 +26,0 +26,1 +26,9 +26,13 +26,15 +26,18 +26,19 +27,9 +27,10 +27,12 +27,13 +27,14 +28,5 +28,7 +28,8 +28,10 +28,13 +28,17 +28,19 +29,3 +29,5 +29,8 +29,11 +29,15 +29,18 +30,0 +30,5 +30,9 +30,11 +30,15 +31,0 +31,1 +31,17 +32,0 +32,1 +32,5 +32,7 +32,11 +32,13 +32,17 +32,19 +34,0 +34,12 +34,14 +34,16 +34,17 +35,2 +35,11 +35,17 +36,6 +36,7 +37,0 +37,8 +37,11 +37,17 +38,3 +38,5 +38,10 +38,13 +39,1 +39,12 +39,17 diff --git a/example/boundary_matrix.chpl b/example/homology_experimental/boundary_matrix.chpl similarity index 68% rename from example/boundary_matrix.chpl rename to example/homology_experimental/boundary_matrix.chpl index d48aa2b..4e1493d 100644 --- a/example/boundary_matrix.chpl +++ b/example/homology_experimental/boundary_matrix.chpl @@ -10,16 +10,6 @@ use Search; var hypergraph = new AdjListHyperGraph(4, 1, new unmanaged Cyclic(startIdx=0)); for v in hypergraph.getVertices() do hypergraph.addInclusion(v, 0); - -// writeln(e : string + " vertices:" + vertices :string); -// writeln("-----"); - /* for currentsize in 1..#vertices.size by -1 { */ - /* writeln("Strings: "); */ - -// writeln(elmInSubset : string); - -// var vertices = graph.incidence(graph.toEdge(eIdx)); - var _vtxSubsetSet = new set(string); iter processVtxSubset(vtxSubset) { @@ -54,7 +44,6 @@ proc doProcessVertices (verticesSet) { /*For each of the hyperedge, do the permutation of all the vertices.*/ for e in hypergraph.getEdges() { var vertices = hypergraph.incidence(e); // ABCD - // writeln(vertices.domain); ref tmp = vertices[1..#vertices.size]; var verticesInEdge : [1..#vertices.size] int; verticesInEdge[1..#vertices.size] = tmp.id; // ABCD vertices.low @@ -62,21 +51,12 @@ for e in hypergraph.getEdges() { doProcessVertices(verticesInEdge); } -/* writeln("Printing all generated combination"); */ -/* /\*Verify the set by printing*\/ */ -/* var setContent = _vtxSubsetSet.toArray(); */ -/* for c in setContent do */ -/* writeln(c); */ - -/* writeln("-----"); */ var _sz = 0; -/* writeln("Printing bins"); */ /*bin k-cells, with key as the length of the list and value is a list with all the k-cells*/ var kCellMap = new map(int, list(string, true)); for vtxSet in _vtxSubsetSet { //var _vtxSet = vtxSet.split(" "); var sz = + reduce [ch in vtxSet] ch == ' '; - /* writeln(sz : string + " " + vtxSet : string); */ kCellMap[sz].append(vtxSet); _sz = sz; } @@ -106,7 +86,6 @@ record Comparator { } proc Comparator.compare(a :string, b :string) : int { var retVal : int = 0; if (b == "" || a == "") { - /* writeln("a: " + a : string + " b: " + b : string); */ retVal = -1; return retVal; } @@ -132,46 +111,13 @@ proc Comparator.compare(a :string, b :string) : int { } var absComparator: Comparator; - -// sort(Array, comparator=absComparator); -/*TODO: change the following loop as follows:*/ -/*forall k in 0..K { - kCellsArrayMap[k] = new owned kCellsArray(k + 1); - kCellsArrayMap[k].A = kCellMap[k + 1].toArray(); - sort(kCellsArrayMap[k].A, comparator=absComparator); -}*/ - -/* writeln("%%%%%%%%%%%%%"); */ // Leader-follower iterator // Create the new KcellMaps for convenience of sorting for (_kCellsArray, kCellKey) in zip(kCellsArrayMap, kCellKeys) { - /* writeln("listsize: " + kCellMap[kCellKey].size : string); */ _kCellsArray = new owned kCellsArray(kCellMap[kCellKey].size); _kCellsArray.A = kCellMap[kCellKey].toArray(); - // compilerWarning(kCellMap[kCellKey].toArray().type : string); sort(_kCellsArray.A, comparator=absComparator); - /* for c in kCellMap[kCellKey].toArray() { */ - /* writeln(c); */ - /* compilerWarning(c.type: string); */ - /* } */ -} -/* writeln("%%%%%%%%%%%%%"); */ - -// TODO: change the following: -/* -for (_kCellsArray, idx) in (kCellsArrayMap, 1..K) { - writeln((_kCellsArray.A, idx) : string); } -*/ -/* writeln("Printing after sorting"); */ -/* writeln("^^^^^^^^^^^^^^^^^^^^^^^"); */ -/* /\* for (_kCellsArray, idx) in zip(kCellsArrayMap, 1..numBins) { *\/ */ -/* /\* writeln((_kCellsArray.A, idx) : string); *\/ */ -/* /\* } *\/ */ -/* for _kCellsArray in kCellsArrayMap { */ -/* writeln(_kCellsArray.A : string); */ -/* } */ -/* writeln("^^^^^^^^^^^^^^^^^^^^^^^"); */ /*Start of the construction of boundary matrices.*/ class Matrix { @@ -191,16 +137,9 @@ var i : int = 1; // Leader-follower iterator // Create the boundary Maps for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { - /* writeln("dimensions: " + kCellsArrayMap[dimension_k_1].numKCells: string + " " + kCellsArrayMap[dimension_k].numKCells : string); */ boundaryMap = new owned Matrix(kCellsArrayMap[dimension_k_1].numKCells, kCellsArrayMap[dimension_k].numKCells); } -/* forall (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { */ -/* writeln("dimensions: " + kCellMap[dimension_k_1].size: string + " " + kCellMap[dimension_k].size : string); */ -/* boundaryMap = new owned Matrix(kCellMap[dimension_k_1].size, kCellMap[dimension_k].size); */ -/* } */ - - var vs = new set(string); iter processVtxSubset2(vtxSubset) { @@ -233,42 +172,29 @@ proc doProcessVertices2 (verticesSet) { } -writeln("####"); // Compute values for each entries in each of the boundary map for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { var arrayOfKCells = kCellsArrayMap[dimension_k].A; // Arrays of strings, each string being 1 kcell var arrayOfK_1Cells = kCellsArrayMap[dimension_k_1].A; - /* compilerWarning(arrayOfK_1Cells.type : string); */ - /* writeln("$$$$$$$$$$$"); */ - /* writeln(arrayOfKCells); */ - /* writeln(arrayOfK_1Cells); */ - /* writeln("$$$$$$$$$$$"); */ var i : int = 0; var j : int = 0; for SkCell in arrayOfKCells { // iterate through all the k-cells i = i + 1; /* Generate permutation of the current k-Cell*/ - // compilerWarning(SkCell.type : string); var kCell = SkCell.split(" ") : int; - // compilerWarning(kCell.type : string); - /* writeln("#kcell: " + kCell :string); */ - /* writeln("Combinations generated ": string); */ for sc in processVtxSubset(kCell) { compilerWarning(sc.type : string); - /* writeln(sc); */ var st = stringify(sc); j = 0; for Sk_1Cell in arrayOfK_1Cells { j = j + 1; if (st == Sk_1Cell) { - /* writeln(st :string + "matches"); */ boundaryMap.matrix[j, i] = 1; break; } } } } - /* writeln("$$$$$$$$$$$"); */ } proc printBoundaryMap(boundaryMap) { diff --git a/example/homology_experimental/homology_dns.chpl b/example/homology_experimental/homology_dns.chpl new file mode 100644 index 0000000..00fadd5 --- /dev/null +++ b/example/homology_experimental/homology_dns.chpl @@ -0,0 +1,808 @@ +/*Homology computation on small DNS datasets*/ +/*To compile : chpl -o homology_dns --fast --cc-warnings -M../../src --dynamic --no-lifetime-checking --no-warnings homology_dns.chpl */ + +use CHGL; // Includes all core and utility components of CHGL +use Time; // For Timer +use Set; +use Map; +use List; +use Sort; +use Search; +use Regexp; +use FileSystem; +use BigInteger; + +config const datasetDirectory = "./homology_dns_data/"; +/* + Output directory. +*/ +config const outputDirectory = "tmp/"; +// Maximum number of files to process. +config const numMaxFiles = max(int(64)); + +var files : [0..-1] string; +var vPropMap = new PropertyMap(string); +var ePropMap = new PropertyMap(string); +var wq = new WorkQueue(string, 1024); +var td = new TerminationDetector(); +var t = new Timer(); + +proc printPropertyDistribution(propMap) : void { + var localNumProperties : [LocaleSpace] int; + coforall loc in Locales do on loc do localNumProperties[here.id] = propMap.numProperties(); + var globalNumProperties = + reduce localNumProperties; + for locid in LocaleSpace { + writeln("Locale#", locid, " has ", localNumProperties[locid], "(", localNumProperties[locid] : real / globalNumProperties * 100, "%)"); + } +} + +//Need to create outputDirectory prior to opening files +if !exists(outputDirectory) { + try { + mkdir(outputDirectory); + } + catch { + halt("*Unable to create directory ", outputDirectory); + } +} +// Fill work queue with files to load up +var currLoc : int; +var nFiles : int; +var fileNames : [0..-1] string; +for fileName in listdir(datasetDirectory, dirs=false) { + if !fileName.endsWith(".csv") then continue; + if nFiles == numMaxFiles then break; + files.push_back(fileName); + fileNames.push_back(datasetDirectory + fileName); + currLoc += 1; + nFiles += 1; +} + +// Spread out the work across multiple locales. +var _currLoc : atomic int; +forall fileName in fileNames { + td.started(1); + wq.addWork(fileName, _currLoc.fetchAdd(1) % numLocales); +} +wq.flush(); + + +// Initialize property maps; aggregation is used as properties can be remote to current locale. +forall fileName in doWorkLoop(wq, td) { + for line in getLines(fileName) { + var attrs = line.split(","); + var qname = attrs[1].strip(); + var rdata = attrs[2].strip(); + + vPropMap.create(rdata, aggregated=true); + ePropMap.create(qname, aggregated=true); + } + td.finished(); +} +vPropMap.flushGlobal(); +ePropMap.flushGlobal(); +// t.stop(); +writeln("Constructed Property Map with ", vPropMap.numPropertiesGlobal(), + " vertex properties and ", ePropMap.numPropertiesGlobal(), + " edge properties in ", t.elapsed(), "s"); +t.clear(); + +writeln("Vertex Property Map"); +printPropertyDistribution(vPropMap); +writeln("Edge Property Map"); +printPropertyDistribution(ePropMap); + +writeln("Constructing HyperGraph..."); +t.start(); +var hypergraph = new AdjListHyperGraph(vPropMap, ePropMap, new unmanaged Cyclic(startIdx=0)); +t.stop(); +writeln("Constructed HyperGraph in ", t.elapsed(), "s"); +t.clear(); +writeln("Populating HyperGraph..."); + +t.start(); +// Spread out the work across multiple locales. +_currLoc.write(0); +forall fileName in fileNames { + td.started(1); + wq.addWork(fileName, _currLoc.fetchAdd(1) % numLocales); +} +wq.flush(); + +// Aggregate fetches to properties into another work queue; when we flush +// each of the property maps, their individual PropertyHandle will be finished. +// Also send the 'String' so that it can be reclaimed. +var handleWQ = new WorkQueue((unmanaged PropertyHandle?, unmanaged PropertyHandle?), 64 * 1024); +var handleTD = new TerminationDetector(); +forall fileName in doWorkLoop(wq, td) { + for line in getLines(fileName) { + var attrs = line.split(","); + var qname = attrs[1].strip(); + var rdata = attrs[2].strip(); + handleTD.started(1); + handleWQ.addWork((vPropMap.getPropertyAsync(rdata), ePropMap.getPropertyAsync(qname))); + } + td.finished(); +} +vPropMap.flushGlobal(); +ePropMap.flushGlobal(); + +// Finally aggregate inclusions for the hypergraph. +hypergraph.startAggregation(); +forall (vHandle, eHandle) in doWorkLoop(handleWQ, handleTD) { + hypergraph.addInclusion(vHandle.get(), eHandle.get()); + delete vHandle; + delete eHandle; + handleTD.finished(1); +} +hypergraph.stopAggregation(); +hypergraph.flushBuffers(); + +t.stop(); +writeln("Populated HyperGraph in ", t.elapsed(), "s"); +t.clear(); +writeln("Number of Inclusions: ", hypergraph.getInclusions()); +writeln("Deleting Duplicate edges: ", hypergraph.removeDuplicates()); +writeln("Number of Inclusions: ", hypergraph.getInclusions()); + + +t.start(); +var _vtxSubsetSet = new set(string); + +iter processVtxSubset(vtxSubset) { + for i in 1..#vtxSubset.size { + var tmp : [1..#vtxSubset.size - 1] int; + tmp[1..i - 1] = vtxSubset[1..i - 1]; + tmp[i..] = vtxSubset[i + 1..]; + yield tmp; + } +} + +/* Generate the permutation */ +proc doProcessVertices (verticesSet) { + /* writeln(stringify(verticesSet)); */ + if (verticesSet.size == 0) { + return; + } else if (verticesSet.size == 1) { + var verticesStr = stringify(verticesSet); + if !_vtxSubsetSet.contains(verticesStr) { // TODO: redundant? + _vtxSubsetSet.add(verticesStr); + } + } else { + var verticesStr = stringify(verticesSet); + if !_vtxSubsetSet.contains(verticesStr) { + _vtxSubsetSet.add(verticesStr); + for _vtxSubset in processVtxSubset(verticesSet) { + doProcessVertices(_vtxSubset); + } + } + } +} + +/*For each of the hyperedge, do the permutation of all the vertices.*/ +for e in hypergraph.getEdges() { + var vertices = hypergraph.incidence(e); // ABCD + ref tmp = vertices[1..#vertices.size]; + var verticesInEdge : [1..#vertices.size] int; + verticesInEdge[1..#vertices.size] = tmp.id; // ABCD vertices.low + doProcessVertices(verticesInEdge); +} + +/* writeln("Printing all generated combination"); */ +/* /\*Verify the set by printing*\/ */ +/* var setContent = _vtxSubsetSet.toArray(); */ +/* for c in setContent do */ +/* writeln(c); */ + +/* writeln("-----"); */ +/* writeln("Printing bins"); */ +/*bin k-cells, with key as the length of the list and value is a list with all the k-cells*/ +var kCellMap = new map(int, list(string, true)); +for vtxSet in _vtxSubsetSet { + var sz = + reduce [ch in vtxSet] ch == ' '; + /* writeln(sz : string + " " + vtxSet : string); */ + kCellMap[sz].append(vtxSet); +} + +class kCellsArray{ + var numKCells : int; + var D = {1..numKCells}; + var A : [D] string; + proc init(_N: int) { + numKCells = _N; + } +} + +var numBins = kCellMap.size - 1; +var kCellsArrayMap : [0..numBins] owned kCellsArray?; +var kCellKeys = kCellMap.keysToArray(); +sort(kCellKeys); + +// Empty record serves as comparator +record Comparator { } +// compare method defines how 2 elements are compared +proc Comparator.compare(a :string, b :string) : int { + var retVal : int = 0; + if (b == "" || a == "") { + /* writeln("a: " + a : string + " b: " + b : string); */ + retVal = -1; + return retVal; + } + var aa = a.split(" ") : int; + var bb = b.split(" ") : int; + var done : bool = false; + var ndone : bool = false; + for i in 1..#aa.size { + for j in i..#bb.size { + if (aa[i] == bb[j]) { + break; + } + if (aa[i] < bb[j]) { + retVal = -1; done = true; break; + } + if (aa[i] > bb[j]) { + retVal = 1; done = true; break; + } + } + if (done) {break;} + } + return retVal; +} + +var absComparator: Comparator; + +/* /\* writeln("%%%%%%%%%%%%%"); *\/ */ +/* // Leader-follower iterator */ +/* // Create the new KcellMaps for convenience of sorting */ +for (_kCellsArray, kCellKey) in zip(kCellsArrayMap, kCellKeys) { + /* writeln("kCellkey:" + kCellKey : string); */ + /* writeln("listsize: " + kCellMap[kCellKey].size : string); */ + _kCellsArray = new owned kCellsArray(kCellMap[kCellKey].size); + _kCellsArray.A = kCellMap[kCellKey].toArray(); + sort(_kCellsArray.A, comparator=absComparator); +} +/* writeln("%%%%%%%%%%%%%"); */ + +/* writeln("Printing after sorting"); */ +/* writeln("^^^^^^^^^^^^^^^^^^^^^^^"); */ +/* for _kCellsArray in kCellsArrayMap { */ +/* writeln(_kCellsArray.A : string); */ +/* } */ +/* writeln("^^^^^^^^^^^^^^^^^^^^^^^"); */ + +/*Start of the construction of boundary matrices.*/ +class Matrix { + var N : int; + var M : int; + var matrix : [1..N, 1..M] int; + proc init(_N: int, _M:int) { + N = _N; + M = _M; + } +} + +var K = kCellMap.size - 1; +var boundaryMaps : [1..K] owned Matrix?; +var i : int = 1; + +// Leader-follower iterator +// Create the boundary Maps +for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { + /* writeln("dimensions: " + kCellsArrayMap[dimension_k_1].numKCells: string + " " + kCellsArrayMap[dimension_k].numKCells : string); */ + boundaryMap = new owned Matrix(kCellsArrayMap[dimension_k_1].numKCells, kCellsArrayMap[dimension_k].numKCells); +} + +var vs = new set(string); + +iter processVtxSubset2(vtxSubset) { + for i in 1..#vtxSubset.size { + var tmp : [1..#vtxSubset.size - 1] int; + tmp[1..i - 1] = vtxSubset[1..i - 1]; + tmp[i..] = vtxSubset[i + 1..]; + yield tmp; + } +} + +/* Generate the permutation */ +proc doProcessVertices2 (verticesSet) { + if (verticesSet.size == 0) { + return; + } else if (verticesSet.size == 1) { + var verticesStr = stringify(verticesSet); + if !vs.contains(verticesStr) { + vs.add(verticesStr); + } + } else { + var verticesStr = stringify(verticesSet); + if !vs.contains(verticesStr) { + vs.add(verticesStr); + for _vtxSubset in processVtxSubset2(verticesSet) { + doProcessVertices2(_vtxSubset); + } + } + } +} + + +/* writeln("####"); */ +// Compute values for each entries in each of the boundary map +for (dimension_k_1, dimension_k) in zip(0..2, 1..3) { + var arrayOfKCells = kCellsArrayMap[dimension_k].A; // Arrays of strings, each string being 1 kcell + var arrayOfK_1Cells = kCellsArrayMap[dimension_k_1].A; + /* writeln("$$$$$$$$$$$"); */ + /* writeln(arrayOfKCells); */ + /* writeln(arrayOfK_1Cells); */ + /* writeln("$$$$$$$$$$$"); */ + var i : int = 0; + var j : int = 0; + for SkCell in arrayOfKCells { // iterate through all the k-cells + i = i + 1; + /* Generate permutation of the current k-Cell*/ + var kCell = SkCell.split(" ") : int; + /* writeln("#kcell: " + kCell :string); */ + /* writeln("Combinations generated ": string); */ + for sc in processVtxSubset(kCell) { + var st = stringify(sc); + j = 0; + for Sk_1Cell in arrayOfK_1Cells { + j = j + 1; + if (st == Sk_1Cell) { + // writeln(st :string + "matches"); + boundaryMaps[dimension_k].matrix[j, i] = 1; + break; + } + } + } + } + /* writeln("$$$$$$$$$$$"); */ +} + +proc printBoundaryMap(boundaryMap) { + var row : int = boundaryMap.matrix.domain.high(1); + var col : int = boundaryMap.matrix.domain.high(2); + for i in 1..row { + for j in 1..col { + write(boundaryMap.matrix[i, j] : string + " "); + } + writeln(); + } +} + +/* for (dimension_k_1, dimension_k) in zip(0..1, 1..2) { */ +/* writeln("Printing boundary map for: " : string + dimension_k_1 : string + " " :string + dimension_k : string); */ +/* printBoundaryMap(boundaryMaps[dimension_k]); */ +/* } */ + + +proc printmatrix(M) { + for i in {1..M.domain.high(1)} { + for j in {1..M.domain.high(2)} { + write(M(i,j):string + " "); + } + writeln(); + } +} + + +proc IdentityMatrix(n) { + var A : [1..n, 1..n] int; + [i in A.domain.dim(1)] A[i,i] = 1; + return A; +} + +use List; +class Matrix2D { + var N : int; + var M : int; + var _arr : [1..N, 1..M] int; + proc init (row : int, col : int) { + N = row; + M = col; + } +} + +proc _get_next_pivot(M, s1, in s2 : int = 0) { + var dims = M.domain.high; + var dimR = dims(1); + var dimC = dims(2); + if (s2 == 0) { + s2 = s1; + } + for c in s2..dimC { + for r in s1..dimR { + if (M(r,c) != 0) { + return (r,c); + } + } + } + return (-1,-1); // TODO: return +} + + +proc swap_rows(i, j, M) { + var N = M; + N[i, ..] <=> N[j, ..]; + return N; +} + +proc swap_columns(i, j, M) { + var N = M; + N[.., i] <=> N[.., j]; + return N; +} + +// Replaces row i (of M) with sum ri multiple of ith row and rj multiple of jth row +proc add_to_row(M, i, j, ri = 1, rj = 1, mod = 2) { + var N = M; + N[i, ..] = (ri * N[i, ..] + rj * N[j, ..]) % mod; + return N; +} + + +proc add_to_column(M, i, j, ci = 1, cj = 1, mod = 2) { + var N = M; + N[.., i] = (ci * N[.., i] + cj * N[..,j]) % mod; + return N; +} + +proc matmultmod2 (M, N, mod = 2) { + var nr = M.domain.high(1); + var nc = N.domain.high(2); + var m = M.domain.high(2); + var C : [1..nr, 1..nc] atomic int; + + forall i in 1..nr { + for j in 1..nc { + C[i,j].write((+ reduce M[i, 1..m] * N[1..m, j]) % 2) ; + } + } + return C.read(); +} + +proc matmultmod3 (M, N, mod = 2) { + var C : [M.domain.dim(1), N.domain.dim(2)] atomic int; + forall (i,j) in C.domain { + C[i,j].write((+ reduce M[i, M.domain.dim(2)] * N[M.domain.dim(2), j]) % 2); + } + return C.read(); +} + +proc matmultmod (M, N, mod =2) { + var C : [M.domain.dim(1), N.domain.dim(2)] int; + forall (i,j) in C.domain { + C[i,j] = (+ reduce (M[i, M.domain.dim(2)] * N[M.domain.dim(2), j])) % 2; + } + return C; +} + +type listType = list(unmanaged Matrix2D?, true); +proc matmulreduce(arr : listType, reverse = false, mod = 2) { + var PD: domain(2) = {1..arr(1)._arr.domain.high(1), 1..arr(1)._arr.domain.high(2)}; + var P : [PD] int; + if (reverse) { + PD = {1..arr(arr.size)._arr.domain.high(1), 1..arr(arr.size)._arr.domain.high(2)}; + P = arr(arr.size)._arr; + for i in 1..#arr.size - 1 by -1 { + var tempD : domain(2) = {1..P.domain.high(1), 1..arr(i)._arr.domain.high(2)}; + var temp : [tempD] int; + temp = matmultmod(P, arr(i)._arr); + PD = tempD; + P = temp; + } + } else { + P = arr(1)._arr; + for i in 2..arr.size { + var tempD : domain(2) = {1..P.domain.high(1), 1..arr(i)._arr.domain.high(2)}; + var temp : [tempD] int; + temp = matmultmod(P, arr(i)._arr); + PD = tempD; + P = temp; + } + } + return P; +} + +// rank calculation: +proc calculateRank(M) { + var rank = + reduce [i in M.domain.dim(2)] (max reduce M[.., i]); + return rank; +} + + +// printmatrix(b); + +proc smithNormalForm(b) { + var dims = b.domain.high; + var dimL = dims(1); + var dimR = dims(2); + var minDim = if dimL <= dimR then dimL else dimR; + + // writeln(dimL : string ); // dims give me the index set but I need the max value of the index set + // writeln(minDim); + + + var S = b; + var IL = IdentityMatrix(dimL); + var IR = IdentityMatrix(dimR); + + var Linv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation + var Rinv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation + + var Linit = new unmanaged Matrix2D(IL.domain.high(1), IL.domain.high(2)); + Linit._arr = IL; + Linv.append(Linit); + var Rinit = new unmanaged Matrix2D(IR.domain.high(1), IR.domain.high(2)); + Rinit._arr = IR; + Rinv.append(Rinit); + + var L = IL; + var R = IR; + + /* writeln("###############"); */ + /* writeln("L:"); */ + /* printmatrix(L); */ + /* writeln("###############"); */ + /* writeln("R:"); */ + /* printmatrix(R); */ + + // var rc = _get_next_pivot(b, 3); + // writeln(rc : string); + + + writeln("########"); + for s in 1..minDim { + /* writeln("Iteration: " + s : string); */ + var pivot = _get_next_pivot(S,s); + var rdx : int, cdx : int; + if (pivot(1) == -1 && pivot(2) == -1) { + break; + } + else { + (rdx, cdx) = pivot; + } + + // Swap rows and columns as needed so the 1 is in the s,s position + if (rdx > s) { + S = swap_rows(s, rdx, S); + L = swap_rows(s, rdx, L); + var tmp = swap_rows(s, rdx, IL); + var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + LM._arr = tmp; + Linv.append(LM); + } + if (cdx > s) { + S = swap_columns(s, cdx, S); + R = swap_columns(s, cdx, R); + var tmp = swap_columns(s, cdx, IR); + var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + RM._arr = tmp; + Rinv.append(RM); + } + + // add sth row to every nonzero row & sth column to every nonzero column + // zip(S[.., s], S.dim(1)) gives you (S[i,j], 1..N) + // row_indices = [idx for idx in range(dimL) if idx != s and S[idx][s] == 1] + // var RD: domain(2) = {1..dimL, 1..dimL}; + // var row_indices = [(x,(i,j)) in zip(S, 1..dimL)] if x == 1 && j != s then (i,j); + // var row_indices = [(s,idx) in zip(S, {1..dimL})] if s == 1 then idx; + + var row_indices = [idx in 1..dimL] if (idx != s && S(idx,s) == 1) then idx; + // compilerWarning(row_indices.type : string); + + for rdx in row_indices { + // writeln("rdx: " + rdx : string); + S = add_to_row(S, rdx, s); + L = add_to_row(L, rdx, s); + var tmp = add_to_row(IL, rdx, s); + var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + LM._arr = tmp; + Linv.append(LM); + } + + var column_indices = [jdx in 1..dimR] if (jdx != s && S(s,jdx) == 1) then jdx; + + for (jdx,cdx) in zip(1..,column_indices) {// TODO: check + // writeln("rdx: " + rdx : string); + S = add_to_column(S, cdx, s); + R = add_to_column(R, cdx, s); + var tmp = add_to_column(IR, cdx, s); + var RM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + RM._arr = tmp; + Rinv.append(RM); + } + } + + + var LinvF = matmulreduce(Linv); + var RinvF = matmulreduce(Rinv, true, 2); + return (L,R,S,LinvF,RinvF); +} + +var computedMatrices = smithNormalForm(boundaryMaps[1].matrix); +var computedMatrices2 = smithNormalForm(boundaryMaps[2].matrix); +var computedMatrices3 = smithNormalForm(boundaryMaps[3].matrix); +var L1 = computedMatrices(1); +var R1 = computedMatrices(2); +var S1 = computedMatrices(3); +var L1invF = computedMatrices(4); +var R1invF = computedMatrices(5); +var L2 = computedMatrices2(1); +var R2 = computedMatrices2(2); +var S2 = computedMatrices2(3); +var L2invF = computedMatrices2(4); +var R2invF = computedMatrices2(5); +var L3 = computedMatrices3(1); +var R3 = computedMatrices3(2); +var S3 = computedMatrices3(3); +var L3invF = computedMatrices3(4); +var R3invF = computedMatrices3(5); +writeln("###############"); +writeln("L1:"); +printmatrix(L1); +writeln("###############"); +writeln("R1:"); +printmatrix(R1); +writeln("###############"); +writeln("S1:"); +printmatrix(S1); +writeln("###############"); +writeln("L1inv:"); +printmatrix(L1invF); +writeln("###############"); +writeln("R1inv:"); +printmatrix(R1invF); +writeln("###############"); +writeln("L2inv:"); +printmatrix(L2invF); + +var rank1 = calculateRank(S1); +writeln("Rank of S1: " + rank1 : string); +var rank2 = calculateRank(S2); +writeln("Rank of S2: " + rank2 : string); +var nullity1 = S1.domain.high(2) - rank1; +var betti1 = S1.domain.high(2) - rank1 - rank2; +writeln("Betti 1: " + betti1 : string); + +/* var rank3 = calculateRank(S2); */ +/* writeln("Rank of S2: " + rank1 : string); */ +var rank3 = calculateRank(S3); +writeln("Rank of S3: " + rank3 : string); +// var betti2 = S2.domain.high(2) - rank2 - rank3; +// writeln("Betti 2: " + betti2 : string); + +var cokernel2_dim = S1.domain.high(2) - rank2; + +var nr1 = R1.domain.high(2) - rank1; +var ker1 : [1..R1.domain.high(1), 1..nr1] int = R1[..,rank1+1..]; +writeln("###############"); +writeln("ker1:"); +printmatrix(ker1); + +// im2 = L2inv[:,:rank2] +var im2 : [1..L2invF.domain.high(1), 1..rank2] int = L2invF[..,1..rank2]; +var nr2 = L2invF.domain.high(2) - rank2; +var cokernel2 : [1..L2invF.domain.high(1), 1..nr2] int = L2invF[..,rank2 + 1..]; + +writeln("###############"); +writeln("Cokernel:"); +printmatrix(cokernel2); + +writeln("###############"); +writeln("L2:"); +printmatrix(L2); + +var LKernel = new list(unmanaged Matrix2D?, true); + +var _L2 = new unmanaged Matrix2D(L2.domain.high(1), L2.domain.high(2)); +_L2._arr = L2; +LKernel.append(_L2); + +var _ker1 = new unmanaged Matrix2D(ker1.domain.high(1), ker1.domain.high(2)); +_ker1._arr = ker1; +LKernel.append(_ker1); + +writeln("L2 dimension: " + L2.domain.high(1) :string + "X" + L2.domain.high(2):string); +writeln("ker1 dimension: " + ker1.domain.high(1) :string + "X" + ker1.domain.high(2):string); + +var result = matmulreduce(LKernel); +var slc = result.domain.high(1) - rank2; +var proj : [1..slc, 1..result.domain.high(2)] int = result[rank2 + 1..,..]; +writeln("###############"); +writeln("Projection1:"); +printmatrix(proj); + +// proj = matmulreduce([L2,ker1])[rank2:,:] +// proj = matmulreduce([L2inv[:,rank2:],proj]).transpose() + +var L2invKernel = new list(unmanaged Matrix2D?, true); + +// var nr2 = L2invF.domain.high(2) - rank2; +var _L2inv = new unmanaged Matrix2D(L2invF.domain.high(1), nr2); +_L2inv._arr = L2invF[..,rank2 + 1..]; +L2invKernel.append(_L2inv); + +var _proj = new unmanaged Matrix2D(proj.domain.high(1), proj.domain.high(2)); +_proj._arr = proj; +L2invKernel.append(_proj); + +var proj2 = matmulreduce(L2invKernel); + +writeln("###############"); +writeln("Projection2:"); +printmatrix(proj2); + +t.stop(); +writeln("Homology computed in ", t.elapsed(), "s"); + + +proc reducedRowEchelonForm(b) { + var dims = b.domain.high; + var dimL = dims(1); + var dimR = dims(2); + var minDim = if dimL <= dimR then dimL else dimR; + + // writeln(dimL : string ); // dims give me the index set but I need the max value of the index set + // writeln(minDim); + + + var S = b; + var IL = IdentityMatrix(dimL); + + var Linv = new list(unmanaged Matrix2D?, true); // listOfMatrixTransformation + + var Linit = new unmanaged Matrix2D(IL.domain.high(1), IL.domain.high(2)); + Linit._arr = IL; + Linv.append(Linit); + + var L = IL; + + /* writeln("###############"); */ + /* writeln("L:"); */ + /* printmatrix(L); */ + /* writeln("###############"); */ + /* writeln("R:"); */ + /* printmatrix(R); */ + + // var rc = _get_next_pivot(b, 3); + // writeln(rc : string); + + var s2 : int = 1; + writeln("########"); + for s1 in 1..dimL { + writeln("Iteration: " + s1 : string); + var rdx : int, cdx : int; + for s2 in s2..dimR { + var pivot = _get_next_pivot(S,s1, s2); + if (pivot(1) != -1 && pivot(2) != -1) { + (rdx, cdx) = pivot; + s2 = cdx; + break; + } + } + // Swap rows + if (rdx > s1) { + S = swap_rows(s1, rdx, S); + L = swap_rows(s1, rdx, L); + var tmp = swap_rows(s1, rdx, IL); + var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + LM._arr = tmp; + Linv.append(LM); + } + + var row_indices = [idx in 1..dimL] if (idx != s1 && S(idx,cdx) == 1) then idx; + // compilerWarning(row_indices.type : string); + + for idx in row_indices { + // writeln("rdx: " + rdx : string); + S = add_to_row(S, idx, s1); + L = add_to_row(L, idx, s1); + var tmp = add_to_row(IL, idx, s1); + var LM = new unmanaged Matrix2D(tmp.domain.high(1), tmp.domain.high(2)); + LM._arr = tmp; + Linv.append(LM); + } + } + + var LinvF = matmulreduce(Linv); + return (L,S,LinvF); +} \ No newline at end of file diff --git a/example/homology_experimental/homology_dns_data/dns1.csv b/example/homology_experimental/homology_dns_data/dns1.csv new file mode 100644 index 0000000..b2ac29f --- /dev/null +++ b/example/homology_experimental/homology_dns_data/dns1.csv @@ -0,0 +1,37 @@ +bf7b8-q.com,34.214.56.13 +bf7b8-q.com,34.217.235.253 +bf7b8-q.com,52.27.189.82 +bf7b8-q.com,54.214.194.90 +pqim5gw.com,34.217.235.253 +pqim5gw.com,54.189.204.76 +pqim5gw.com,54.189.226.126 +pqim5gw.com,54.214.194.90 +b-2h82v.com,50.112.85.115 +b-2h82v.com,52.13.150.199 +b-2h82v.com,54.190.214.102 +vlb-10in.com,34.209.197.117 +vlb-10in.com,34.211.140.76 +vlb-10in.com,54.190.214.102 +u7ce7iel.com,54.189.226.126 +u7ce7iel.com,54.214.194.90 +u7ce7iel.com,54.70.149.65 +16c1krs.com,34.217.235.253 +16c1krs.com,50.112.85.115 +16c1krs.com,54.201.32.214 +16c1krs.com,54.70.149.65 +i6g71e1.com,34.217.235.253 +i6g71e1.com,50.112.85.115 +i6g71e1.com,52.13.150.199 +i6g71e1.com,54.214.194.90 +e-ekc02d.com,50.112.85.115 +e-ekc02d.com,52.13.150.199 +e-ekc02d.com,54.214.194.90 +e-ekc02d.com,54.70.149.65 +7jlh-0iu.com,34.209.197.117 +7jlh-0iu.com,34.211.140.76 +7jlh-0iu.com,34.217.235.253 +7jlh-0iu.com,54.214.194.90 +4m0i-mh6.com,34.217.235.253 +4m0i-mh6.com,50.112.85.115 +4m0i-mh6.com,54.189.226.126 +4m0i-mh6.com,54.214.194.90 diff --git a/example/homology_experimental/homology_dns_data/dns1.csv~ b/example/homology_experimental/homology_dns_data/dns1.csv~ new file mode 100644 index 0000000..4444cd8 --- /dev/null +++ b/example/homology_experimental/homology_dns_data/dns1.csv~ @@ -0,0 +1,38 @@ +10,13 +bf7b8-q.com,34.214.56.13 +bf7b8-q.com,34.217.235.253 +bf7b8-q.com,52.27.189.82 +bf7b8-q.com,54.214.194.90 +pqim5gw.com,34.217.235.253 +pqim5gw.com,54.189.204.76 +pqim5gw.com,54.189.226.126 +pqim5gw.com,54.214.194.90 +b-2h82v.com,50.112.85.115 +b-2h82v.com,52.13.150.199 +b-2h82v.com,54.190.214.102 +vlb-10in.com,34.209.197.117 +vlb-10in.com,34.211.140.76 +vlb-10in.com,54.190.214.102 +u7ce7iel.com,54.189.226.126 +u7ce7iel.com,54.214.194.90 +u7ce7iel.com,54.70.149.65 +16c1krs.com,34.217.235.253 +16c1krs.com,50.112.85.115 +16c1krs.com,54.201.32.214 +16c1krs.com,54.70.149.65 +i6g71e1.com,34.217.235.253 +i6g71e1.com,50.112.85.115 +i6g71e1.com,52.13.150.199 +i6g71e1.com,54.214.194.90 +e-ekc02d.com,50.112.85.115 +e-ekc02d.com,52.13.150.199 +e-ekc02d.com,54.214.194.90 +e-ekc02d.com,54.70.149.65 +7jlh-0iu.com,34.209.197.117 +7jlh-0iu.com,34.211.140.76 +7jlh-0iu.com,34.217.235.253 +7jlh-0iu.com,54.214.194.90 +4m0i-mh6.com,34.217.235.253 +4m0i-mh6.com,50.112.85.115 +4m0i-mh6.com,54.189.226.126 +4m0i-mh6.com,54.214.194.90 diff --git a/example/snf.chpl b/example/homology_experimental/snf.chpl similarity index 99% rename from example/snf.chpl rename to example/homology_experimental/snf.chpl index 702a59a..81dab98 100644 --- a/example/snf.chpl +++ b/example/homology_experimental/snf.chpl @@ -1,3 +1,5 @@ +/*Implementation of Smith Normal Form and test with small example.*/ + /*Test matrix 1*/ var b: [1..7, 1..11] int; b(1,1) = 1; From 396c42c8805665cd321a0a94f69ae3b1d82158df Mon Sep 17 00:00:00 2001 From: Jesun Sahariar Firoz Date: Thu, 13 Feb 2020 18:31:38 -0800 Subject: [PATCH 23/23] Removing some print statements. --- .../homology_experimental/homology_dns.chpl | 60 ------------------- 1 file changed, 60 deletions(-) diff --git a/example/homology_experimental/homology_dns.chpl b/example/homology_experimental/homology_dns.chpl index 00fadd5..d865439 100644 --- a/example/homology_experimental/homology_dns.chpl +++ b/example/homology_experimental/homology_dns.chpl @@ -188,19 +188,10 @@ for e in hypergraph.getEdges() { doProcessVertices(verticesInEdge); } -/* writeln("Printing all generated combination"); */ -/* /\*Verify the set by printing*\/ */ -/* var setContent = _vtxSubsetSet.toArray(); */ -/* for c in setContent do */ -/* writeln(c); */ - -/* writeln("-----"); */ -/* writeln("Printing bins"); */ /*bin k-cells, with key as the length of the list and value is a list with all the k-cells*/ var kCellMap = new map(int, list(string, true)); for vtxSet in _vtxSubsetSet { var sz = + reduce [ch in vtxSet] ch == ' '; - /* writeln(sz : string + " " + vtxSet : string); */ kCellMap[sz].append(vtxSet); } @@ -224,7 +215,6 @@ record Comparator { } proc Comparator.compare(a :string, b :string) : int { var retVal : int = 0; if (b == "" || a == "") { - /* writeln("a: " + a : string + " b: " + b : string); */ retVal = -1; return retVal; } @@ -251,24 +241,13 @@ proc Comparator.compare(a :string, b :string) : int { var absComparator: Comparator; -/* /\* writeln("%%%%%%%%%%%%%"); *\/ */ /* // Leader-follower iterator */ /* // Create the new KcellMaps for convenience of sorting */ for (_kCellsArray, kCellKey) in zip(kCellsArrayMap, kCellKeys) { - /* writeln("kCellkey:" + kCellKey : string); */ - /* writeln("listsize: " + kCellMap[kCellKey].size : string); */ _kCellsArray = new owned kCellsArray(kCellMap[kCellKey].size); _kCellsArray.A = kCellMap[kCellKey].toArray(); sort(_kCellsArray.A, comparator=absComparator); } -/* writeln("%%%%%%%%%%%%%"); */ - -/* writeln("Printing after sorting"); */ -/* writeln("^^^^^^^^^^^^^^^^^^^^^^^"); */ -/* for _kCellsArray in kCellsArrayMap { */ -/* writeln(_kCellsArray.A : string); */ -/* } */ -/* writeln("^^^^^^^^^^^^^^^^^^^^^^^"); */ /*Start of the construction of boundary matrices.*/ class Matrix { @@ -288,7 +267,6 @@ var i : int = 1; // Leader-follower iterator // Create the boundary Maps for (boundaryMap, dimension_k_1, dimension_k) in zip(boundaryMaps, 0.., 1..) { - /* writeln("dimensions: " + kCellsArrayMap[dimension_k_1].numKCells: string + " " + kCellsArrayMap[dimension_k].numKCells : string); */ boundaryMap = new owned Matrix(kCellsArrayMap[dimension_k_1].numKCells, kCellsArrayMap[dimension_k].numKCells); } @@ -324,37 +302,28 @@ proc doProcessVertices2 (verticesSet) { } -/* writeln("####"); */ // Compute values for each entries in each of the boundary map for (dimension_k_1, dimension_k) in zip(0..2, 1..3) { var arrayOfKCells = kCellsArrayMap[dimension_k].A; // Arrays of strings, each string being 1 kcell var arrayOfK_1Cells = kCellsArrayMap[dimension_k_1].A; - /* writeln("$$$$$$$$$$$"); */ - /* writeln(arrayOfKCells); */ - /* writeln(arrayOfK_1Cells); */ - /* writeln("$$$$$$$$$$$"); */ var i : int = 0; var j : int = 0; for SkCell in arrayOfKCells { // iterate through all the k-cells i = i + 1; /* Generate permutation of the current k-Cell*/ var kCell = SkCell.split(" ") : int; - /* writeln("#kcell: " + kCell :string); */ - /* writeln("Combinations generated ": string); */ for sc in processVtxSubset(kCell) { var st = stringify(sc); j = 0; for Sk_1Cell in arrayOfK_1Cells { j = j + 1; if (st == Sk_1Cell) { - // writeln(st :string + "matches"); boundaryMaps[dimension_k].matrix[j, i] = 1; break; } } } } - /* writeln("$$$$$$$$$$$"); */ } proc printBoundaryMap(boundaryMap) { @@ -368,12 +337,6 @@ proc printBoundaryMap(boundaryMap) { } } -/* for (dimension_k_1, dimension_k) in zip(0..1, 1..2) { */ -/* writeln("Printing boundary map for: " : string + dimension_k_1 : string + " " :string + dimension_k : string); */ -/* printBoundaryMap(boundaryMaps[dimension_k]); */ -/* } */ - - proc printmatrix(M) { for i in {1..M.domain.high(1)} { for j in {1..M.domain.high(2)} { @@ -538,20 +501,7 @@ proc smithNormalForm(b) { var L = IL; var R = IR; - /* writeln("###############"); */ - /* writeln("L:"); */ - /* printmatrix(L); */ - /* writeln("###############"); */ - /* writeln("R:"); */ - /* printmatrix(R); */ - - // var rc = _get_next_pivot(b, 3); - // writeln(rc : string); - - - writeln("########"); for s in 1..minDim { - /* writeln("Iteration: " + s : string); */ var pivot = _get_next_pivot(S,s); var rdx : int, cdx : int; if (pivot(1) == -1 && pivot(2) == -1) { @@ -579,18 +529,9 @@ proc smithNormalForm(b) { Rinv.append(RM); } - // add sth row to every nonzero row & sth column to every nonzero column - // zip(S[.., s], S.dim(1)) gives you (S[i,j], 1..N) - // row_indices = [idx for idx in range(dimL) if idx != s and S[idx][s] == 1] - // var RD: domain(2) = {1..dimL, 1..dimL}; - // var row_indices = [(x,(i,j)) in zip(S, 1..dimL)] if x == 1 && j != s then (i,j); - // var row_indices = [(s,idx) in zip(S, {1..dimL})] if s == 1 then idx; - var row_indices = [idx in 1..dimL] if (idx != s && S(idx,s) == 1) then idx; - // compilerWarning(row_indices.type : string); for rdx in row_indices { - // writeln("rdx: " + rdx : string); S = add_to_row(S, rdx, s); L = add_to_row(L, rdx, s); var tmp = add_to_row(IL, rdx, s); @@ -602,7 +543,6 @@ proc smithNormalForm(b) { var column_indices = [jdx in 1..dimR] if (jdx != s && S(s,jdx) == 1) then jdx; for (jdx,cdx) in zip(1..,column_indices) {// TODO: check - // writeln("rdx: " + rdx : string); S = add_to_column(S, cdx, s); R = add_to_column(R, cdx, s); var tmp = add_to_column(IR, cdx, s);