private void unfoldAndOptimizeAndStore(IList <RewriteTreeElement> rewriteTreeElementsFromRootToChildrens) { RewriteTreeElement lastChildrenRewriteTreeElement = rewriteTreeElementsFromRootToChildrens[rewriteTreeElementsFromRootToChildrens.Count - 1]; // we have to copy because CausalSetNodeFuser.fuse() modifies the argument CausalSetSystemBlock modifiedRootSystemBlock = unmodifiedRootSystemBlock.copyShallow(); CausalSetSystemBlock currentTopBlock = unmodifiedRootSystemBlock; for (int rewriteChainIndex = 0; rewriteChainIndex < rewriteTreeElementsFromRootToChildrens.Count(); rewriteChainIndex++) { RewriteTreeElement iterationRewriteTreeElement = rewriteTreeElementsFromRootToChildrens[rewriteChainIndex]; CausalSetSystemBlock modifiedParent; CausalSetSystemBlock afterFusion = CausalSetNodeFuser.fuse(currentTopBlock, out modifiedParent, iterationRewriteTreeElement.indicesOfParentNodesForRewrite.ToList()); currentTopBlock = afterFusion; } // linearize and calculate energy, store back to tree (in the children) IList <uint> globalLinearized = linearizer.linearize(modifiedRootSystemBlock, /*recursive*/ true); lastChildrenRewriteTreeElement.globalLinearized = GlobalLinearization.make(linearizer.linearize(modifiedRootSystemBlock, /*recursive*/ true)); Debug.Assert(lastChildrenRewriteTreeElement.globalLinearized.linearization.Count == unmodifiedRootSystemBlock.nodes.Count); // calculate global energy lastChildrenRewriteTreeElement.globalEnergyAfterRewrite = calculateEnergy(lastChildrenRewriteTreeElement.globalLinearized, modifiedRootSystemBlock); }
// \param recursive do we recurse down if the embeded block is present public IList <uint> linearize(CausalSetSystemBlock causalSystemBlock, bool recusive = false) { IList <uint> linearization = new List <uint>(); // (global) indices of nodes of the linearlization linearizeInternal(causalSystemBlock, linearization, recusive); return(linearization); }
void buildTree(CausalSetSystemBlock entryBlock) { // store it for later reference for calculating the global energy unmodifiedRootSystemBlock = entryBlock; rootRewriteTreeElement = new RewriteTreeElement(); buildRewriteTreeRecursive(rootRewriteTreeElement, entryBlock.copyDeep()); }
public CausalSetSystemBlock copyDeep() { CausalSetSystemBlock copyResult = new CausalSetSystemBlock(); copyResult.indirectionArray = ArrayHelpers.copy(indirectionArray); copyResult.indirectionCounter = indirectionCounter; copyResult.entryIndices = entryIndices != null?ListHelpers.copy(entryIndices) : null; foreach (CausalSetNode iteratorNode in nodes) { copyResult.nodes.Add(iteratorNode.copyDeep()); } return(copyResult); }
void buildRewriteTreeRecursive(RewriteTreeElement parentRewriteTreeElement, CausalSetSystemBlock recursedSystemBlock) { uint rewriteRounds = 1; // for now we just do one rewrite for testing for (uint rewriteRound = 0; rewriteRound < rewriteRounds; rewriteRound++) { uint fuseEntryIndex = (uint)random.Next(recursedSystemBlock.nodes.Count); RewriteTreeElement rewriteTreeElementAfterRewrite = new RewriteTreeElement(); rewriteTreeElementAfterRewrite.indicesOfParentNodesForRewrite = recursedSystemBlock.getRandomFollowerAsEnumerable(fuseEntryIndex, terminationPropability); // rewrite rewriteTreeElementAfterRewrite.blockAfterRewrite = CausalSetNodeFuser.fuse(recursedSystemBlock, out recursedSystemBlock, rewriteTreeElementAfterRewrite.indicesOfParentNodesForRewrite.ToList()); parentRewriteTreeElement.childrenRewrites.Add(rewriteTreeElementAfterRewrite); } }
void linearizeInternal(CausalSetSystemBlock causalSystemBlock, IList <uint> linearization, bool recusive) { causalSystemBlock.updateEntryIndices(); // we calculate this always new because we don't care about performance for now IList <uint> indicesOfEntryNodes = causalSystemBlockAccessor.getEntryIndicesAsList(causalSystemBlock); IList <uint> openNodeIndices = ListHelpers.copy(indicesOfEntryNodes); ISet <uint> nodeIndicesInLinearization = new HashSet <uint>(); // set, bool values hae no meaning while (!openNodeIndices.isEmpty()) { uint currentCandidateNodeIndex; {// choose random element from openNodeIndices and remove uint candidateIndexOfOpenNodeIndices = (uint)random.Next(openNodeIndices.Count); currentCandidateNodeIndex = openNodeIndices[(int)candidateIndexOfOpenNodeIndices]; openNodeIndices.RemoveAt((int)candidateIndexOfOpenNodeIndices); } Ensure.ensureHard(!nodeIndicesInLinearization.Contains(currentCandidateNodeIndex)); nodeIndicesInLinearization.Add(currentCandidateNodeIndex); // if we can and should recurse down if (recusive && causalSystemBlock.nodes[(int)currentCandidateNodeIndex].content != null) { CausalSetSystemBlock childrenBlock = causalSystemBlock.nodes[(int)currentCandidateNodeIndex].content; linearizeInternal(childrenBlock, linearization, recusive); } else { // the global index must be valid linearization.Add(causalSystemBlock.nodes[(int)currentCandidateNodeIndex].globalIndex.Value); } ISet <uint> nextIndicesOfCurrentCandidate = SetHelpers.subtract(causalSystemBlockAccessor.getNextIndicesOfNodeAsSet(causalSystemBlock, currentCandidateNodeIndex), nodeIndicesInLinearization); openNodeIndices = SetHelpers.union(SetHelpers.toSet(openNodeIndices), nextIndicesOfCurrentCandidate).ToList(); } }
private long calculateEnergy(GlobalLinearization linearization, CausalSetSystemBlock root) { IDictionary <uint, uint> indexInLinearizationByIndex = new Dictionary <uint, uint>(); for (uint i = 0; i < linearization.linearization.Count; i++) { uint nodeIndex = linearization.linearization[(int)i]; Ensure.ensureHard(!indexInLinearizationByIndex.ContainsKey(nodeIndex)); indexInLinearizationByIndex[nodeIndex] = i; } long energy = 0; for (uint indexInLinearization = 0; indexInLinearization < linearization.linearization.Count; indexInLinearization++) { uint nodeIndex = linearization.linearization[(int)indexInLinearization]; foreach (CausalIndirectionIndex nextNodeIndicesFromCurrentNode in unmodifiedRootSystemBlock.nodes[(int)nodeIndex].next) { uint nextNodeIndexFromCurrentNode = root.translateIndirectIndexToIndex(nextNodeIndicesFromCurrentNode); // translate the index of the next node which follows the current node to the index in the linearization uint indexInLinearizationOfNextNode = indexInLinearizationByIndex[nextNodeIndexFromCurrentNode]; // calculate energy from current node to next node based on linearization Debug.Assert(indexInLinearizationOfNextNode >= 0); int energyFromCurrentNodeToNextNode = (int)indexInLinearizationOfNextNode - (int)indexInLinearization; // must be greater than zero else we have some really nasty bug in the code Ensure.ensureHard(energyFromCurrentNodeToNextNode > 0); energy += energyFromCurrentNodeToNextNode; } } return(energy); }
public void entry(CausalSetSystemBlock entryBlock) { Ensure.ensureHard(rootRewriteTreeElement == null); buildTree(entryBlock); }
public CausalSetNode(CausalSetSystemBlock content = null) { this.content = content; }
// creates a new block with the content as the fused nodes and fuses the nodes in the "entryBlock" and returns the created "CausalSystemBlock" which contains all fused nodes on the next level // entryblock doesn't get modified static public CausalSetSystemBlock fuse(CausalSetSystemBlock entryBlock, out CausalSetSystemBlock modifiedEntryBlock, IList <uint> indices) { CausalSetSystemBlock modifiedEntryBlock_localVar = entryBlock.copyDeep(); CausalSetSystemBlock higherLevelBlock = new CausalSetSystemBlock(); // fill higherLevelBlock with as many nodes as required foreach (uint iterationIndex in indices) { CausalSetNode createdNode = new CausalSetNode(); createdNode.nodeIndexInParentSystemBlock = iterationIndex; higherLevelBlock.nodes.Add(createdNode); higherLevelBlock.indirectionArray.Add(higherLevelBlock.getNewIndirectionNumber()); } // translates the index in entryBlock to the index in higherLevelBlock Dictionary <uint, uint> indexToElementInHigherLevelBlock = new Dictionary <uint, uint>(); for (uint i = 0; i < indices.Count; i++) { uint redirectedIndex = indices[(int)i]; indexToElementInHigherLevelBlock[redirectedIndex] = i; } // rewire from entryBlock the subnetwork to HigherLevelBlock foreach (Tuple <uint, CausalSetNode> iterationIndexAndNodePair in indices.Select(index => new Tuple <uint, CausalSetNode>(index, modifiedEntryBlock_localVar.getNodeByIndex(index)))) { uint higherLevelBlock_index = indexToElementInHigherLevelBlock[iterationIndexAndNodePair.Item1]; var nextValidIndicesFromIterationNode = iterationIndexAndNodePair.Item2.next .Select(nextIndirection => modifiedEntryBlock_localVar.translateIndirectIndexToIndex(nextIndirection)) .Where(index => indexToElementInHigherLevelBlock.ContainsKey(index)); // if the node points to an node which is not in nextLevelBlock then we ignore it foreach (uint iterationNextValidIndexFromIterationNode in nextValidIndicesFromIterationNode) { uint higherLevelBlock_nextIndex = indexToElementInHigherLevelBlock[iterationNextValidIndexFromIterationNode]; // make sure that the indirection is an identity // only this way we don't have to do an inverse lookup to get the CausalIndirectionIndex Ensure.ensureHard(higherLevelBlock.translateIndirectIndexToIndex(new CausalIndirectionIndex(higherLevelBlock_nextIndex)) == higherLevelBlock_nextIndex); higherLevelBlock.nodes[(int)higherLevelBlock_index].next.Add(new CausalIndirectionIndex(higherLevelBlock_nextIndex)); } } // transfer global index // global indices of fused nodes get reset to null by fuse so we ignore them for (uint i = 0; i < indices.Count; i++) { uint entryBlockIndex = indices[(int)i]; uint higherLevelBlock_index = indexToElementInHigherLevelBlock[entryBlockIndex]; higherLevelBlock.nodes[(int)higherLevelBlock_index].globalIndex = modifiedEntryBlock_localVar.nodes[(int)entryBlockIndex].globalIndex; } // now do the fuse uint fuseAsIndirectionNumber = modifiedEntryBlock_localVar.getNewIndirectionNumber(); modifiedEntryBlock_localVar.fuse(indices, fuseAsIndirectionNumber); // add fused node modifiedEntryBlock_localVar.nodes.Add(new CausalSetNode(higherLevelBlock)); // remove fused nodes and rewire indirectionArray accordingly indices.ToList().Sort(); var reversedSortedIndices = indices.Reverse(); foreach (uint iterationNodeIndex in reversedSortedIndices) { // redirect all indices pointing at the element behind the removed one to one before it modifiedEntryBlock_localVar.indirectionArray = modifiedEntryBlock_localVar.indirectionArray.Select(v => v > iterationNodeIndex ? v - 1 : v).ToList(); modifiedEntryBlock_localVar.nodes.RemoveAt((int)iterationNodeIndex); } modifiedEntryBlock = modifiedEntryBlock_localVar; return(higherLevelBlock); }
public ISet <uint> getNextIndicesOfNodeAsSet(CausalSetSystemBlock causalSystemBlock, uint nodeIdx) { uint[] nodeIndicesAsList = causalSystemBlock.nodes[(int)nodeIdx].next.Select(n => causalSystemBlock.indirectionArray[(int)n.value]).ToArray(); return(SetHelpers.toSet(nodeIndicesAsList)); }
public IList <uint> getEntryIndicesAsList(CausalSetSystemBlock causalSystemBlock) { return(causalSystemBlock.entryIndices); }