예제 #1
0
        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);
        }
예제 #2
0
        // \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);
        }
예제 #3
0
        void buildTree(CausalSetSystemBlock entryBlock)
        {
            // store it for later reference for calculating the global energy
            unmodifiedRootSystemBlock = entryBlock;

            rootRewriteTreeElement = new RewriteTreeElement();
            buildRewriteTreeRecursive(rootRewriteTreeElement, entryBlock.copyDeep());
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
            }
        }
예제 #6
0
        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();
            }
        }
예제 #7
0
        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);
        }
예제 #8
0
        public void entry(CausalSetSystemBlock entryBlock)
        {
            Ensure.ensureHard(rootRewriteTreeElement == null);

            buildTree(entryBlock);
        }
예제 #9
0
 public CausalSetNode(CausalSetSystemBlock content = null)
 {
     this.content = content;
 }
예제 #10
0
        // 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);
        }
예제 #11
0
 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));
 }
예제 #12
0
 public IList <uint> getEntryIndicesAsList(CausalSetSystemBlock causalSystemBlock)
 {
     return(causalSystemBlock.entryIndices);
 }