World: r3wp
[Core] Discuss core issues
older newer | first last |
BrianH 10-Dec-2010 [753] | Same here - a C function pointer. |
Andreas 10-Dec-2010 [754x4] | Then I don't understand your EQUAL?/SAME? remark. |
If two elements are EQUAL?, fall back to comparing their addresses in memory. | |
Won't work for linked lists, will work for arrays stored consecutively. | |
Sorry, missed that. Yes, qsort takes a callback used for comparison. Here's the decl: void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*)); | |
BrianH 10-Dec-2010 [758] | Sorry, I just got that you were talking about using <= instead of <. |
Andreas 10-Dec-2010 [759x2] | My remark above was to the effect: if two elements are EQUAL? compare their INDEX? instead. This may sound ridiculous in context of REBOL's SORT, but it is no problem in C. |
As the comparison callback gets pointers to the elements anyway. | |
BrianH 10-Dec-2010 [761] | I still think that you need to write this stuff in a ticket comment. Writing it here will have no effect - the ticket is where the real discussion happens, and I don't seem to understand your argument well enough in this case to paraphrase you there. |
Andreas 10-Dec-2010 [762] | I'm writing already. |
BrianH 10-Dec-2010 [763] | All :) intended, of course. |
Andreas 10-Dec-2010 [764] | In any case, I find this channel more fruitful for interactive discussion. |
BrianH 10-Dec-2010 [765] | True. But Carl won't see it. |
Sunanda 10-Dec-2010 [766] | BrianH <And not well enough documented either. I don't really know how /compare works, not completely.> Comparators and the stable-sort trick (-1, 0 +1) are documented here in an old change log. It never made it into the dictionary for SORT: http://www.rebol.com/docs/changes-2-5.html#section-72 |
BrianH 10-Dec-2010 [767x2] | Documentation request referencing that link added here: http://curecode.org/rebol3/ticket.rsp?id=1793 |
Thanks :) | |
Ladislav 11-Dec-2010 [769] | Re -1 0 1 - as far as I remember, I read somewhere about negative, 0, positive? |
BrianH 11-Dec-2010 [770] | That works too: >> sort/compare [20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1] func [x y] [case [x < y [3] x = y [0] 'else [-4]]] == [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20] |
Gabriele 11-Dec-2010 [771x2] | Are we talking R2's sort or R3's sort here? I know for a fact that R2's sort is stable. Obviously you can't get a stable sort if you use a comparator function and you return a logic! value. |
Also, the current "best" algorithm appears to be http://en.wikipedia.org/wiki/Timsort | |
Steeve 11-Dec-2010 [773] | We must focus on algos which are doing the fewer comarisons and are fast with data almost sorted (it's our common case). in that sense, Timsort would be a good choice because it's unsing a combination of merge sort + insertion sort merge sort = fewer comparisons. insertion sort = the faster one on data already sorted and small subsets of data |
Maxim 12-Dec-2010 [774] | yes looks pretty decent... a nice wrap up here: http://corte.si/posts/code/timsort/index.html |
Ladislav 13-Dec-2010 [775] | http://www.rebol.org/ml-display-message.r?m=rmlVPRF |
Steeve 14-Dec-2010 [776x3] | Funny, I've coded "bottom-up heapsort" last night (improved version of heapsort). I give the "clean" version. |
heapify: func [s start len comp /local child sav][ ;-- search terminal leaf. child: start while [2 * child < len][ child: 2 * child unless (comp s/(++ child) s/:child) [-- child] ] if 2 * child = len [child: len] ;-- bottom-up, search insertion point while [comp s/:child s/:start][child: shift child -1] ;-- bottom-up swap sav: s/:start while [child > start][ s/:child: also sav sav: s/:child child: shift child -1 ] s/:child: sav ] heapsort: func [serie comp /local len][ len: length? serie ;-- build heap for i shift len -1 1 -1 [heapify serie i len :comp] ;-- sort for i len 1 -1 [ swap serie at serie i heapify serie 1 i - 1 :comp ] serie ] | |
>> heapsort serie func [a b][a < b] | |
Ladislav 14-Dec-2010 [779x2] | Is it stable, Steeve? |
>> heapsort [5 1 2 4] :lesser? == [1 2 4 5] , while >> heapsort [5 1 2 4] :lesser-or-equal? ** Script error: cannot compare none! with integer! ** Where: comp while heapify for heapsort ** Near: comp s/:child s/:start , is that intended? | |
GrahamC 14-Dec-2010 [781] | Mindblock a: "testing" foreach v [ a ] [ .... ] in .. .how to test if v is an empty? string? |
Ladislav 14-Dec-2010 [782] | don't you mean: foreach v reduce [a] [if all [string? :v empty? :v] [...]...] |
GrahamC 14-Dec-2010 [783] | I didn't want to reduce first as then I can't report which one is empty? |
Ladislav 14-Dec-2010 [784] | I do not understand |
GrahamC 14-Dec-2010 [785x2] | say I have a: "testing" b: "" how would I say .. variable b is empty? |
If I reduce the block of words first, then I no longer know which word is empty | |
Ladislav 14-Dec-2010 [787] | if you have foreach v [a] [...] , then v is a word, not a string, so, in case you really mean it, you need something like: if all [string? get v empty? get v] |
GrahamC 14-Dec-2010 [788x2] | sounds right |
thanks | |
Steeve 14-Dec-2010 [790x4] | Ladislav, I corrected the issue with :less-or-equal? And made some optimizations (I hope so). On large serie |
heapify: func [s start len comp /local step sav inc][ inc: 0 ;-- search terminal leaf. step: start while [2 * step < len][ ++ inc step: 2 * step unless (comp s/(++ step) s/:step) [-- step] ] if 2 * step = len [++ inc step: len] ;-- bottom-up, search insertion point loop inc [ unless (comp s/:step s/:start) [break] step: shift step -1 -- inc ] ;-- bottom-up swap switch/default inc [ 1 [swap at s start at s step] ;-- single swap 0 [] ;-- no swap ][ sav: s/:start ;-- chain swap loop inc [ s/:step: also sav sav: s/:step step: shift step -1 ] s/:step: sav ] ] heapsort: func [serie comp /local len][ len: length? serie ;-- build heap for i shift len -1 1 -1 [heapify serie i len :comp] ;-- sort for i len 1 -1 [ swap serie at serie i heapify serie 1 i - 1 :comp ] serie ] | |
s: make block! len: 1000 loop len [append s random len] s2: copy s n: 0 heapsort s func [a b][++ n a < b] print ["bottom-up heapsort, number of comparisons =" n] n: 0 sort/compare s2 func [a b][++ n a < b] print ["Rebol sort (R3 + Vista), number of comparisons =" n] | |
bottom-up heapsort, number of comparisons = 10301 Rebol sort (R3 + Vista), number of comparisons = 12726 | |
Ladislav 14-Dec-2010 [794x4] | Steeve, my measurements suggest, that your previous version was a bit faster (is it caused by the fact, that you have to provide also for :lesser-or-equal? |
My result: random/seed 0 s: make block! len: 1000 loop len [append s random len] n: 0 heapsort copy s func [a b][++ n a < b] print ["bottom-up heapsort, number of comparisons =" n] n: 0 sort/compare copy s func [a b][++ n a < b] print ["Rebol sort (R3 + Windows 7 Home Premium), number of comparisons =" n] n: 0 msort copy s func [a b][++ n a < b] print ["Merge sort, number of comparisons =" n] | |
bottom-up heapsort, number of comparisons = 10406 Rebol sort (R3 + Windows 7 Home Premium), number of comparisons = 12726 Merge sort, number of comparisons = 8715 | |
BTW, the "information-theoretical limit" of comparisons is: 8530 | |
Steeve 14-Dec-2010 [798x2] | I should have a look on your merge implementation. It's said that "merging" merge with insertion sort give better results |
but as it is now, you got pretty nice results | |
Ladislav 14-Dec-2010 [800x2] | merging merge with insertion sort give better results - actually, it depends; "merging merge with insertion sort" gives worse results from the information-theoretical POV (IMO), since you "prefer certain permutations" (= give them higher probability) |
Thus, you can sort certain permutations (the ones already sorted) much faster, than is the "information theoretical limit", but at the cost of exceeding it noticeably sorting other permutations. | |
Steeve 15-Dec-2010 [802] | Searching for an optimal (small and fast) implementation of the following pattern. * Swap two subsets inside a serie. input block: [4 5 6 1 2] (5 values) Starting index of the 2nd subset inside the block: 4 Output: [ 1 2 4 5 6] Easy to do in plain Rebol right ? But here's the trouble, It must be memory safe. You're not allowed to do any memory allocation. You're can only swap values inside the block. And the number of swaps should be optimal. (no sort, no parse, no copy/make/insert/append/change) |
older newer | first last |