def add(self, *args): """ Adds args to entityset's elements, checking to make sure no self references are made to element ids. Ensures Bipartite Condition of EntitySet. Parameters ---------- args : One or more entities or hashables Returns ------- self : EntitySet """ for item in args: if isinstance(item, Entity): if item.uid in self.children: raise HyperNetXError( f'Error: Fails the Bipartite Condition for EntitySet. {item.uid} references a child of an existing Entity in the EntitySet.' ) elif not self.uidset.isdisjoint(item.uidset): raise HyperNetXError( f'Error: Fails the bipartite condition for EntitySet.') else: Entity.add_element(self, item) else: if not item in self.children: Entity.add_element(self, item) else: raise HyperNetXError( f'Error: {item} references a child of an existing Entity in the EntitySet.' ) return self
def interpret(Ck, arr): """ Returns the data as represented in Ck associated with the arr Parameters ---------- Ck : list a list of k-cells being referenced by arr arr : np.array array of 0-1 vectors Returns ---- : list list of k-cells referenced by data in Ck """ output = list() for vec in arr: if len(Ck) != len(vec): raise HyperNetXError( 'elements of arr must have the same length as Ck') output.append([Ck[idx] for idx in range(len(vec)) if vec[idx] == 1]) return output
def logical_dot(ar1, ar2): """ Returns the boolean equivalent of the dot product mod 2 on two 1-d arrays of the same length. Parameters ---------- ar1 : numpy.ndarray 1-d array ar2 : numpy.ndarray 1-d array Returns ------- : bool boolean value associated with dot product mod 2 Raises ------ HyperNetXError If arrays are not of the same length an error will be raised. """ if len(ar1) != len(ar2): raise HyperNetXError( 'logical_dot requires two 1-d arrays of the same length') else: return 1 * np.logical_xor.reduce(np.logical_and(ar1, ar2))
def __setattr__(self, k, v): """Sets entity property. Parameters ---------- k : hashable, property key v : hashable, property value Will not set uid or change elements or memberships. Returns ------- None """ if k == 'uid': raise HyperNetXError('Cannot reassign uid to Entity once it' ' has been created. Create a clone instead.') elif k == 'elements': raise HyperNetXError('To add elements to Entity use self.add().') elif k == 'memberships': raise HyperNetXError('Can\'t choose your own memberships, ' 'they are like parents!') else: self.__dict__[k] = v
def logical_matmul(mat1, mat2): """ Returns the boolean equivalent of matrix multiplication mod 2 on two binary arrays stored as type boolean Parameters ---------- mat1 : np.ndarray 2-d array of boolean values mat2 : np.ndarray 2-d array of boolean values Returns ------- mat : np.ndarray boolean matrix equivalent to the mod 2 matrix multiplication of the matrices as matrices over Z/2Z Raises ------ HyperNetXError If inner dimensions are not equal an error will be raised. """ L1, R1 = mat1.shape L2, R2 = mat2.shape if R1 != L2: raise HyperNetXError( "logical_matmul called for matrices with inner dimensions mismatched" ) mat = np.zeros((L1, R2), dtype=int) mat2T = mat2.transpose() for i in range(L1): if np.any(mat1[i]): for j in range(R2): mat[i, j] = logical_dot(mat1[i], mat2T[j]) else: mat[i] = np.zeros((1, R2), dtype=int) return mat
def logical_matadd(mat1, mat2): """ Returns the boolean equivalent of matrix addition mod 2 on two binary arrays stored as type boolean Parameters ---------- mat1 : np.ndarray 2-d array of boolean values mat2 : np.ndarray 2-d array of boolean values Returns ------- mat : np.ndarray boolean matrix equivalent to the mod 2 matrix addition of the matrices as matrices over Z/2Z Raises ------ HyperNetXError If dimensions are not equal an error will be raised. """ S1 = mat1.shape S2 = mat2.shape mat = np.zeros(S1, dtype=int) if S1 != S2: raise HyperNetXError( "logical_matadd called for matrices with different dimensions") if len(S1) == 1: for idx in range(S1[0]): mat[idx] = 1 * np.logical_xor(mat1[idx], mat2[idx]) else: for idx in range(S1[0]): for jdx in range(S1[1]): mat[idx, jdx] = 1 * np.logical_xor(mat1[idx, jdx], mat2[idx, jdx]) return mat
def interpret(Ck, arr, labels=None): """ Returns the data as represented in Ck associated with the arr Parameters ---------- Ck : list a list of k-cells being referenced by arr arr : np.array array of 0-1 vectors labels : dict, optional dictionary of labels to associate to the nodes in the cells Returns ---- : list list of k-cells referenced by data in Ck """ def translate(cell, labels=labels): if not labels: return cell else: temp = list() for node in cell: temp.append(labels[node]) return tuple(temp) output = list() for vec in arr: if len(Ck) != len(vec): raise HyperNetXError( "elements of arr must have the same length as Ck") output.append( [translate(Ck[idx]) for idx in range(len(vec)) if vec[idx] == 1]) return output
def __init__(self, uid, elements=[], **props): super().__init__(uid, elements, **props) if not self.is_bipartite: raise HyperNetXError( 'Entity does not satisfy the Bipartite Condition, elements and children are not disjoint.' )
def add_element(self, item): """ Adds item to entity elements and adds entity to item.memberships. Parameters ---------- item : hashable or Entity If hashable, will be replaced with empty Entity using hashable as uid Returns ------- self : Entity Notes ----- If item is in entity elements, no new element is added but properties will be updated. If item is in complete_registry(), only the item already known to self will be added. This method employs the `Honor System`_ since membership in complete_registry is checked using the item's uid. It is assumed that the user will only use the same uid for identical instances within the entities registry. """ checkelts = self.complete_registry() if isinstance(item, Entity): ## if item is an Entity, descendents will be compared to avoid collisions if item.uid == self.uid: raise HyperNetXError( f'Error: Self reference in submitted elements.' f' Entity {self.uid} may not contain itself. ') elif item in self: ## item is already an element so only the properties will be updated checkelts[item.uid].__dict__.update(item.properties) elif item.uid in checkelts: ## if item belongs to an element or a desendent of an element ## then the existing descendent becomes an element ## and properties are updated. self._elements[item.uid] = checkelts[item.uid] checkelts[item.uid]._memberships[self.uid] = self checkelts[item.uid].__dict__.update(item.properties) else: ## if item's uid doesn't appear in complete_registry ## then it is added as something new item._memberships[self.uid] = self self._elements[item.uid] = item else: ## item must be a hashable. ## if it appears as a uid in checkelts then ## the corresponding Entity will become an element of entity. ## Otherwise, at most it will be added as an empty Entity. if self.uid == item: raise HyperNetXError( f'Error: Self reference in submitted elements.' f' Entity {self.uid} may not contain itself.') elif item not in self._elements: if item in checkelts: self._elements[item] = checkelts[item] checkelts[item]._memberships[self.uid] = self else: self._elements[item] = \ Entity(item, _memberships={self.uid: self}) return self