i made a list sort abstraction that seems to be faster and more stable (at least for long lists) than the list-abs abstraction. at the moment it only sorts lists with numbers (thought about how to sort symbols too). the abstraction from list-abs is on the right side of the patch for comparison: vListSort.pd
-
new vanilla list sort
-
@Jona Funny, as there was a question in the FB-Group regarding list sorting, i build another sorting abstraction that looks a lot like the one you did. Instead of breaking the list apart to eliminate the found element, i just set it to higher than maximum if the minimum is searched for, and the other way around: vsort.zip
But more interestingly, i took a look at [list-sort] in the list-abs collection and found that they amazingly used a seemingly otherwise undocumented sort function of data structures. They just write the data to a subpatch and send a [sort( message to it. I tried to find it in the source code, but was not lucky.
-
@ingox If you are looking for source code for any old extended externals they are all in https://sourceforge.net/projects/pure-data/files/pd-extended/0.43.4/Pd-extended_0.43.4-source.tar.bz2/download
Worth grabbing a copy while it remains available.
All the "makefile"s are included.
Useful for compiling externals for 64-bit (when they work).I have seen the sort message almost hidden in a subpatch in 12-tut.pd in a tutorial on scalars here...... https://puredata.info/community/projects/convention04/lectures/tk-barknecht/tut.tgz
and it is mentioned (again... sort of.... with no explanation of the message call) as a function in Chapter 2.9.1 here...... http://puredata.info/docs/manuals/pd/x2.htm
and so it is also in Pd's \doc\1.manual\x2.htmZexy sort below. But it looks like the canvas sort is in g.graph.c.
There is an "if scalar sort" statement in there.
However g.graph.c has been disappeared from 0.49...... so......?
David.
.... sort.c.... (zexy)In/* * sort : sort a list of floats * * (c) 1999-2011 IOhannes m zmölnig, forum::für::umläute, institute of electronic music and acoustics (iem) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "zexy.h" /* ------------------------- sort ------------------------------- */ /* SHELL SORT: simple and easy */ static t_class *sort_class; typedef struct _sort { t_object x_obj; int bufsize; t_float *buffer; t_int *indices; int ascending; t_outlet*indexOut, *sortedOut; } t_sort; static void sort_dir(t_sort *x, t_float f) { x->ascending = (f < 0.f)?0:1; } static void sort_buffer(t_sort *x, int argc, t_atom *argv) { int n = argc; t_float *buf; t_atom *atombuf = argv; if (argc != x->bufsize) { if (x->buffer) freebytes(x->buffer, x->bufsize * sizeof(t_float)); if (x->indices)freebytes(x->indices, x->bufsize * sizeof(t_int)); x->bufsize = argc; x->buffer = getbytes(x->bufsize * sizeof(t_float)); x->indices = getbytes(x->bufsize * sizeof(t_int)); } buf = x->buffer; while (n--){ *buf++ = atom_getfloat(atombuf++); x->indices[n] = n; } } static void sort_list(t_sort *x, t_symbol *s, int argc, t_atom *argv) { int step = argc, n; t_atom *atombuf = (t_atom *)getbytes(sizeof(t_atom) * argc); t_float *buf; t_int *idx; int i, loops = 1; sort_buffer(x, argc, argv); buf = x->buffer; idx = x->indices; while (step > 1) { step = (step % 2)?(step+1)/2:step/2; i = loops; loops += 2; while(i--) { /* there might be some optimization in here */ for (n=0; n<(argc-step); n++) { if (buf[n] > buf[n+step]) { t_int i_tmp = idx[n]; t_float f_tmp = buf[n]; buf[n] = buf[n+step]; buf[n+step] = f_tmp; idx[n] = idx[n+step]; idx[n+step] = i_tmp; } } } } if (x->ascending) for (n = 0; n < argc; n++) SETFLOAT(&atombuf[n], idx[n]); else for (n = 0, i=argc-1; n < argc; n++, i--) SETFLOAT(&atombuf[n], idx[i]); outlet_list(x->indexOut , gensym("list"), n, atombuf); if (x->ascending) for (n = 0; n < argc; n++) SETFLOAT(&atombuf[n], buf[n]); else for (n = 0, i=argc-1; n < argc; n++, i--) SETFLOAT(&atombuf[n], buf[i]); outlet_list(x->sortedOut, gensym("list"), n, atombuf); freebytes(atombuf, argc*sizeof(t_atom)); } static void *sort_new(t_floatarg f) { t_sort *x = (t_sort *)pd_new(sort_class); x->ascending = (f < 0.f)?0:1; x->sortedOut=outlet_new(&x->x_obj, gensym("list")); x->indexOut=outlet_new(&x->x_obj, gensym("list")); x->bufsize = 0; x->buffer = NULL; inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("direction")); return (x); } static void sort_help(t_sort*x) { post("\n%c sort\t\t:: sort a list of numbers", HEARTSYMBOL); } void sort_setup(void) { sort_class = class_new(gensym("sort"), (t_newmethod)sort_new, 0, sizeof(t_sort), 0, A_DEFFLOAT, 0); class_addlist (sort_class, sort_list); class_addmethod (sort_class, (t_method)sort_dir, gensym("direction"), A_DEFFLOAT, 0); class_addmethod(sort_class, (t_method)sort_help, gensym("help"), A_NULL); zexy_register("sort"); } `
-
@whale-av Yes, thank you! But i was talking about [list-sort] from list-abs, which in itself is vanilla. [list-sort] seems to use a hidden feature of data structures by just sending [sort( to the data subpatch. If this is the case, it would be remarkable in my opinion.
-
@whale-av Ah, you updated your post, i still had it open from yesterday. Great find, that it is actually somehow documented! Thanks again!
-
@ingox thats funny and interesting. i think i saw the data structure sort documentation once, but never in use. nice way to use it with list sort i have to admit that i was using the old extended list-abs library until now (with a different list-sort).
the "new" list sort abstraction is already much better (and faster than my attempt).
on the right side of this patch i still tried to optimize the abstraction, on the left is the original (with the newer list-abs library installed):
struct_list_sort.pd