def __init__(self, elements, transpose=False, isVector=False): if isVector: els = [OrderedSet(x) for x in elements] else: els = [[OrderedSet(x) for x in row] for row in elements] self.mat = np.array(els, dtype=object) if transpose: self.mat = self.mat.T
def testMul(self): lhs = OrderedSet(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']) rhs = OrderedSet(['1', '2', '3', '4', '5', '6', '7', '8']) prod = mul(lhs, rhs) result = OrderedSet(['a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'g1', 'g2', 'g3', 'g4', 'g5', 'g6', 'g7', 'g8', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'h7', 'h8']) self.assertEqual(prod, result)
def setChannel(self,cpt): codomainElements = OrderedSet([names[-1] for (names,_) in cpt]) NumCodElems = len(codomainElements) codomain = efp.Dom([self.name+"_"+elem for elem in codomainElements],names = efp.Name(self.name)) doms = [] steps = 1 for (i,pn) in enumerate(self.parents): domainElements = OrderedSet([names[i] for (names,_) in cpt]) doms.append(efp.Dom([pn.name+"_"+elem for elem in domainElements],names = efp.Name(pn.name))) steps *= len(domainElements) dom = functools.reduce(lambda d1, d2: d1 + d2, doms) pvalues = [row for (_,row) in cpt] matrix = [pvalues[n:n+NumCodElems] for n in range(0,len(pvalues),NumCodElems)] states = [efp.State(matrix[j], codomain) for j in range(steps)] self.channel = efp.chan_from_states(states, dom) self.node_size = len(self.channel.cod[0])
def add(self, rhs): assert self.mat.shape == rhs.mat.shape els = [[OrderedSet([]) for _ in range(self.mat.shape[1])] for _ in range(self.mat.shape[0])] result = np.array(els, dtype=object) for i in range(self.mat.shape[0]): for j in range(self.mat.shape[1]): result[i, j] = add(self.mat[i, j], rhs.mat[i, j]) m = Matrix([]) m.mat = result return m
def dot(self, rhs): assert self.mat.shape[1] == rhs.mat.shape[0] els = [[OrderedSet([]) for _ in range(rhs.mat.shape[1])] for _ in range(self.mat.shape[0])] result = np.array(els, dtype=object) for i in range(self.mat.shape[0]): for j in range(rhs.mat.shape[1]): for k in range(self.mat.shape[1]): m = mul(self.mat[i, k], rhs.mat[k, j]) result[i, j] = add(result[i, j], m) m = Matrix([]) m.mat = result return m
def mul(lhs, rhs): """lhs and rhs are sets multiplication is concatenation see: https://en.wikipedia.org/wiki/Concatenation#Concatenation_of_sets_of_strings """ return OrderedSet([a + b for a in lhs for b in rhs])
def toGNF(self): """Convert grammar to Greibach normal form """ # 1) convert to matrix form: X * H + K, # where X is a row vector of nonterminals, # H is a matrix of productions which start with nonterminal # K is a row vector of productions which start with terminal # for example look at [1] starting on page 20 # [1] https://www.cis.upenn.edu/~jean/old511/html/cis51108sl4b.pdf X, H, K = self._toMatrix() # 2) write system of equations # { X = K * Y + K # { Y = H * Y + H # where Y is a matrix of new nonterminals with size same as H Y = [[[(('Y{}{}'.format(j, i), False), )] for i in range(H.mat.shape[0])] for j in range(H.mat.shape[1])] Y = Matrix(Y) # 3) calculate X from step 2 # substitute nonterminals in matrix H with calculated X values # and get matrix L # the new system is: # { X = K * Y + K # { Y = L * Y + L # calculate X, calculate Y # convert these matrices to one grammar xCalc = K.dot(Y).add(K) subs = {} for i, nt in enumerate(self.nonterminals): subs[nt] = xCalc.mat[0][i] L = H for i, row in enumerate(H.mat): for j, val in enumerate(row): newCell = [] for tup in val: if tup[0][0] in subs: for sub in subs[tup[0][0]]: newCell.append(sub + tup[1:]) else: newCell.append(tup) L.mat[i, j] = OrderedSet(newCell) yCalc = L.dot(Y).add(L) terminals = self.terminals nonterminals = self.nonterminals + \ ['Y{}{}'.format(j, i) for i in range(H.mat.shape[0]) for j in range(H.mat.shape[1])] productions = {} start = self.start for i, oldNT in enumerate(self.nonterminals): productions[oldNT] = xCalc.mat[0][i] for i, row in enumerate(yCalc.mat): for j, val in enumerate(row): lhs = 'Y{}{}'.format(j, i) productions[lhs] = val return Grammar(nonterminals, terminals, productions, start)