def createIntegerForm(self, node, value): newForm = CanonicalForm() newForm.subforms[1] = value self.graph.nodes[node]["form"] = newForm newKey = newForm.generateKey() self.graph.nodes[node]["canonicalKey"] = newKey self.key2uniqueOperatorNodes[newKey] = node
def generateCanonicalFormForNode(self, node): nodeOperator = self.subgraph.nodes[node]["operator"] predecessors = list(self.subgraph.predecessors(node)) if nodeOperator == "+": firstPredecessor = predecessors.pop(0) newForm = deepcopy(self.subgraph.nodes[firstPredecessor]["form"]) for pred in predecessors: fold = self.subgraph[pred][node]["fold"] for i in range(fold): newForm.add(self.subgraph.nodes[pred]["form"]) self.subgraph.nodes[node]["form"] = newForm elif nodeOperator == "*": firstPredecessor = predecessors.pop(0) newForm = deepcopy(self.subgraph.nodes[firstPredecessor]["form"]) for pred in predecessors: fold = self.subgraph[pred][node]["fold"] for i in range(fold): newForm.multiply(self.subgraph.nodes[pred]["form"]) self.subgraph.nodes[node]["form"] = newForm elif nodeOperator == "-": order2pred = {} if not self.subgraph.nodes[node]["symmetric"]: for pred in predecessors: order2pred[self.subgraph[pred][node]["order"]] = pred else: if len(predecessors) > 1: raise Exception( "Symmetric - operator with more than one argument " + str(node)) order2pred[0] = predecessors[0] sortedOrders = sorted(list(order2pred.keys())) if not self.subgraph.nodes[node]["symmetric"]: newForm = deepcopy( self.subgraph.nodes[order2pred[sortedOrders[0]]]["form"]) newForm.subtract( self.subgraph.nodes[order2pred[sortedOrders[1]]]["form"]) else: newForm = CanonicalForm() newForm.subtract( self.subgraph.nodes[order2pred[sortedOrders[0]]]["form"]) self.subgraph.nodes[node]["form"] = newForm else: raise Exception("Operator not supported! " + nodeOperator)
def createPrimeForm(self, node): newSubformKey = self.subformFactory.createSubform(node) newForm = CanonicalForm() newForm.subforms[newSubformKey] = 1 self.graph.nodes[node]["form"] = newForm newKey = newForm.generateKey() self.graph.nodes[node]["canonicalKey"] = newKey self.key2uniqueOperatorNodes[newKey] = node
def reduceForm(form): gcd = reduce(math.gcd, list(form.subforms.keys())) if gcd == 1: return form reducedForm = CanonicalForm() for subKey in form.subforms: reducedForm.subforms[subKey] = form.subforms[subKey] // gcd return reducedForm
def clusterSubforms(self): #zmienic na generacje kluczy zredukowanych form reducedKey2nodes = {} subKeyList = list( self.monomials ) reducedKey2form = {} for node in self.node2subforms: coeffs = [] for subKey in subKeyList: coeffs.append(self.node2subforms[node][subKey]) gcd = reduce(math.gcd, coeffs) if gcd != 1: form = CanonicalForm() subforms = self.node2subforms[node] for subKey in subforms: form.subforms[subKey] = subforms[subKey] // gcd reducedKey = form.generateKey() else: form = CanonicalForm() form.subforms = self.node2subforms[node] reducedKey = form.generateKey() if reducedKey in reducedKey2nodes: reducedKey2nodes[reducedKey].add(node) else: reducedKey2nodes[reducedKey] = set([ node ]) reducedKey2form[reducedKey] = form # return reducedKey2nodes, reducedKey2form
def insertNode(self, node): originalSucc = list(self.graph.successors(node)) originalPred = list(self.graph.predecessors(node)) newSucc = list(self.subgraph.successors(node)) newPred = list(self.subgraph.predecessors(node)) if len(originalPred) > len(newPred): newInputs = set(originalPred) - set(newPred) for newInp in newInputs: if not newInp in self.inputNodes: self.inputNodes.append(newInp) name = "i" + str(self.inpInd) self.inpInd += 1 newAtom = CanonicalAtom(name, 1, newInp) newSubform = CanonicalSubform() newSubform.atoms[newAtom.name] = newAtom newForm = CanonicalForm() newForm.subforms[newSubform.getKey()] = newSubform self.subgraph.add_node(newInp, form=newForm, kind="input", variable=name) newEdgeFold = self.graph[newInp][node]["fold"] if self.graph.nodes[node]["symmetric"]: self.subgraph.add_edge(newInp, node, fold=newEdgeFold) else: newEdgeOrder = self.graph[newInp][node]["order"] self.subgraph.add_edge(newInp, node, fold=newEdgeFold, order=newEdgeOrder) self.generateCanonicalFormForNode(node) if len(originalSucc) > len(newSucc): self.outputNodes.append(node) self.subgraph.nodes[node]["kind"] = "output" self.subgraph.nodes[node]["variable"] = "return"
def optimize(self): self.findPotentialSolutions() unitPolynomial = frozenset([1]) optimizationResult = OptimizationResult() if not self.potentialSolutions: optimizationResult.dividingWasPossible = False # print("nie znaleziono zadnych rozwiazan!") # print(self.form.subforms) if not optimizationResult.relativelyPrimes: for subKey in self.form.subforms: newForm = CanonicalForm() newForm.subforms[subKey] = self.form.subforms[subKey] optimizationResult.relativelyPrimes.append(newForm) return optimizationResult if self.gcdKeys == unitPolynomial: optimizationResult.dividingWasPossible = False for subKey in self.form.subforms: newForm = CanonicalForm() newForm.subforms[subKey] = self.form.subforms[subKey] optimizationResult.relativelyPrimes.append(newForm) return optimizationResult bestPolynomial = max(self.potentialSolutions, key=lambda item: item.profit) gcdCoeff = reduce(math.gcd, list(self.form.subforms.values())) quotientForm, dividerForm, divisibleForm, restForm = findPolynomialCoeff( self.form, bestPolynomial, gcdCoeff) optimizationResult.dividingWasPossible = True optimizationResult.quotientForm = quotientForm optimizationResult.deviderForm = dividerForm optimizationResult.divisibleForm = divisibleForm optimizationResult.remainderForm = restForm # if len( bestPolynomial.resultsMonomials ) < len(bestPolynomial.gcdMonomials)*len(bestPolynomial.intermediateMonomials): # print(15*"#") # print("Found best solution from ", len(processedPolynomials)) # print("Highest profit: ", bestPolynomial.profit) # print("Full form len: ", len(self.form.subforms)) # print("Best poly describes: ", len(bestPolynomial.resultsMonomials)) # print("Using polynomials of size: ", len(bestPolynomial.gcdMonomials), " and ",len(bestPolynomial.intermediateMonomials)) return optimizationResult
def findPolynomialCoeff(form, poly, gcdCoeff): # remainderForm = CanonicalForm() #inicjalizacja wartosci quotientForm = CanonicalForm() dividerForm = CanonicalForm() # if len(poly.intermediateMonomials) > len(poly.gcdMonomials): # reverseGcdMat = {} # # for gcdKey in poly.gcdMatrix: # for interKey in poly.gcdMatrix[gcdKey]: # resKey = poly.gcdMatrix[gcdKey][interKey] # # if not interKey in reverseGcdMat: # reverseGcdMat[interKey] = {} # # reverseGcdMat[interKey][gcdKey] = resKey # # poly = DivisiblePolynomial(reverseGcdMat, form) for subKey in poly.gcdMonomials: dividerForm.subforms[subKey] = None for subKey in poly.intermediateMonomials: quotientForm.subforms[subKey] = None #znalezienie wynikow zaleznych tylko i wylacznie od pojedynczych intermediatow intermediate2results = {} for dividerKey in poly.gcdMatrix: for interKey in poly.gcdMatrix[dividerKey]: if not interKey in intermediate2results: intermediate2results[interKey] = set([]) intermediate2results[interKey].add( poly.gcdMatrix[dividerKey][interKey]) intermediate2uniqueResults = {} for interKey in intermediate2results: uniqueInters = intermediate2results[interKey] otherInters = set(intermediate2results.keys()) otherInters.remove(interKey) for otherInter in otherInters: uniqueInters -= intermediate2results[otherInter] intermediate2uniqueResults[interKey] = uniqueInters #okreslenie wartosci intermediatow for intermediate in intermediate2uniqueResults: uniqueResCoeffs = [ form.subforms[subKey] for subKey in intermediate2uniqueResults[intermediate] ] # print(uniqueResCoeffs) newCoeff = 1 if uniqueResCoeffs: newCoeff = reduce(math.gcd, uniqueResCoeffs) quotientForm.subforms[intermediate] = newCoeff #okreslenie wartosci dzielnikow for gcdKey in poly.gcdMatrix: for interKey in poly.gcdMatrix[gcdKey]: resKey = poly.gcdMatrix[gcdKey][interKey] if resKey in intermediate2uniqueResults[interKey]: b = form.subforms[resKey] // quotientForm.subforms[interKey] # if b > 1: # print("lol") # dividerForm.subforms[gcdKey] = randint( 1, b ) # else: dividerForm.subforms[gcdKey] = b # dividerForm.subforms[gcdKey] = form.subforms[resKey]//quotientForm.subforms[interKey] divisibleForm = multiplyForms(quotientForm, dividerForm) restForm = subtractForms(form, divisibleForm) # testForm = addForms(restForm, divisibleForm) # if form.generateKey() != testForm.generateKey(): # raise Exception("Simplyfied form is not identical to source form!") #wiecej info # print(15*"#") # print("Full form len: ", len(self.form.subforms)) # print("Divisible describes: ", len(divisibleForm.subforms)) # print("By multipling: ", len(quotientForm.subforms), " and ", len(dividerForm.subforms)) # print("Rest size: ", len(restForm.subforms)) return quotientForm, dividerForm, divisibleForm, restForm
def createIntegerCanonical(self, value): newForm = CanonicalForm() newForm.subforms[1] = value return newForm