def _distributive(self): if self.type in __distributions: star = __distributions[self.type] extracted = [] factorList = Counter() def _pushToExtracted(child, count): assert count == 1 extracted.append(child) factorList.update(keysExcept(child.children, Expression.isConstant)) (rest, hasStar) = performIf(self.children, Expression.isType(star), _pushToExtracted) if hasStar: # Algorithm for factorization: # # 1. find the most common factor # 2. check if that factor has appeared >1 times. If no, quit. # 3. otherwise, scan for all children which contain that factor. # 4. remove that factor from those children, and create a new # a*(b+c+d) style expression. factorizedOnce = False while factorList: (commonest, count) = factorList.most_common(1)[0] if count == 1: if factorizedOnce: rest.update(extracted) return self.replaceChildren(rest) else: return None else: factorizedOnce = True oldExtracted = extracted extracted = [] newChildrenList = [] for child in oldExtracted: if commonest in child.children: factorList.subtract( keysExcept(child.children, Expression.isConstant)) newChildChildren = Counter(child.children) newChildChildren[commonest] -= 1 newChild = child.replaceChildren(newChildChildren) newChildrenList.append(newChild) else: extracted.append(child) newExpression = Expression( star, commonest, Expression(self.type, *newChildrenList)) extracted.append(newExpression) factorList.update( keysExcept(child.children, Expression.isConstant))
def _distributive(self): if self.type in __distributions: star = __distributions[self.type] extracted = [] factorList = Counter() def _pushToExtracted(child, count): assert count == 1 extracted.append(child) factorList.update( keysExcept(child.children, Expression.isConstant)) (rest, hasStar) = performIf(self.children, Expression.isType(star), _pushToExtracted) if hasStar: # Algorithm for factorization: # # 1. find the most common factor # 2. check if that factor has appeared >1 times. If no, quit. # 3. otherwise, scan for all children which contain that factor. # 4. remove that factor from those children, and create a new # a*(b+c+d) style expression. factorizedOnce = False while factorList: (commonest, count) = factorList.most_common(1)[0] if count == 1: if factorizedOnce: rest.update(extracted) return self.replaceChildren(rest) else: return None else: factorizedOnce = True oldExtracted = extracted extracted = [] newChildrenList = [] for child in oldExtracted: if commonest in child.children: factorList.subtract( keysExcept(child.children, Expression.isConstant)) newChildChildren = Counter(child.children) newChildChildren[commonest] -= 1 newChild = child.replaceChildren(newChildChildren) newChildrenList.append(newChild) else: extracted.append(child) newExpression = Expression( star, commonest, Expression(self.type, *newChildrenList)) extracted.append(newExpression) factorList.update( keysExcept(child.children, Expression.isConstant))
def _pushToExtracted(child, count): assert count == 1 extracted.append(child) factorList.update(keysExcept(child.children, Expression.isConstant))