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); }
// 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); }
public static PermutationNetwork CreateBitonicSplit(int wireCount, bool invertOrder) { Debug.Assert(SortingNetwork.isPowerOfTwo((uint)wireCount)); PermutationNetwork pn = new PermutationNetwork(wireCount); for (int i = 0; i < wireCount / 2; i++) { pn.AppendGate(new ComputationGate(ComputationGateType.COMPARE_AND_SWAP), new int[] { i, i + wireCount / 2 }); if (invertOrder) { pn.AppendGate(PermutationGateFactory.CreateSwapGate(), new int[] { i, i + wireCount / 2 }); } } return(pn); }
// 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); }