Exemplo n.º 1
0
        private PermutationNetwork CreateBorderSorter(int borderBitLength, int intraBlockSortQuality)
        {
            PermutationNetwork pn = new PermutationNetwork(1 << (borderBitLength + 1));

            int borderSize = 1 << borderBitLength;
            int listCount  = (1 << (intraBlockSortQuality + 1));
            int listSize   = borderSize / listCount;

            pn.AppendGate(PermutationGateFactory.CreateUnshuffleGate(borderSize, listCount), 0);
            pn.AppendGate(PermutationGateFactory.CreateUnshuffleGate(borderSize, listCount), borderSize);

            // merge the corresponding lists
            for (int i = 0; i < listCount; i++)
            {
                int[] wires = new int[listSize * 2];
                for (int j = 0; i < listSize; i++)
                {
                    wires[j]            = i * listSize + j;
                    wires[j + listSize] = wires[j] + borderSize;
                }

                pn.AppendNetwork(SortingNetworkFactory.CreateBitonicMerge(listSize * 2, false), wires);
            }

            // shuffle the lists back into the blocks
            pn.AppendGate(PermutationGateFactory.CreateShuffleGate(borderSize, listCount), 0);
            pn.AppendGate(PermutationGateFactory.CreateShuffleGate(borderSize, listCount), borderSize);

            return(pn);
        }
Exemplo n.º 2
0
        // Lemma 4.1
        private PermutationNetwork CreateBlockCorrectionNetwork(int blockBitLength, int unsortedness)
        {
            PermutationNetwork pn = new PermutationNetwork(1 << blockBitLength);

            SortedSet <int> ySet = new SortedSet <int>(CalculationCache.generateY(blockBitLength));

            Debug.Assert(ySet.Count <= 1 << unsortedness);
            // augment Y with arbitrary elements
            int ySize     = 1 << (unsortedness + 1);
            int blockSize = 1 << blockBitLength;

            Random rand = new Random(0);

            while (ySet.Count < ySize)
            {
                ySet.Add(rand.Next(blockSize));
            }

            // here our implementation differs from the paper.  The paper first to extract Y then order the X by the permutation pi.
            // Instead, we will order all of the inputs by the permutation pi, then map Y using the permutation pi and move X to the top of the block
            // and Y to the bottom so that we can unshuffle X and add Y.

            int[] pi = CalculationCache.generatePi(blockBitLength);

            pn.AppendGate(new PermutationGate(pi), 0);

            int[] mappedY = new int[ySize];
            int   i       = 0;

            foreach (var yElem in ySet)
            {
                mappedY[i++] = pi[yElem];
            }

            pn.AppendGate(PermutationGateFactory.CreateSplitGate(blockSize, mappedY, false), 0);

            // we now want to unshuffle X into 2^(l+1) groups and add one element of Y to each group

            pn.AppendGate(PermutationGateFactory.CreateUnshuffleGate(blockSize - ySize, ySize), 0);

            pn.AppendGate(PermutationGateFactory.CreateMultiGroupInserterGate(blockSize, (blockSize / ySize) - 1, ySize), 0);

            var treeInsertion = SortingNetworkFactory.CreateBinaryTreeInsertion(blockSize / ySize);

            // use binary tree insertion to insert the elemnt we just added to each group
            for (int j = 0; j < ySize; j++)
            {
                pn.AppendNetwork(treeInsertion.Clone() as PermutationNetwork, j * blockSize / ySize);
            }

            // now shuffle all of the lists back together
            pn.AppendGate(PermutationGateFactory.CreateShuffleGate(blockSize, ySize), 0);

            return(pn);
        }
Exemplo n.º 3
0
        // Lemma 4.2
        private PermutationNetwork CreateTournament(int sortInaccuracy)
        {
            PermutationNetwork pn = new PermutationNetwork(1 << K);

            int blockSize = 1 << sortInaccuracy;

            // for the permutation rho
            PermutationGate permuteGate = new PermutationGate(GenerateArbitraryPermutation(blockSize));

            pn.AppendGate(permuteGate.Copy() as Gate, 0);
            pn.AppendNetwork(SortingNetworkFactory.CreateButterflyTournament(blockSize), 0);
            return(pn);
        }
Exemplo n.º 4
0
        // Lemma 4.3
        private PermutationNetwork CreateFinalSorter(int blockBitLength)
        {
            PermutationNetwork pn = new PermutationNetwork(1 << K);

            int blockSize  = 1 << blockBitLength;
            int blockCount = 1 << (K - blockBitLength);

            // sort each block, alternate orders for bitonic merge coming up
            var bitonicSort = SortingNetworkFactory.CreateBitonicSort(blockSize, false);

            for (int i = 0; i < blockCount; i++)
            {
                pn.AppendNetwork(bitonicSort, i * blockSize);
                if (i % 2 == 1)
                {
                    pn.AppendGate(PermutationGateFactory.CreateInvertGate(blockSize), i * blockSize);
                }
            }

            PermutationNetwork twoBlockMerge = SortingNetworkFactory.CreateBitonicMerge(blockSize * 2, false);

            // merge each block with the one next to it.  alternate ordern for bitonic merge coming up

            var bitonicMerge = SortingNetworkFactory.CreateBitonicMerge(blockSize * 2, false);

            for (int i = 0; i < blockCount; i += 2)
            {
                pn.AppendNetwork(bitonicMerge.Clone() as PermutationNetwork, i * blockSize);
                if ((i / 2) % 2 == 1)
                {
                    pn.AppendGate(PermutationGateFactory.CreateInvertGate(2 * blockSize), i * blockSize);
                }
            }

            // do another round of merges, this time offset by 1
            for (int i = 1; i < blockCount; i += 2)
            {
                pn.AppendNetwork(bitonicMerge.Clone() as PermutationNetwork, i * blockSize);
            }

            // the last block will be inverted, so uninvert it
            pn.AppendGate(PermutationGateFactory.CreateInvertGate(blockSize), (blockCount - 1) * blockSize);

            return(pn);
        }
Exemplo n.º 5
0
        // the subsequent rounds
        private LPSortingNetwork(int k, int l, LPSortingCalculationCache calculationCache)
            : base(1 << k)
        {
            Console.WriteLine(k + " " + l);
            CalculationCache = calculationCache;

            K = k;

            if (l <= (int)Math.Floor(gamma * (l + 2)) + c + 5)
            {
                // if we would get worse by doing the procedure, then finish
                if (k <= l)
                {
                    AppendNetwork(SortingNetworkFactory.CreateBitonicSort(1 << K, false), 0);
                }
                else
                {
                    // Apply Lemma 4.3
                    AppendNetwork(CreateFinalSorter(l), 0);
                }
            }
            else
            {
                // Apply Lemma 4.2
                PermutationNetwork tournament = CreateTournament(l + 2);
                // Apply Lemma 4.1
                PermutationNetwork tournamentCorrecter = CreateBlockCorrectionNetwork(l + 2, (int)Math.Floor(gamma * (l + 2)) + c);

                for (int i = 0; i < 1 << (k - (l + 2)); i++)
                {
                    AppendNetwork(tournament.Clone() as PermutationNetwork, i * (1 << (l + 2)));
                    AppendNetwork(tournamentCorrecter.Clone() as PermutationNetwork, i * (1 << (l + 2)));
                }

                // Apply Lemma 4.4
                PermutationNetwork neighborCorrecter = CreateBlockNeighborSorter(l + 2, l + 1, (int)Math.Floor(gamma * (l + 2)) + c + 2);
                AppendNetwork(neighborCorrecter, 0);

                AppendNetwork(new LPSortingNetwork(k, (int)Math.Floor(gamma * (l + 2)) + c + 5, CalculationCache), 0);
            }
        }
Exemplo n.º 6
0
        // the initial round
        private LPSortingNetwork(int k, LPSortingCalculationCache calculationCache)
            : base(1 << k)
        {
            CalculationCache = calculationCache;
            K = k;

            if (k <= (int)Math.Floor(gamma * (k)) + c + 2)
            {
                // network too small to be sorted by this method
                AppendNetwork(SortingNetworkFactory.CreateBitonicSort(1 << K, false), 0);
            }
            else
            {
                // Apply Lemma 4.2
                AppendNetwork(CreateTournament(k), 0);
                // Apply Lemma 4.1
                AppendNetwork(CreateBlockCorrectionNetwork(k, (int)Math.Floor(gamma * (k)) + c), 0);

                AppendNetwork(new LPSortingNetwork(K, (int)Math.Floor(gamma * (k)) + c + 2, CalculationCache), 0);
            }
        }