From 8bc89ee3a06749fbdd12d638049e813d8dde733c Mon Sep 17 00:00:00 2001 From: kaBeech Date: Tue, 13 Aug 2024 20:38:33 -0700 Subject: [PATCH 01/20] Update types in DocTests --- src/Data/Tensort/Utils/Compose.hs | 61 ++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/src/Data/Tensort/Utils/Compose.hs b/src/Data/Tensort/Utils/Compose.hs index 3ea296c..3939f7b 100644 --- a/src/Data/Tensort/Utils/Compose.hs +++ b/src/Data/Tensort/Utils/Compose.hs @@ -4,12 +4,37 @@ module Data.Tensort.Utils.Compose ) where -import qualified Data.Bifunctor -import Data.Data (ConstrRep (..)) -import Data.Tensort.Utils.SimplifyRegister (applySortingFromSimplifiedRegister, simplifyRegister) +import Data.Tensort.Utils.SimplifyRegister + ( applySortingFromSimplifiedRegister, + simplifyRegister, + ) import Data.Tensort.Utils.Split (splitEvery) -import Data.Tensort.Utils.Types (Bit, Byte, ByteR, Memory (..), MemoryR (..), Record, RecordR, SBit (..), SBytes (..), SMemory (..), SRecord (..), SRecords (SRecordsBit), STensor (..), STensors (..), SortAlg, Sortable (..), Tensor, TensorR, TensortProps (..), fromSBitBit, fromSBitRec, fromSRecordArrayBit, fromSRecordArrayRec, fromSRecordBit, fromSRecordsBit, fromSTensorBit, fromSTensorRec, fromSTensorsBit, fromSortRec) -import GHC.Base (RuntimeRep (TupleRep)) +import Data.Tensort.Utils.Types + ( Byte, + ByteR, + Memory (..), + MemoryR (..), + Record, + RecordR, + SBit (..), + SBytes (..), + SMemory (..), + SRecord (..), + STensor (..), + STensors (..), + SortAlg, + Sortable (..), + Tensor, + TensorR, + TensortProps (..), + fromSBitBit, + fromSBitRec, + fromSRecordArrayBit, + fromSRecordArrayRec, + fromSTensorBit, + fromSTensorRec, + fromSortRec, + ) -- | Convert a list of Bytes to a list of TensorStacks. @@ -20,11 +45,13 @@ import GHC.Base (RuntimeRep (TupleRep)) -- | ==== __Examples__ -- >>> import Data.Tensort.Subalgorithms.Bubblesort (bubblesort) -- >>> import Data.Tensort.Utils.MkTsProps (mkTsProps) --- >>> createInitialTensors (mkTsProps 2 bubblesort) [[2,4],[6,8],[1,3],[5,7]] --- [([(0,3),(1,7)],ByteMem [[1,3],[5,7]]),([(0,4),(1,8)],ByteMem [[2,4],[6,8]])] +-- >>> createInitialTensors (mkTsProps 2 bubblesort) (SBytesBit [[2,4],[6,8],[1,3],[5,7]]) +-- STensorsBit [([(0,3),(1,7)],ByteMem [[1,3],[5,7]]),([(0,4),(1,8)],ByteMem [[2,4],[6,8]])] createInitialTensors :: TensortProps -> SBytes -> STensors -createInitialTensors tsProps (SBytesBit bytes) = STensorsBit (createInitialTensorsBits tsProps bytes) -createInitialTensors tsProps (SBytesRec recs) = STensorsRec (createInitialTensorsRecs tsProps recs) +createInitialTensors tsProps (SBytesBit bytes) = + STensorsBit (createInitialTensorsBits tsProps bytes) +createInitialTensors tsProps (SBytesRec recs) = + STensorsRec (createInitialTensorsRecs tsProps recs) createInitialTensorsBits :: TensortProps -> [Byte] -> [Tensor] createInitialTensorsBits tsProps bytes = foldr acc [] (splitEvery (bytesize tsProps) bytes) @@ -66,8 +93,8 @@ createTensorR subAlg (TensorMemR tensorsR) = getTensorFromTensors subAlg (STenso -- | ==== __Examples__ -- >>> import Data.Tensort.Subalgorithms.Bubblesort (bubblesort) --- >>> getTensorFromBytes bubblesort [[2,4,6,8],[1,3,5,7]] --- ([(1,7),(0,8)],ByteMem [[2,4,6,8],[1,3,5,7]]) +-- >>> getTensorFromBytes bubblesort (SBytesBit [[2,4,6,8],[1,3,5,7]]) +-- STensorBit ([(1,7),(0,8)],ByteMem [[2,4,6,8],[1,3,5,7]]) getTensorFromBytes :: SortAlg -> SBytes -> STensor getTensorFromBytes subAlg (SBytesBit bytes) = STensorBit (getTensorFromBytesB subAlg bytes) getTensorFromBytes subAlg (SBytesRec recs) = STensorRec (getTensorFromBytesR subAlg recs) @@ -101,8 +128,8 @@ getTensorFromBytesR subAlg bytesR = do -- | ==== __Examples__ -- >>> import Data.Tensort.Subalgorithms.Bubblesort (bubblesort) --- >>> getTensorFromTensors bubblesort [([(0,13),(1,18)],ByteMem [[11,13],[15,18]]),([(1,14),(0,17)],ByteMem [[16,17],[12,14]])] --- ([(1,17),(0,18)],TensorMem [([(0,13),(1,18)],ByteMem [[11,13],[15,18]]),([(1,14),(0,17)],ByteMem [[16,17],[12,14]])]) +-- >>> getTensorFromTensors bubblesort (STensorsBit [([(0,13),(1,18)],ByteMem [[11,13],[15,18]]),([(1,14),(0,17)],ByteMem [[16,17],[12,14]])]) +-- STensorBit ([(1,17),(0,18)],TensorMem [([(0,13),(1,18)],ByteMem [[11,13],[15,18]]),([(1,14),(0,17)],ByteMem [[16,17],[12,14]])]) getTensorFromTensors :: SortAlg -> STensors -> STensor getTensorFromTensors subAlg (STensorsBit tensors) = STensorBit (getTensorFromTensorsB subAlg tensors) getTensorFromTensors subAlg (STensorsRec tensors) = STensorRec (getTensorFromTensorsR subAlg tensors) @@ -125,8 +152,8 @@ getTensorFromTensorsR subAlg tensorsR = do -- getTensorFromTensors function -- | ==== __Examples__ --- >>> getRegisterFromTensors [([(0,13),(1,18)],ByteMem [[11,13],[15,18]]),([(0,14),(1,17)],ByteMem [[12,14],[16,17]]),([(0,3),(1,7)],ByteMem [[1,3],[5,7]]),([(0,4),(1,8)],ByteMem [[2,4],[6,8]])] --- [(0,18),(1,17),(2,7),(3,8)] +-- >>> getRegisterFromTensors (STensorsBit [([(0,13),(1,18)],ByteMem [[11,13],[15,18]]),([(0,14),(1,17)],ByteMem [[12,14],[16,17]]),([(0,3),(1,7)],ByteMem [[1,3],[5,7]]),([(0,4),(1,8)],ByteMem [[2,4],[6,8]])]) +-- [SRecordBit (0,18),SRecordBit (1,17),SRecordBit (2,7),SRecordBit (3,8)] getRegisterFromTensors :: STensors -> [SRecord] getRegisterFromTensors (STensorsBit tensors) = getRegisterFromTensorsB tensors getRegisterFromTensors (STensorsRec tensors) = getRegisterFromTensorsR tensors @@ -160,8 +187,8 @@ getRegisterFromTensorsR tensorsR = acc tensorsR [] -- | This is also expected to be the highest value in the TensorStack -- | ==== __Examples__ --- >>> getTopBitFromTensorStack (([(0,28),(1,38)],TensorMem [([(0,27),(1,28)],TensorMem [([(0,23),(1,27)],ByteMem [[21,23],[25,27]]),([(0,24),(1,28)],ByteMem [[22,24],[26,28]])]),([(1,37),(0,38)],TensorMem [([(0,33),(1,38)],ByteMem [[31,33],[35,38]]),([(0,34),(1,37)],ByteMem [[32,14],[36,37]])])])) --- 38 +-- >>> getTopBitFromTensorStack (STensorBit ([(0,28),(1,38)],TensorMem [([(0,27),(1,28)],TensorMem [([(0,23),(1,27)],ByteMem [[21,23],[25,27]]),([(0,24),(1,28)],ByteMem [[22,24],[26,28]])]),([(1,37),(0,38)],TensorMem [([(0,33),(1,38)],ByteMem [[31,33],[35,38]]),([(0,34),(1,37)],ByteMem [[32,14],[36,37]])])])) +-- SBitBit 38 getTopBitFromTensorStack :: STensor -> SBit getTopBitFromTensorStack (STensorBit tensor) = getTopBitFromTensorStackB tensor getTopBitFromTensorStack (STensorRec tensorR) = getTopBitFromTensorStackR tensorR From 9c1b611c6da977bc983a8840e31c0e6ccbfb39b6 Mon Sep 17 00:00:00 2001 From: kaBeech Date: Tue, 13 Aug 2024 20:45:38 -0700 Subject: [PATCH 02/20] Update types in DocTests --- src/Data/Tensort/Utils/Render.hs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Data/Tensort/Utils/Render.hs b/src/Data/Tensort/Utils/Render.hs index 84e079b..9a45fec 100644 --- a/src/Data/Tensort/Utils/Render.hs +++ b/src/Data/Tensort/Utils/Render.hs @@ -8,10 +8,10 @@ import Data.Tensort.Utils.Types (Bit, BitR, Memory (..), MemoryR (..), SBit (..) -- | ==== __Examples__ -- >>> import Data.Tensort.Subalgorithms.Bubblesort (bubblesort) --- >>> getSortedBitsFromTensor bubblesort ([(0,5),(1,7)],ByteMem [[1,5],[3,7]]) --- [1,3,5,7] --- >>> getSortedBitsFromTensor bubblesort ([(0,8),(1,18)],TensorMem [([(0,7),(1,8)],TensorMem [([(0,3),(1,7)],ByteMem [[1,3],[5,7]]),([(0,4),(1,8)],ByteMem [[2,4],[6,8]])]),([(1,17),(0,18)],TensorMem [([(0,13),(1,18)],ByteMem [[11,13],[15,18]]),([(0,14),(1,17)],ByteMem [[12,14],[16,17]])])]) --- [1,2,3,4,5,6,7,8,11,12,13,14,15,16,17,18] +-- >>> getSortedBitsFromTensor bubblesort (STensorBit ([(0,5),(1,7)],ByteMem [[1,5],[3,7]])) +-- [SBitBit 1,SBitBit 3,SBitBit 5,SBitBit 7] +-- >>> getSortedBitsFromTensor bubblesort (STensorBit ([(0,8),(1,18)],TensorMem [([(0,7),(1,8)],TensorMem [([(0,3),(1,7)],ByteMem [[1,3],[5,7]]),([(0,4),(1,8)],ByteMem [[2,4],[6,8]])]),([(1,17),(0,18)],TensorMem [([(0,13),(1,18)],ByteMem [[11,13],[15,18]]),([(0,14),(1,17)],ByteMem [[12,14],[16,17]])])])) +-- [SBitBit 1,SBitBit 2,SBitBit 3,SBitBit 4,SBitBit 5,SBitBit 6,SBitBit 7,SBitBit 8,SBitBit 11,SBitBit 12,SBitBit 13,SBitBit 14,SBitBit 15,SBitBit 16,SBitBit 17,SBitBit 18] getSortedBitsFromTensor :: SortAlg -> STensorStack -> [SBit] getSortedBitsFromTensor subAlg (STensorBit tensorRaw) = getSortedBitsFromTensorB subAlg tensorRaw getSortedBitsFromTensor subAlg (STensorRec tensorRaw) = getSortedBitsFromTensorR subAlg tensorRaw From e5c37d073c36f281316216afad697328dfd41c8e Mon Sep 17 00:00:00 2001 From: kaBeech Date: Tue, 13 Aug 2024 20:53:24 -0700 Subject: [PATCH 03/20] Update types in DocTests --- src/Data/Tensort/Utils/Reduce.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Data/Tensort/Utils/Reduce.hs b/src/Data/Tensort/Utils/Reduce.hs index b8c8755..1d521e2 100644 --- a/src/Data/Tensort/Utils/Reduce.hs +++ b/src/Data/Tensort/Utils/Reduce.hs @@ -13,8 +13,8 @@ import Data.Tensort.Utils.Types (Memory (..), MemoryR (..), SMemory (..), STenso -- | ==== __Examples__ -- >>> import Data.Tensort.Subalgorithms.Bubblesort (bubblesort) -- >>> import Data.Tensort.Utils.MkTsProps (mkTsProps) --- >>> reduceTensorStacks (mkTsProps 2 bubblesort) [([(0, 33), (1, 38)], ByteMem [[31, 33], [35, 38]]), ([(0, 34), (1, 37)], ByteMem [[32, 14], [36, 37]]), ([(0, 23), (1, 27)], ByteMem [[21, 23], [25, 27]]), ([(0, 24), (1, 28)], ByteMem [[22, 24], [26, 28]]),([(0,13),(1,18)],ByteMem [[11,13],[15,18]]),([(0,14),(1,17)],ByteMem [[12,14],[16,17]]),([(0,3),(1,7)],ByteMem [[1,3],[5,7]]),([(0,4),(1,8)],ByteMem [[2,4],[6,8]])] --- ([(1,18),(0,38)],TensorMem [([(0,28),(1,38)],TensorMem [([(0,27),(1,28)],TensorMem [([(0,23),(1,27)],ByteMem [[21,23],[25,27]]),([(0,24),(1,28)],ByteMem [[22,24],[26,28]])]),([(1,37),(0,38)],TensorMem [([(0,33),(1,38)],ByteMem [[31,33],[35,38]]),([(0,34),(1,37)],ByteMem [[32,14],[36,37]])])]),([(0,8),(1,18)],TensorMem [([(0,7),(1,8)],TensorMem [([(0,3),(1,7)],ByteMem [[1,3],[5,7]]),([(0,4),(1,8)],ByteMem [[2,4],[6,8]])]),([(1,17),(0,18)],TensorMem [([(0,13),(1,18)],ByteMem [[11,13],[15,18]]),([(0,14),(1,17)],ByteMem [[12,14],[16,17]])])])]) +-- >>> reduceTensorStacks (mkTsProps 2 bubblesort) (STensorsBit [([(0, 33), (1, 38)], ByteMem [[31, 33], [35, 38]]), ([(0, 34), (1, 37)], ByteMem [[32, 14], [36, 37]]), ([(0, 23), (1, 27)], ByteMem [[21, 23], [25, 27]]), ([(0, 24), (1, 28)], ByteMem [[22, 24], [26, 28]]),([(0,13),(1,18)],ByteMem [[11,13],[15,18]]),([(0,14),(1,17)],ByteMem [[12,14],[16,17]]),([(0,3),(1,7)],ByteMem [[1,3],[5,7]]),([(0,4),(1,8)],ByteMem [[2,4],[6,8]])]) +-- STensorBit ([(1,18),(0,38)],TensorMem [([(0,28),(1,38)],TensorMem [([(0,27),(1,28)],TensorMem [([(0,23),(1,27)],ByteMem [[21,23],[25,27]]),([(0,24),(1,28)],ByteMem [[22,24],[26,28]])]),([(1,37),(0,38)],TensorMem [([(0,33),(1,38)],ByteMem [[31,33],[35,38]]),([(0,34),(1,37)],ByteMem [[32,14],[36,37]])])]),([(0,8),(1,18)],TensorMem [([(0,7),(1,8)],TensorMem [([(0,3),(1,7)],ByteMem [[1,3],[5,7]]),([(0,4),(1,8)],ByteMem [[2,4],[6,8]])]),([(1,17),(0,18)],TensorMem [([(0,13),(1,18)],ByteMem [[11,13],[15,18]]),([(0,14),(1,17)],ByteMem [[12,14],[16,17]])])])]) reduceTensorStacks :: TensortProps -> STensorStacks -> STensorStack reduceTensorStacks tsProps (STensorsBit tensorStacks) = reduceTensorStacksB tsProps tensorStacks reduceTensorStacks tsProps (STensorsRec tensorStacks) = reduceTensorStacksR tsProps tensorStacks From 2618f4288cee42b670135d1dea39b75e7f76da75 Mon Sep 17 00:00:00 2001 From: kaBeech Date: Tue, 13 Aug 2024 20:58:25 -0700 Subject: [PATCH 04/20] Update types in DocTests --- src/Data/Tensort/Tensort.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Data/Tensort/Tensort.hs b/src/Data/Tensort/Tensort.hs index e1dfddb..6cf7a92 100644 --- a/src/Data/Tensort/Tensort.hs +++ b/src/Data/Tensort/Tensort.hs @@ -20,9 +20,9 @@ import Data.Tensort.Utils.Types (Sortable (..), TensortProps (..), fromSBitBits, -- | ==== __Examples__ -- >>> import Data.Tensort.Subalgorithms.Bubblesort (bubblesort) -- >>> import Data.Tensort.Utils.MkTsProps (mkTsProps) --- >>> let inputList = fromSortBit (randomizeList 143 (SortBit [1..100]) ) +-- >>> let inputList = randomizeList 143 (SortBit [1..100]) -- >>> tensort (mkTsProps 2 bubblesort) inputList --- [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100] +-- SortBit [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100] tensort :: TensortProps -> Sortable -> Sortable tensort _ (SortBit []) = SortBit [] tensort _ (SortBit [x]) = SortBit [x] From f04532003da5c24be194ada70661931e9b24576f Mon Sep 17 00:00:00 2001 From: kaBeech Date: Tue, 13 Aug 2024 21:05:35 -0700 Subject: [PATCH 05/20] Update disclaimer --- README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ef44427..58b240e 100644 --- a/README.md +++ b/README.md @@ -14,11 +14,10 @@ then transforms the tensor field back into a sorted list. These transformations provide opportunities to increase redundancy for improved robustness and can be leveraged to include any further processing we wish to do on the elements. -Note: This project is still under construction. Everything works and according -to my calculations will perform excellently under Ackley's testing conditions. -Still to add: benchmarking to prove how cool it is, documentation -additions/revisions, memes. There's likely a lot of room for improvement in the -code as well. +Note: This project is still under construction. Everything works and performs +excellently under Ackley's testing conditions. Still to add: documentation +additions/revisions, convenience wrappers for the top-level functions, memes. +There's likely a lot of room for improvement in the code as well. ## Table of Contents From 2002478f17d9c90fe1882ddedf3b0d1ca4e08c94 Mon Sep 17 00:00:00 2001 From: kaBeech Date: Tue, 13 Aug 2024 21:09:22 -0700 Subject: [PATCH 06/20] Move benchmarking info Remove scratch benchmarking work and add notice pointing to current --- app/Main.hs | 64 ++--------------------------------------------------- 1 file changed, 2 insertions(+), 62 deletions(-) diff --git a/app/Main.hs b/app/Main.hs index 4774e60..f7ce24c 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -1,66 +1,6 @@ module Main where -import Data.Tensort.OtherSorts.Mergesort (mergesort) -import Data.Tensort.OtherSorts.Quicksort (quicksort) -import Data.Tensort.Robustsort (robustsortB, robustsortM, robustsortP, robustsortRM) -import Data.Tensort.Subalgorithms.Bubblesort (bubblesort) -import Data.Tensort.Tensort (tensortB4, tensortBL) -import Data.Tensort.Utils.RandomizeList (randomizeList) -import Data.Tensort.Utils.Types (Sortable (..), fromSortBit) -import Data.Time.Clock - -genUnsortedBits :: Int -> Sortable -genUnsortedBits n = randomizeList 143 (SortBit [1 .. n]) - main :: IO () main = do - -- Eventually I hope to turn that 14 into a 20 - printTimes (map (genUnsortedBits . (2 ^)) [3 .. 14]) - -printTimes :: [Sortable] -> IO () -printTimes [] = return () -printTimes (x : xs) = do - printTime x - printTimes xs - -printTime :: Sortable -> IO () -printTime l = do - putStr " Algorithm | Time | n =" - startTensortB4 <- getCurrentTime - putStrLn (" " ++ show (length (fromSortBit (tensortB4 l)))) - endTensortB4 <- getCurrentTime - putStr (" Tensort4Bit | " ++ show (diffUTCTime endTensortB4 startTensortB4) ++ " | ") - startTensortBL <- getCurrentTime - putStrLn (" " ++ show (length (fromSortBit (tensortBL l)))) - endTensortBL <- getCurrentTime - putStr (" TensortBL | " ++ show (diffUTCTime endTensortBL startTensortBL) ++ " | ") - startRSortP <- getCurrentTime - putStrLn (" " ++ show (length (fromSortBit (robustsortP l)))) - endRSortP <- getCurrentTime - putStr (" RobustsortP | " ++ show (diffUTCTime endRSortP startRSortP) ++ " | ") - startRSortB <- getCurrentTime - putStrLn (" " ++ show (length (fromSortBit (robustsortB l)))) - endRSortB <- getCurrentTime - putStr (" RobustsortB | " ++ show (diffUTCTime endRSortB startRSortB) ++ " | ") - startRSortM <- getCurrentTime - putStrLn (" " ++ show (length (fromSortBit (robustsortM l)))) - endRSortM <- getCurrentTime - putStr (" RobustsortM | " ++ show (diffUTCTime endRSortM startRSortM) ++ " | ") - startRSortRM <- getCurrentTime - putStrLn (" " ++ show (length (fromSortBit (robustsortRM l)))) - endRSortRM <- getCurrentTime - putStr (" RobustsortRM | " ++ show (diffUTCTime endRSortRM startRSortRM) ++ " | ") - startMergesort <- getCurrentTime - putStrLn (" " ++ show (length (fromSortBit (mergesort l)))) - endMergesort <- getCurrentTime - putStr (" Mergesort | " ++ show (diffUTCTime endMergesort startMergesort) ++ " | ") - startQuicksort <- getCurrentTime - putStrLn (" " ++ show (length (fromSortBit (quicksort l)))) - endQuicksort <- getCurrentTime - putStr (" Quicksort | " ++ show (diffUTCTime endQuicksort startQuicksort) ++ " | ") - startBubblesort <- getCurrentTime - putStrLn (" " ++ show (length (fromSortBit (bubblesort l)))) - endBubblesort <- getCurrentTime - putStr (" Bubblesort | " ++ show (diffUTCTime endBubblesort startBubblesort) ++ " | ") - putStrLn (" " ++ show (length (fromSortBit l))) - putStrLn "----------------------------------------------------------" + print + "To run benchmarks, switch to the 'benchmarking' branch in this repository" From e60e1726cb2a6d2cd7a41c43ac81acc761a1516f Mon Sep 17 00:00:00 2001 From: kaBeech Date: Tue, 13 Aug 2024 21:33:00 -0700 Subject: [PATCH 07/20] Clarify heading --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 58b240e..dece73f 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ There's likely a lot of room for improvement in the code as well. - [Structure](#structure) - [Algorithm](#algorithm) - [What are the benefits?](#what-are-the-benefits) - - [Logarithmic Tensort](#logarithmic-tensort) + - [Logarithmic Bytesize](#logarithmic-bytesize) - [Robustsort](#robustsort) - [Preface](#preface-1) - [Overview](#overview) @@ -324,7 +324,7 @@ last element is in the final position of a list, and B) at each step of Tensort the only element we *really* care about is the last element in a given list (or to look at it another way, the TopBit of a given Tensor). -#### Logarithmic Tensort +#### Logarithmic Bytesize When using standard Tensort (i.e. using Bubblesort as the SubAlgoritm), as the Bytesize approaches the square root of the number of elements in the From f88627ea79f8981c0f2c4ad782bd994157df4102 Mon Sep 17 00:00:00 2001 From: kaBeech Date: Tue, 13 Aug 2024 21:34:17 -0700 Subject: [PATCH 08/20] Update Robustsort intro --- README.md | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index dece73f..f929699 100644 --- a/README.md +++ b/README.md @@ -375,11 +375,12 @@ With those ground rules in place, let's get to Robustsort! #### Overview -Once we have Tensort in our toolbox, the road to Robustsort is pretty simple. -Robustsort is a 3-bit Tensort with a custom SubAlgorithm that compares other +Once we have Tensort in our toolbox, the road to Robustsort is not long. +Robustsort is a recursive version of Tensort, so first we'll look at its base +case, a 3-bit Tensort with a custom SubAlgorithm that compares other sub-algorithms. For convenience, we will call this custom SubAlgorithm -Supersort. We use a 3-bit Tensort here because there's something -magical that happens around these numbers. +Supersort. We use a 3-bit Tensort here because there's something magical that +happens around the number 3. Robust sorting algorithms tend to be slow. Bubblesort, for example, has an average time efficiency of O(n^2), @@ -389,13 +390,9 @@ Here's the trick though: with small numbers the difference between these values is minimal. For example, when n=4, Mergesort will make 6 comparisons, while Bubblesort will make 12. A Byte holding 4 Bites is both small enough to run the Bubblesort quickly and large enough to allow multiple opportunities for a -mistake to be corrected. Since we don't as much built-in parallelism in -Tensort, it can make sense to weight more heavily on the side of making more -checks. +mistake to be corrected. -In Robustsort, however, we have parallelism built into the Supersort -SubAlgorithm, so we can afford to make less checks during this step. -We choose a Bytesize of +In Robustsort, we choose a Bytesize of 3 because a list of 3 Bits has some special properties. For one thing, sorting at this length greatly reduces the time it takes to run our slow-but-robust @@ -413,9 +410,8 @@ Note: One might ask why we don't use a Bytesize of 2, since it would be even fas and still have the same property of displacing an element by only 1 or 2 positions. Well, how many different algorithms can you use to sort 2 elements? At this length, most algorithms function equivalently (in terms of the -sub-operations performed) and in my mind running two such algorithms is -equivalent to re-running a single algorithm (which violates the requirements -of this project). +sub-operations performed) and as we will see, it pays to have some diversity +in our sub-algorithms. #### Examining Bubblesort From 79e7f1ec9d2ae4e9f19c43efbb6a93ba61dcdced Mon Sep 17 00:00:00 2001 From: kaBeech Date: Tue, 13 Aug 2024 22:42:50 -0700 Subject: [PATCH 09/20] Update Bubblesort and Exchangesort probability notes --- README.md | 78 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index f929699..f5589d3 100644 --- a/README.md +++ b/README.md @@ -425,27 +425,35 @@ We've said before that Bubblesort is likely to put the last element in the correct position. Let's examine this in the context of Bubblesorting a 3-element list. -Our implementation of Bubblesort (which mirrors Ackley's) will perform three -iterations over a 3-element list. After the second iteration, if everything -goes as planned, the list will be sorted and the final iteration is an extra -verification step. Therefore, to simplify the analysis, we will consider -what happens with a faulty comparator during the final iteration, assuming the -list has been correctly sorted up to that point. + + + + + + -Given a Byte of [1,2,3], here are the chances of various outcomes from using a -faulty comparator that gives a random result 10% of the time: +I ran Bubblesort 1000 times on Bytes of random permutations of [1,2,3] using a +faulty comparator that gives a random result 10% of the time. Here is how often +each outcome was returned: + + 87.1% <- [1,2,3] + + 4.1% <- [1,3,2] + + 6.6% <- [2,1,3] - 81% <- [1,2,3] (correct - no swaps made) + 0.2% <- [2,3,1] - 9% <- [2,1,3] (faulty first swap) + 1.8% <- [3,1,2] - 9% <- [1,3,2] (faulty second swap) + 0.2% <- [3,2,1] - 1% <- [2,3,1] (faulty first and second swap) +In these results, 93.7% of the time the Top Bit was returned in the correct +position, and the bottom value was returned in the top position only 0.4% of +the time. -In these cases, 90% of the time the Top Bit will be in the correct position, -and in the other cases it will be off by one position, and in no case will the -Byte be reverse sorted. +Notably, the far more likely result where the Top Bit was at the bottom was +[3,1,2], with [3,2,1] occurring only 0.2% of the time. #### Exchangesort @@ -455,6 +463,10 @@ however, want something similar to Bubblesort in that it compares our elements multiple times. And, as mentioned above, the element that is most important to our sorting is the top (biggest) element, by a large degree. +In terms of the probability of different outcomes, if our algorithm returns +an incorrect result, we want that result to be different than what Bubblesort +is likely to return. + With these priorities in mind, the comparison algorithm we choose shall be Exchangesort. If you're not familiar with this algorithm, I'd recommend checking out [this video](https://youtu.be/wqibJMG42Ik?feature=shared&t=143). @@ -475,26 +487,38 @@ using this variation for our Exchangesort. Exchangesort will also make an average of 6 comparisons when sorting a 3-element list. -As with Bubblesort, Exchangesort will perform three iterations over a 3-element -list, with the final iteration being redundant. + + Given a Byte of [1,2,3], here are the chances of various outcomes from using a faulty comparator that gives a random result 10% of the time: - 81% <- [1,2,3] (correct - no swaps made) + 91.8% <- [1,2,3] + + 3.4% <- [1,3,2] + + 2.5% <- [2,1,3] + + 0% <- [2,3,1] + + 0.2% <- [3,1,2] - 9% <- [2,1,3] (faulty first swap) + 2.1% <- [3,2,1] - 9% <- [3,2,1] (faulty second swap) +In these results, 94,3% of the time the Top Bit was returned in the correct +position and it returned the bottom value in the top position only 2.1% of the +time. - 1% <- [3,1,2] (faulty first and second swap) +In results where the Top Bit was in the +bottom position, [3,2,1] was the most likely outcome, with [3,1,2] occurring +only 0.2% of the time. This is opposite to what happens in Bubblesort, +making cases in which they agree with the Top Bit in the bottom position +very rare. -In these cases, 90% of the time the Top Bit will have the correct value. -Notably there is a 9% chance that the Byte will be reverse sorted, but we will -exploit this trait later on in the Supersort SubAlgorithm. Note also that the -only possible outcomes shared between this example and the Bubblesort example -are the correct outcome and [2,1,3], which retains the TopBit with the correct -value. +Overall, there is a modest probability (about 0.14% according to these results) +that Bubblesort and Exchangesort will agree on [1,3,2] as the result, but it is +very unlikely that they will agree on any other result that does not have the +Top Bit in the correct position. #### Introducing Supersort From 0b8a7038690e359da90e97944cf958e64cf58768 Mon Sep 17 00:00:00 2001 From: kaBeech Date: Tue, 13 Aug 2024 23:23:02 -0700 Subject: [PATCH 10/20] Update Bubblesort and Exchangesort agreement probability notes --- README.md | 54 ++++++++++-------------------------------------------- 1 file changed, 10 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index f5589d3..680720c 100644 --- a/README.md +++ b/README.md @@ -490,8 +490,9 @@ Exchangesort will also make an average of 6 comparisons when sorting a -Given a Byte of [1,2,3], here are the chances of various outcomes from using a -faulty comparator that gives a random result 10% of the time: +Here are the results of runnitng Exchangesort 1000 times on Bytes of random +permutations of [1,2,3] using a faulty comparator that gives a random result +10% of the time: 91.8% <- [1,2,3] @@ -527,53 +528,18 @@ sorting algorithms, in our case Bubblesort and Exchangesort. If both algorithms agree on the result, that result is used. Looking at our analysis on Bubblesort and Exchangesort, we can -approximate the chances of various outcomes when comparing the results of -running these two algorithms in similar conditions: - - 65.61% <- [1,2,3], [1,2,3] (Agree Correctly) - - 7.29% <- [1,2,3], [2,1,3] (Disagree - TopBit agrees correctly) - - 7.29% <- [1,2,3], [3,2,1] (Disagree Fully) - - 7.29% <- [2,1,3], [1,2,3] (Disagree - TopBit agrees correctly) - - 7.29% <- [1,3,2], [1,2,3] (Disagree Fully) - - 0.81% <- [2,1,3], [2,1,3] (Agree Incorrectly - TopBit correct) - - 0.81% <- [2,1,3], [3,2,1] (Disagree Fully) - - 0.81% <- [1,3,2], [2,1,3] (Disagree Fully) - - 0.81% <- [1,3,2], [3,2,1] (Disagree Fully) - - 0.09% <- [2,1,3], [3,1,2] (Disagree Fully) - - 0.09% <- [1,3,2], [3,1,2] (Disagree - TopBit agrees incorrectly) - - 0.09% <- [2,3,1], [2,1,3] (Disagree Fully) - - 0.09% <- [2,3,1], [3,2,1] (Disagree - TopBit agrees incorrectly) - - 0.01% <- [2,3,1], [3,1,2] (Disagree Fully) - -In total, that makes: - - 65.61% <- Agree Correctly - - 17.2% <- Disagree Fully +approximate the chances of how often they will agree in similar conditions: - 14.58% <- Disagree - TopBit agrees correctly + 79.96% <- Agree Correctly - 0.81% <- Agree Incorrectly - TopBit correct + 19.73% <- Disagree - 0.18% <- Disagree - TopBit agrees incorrectly + 0.17% <- Agree Incorrectly - TopBit correct - [no outcome] <- Agree with TopBit incorrect + 0.14% <- Agree Incorectly - TopBit incorrect -The first thing that might stand out is that around 34% of the time, these -sub-algorithms will disagree with each other. What happens then? +Hey, that's pretty good! One thing that stands out is that around 20% of the +time, these sub-algorithms will disagree with each other. What happens then? Well, in that case we run a third sub-algorithm to compare the results with: Permutationsort. From c7d8b80c7f99d31e5dcb7af13119e794b9ae3080 Mon Sep 17 00:00:00 2001 From: kaBeech Date: Tue, 13 Aug 2024 23:23:41 -0700 Subject: [PATCH 11/20] Update Permutationsort probability notes --- README.md | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 680720c..0715369 100644 --- a/README.md +++ b/README.md @@ -561,24 +561,26 @@ B) it uses logic that is completely different from Bubblesort and Exchangesort. Using different manners of reasoning to reach an agreed-upon answer greatly increases the robustness of the system. -Given a Byte of [1,2,3], here are the chances of various outcomes from using a -faulty comparator that gives a random result 10% of the time: +Here are the results of runnitng Permutationsort 1000 times on Bytes of random +permutations of [1,2,3] using a faulty comparator that gives a random result +10% of the time: - ~68.67% <- [1,2,3] (correct) + 81.9% <- [1,2,3] - ~7.63% <- [2,1,3] (faulty first comparator) + 4.1% <- [2,1,3] - ~7.63% <- [3,1,2] (faulty first comparator) + 4.5% <- [3,1,2] - ~7.63% <- [1,3,2] (faulty second comparator) + 5.3% <- [1,3,2] - ~7.63% <- [2,3,1] (faulty second comparator) + 3.4% <- [2,3,1] - ~0.85% <- [3,2,1] (faulty first and second comparator) + 0.8% <- [3,2,1] -In these cases, 76.6% of the time the Top Bit will be in the correct position. +In these cases, 86% of the time the Top Bit was in the correct position. Notably the least likely outcome is a reverse-sorted Byte and the other -possible incorrect outcomes are in even distribution with each other. +possible incorrect outcomes are in approximately even distribution with +each other. #### Supersort Adjudication From 563b985e18d69d354219bb8ee41e5e60b2beeb73 Mon Sep 17 00:00:00 2001 From: kaBeech Date: Wed, 14 Aug 2024 00:15:25 -0700 Subject: [PATCH 12/20] Update SuperStrat notes --- README.md | 64 +++++++++++++++++++------------------------------------ 1 file changed, 22 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 0715369..b564213 100644 --- a/README.md +++ b/README.md @@ -530,13 +530,13 @@ algorithms agree on the result, that result is used. Looking at our analysis on Bubblesort and Exchangesort, we can approximate the chances of how often they will agree in similar conditions: - 79.96% <- Agree Correctly + ~79.96% <- Agree Correctly - 19.73% <- Disagree + ~19.73% <- Disagree - 0.17% <- Agree Incorrectly - TopBit correct + ~0.17% <- Agree Incorrectly - TopBit correct - 0.14% <- Agree Incorectly - TopBit incorrect + ~0.14% <- Agree Incorectly - TopBit incorrect Hey, that's pretty good! One thing that stands out is that around 20% of the time, these sub-algorithms will disagree with each other. What happens then? @@ -595,57 +595,37 @@ Permutationsort will agree on results with Bubblesort or Exchangesort. Permutationsort and Bubblesort: - ~55.62% <- [1,2,3] (Correct) + ~71.33% <- Agree Correctly - ~0.69% <- [2,1,3] (Correct TopBit) + ~28.13% <- Disagree - ~0.69% <- [1,3,2] (Incorrect) + ~0.30% <- Agree Incorrectly - TopBit correct - ~0.08% <- [2,3,1] (Incorrect) + ~0.24% <- Agree Incorectly - TopBit incorrect Permutationsort and Exchangesort: - ~55.62% <- [1,2,3] (Correct) + ~75.18% <- Agree Correctly - ~0.69% <- [2,1,3] (Correct TopBit) + ~25.44% <- Disagree - ~0.08% <- [3,1,2] (Incorrect) + ~0.11% <- Agree Incorrectly - TopBit correct - ~0.08% <- [3,2,1] (Reverse) + ~0.16% <- Agree Incorectly - TopBit incorrect -As we can see, it is very unlikely that Permutationsort will agree with -either Bubblesort or Exchangesort incorrectly. It is even less likely -that they will do so when the TopBit is incorrect. However, there are many -cases in which they do not agree, so let's handle those. +If Permutationsort agrees with either Bubblesort or Exchangesort, then it's +easy - just use that result! -If there is no agreed-upon result between these three algorithms, we will look -at the top bit only. +According to these results, Permutationsort is likely to disagree with both +Bubblesort and Exchangesort about 7.16% of the time if all three are run +indepedently. In practice this will happen more often than that because in +order to reach the point of doing Permutationsort, either Bubblesort or +Exchangesort must have sorted the list incorrectly (which makes it less likely +to agree with Permutationsort). -First we check if the results from Bubblesort and Exchangesort agree on the -TopBit. This is because the chance is very unlikely -(0.18%) that they will agree on an incorrect TopBit. If they do agree, we use -the result from Bubblesort (as it will not return a reverse-sorted list). +In any case, if all three algorithms disagree, use the results from Bubblesort. -If they do not agree, we will check the TopBit results from Bubblesort and -Permutationsort. This is because it is unlikely -(~0.92%) that they will agree on an incorrect TopBit, and the chance of them -incorrectly agreeing on the highest Bit as the TopBit is even lower (~0.16%). -If they do agree, we use the result from Bubblesort. - -If they do not agree, we will check the TopBit results from Exchangesort -and Permutationsort. The chance that they will agree on an -incorrect TopBit is about 1.55%, with the chances of them incorrectly agreeing -on the highest Bit as the TopBit also around 0.16%. If they do agree, we use -the result from Exchangesort. - -If after all this adjudication we still do not have an agreed-upon result, we -will use the result from Bubblesort. - -Now obviously we have made some approximations in our analysis (and I may have -made some mistakes in my calculations), but in general I think we can conclude -that it is very unlikely that this Supersort process will return an incorrect -result, and that if an incorrect result is returned, it is very likely to still -have a correct TopBit. + We now have the basic form of Robustsort: a 3-bit Tensort with a Supersort adjudicating Bubblesort, Exchangesort, and Permutationsort as its From c621f250220adf06177c50a079538605962bc780 Mon Sep 17 00:00:00 2001 From: kaBeech Date: Wed, 14 Aug 2024 01:09:42 -0700 Subject: [PATCH 13/20] Add recursion info --- README.md | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index b564213..62f735b 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ There's likely a lot of room for improvement in the code as well. - [Introducing Supersort](#introducing-supersort) - [Permutationsort](#permutationsort) - [Supersort Adjudication](#supersort-adjudication) + - [Recursion](#recursion) - [Magicsort](#magicsort) - [Supersort adjudication with Magic](#supersort-adjudication-with-magic) - [A note on Robustsort and Bogosort](#a-note-on-robustsort-and-bogosort) @@ -625,16 +626,38 @@ to agree with Permutationsort). In any case, if all three algorithms disagree, use the results from Bubblesort. - +#### Recursion -We now have the basic form of Robustsort: a 3-bit Tensort with a Supersort -adjudicating Bubblesort, Exchangesort, and Permutationsort as its -SubAlgorithm. +I hear you out there. You're asking "But is the trade-off of not having +a logarithmic Bytesize worth the advantages that the 3-magic brings?" + +What if we could have the best of both worlds? With recursion, we can! + + + +Let's take our base Robustsort example above and make it recursive. + +First, instead of using a 3-bit Bytesize, we will use a logarithmic Bytesize. +Then, instead of using our Supersort directly as our +SubAlgorithm, we will use Robustsort itself to sort the records. + +At the base case, this Robustsort will have a Bytesize of 3. If the logarithmic +Bytesize of the input list is greater than 27, then the SubAlgorithm of the +top-level Robustsort will be a recursive Robustsort with a logarithmic +Bytesize. + +The number 27 is chosen because we want a number that has a natural log that is +close to 3 (27's is about 3.3) and since 3 ^ 3 = 27, it is easy to sort lists +of 27 elements in groups of 3. + +We now have the basic form of Robustsort: a recursive Tensort with a 3-bit +base case using a Supersort adjudicating Bubblesort, Exchangesort, and +Permutationsort as its base SubAlgorithm. Well that's pretty cool! But I wonder... can we make this more robust, if we relax the rules just a little more? - + Of course we can! And we will. To do so, we will simply replace Permutationsort with another newly-named sorting algorithm: Magicsort! From 76a4edc4c8265b66c592db4e8c1657c69ee0f053 Mon Sep 17 00:00:00 2001 From: kaBeech Date: Wed, 14 Aug 2024 09:31:11 -0700 Subject: [PATCH 14/20] Update Bogosort probability notes --- README.md | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 62f735b..828c6e9 100644 --- a/README.md +++ b/README.md @@ -667,7 +667,7 @@ with another newly-named sorting algorithm: Magicsort! For our most robust iteration of Robustsort we will relax the requirement on never re-running the same deterministic sub-algorithm in one specific context. Magicsort is an algorithm that will re-run Permutationsort only if it disagrees -with an extremely reliable algorithm algorithm - one that's so good it's robust +with an extremely reliable algorithm - one that's so good it's robust against logic itself... @@ -682,8 +682,30 @@ algorithms are run again. This process is repeated until the two algorithms agree on a result. Strong-brained readers may have already deduced that Permutationsort functions -nearly identically to Bogosort. Indeed, their approximate analysis results are -the same. Magicsort is based on the idea that if you happen to pull the right +nearly identically to Bogosort. Here are the results of runnitng Bogosort 1000 +times on Bytes of random permutations of [1,2,3] using a faulty comparator that +gives a random result 10% of the time: + + 81.3% <- [1,2,3] + + 3.0% <- [2,1,3] + + 3.8% <- [3,1,2] + + 5.8% <- [1,3,2] + + 5.7% <- [2,3,1] + + 0.8% <- [3,2,1] + +In these cases, 84.3% of the time the Top Bit was in the correct position. +Note that even though both Bogosort and Permutationsort were ran with the same +random seeds, they gave slightly different results because their methodology +is slightly different the least likely outcome is a reverse-sorted Byte and the other +possible incorrect outcomes are in approximately even distribution with +each other. + +Magicsort is based on the notion that if you happen to pull the right answer out of a hat once, it might be random chance, but if you do it twice, it might just be magic! @@ -707,8 +729,9 @@ The downside here is that Magisort can take a long time to run. I don't know how many comparisons are made on average, but it's well over 14. Thankfully, Magicsort will only be run in our algorithm if Bubblesort and -Exchangesort disagree on an answer. Overall the Robustsort we're building that -uses Magicsort will still have an average of O(n log n) time efficiency. +Exchangesort disagree on an answer, and then only with 3 elements to sort. +Overall, the Robustsort we're building that uses Magicsort will still have an +average of O(n log n) time efficiency. #### Supersort adjudication with Magic From e889dc2df9d6b2da914838e49345bfd71d570d8e Mon Sep 17 00:00:00 2001 From: kaBeech Date: Wed, 14 Aug 2024 10:02:32 -0700 Subject: [PATCH 15/20] Update Magicsort probability notes --- README.md | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 828c6e9..01aa7bf 100644 --- a/README.md +++ b/README.md @@ -491,7 +491,7 @@ Exchangesort will also make an average of 6 comparisons when sorting a -Here are the results of runnitng Exchangesort 1000 times on Bytes of random +Here are the results of running Exchangesort 1000 times on Bytes of random permutations of [1,2,3] using a faulty comparator that gives a random result 10% of the time: @@ -507,7 +507,7 @@ permutations of [1,2,3] using a faulty comparator that gives a random result 2.1% <- [3,2,1] -In these results, 94,3% of the time the Top Bit was returned in the correct +In these results, 94.3% of the time the Top Bit was returned in the correct position and it returned the bottom value in the top position only 2.1% of the time. @@ -562,7 +562,7 @@ B) it uses logic that is completely different from Bubblesort and Exchangesort. Using different manners of reasoning to reach an agreed-upon answer greatly increases the robustness of the system. -Here are the results of runnitng Permutationsort 1000 times on Bytes of random +Here are the results of running Permutationsort 1000 times on Bytes of random permutations of [1,2,3] using a faulty comparator that gives a random result 10% of the time: @@ -682,7 +682,7 @@ algorithms are run again. This process is repeated until the two algorithms agree on a result. Strong-brained readers may have already deduced that Permutationsort functions -nearly identically to Bogosort. Here are the results of runnitng Bogosort 1000 +nearly identically to Bogosort. Here are the results of running Bogosort 1000 times on Bytes of random permutations of [1,2,3] using a faulty comparator that gives a random result 10% of the time: @@ -709,21 +709,25 @@ Magicsort is based on the notion that if you happen to pull the right answer out of a hat once, it might be random chance, but if you do it twice, it might just be magic! -Given a Byte of [1,2,3], here are the approximate chances of various outcomes -from Magicsort using a faulty comparator that gives a random result 10% of the -time: +Here are the results of running Magicsort 1000 +times on Bytes of random permutations of [1,2,3] using a faulty comparator that +gives a random result 10% of the time: + + ~94.0% <- [1,2,3] (Correct) - ~95.27% <- [1,2,3] (Correct) + ~1.5% <- [2,1,3] (Correct TopBit) - ~1.18% <- [2,1,3] (Correct TopBit) + ~1.4% <- [1,3,2] (Incorrect) - ~1.18% <- [1,3,2] (Incorrect) + ~1.5% <- [3,1,2] (Incorrect) - ~1.18% <- [3,1,2] (Incorrect) + ~1.5% <- [2,3,1] (Incorrect) - ~1.18% <- [2,3,1] (Incorrect) + ~0.1% <- [3,2,1] (Reverse) - ~0.02% <- [3,2,1] (Reverse) +94% of the time we got the absolutely correct answer! In total, 95.5% of the +time we got the Top Bit in the correct position and only 1.6% of the time did +we get the bottom value in the top position. The downside here is that Magisort can take a long time to run. I don't know how many comparisons are made on average, but it's well over 14. From fb09dfb21098715c3ebcc705be77adbfd7e43f81 Mon Sep 17 00:00:00 2001 From: kaBeech Date: Wed, 14 Aug 2024 10:35:10 -0700 Subject: [PATCH 16/20] Update Magic SuperStrat notes --- README.md | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 01aa7bf..c1e52b1 100644 --- a/README.md +++ b/README.md @@ -733,36 +733,42 @@ The downside here is that Magisort can take a long time to run. I don't know how many comparisons are made on average, but it's well over 14. Thankfully, Magicsort will only be run in our algorithm if Bubblesort and -Exchangesort disagree on an answer, and then only with 3 elements to sort. -Overall, the Robustsort we're building that uses Magicsort will still have an +Exchangesort disagree on an answer, and then only with 3 elements to sort. +Overall, the Robustsort we're building that uses Magicsort will still have an average of O(n log n) time efficiency. #### Supersort adjudication with Magic -Since we have replaced Permutationsort with Magicsort (which is far more robust +Since we have replaced Permutationsort with Magicsort (which is far more robust than Bubblesort or Exchangesort), we will adjust our adjudication within the Supersort SubAlgorithm. -If Bubblesort and Exchangesort disagree, we will run Magicsort on the -input. If Magicsort agrees with either Bubblesort or Exchangesort, we -will use the result from Magicsort. Otherwise, if Magicsort agrees on the -TopBit with either Bubblesort or Exchangesort, we will use the result -from Magicsort. Otherwise, if Bubblesort and Exchangesort agree on the -TopBit, we will use the result from Bubblesort. +If Bubblesort and Exchangesort disagree, instead of running Magicsort right +away, we check to see if they agree on the Top Bit. If they do, we run +Magicsort on the input and use the results from that. -If no agreement is reached at this point, we abandon all logic and just use -Magicsort. +The reason we check to see if Bubblesort and Exchangesort agree on the Top Bit +is that based on our results, there is only about a 0.07% chance that they will +agree on the incorrect Top Bit while disagreeing on the total results. This is +due to the fact that these algorithms have only one result with a incorrect +Top Bit ([1,3,2]) that they both return more than 1% of the time, so one of +them has to return a rare result for this peculiar semi-agreement to occur. + +The reason that we don't check to see whether Magicsort agrees with any of the +other algorithms is that we would end up using the results from Magicsort in +all pass cases and fail cases. ### A note on Robustsort and Bogosort -It is perfectly valid to use Bogosort in place of Permutationsort in Robustsort's -standard Supersort SubAlgorithm. It may be argued that doing so is even more -robust, since it barely even relies on logic. Here are some considerations to +It is perfectly valid to use Bogosort in place of Permutationsort in +Robustsort's standard Supersort SubAlgorithm. It may be argued that doing so is +even more robust, since it barely even relies on logic. Here are some +considerations to keep in mind: - - Permutationsort uses additional space and may take slightly longer on average - due to computing all possible permutations of the input and storing them in a - list. + - Permutationsort uses additional space and may take slightly longer on + average due to computing all possible permutations of the input and + storing them in a list. - Bogosort could theoretically run forever without returning a result, even when no errors occur. From af756395ab15b2de0b20f66c33c9075b73ebc7c4 Mon Sep 17 00:00:00 2001 From: kaBeech Date: Wed, 14 Aug 2024 12:38:16 -0700 Subject: [PATCH 17/20] Update SuperStrat info --- README.md | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index c1e52b1..1201611 100644 --- a/README.md +++ b/README.md @@ -539,11 +539,27 @@ approximate the chances of how often they will agree in similar conditions: ~0.14% <- Agree Incorectly - TopBit incorrect -Hey, that's pretty good! One thing that stands out is that around 20% of the -time, these sub-algorithms will disagree with each other. What happens then? +Hey, that's pretty good! If they agree, then return the results from +Bubblesort because if for some reason the module that compares the full Bytes +is also faulty (outside the scope of these benchmarks), Bubblesort is less +likely to have a result with the bottom value set as the Top Bit. -Well, in that case we run a third sub-algorithm to compare the results with: -Permutationsort. +Around 20% of the time, these sub-algorithms will disagree with each other. +What happens then? + +First we check to see if they agree on the Top Bit. If they do, we return the +results from Exchangesort, since it is more likely to have the results exactly +correct. Otherwise, we run a third sub-algorithm to compare the results with. + +The reason we check to see if Bubblesort and Exchangesort agree on the Top Bit +is that based on our results, there is only about a 0.07% chance that they will +agree on the incorrect Top Bit while disagreeing on the total results. This is +due to the fact that these algorithms have only one result with a incorrect +Top Bit ([1,3,2]) that they both return more than 1% of the time, so one of +them has to return a rare result for this peculiar semi-agreement to occur. + +If the first two sub-algorithms don't agree on a Top Bit then we run our third +sub-algorithm: Permutationsort. #### Permutationsort @@ -741,22 +757,13 @@ average of O(n log n) time efficiency. Since we have replaced Permutationsort with Magicsort (which is far more robust than Bubblesort or Exchangesort), we will adjust our adjudication -within the Supersort SubAlgorithm. - -If Bubblesort and Exchangesort disagree, instead of running Magicsort right -away, we check to see if they agree on the Top Bit. If they do, we run -Magicsort on the input and use the results from that. - -The reason we check to see if Bubblesort and Exchangesort agree on the Top Bit -is that based on our results, there is only about a 0.07% chance that they will -agree on the incorrect Top Bit while disagreeing on the total results. This is -due to the fact that these algorithms have only one result with a incorrect -Top Bit ([1,3,2]) that they both return more than 1% of the time, so one of -them has to return a rare result for this peculiar semi-agreement to occur. +within the Supersort SubAlgorithm. If Bubblesort and Exchangesort don't come +to an agreement, we just use Magicsort. -The reason that we don't check to see whether Magicsort agrees with any of the -other algorithms is that we would end up using the results from Magicsort in -all pass cases and fail cases. +You might expect that we'd check to see whether Magicsort agrees with any of +the other algorithms before just using its results, but even if we were to +check we would end up using the results from Magicsort in all pass cases and +all fail cases. ### A note on Robustsort and Bogosort From da15a4f8cdcc8eea023147f16aaca592996bc278 Mon Sep 17 00:00:00 2001 From: kaBeech Date: Wed, 14 Aug 2024 12:43:26 -0700 Subject: [PATCH 18/20] Add library notes --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 1201611..9aa740a 100644 --- a/README.md +++ b/README.md @@ -806,6 +806,10 @@ Notably, it provides the following: - Magic Robustsort +In the 1.0.0.0 release there will also be a wrapper around top-level +Tensort (Logarithmic) and Robustsort (Magic) that will allow for easy +use without dealing with Type conversions. + Check the code in `src/` or the documentation on Hackage/Hoogle for more details. From 14cb7694597baf9a026fe4e9f7dc02d0dc4d7a91 Mon Sep 17 00:00:00 2001 From: kaBeech Date: Wed, 14 Aug 2024 12:56:12 -0700 Subject: [PATCH 19/20] Adjust recursion intro --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9aa740a..040662b 100644 --- a/README.md +++ b/README.md @@ -644,10 +644,9 @@ In any case, if all three algorithms disagree, use the results from Bubblesort. #### Recursion -I hear you out there. You're asking "But is the trade-off of not having -a logarithmic Bytesize worth the advantages that the 3-magic brings?" - -What if we could have the best of both worlds? With recursion, we can! +You'll remember that our standard Tensort uses a logarithmic Bytesize. Our base +Robustsort uses a Bytesize of 3, but we can use a logarithmic Bytesize by +adding recursion. From 4911492203ec3027028676ee48004774de50c0d2 Mon Sep 17 00:00:00 2001 From: kaBeech Date: Thu, 15 Aug 2024 02:17:02 -0700 Subject: [PATCH 20/20] Add more recursion info --- README.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 040662b..e9a48b4 100644 --- a/README.md +++ b/README.md @@ -377,9 +377,9 @@ With those ground rules in place, let's get to Robustsort! #### Overview Once we have Tensort in our toolbox, the road to Robustsort is not long. -Robustsort is a recursive version of Tensort, so first we'll look at its base -case, a 3-bit Tensort with a custom SubAlgorithm that compares other -sub-algorithms. For convenience, we will call this custom SubAlgorithm +Robustsort is a potentially recursive version of Tensort, but first we'll look +at the basic variant: a 3-bit Tensort with a custom SubAlgorithm that compares +other sub-algorithms. For convenience, we will call this custom SubAlgorithm Supersort. We use a 3-bit Tensort here because there's something magical that happens around the number 3. @@ -665,9 +665,14 @@ The number 27 is chosen because we want a number that has a natural log that is close to 3 (27's is about 3.3) and since 3 ^ 3 = 27, it is easy to sort lists of 27 elements in groups of 3. -We now have the basic form of Robustsort: a recursive Tensort with a 3-bit -base case using a Supersort adjudicating Bubblesort, Exchangesort, and -Permutationsort as its base SubAlgorithm. +This recursive version of Robustsort is more tailored to large input lists +(it doesn't add another layer of recursion until the input list is +is longer than 500 billion elements), but differences can be noticed when +sorting smaller lists as well. + +We now have the standard form of Robustsort: a potentially recursive Tensort +with a 3-bit base case using a Supersort adjudicating Bubblesort, Exchangesort, +and Permutationsort as its base SubAlgorithm. Well that's pretty cool! But I wonder... can we make this more robust, if we relax the rules just a little more?