Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
5ad24da
Merge pull request #18 in ~PRAG717/hnx from develop to master
brendapraggastis May 2, 2019
3238f70
updated gitignore
brendapraggastis Sep 10, 2019
326f82b
updated gitignore
brendapraggastis Sep 16, 2019
dda38fa
updated gitignore
brendapraggastis Sep 16, 2019
25455fe
adding to gitignore
brendapraggastis Oct 9, 2019
1b2c042
Bug fix for hyp-110: prevents edge labels from disappearing
dlarendt Jan 25, 2020
8f90e48
Merge pull request #18 from pnnl/hotfix/hyp-110
brendapraggastis Jan 27, 2020
4625e06
Merge branch 'master' of https://github.com/pnnl/HyperNetX
brendapraggastis Jan 27, 2020
819eb15
updating version after hotfix/hyp-110/43
brendapraggastis Jan 27, 2020
92cea6c
Merge pull request #19 from pnnl/versionupdate
brendapraggastis Jan 28, 2020
aba9788
updating docs for v.0.2.6
brendapraggastis Jan 28, 2020
d2b6fda
Merge pull request #20 from pnnl/docs
brendapraggastis Jan 28, 2020
e28d059
removing build lib hypernetx copy
brendapraggastis Jan 28, 2020
9b7a06f
updating gitignore
brendapraggastis Jan 28, 2020
b821330
updating docs
brendapraggastis Jan 28, 2020
9c8d7bc
removing untested code
brendapraggastis Jan 28, 2020
57910e4
updated nx.connected_component calls to be consistent with newer vers…
brendapraggastis Jan 28, 2020
ab8c192
updating docs
brendapraggastis Jan 28, 2020
04cb370
Merge pull request #23 from pnnl/hotfix/hyp-109
brendapraggastis Jan 28, 2020
1b3cbdc
moved all constructors into hypergraph class to mimic pandas
brendapraggastis Feb 17, 2020
d4ca4ee
updated tests for hypergraph class including tests for constructors
brendapraggastis Feb 17, 2020
da85a7f
added code to compute homology
brendapraggastis Feb 17, 2020
bf75d49
added a tutorial for homology
brendapraggastis Feb 17, 2020
323f4dc
updated gitignore
brendapraggastis Feb 17, 2020
1a84f86
updated version number
brendapraggastis Feb 17, 2020
7e6d938
udated develop from new master
brendapraggastis Feb 17, 2020
a02265f
updated to version 0.3.0
brendapraggastis Feb 17, 2020
020a43a
Merge branch 'master' into develop
brendapraggastis Feb 17, 2020
07f94d3
fixed typo on Emilie's name
brendapraggastis Feb 18, 2020
2d75372
Merge pull request #21 from develop to master
brendapraggastis Feb 18, 2020
83d9552
updated documentation
brendapraggastis Feb 18, 2020
4631586
Merge branch 'master' into develop
brendapraggastis Feb 18, 2020
f0ffeac
Merge branch 'develop'
brendapraggastis Feb 18, 2020
26d7033
Merge branch 'master' of https://stash.pnnl.gov/scm/~prag717/hnx
brendapraggastis Feb 18, 2020
ee0884c
Merge pull request #25 from pnnl/release3
brendapraggastis Feb 18, 2020
b909ba5
Merge branch 'develop'
brendapraggastis Feb 18, 2020
214fef6
updating docs
brendapraggastis Feb 19, 2020
63e7ca5
removed build docs
brendapraggastis Feb 19, 2020
1c24d4f
updated docs
brendapraggastis Feb 19, 2020
7066ea4
Merge branch 'develop'
brendapraggastis Feb 19, 2020
01336a2
rebuilding repo for V 0.3.0
brendapraggastis Feb 19, 2020
c444c48
adding documentation back
brendapraggastis Feb 19, 2020
f24e2d3
updating docs
brendapraggastis Feb 19, 2020
694ae0d
Merge pull request #27 from pnnl/develop
brendapraggastis Feb 19, 2020
dfbd883
fixed typo in tutorial
brendapraggastis Feb 19, 2020
7d48cd2
Merge pull request #28 from pnnl/develop
brendapraggastis Feb 19, 2020
46cef57
improved performance of hom mod2 thanks to Andrew
brendapraggastis Feb 20, 2020
8d5cc2f
removed timings
brendapraggastis Feb 20, 2020
6b6805e
removed unnecessary import
brendapraggastis Feb 20, 2020
68068ed
removed calls to datetime
brendapraggastis Feb 20, 2020
c107a64
updated version for hom optimization
brendapraggastis Feb 20, 2020
9308fc6
Merge pull request #29 from pnnl/develop
brendapraggastis Feb 20, 2020
8af6ae2
removed bug in tutorial
brendapraggastis Feb 20, 2020
a6cabdd
updating documentation and version number
brendapraggastis Feb 20, 2020
66a2e53
Merge branch 'master' of https://github.com/pnnl/HyperNetX
brendapraggastis Feb 20, 2020
2bedaa8
gitignore update
brendapraggastis Feb 20, 2020
3e1d6b6
fixed error in snf documentation
brendapraggastis Feb 20, 2020
f4b1644
updated docs
brendapraggastis Feb 20, 2020
92dafbd
updated docs
brendapraggastis Feb 20, 2020
fe14a20
updating setup file - it didnot have algorithms
brendapraggastis Feb 20, 2020
44a4f29
Merge pull request #30 from pnnl/develop
brendapraggastis Feb 20, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import os
import shlex

__version__ = "0.3.0"
__version__ = "0.3.1"


# If extensions (or modules to document with autodoc) are in another directory,
Expand Down
57 changes: 22 additions & 35 deletions hypernetx/algorithms/homology_mod2.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def kchainbasis(h,k):
- Hypergraph node uids must be sortable.

"""

import itertools as it
kchains = set()
for e in h.edges():
Expand All @@ -70,6 +71,7 @@ def kchainbasis(h,k):
return sorted(list(kchains))

def interpret(Ck,arr):

"""
Returns the data as represented in Ck associated with the arr

Expand All @@ -86,6 +88,7 @@ def interpret(Ck,arr):
list of k-cells referenced by data in Ck

"""

output = list()
for vec in arr:
if len(Ck) != len(vec):
Expand Down Expand Up @@ -301,6 +304,7 @@ def matmulreduce(arr,reverse=False,mod=2):
P : np.array
Product of matrices in the list
"""

if reverse:
items = range(len(arr)-1,-1,-1)
else:
Expand Down Expand Up @@ -333,6 +337,7 @@ def matsumreduce(arr,mod=2):

## Convenience methods for computing Smith Normal Form
## All of these operations have themselves as inverses

def _sr(i,j,M,L):
return swap_rows(i,j,M,L)

Expand Down Expand Up @@ -409,6 +414,7 @@ def smith_normal_form_mod2(M,track=False):
where $L = L[s]L[s-1]...L[1]L[0]$ and $R = R[0]R[1]...R[t]$.

"""

S = copy.copy(M)
dimL,dimR = M.shape
mod = 2
Expand All @@ -420,15 +426,15 @@ def smith_normal_form_mod2(M,track=False):
L = np.eye(dimL,dtype=int)
R = np.eye(dimR,dtype=int)

Linv = [IL] ## keep track of transformations to compute inverses at the end
Rinv = [IR]
Linv = np.eye(dimL,dtype=int)

if track:
print(L,'L\n')
print(M,'M\n')
print(R,'R\n')

for s in range(min(dimL,dimR)):
print('.'),
if track:
print(f'\ns={s}\n')
## Find index pair (rdx,cdx) with value 1 in submatrix M[s:,s:]
Expand All @@ -442,42 +448,27 @@ def smith_normal_form_mod2(M,track=False):
## Swap rows and columns as needed so that 1 is in the s,s position
if rdx > s:
S,L = _sr(s,rdx,S,L)
# This is equivalent to
# S = swap_rows(s,rdx,S)[0]
# L = swap_rows(s,rdx,L)[0]
Linv.append(swap_rows(s,rdx,IL)[0]) ## keep track of transformations on the left to reverse them for the inverse
Linv = swap_columns(s,rdx,Linv)[0]
if track:
print(L,f'L\n',S,'S\n',)
assert(np.all(S == matmulreduce([L,M,R],mod=mod)))
if cdx > s:
S,R= _sc(s,cdx,S,R)
Rinv.append(swap_columns(s,cdx,IR)[0])
if track:
print(S,'S\n',R,f'R\n')
assert(np.all(S == matmulreduce([L,M,R],mod=mod)))

# add sth row to every row with 1 in sth column & sth column to every column with 1 in sth row
row_indices = [idx for idx in range(dimL) if idx != s and S[idx][s] == 1]
row_indices = [idx for idx in range(s+1,dimL) if S[idx][s] == 1]
for rdx in row_indices:
S,L = _ar(rdx,s,S,L,mod=mod)
temp = add_to_row(IL,rdx,s,mod=mod)
Linv.append(temp)
Linv = add_to_column(Linv,s,rdx,mod=mod)
if track:
print(L,f'L\n',S,'S\n',)
assert(np.all(S == matmulreduce([L,M,R],mod=mod)))
column_indices = [jdx for jdx in range(dimR) if jdx != s and S[s][jdx] == 1]
column_indices = [jdx for jdx in range(s+1,dimR) if S[s][jdx] == 1]
for jdx,cdx in enumerate(column_indices):
S,R = _ac(cdx,s,S,R)
temp = add_to_column(IR,cdx,s,mod=mod)
Rinv.append(temp)
if track:
print(R,f'R\n',S,'S\n',)
assert(np.all(S == matmulreduce([L,M,R],mod=mod)))
Linv = matmulreduce(Linv,mod=mod)
Rinv = matmulreduce(Rinv,reverse=True,mod=mod)
assert(np.all(IL == matmulreduce([L,Linv],mod=mod)))
assert(np.all(IR == matmulreduce([R,Rinv],mod=mod)))
return L,R,S,Linv,Rinv
return L,R,S,Linv


def reduced_row_echelon_form_mod2(M,track=False,mod=2):
Expand Down Expand Up @@ -511,14 +502,15 @@ def reduced_row_echelon_form_mod2(M,track=False,mod=2):
verify the product:
L[s]L[s-1]...L[0] M = S .
"""

S = copy.copy(M)
dimL,dimR = M.shape
mod = 2

## method with numpy
IL = np.eye(dimL,dtype=int)

Linv = [np.eye(dimL,dtype=int)]
Linv = np.eye(dimL,dtype=int)
L = np.eye(dimL,dtype=int)

if track:
Expand All @@ -540,22 +532,17 @@ def reduced_row_echelon_form_mod2(M,track=False,mod=2):
continue
if rdx > s1:
S,L = _sr(s1,rdx,S,L)
Linv.append(swap_rows(s1,rdx,IL)[0]) ## keep track of transformations on the left to reverse them for the inverse
Linv = swap_columns(rdx,s1,Linv)[0]
if track:
print(L,f'L\n',S,'S\n',)
assert(np.all(S == matmulreduce([L,M],mod=mod)))

# add sth row to every nonzero row
row_indices = [idx for idx in range(dimL) if idx != s1 and S[idx][cdx] == 1]
for idx in row_indices:
S,L = _ar(idx,s1,S,L,mod=mod)
temp = add_to_row(IL,idx,s1,mod=mod)
Linv.append(temp)
Linv = add_to_column(Linv,s1,idx,mod=mod)
if track:
print(L,f'L\n',S,'S\n',)
assert(np.all(S == matmulreduce([L,M],mod=mod)))
Linv = matmulreduce(Linv,mod=mod)
assert(np.all(IL == matmulreduce([L,Linv],mod=mod)))

return L,S,Linv

## Private
Expand Down Expand Up @@ -674,8 +661,8 @@ def homology_basis(bd,k,C=None,shortest=False):
k-chains
if shortest then returns a dictionary of shortest cycles for each coset.
"""
L1,R1,S1,L1inv,R1inv = smith_normal_form_mod2(bd[k])
L2,R2,S2,L2inv,R2inv = smith_normal_form_mod2(bd[k+1])
L1,R1,S1,L1inv = smith_normal_form_mod2(bd[k])
L2,R2,S2,L2inv = smith_normal_form_mod2(bd[k+1])

rank1 = np.sum(S1); print(f"rank{k} = {rank1}")
rank2 = np.sum(S2); print(f"rank{k+1} = {rank2}")
Expand All @@ -686,9 +673,9 @@ def homology_basis(bd,k,C=None,shortest=False):
ker1 = R1[:,rank1:]
im2 = L2inv[:,:rank2]
cokernel2 = L2inv[:,rank2:]
cokproj2 = L2[rank2:,:]

proj = matmulreduce([L2,ker1])[rank2:,:]
proj = matmulreduce([L2inv[:,rank2:],proj]).transpose()
proj = matmulreduce([cokernel2,cokproj2,ker1]).transpose()
_,proj,_ = reduced_row_echelon_form_mod2(proj)
proj = np.array([row for row in proj if np.sum(row)>0])
print('hom basis reps\n',proj)
Expand Down
22 changes: 14 additions & 8 deletions hypernetx/algorithms/tests/test_homology_mod_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,28 @@ def test_bkMatrix(triloop):
def test_smith_normal_form_mod2(triloop):
Ck = {k:hnx.kchainbasis(triloop.hypergraph,k) for k in range(0,2)}
bd = bkMatrix(Ck[0],Ck[1])
P1,Q1,S1,P1inv,Q1inv = smith_normal_form_mod2(bd)
P1,Q1,S1,P1inv = smith_normal_form_mod2(bd)
assert np.array_equal(P1[0],np.array([1, 0, 0, 0]))
assert np.array_equal(Q1[:,2],np.array([0, 1, 1, 0, 0]))
assert(np.all(S1 == matmulreduce([P1,bd,Q1],mod=2)))
r = len(P1)
assert(np.all(np.eye(r) == modmult(P1,P1inv,mod=2)))
assert(np.all(S1 == matmulreduce([P1,bd,Q1],mod=2)))

def test_reduced_row_echelon_form_mod2():
m = np.array([[0,1,0,1,0,0,1,0,0,1],
[0,0,0,0,0,0,0,0,0,1],
[1,0,0,1,0,0,0,0,0,0]])
L,rm,R = reduced_row_echelon_form_mod2(m)
assert np.array_equal(rm,np.array([[1, 0, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1]]))
r = 3
L,S,Linv = reduced_row_echelon_form_mod2(m)
assert np.array_equal(S,np.array([[1, 0, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1]]))
assert np.array_equal(L,np.array([[0, 0, 1],
[1, 1, 0],
[0, 1, 0]]))

[1, 1, 0],
[0, 1, 0]]))
assert(np.all(S == modmult(L,m,mod=2)))
assert(np.all(np.eye(3) == modmult(L,Linv,mod=2)))

def test_homology_basis(triloop):
Ck = {k:hnx.kchainbasis(triloop.hypergraph,k) for k in range(0,3)}
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from setuptools import setup
import sys, os.path

__version__ = '0.3.0'
__version__ = '0.3.1'

if sys.version_info < (3,6):
sys.exit('HyperNetX requires Python 3.6 or later.')
Expand Down