From 208200ef713d588a1cb5c4d125b2bfccc9a7e2ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?IOhannes=20m=20zm=C3=B6lnig?= Date: Mon, 19 Sep 2005 14:47:50 +0000 Subject: added a bunch of new objects (from f.zotter); some of them are unstable, some are likely to change in their behaviour (read: not yet for use) svn path=/trunk/externals/iem/iemmatrix/; revision=3598 --- src/mtx_sort.c | 325 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 325 insertions(+) create mode 100644 src/mtx_sort.c (limited to 'src/mtx_sort.c') diff --git a/src/mtx_sort.c b/src/mtx_sort.c new file mode 100644 index 0000000..fb47ed6 --- /dev/null +++ b/src/mtx_sort.c @@ -0,0 +1,325 @@ +/* + * iemmatrix + * + * objects for manipulating simple matrices + * mostly refering to matlab/octave matrix functions + * + * Copyright (c) 2005, Franz Zotter + * IEM, Graz, Austria + * + * For information on usage and redistribution, and for a DISCLAIMER OF ALL + * WARRANTIES, see the file, "LICENSE.txt," in this distribution. + * + */ + +#include "iemmatrix.h" + +static t_class *mtx_sort_class; + +typedef struct _MTXSort_ MTXSort; +struct _MTXSort_ +{ + t_object x_obj; + int rows; + int columns; + int size; + int sort_dimension; + int sort_direction; + + t_outlet *list_outlet1; + t_outlet *list_outlet2; + + t_atom *list_out1; + t_atom *list_out2; + t_atom *list_in; + t_float *x; +// t_float *y; + t_float *i; +}; + +static void deleteMTXSort (MTXSort *mtx_sort_obj) +{ + if (mtx_sort_obj->list_out1) + freebytes (mtx_sort_obj->list_out1, sizeof(t_atom)*(mtx_sort_obj->size+2)); + if (mtx_sort_obj->list_out2) + freebytes (mtx_sort_obj->list_out2, sizeof(t_atom)*(mtx_sort_obj->size+2)); + if (mtx_sort_obj->x) + freebytes (mtx_sort_obj->x, sizeof(t_float)*(mtx_sort_obj->size)); + //if (mtx_sort_obj->y) + // freebytes (mtx_sort_obj->y, sizeof(t_float)*(mtx_sort_obj->size)); + if (mtx_sort_obj->i) + freebytes (mtx_sort_obj->i, sizeof(t_float)*(mtx_sort_obj->size)); +} + +static void mTXSetSortDirection (MTXSort *mtx_sort_obj, t_float s_dir) +{ + int direction = (int) s_dir; + mtx_sort_obj->sort_direction = (direction==-1)?direction:1; +} +static void mTXSetSortDimension (MTXSort *mtx_sort_obj, t_float s_dim) +{ + int dimension = (int) s_dim; + dimension = (dimension<2)?dimension:2; + dimension = (dimension>0)?dimension:0; + mtx_sort_obj->sort_dimension = dimension; +} + +static void *newMTXSort (t_symbol *s, int argc, t_atom *argv) +{ + MTXSort *mtx_sort_obj = (MTXSort *) pd_new (mtx_sort_class); + int c_dir = 1; + int c_dim = 1; + + mtx_sort_obj->sort_dimension = c_dim; + switch ((argc>2)?2:argc) { + case 2: + c_dir = atom_getint(argv+1); + case 1: + c_dim = atom_getint(argv); + } + mTXSetSortDirection (mtx_sort_obj, (t_float) c_dir); + mTXSetSortDimension (mtx_sort_obj, (t_float) c_dim); + + mtx_sort_obj->list_outlet1 = outlet_new (&mtx_sort_obj->x_obj, gensym("matrix")); + mtx_sort_obj->list_outlet2 = outlet_new (&mtx_sort_obj->x_obj, gensym("matrix")); + return ((void *) mtx_sort_obj); +} + +static void mTXSortBang (MTXSort *mtx_sort_obj) +{ + if (mtx_sort_obj->list_out1) + outlet_anything(mtx_sort_obj->list_outlet1, gensym("matrix"), + mtx_sort_obj->size+2, mtx_sort_obj->list_out1); + if (mtx_sort_obj->list_out2) + outlet_anything(mtx_sort_obj->list_outlet2, gensym("matrix"), + mtx_sort_obj->size+2, mtx_sort_obj->list_out2); +} + +static void writeFloatIntoList (int n, t_atom *l, t_float *f) +{ + for (;n--;f++, l++) + SETFLOAT (l, *f); +} +static void readFloatFromList (int n, t_atom *l, t_float *f) +{ + while (n--) + *f++ = atom_getfloat (l++); +} +static void readFloatFromListModulo (int n, int m, t_atom *l, t_float *f) +{ + t_atom *ptr = l; + int count1, count2; + n /= m; + count1 = m; + while (count1--) + for (count2 = n, ptr = l++; count2--; ptr += m, f++) + *f = atom_getfloat (ptr); +} +static void writeFloatIntoListModulo (int n, int m, t_atom *l, t_float *f) +{ + t_atom *ptr = l; + int count1, count2; + n /= m; + count1 = m; + while (count1--) + for (count2 = n, ptr = l++; count2--; ptr += m, f++) + SETFLOAT(ptr,*f); +} +static void sortVector (int n, t_float *x, t_float *i, int direction) +{ + int step = n; + int size = n; + int k, loops = 1; + int i_tmp; + t_float x_tmp; + + switch (direction) { + case -1: + while (step > 1) { + step = (step % 2)?(step+1)/2:step/2; + k = loops; + loops += 2; + while(k--) { /* there might be some optimization in here */ + for (n=0; n<(size-step); n++) + if (x[n] < x[n+step]) { + i_tmp = i[n]; + x_tmp = x[n]; + x[n] = x[n+step]; + x[n+step] = x_tmp; + i[n] = i[n+step]; + i[n+step] = i_tmp; + } + } + } + break; + default: + case 1: + while (step > 1) { + step = (step % 2)?(step+1)/2:step/2; + k = loops; + loops += 2; + while(k--) { /* there might be some optimization in here */ + for (n=0; n<(size-step); n++) + if (x[n] > x[n+step]) { + i_tmp = i[n]; + x_tmp = x[n]; + x[n] = x[n+step]; + x[n+step] = x_tmp; + i[n] = i[n+step]; + i[n+step] = i_tmp; + } + } + } + } +} + +static void indexingVector (int n, int m, int dimension, t_float *i) +{ + int count; + int count2; + int idx = n; + t_float *ptr; + i += n; + switch (dimension) { + case 2: + n /= m; + for (count = m; count--;) { + ptr = --i; + for (count2 = n; count2--; ptr -= m) + *ptr = idx--; + } + break; + default: + case 1: + for (; idx;) + *--i = idx--; + } +} + +static void mTXSortMatrix (MTXSort *mtx_sort_obj, t_symbol *s, + int argc, t_atom *argv) +{ + int rows = atom_getint (argv++); + int columns = atom_getint (argv++); + int size = rows * columns; + int list_size = argc - 2; + t_atom *list_ptr = argv; + t_atom *list_out1 = mtx_sort_obj->list_out1; + t_atom *list_out2 = mtx_sort_obj->list_out2; + t_float *x = mtx_sort_obj->x; + //t_float *y = mtx_sort_obj->y; + t_float *i = mtx_sort_obj->i; + int count; + + // size check + if (!size) { + post("mtx_sort: invalid dimensions"); + return; + } + else if (list_sizesize) { + x = (t_float *) resizebytes (x, + sizeof (t_float) * (mtx_sort_obj->size), + sizeof (t_float) * (size)); + //y = (t_float *) resizebytes (y, + // sizeof (t_float) * (mtx_sort_obj->size), + // sizeof (t_float) * (size)); + i = (t_float *) resizebytes (i, + sizeof (t_float) * (mtx_sort_obj->size), + sizeof (t_float) * (size)); + list_out1 = (t_atom *) resizebytes (list_out1, + sizeof (t_atom) * (mtx_sort_obj->size+2), + sizeof (t_atom) * (size + 2)); + list_out2 = (t_atom *) resizebytes (list_out2, + sizeof (t_atom) * (mtx_sort_obj->size+2), + sizeof (t_atom) * (size + 2)); + } + + mtx_sort_obj->list_out1 = list_out1; + mtx_sort_obj->list_out2 = list_out2; + mtx_sort_obj->x = x; + // mtx_sort_obj->y = y; + mtx_sort_obj->i = i; + mtx_sort_obj->size = size; + mtx_sort_obj->rows = rows; + mtx_sort_obj->columns = columns; + + // generating indexing vector + indexingVector (size, columns, mtx_sort_obj->sort_dimension, i); + + // main part + // reading matrix from inlet + if (mtx_sort_obj->sort_dimension == 2) { + readFloatFromListModulo (size, columns, list_ptr, x); + columns = mtx_sort_obj->rows; + rows = mtx_sort_obj->columns; + } + else + readFloatFromList (size, list_ptr, x); + + // calculating sort + if (mtx_sort_obj->sort_dimension == 0) + sortVector (size,x,i,mtx_sort_obj->sort_direction); + else + for (count = rows; count--;x+=columns,i+=columns) + sortVector (columns,x,i,mtx_sort_obj->sort_direction); + x = mtx_sort_obj->x; + i = mtx_sort_obj->i; + + // writing matrix to outlet + if (mtx_sort_obj->sort_dimension == 2) { + columns = mtx_sort_obj->columns; + rows = mtx_sort_obj->rows; + writeFloatIntoListModulo (size, columns, list_out1+2, x); + writeFloatIntoListModulo (size, columns, list_out2+2, i); + } + else { + writeFloatIntoList (size, list_out1+2, x); + writeFloatIntoList (size, list_out2+2, i); + } + + SETSYMBOL(list_out1, gensym("matrix")); + SETFLOAT(list_out1, rows); + SETFLOAT(&list_out1[1], columns); + outlet_anything(mtx_sort_obj->list_outlet1, gensym("matrix"), + mtx_sort_obj->size+2, list_out1); + SETSYMBOL(list_out2, gensym("matrix")); + SETFLOAT(list_out2, rows); + SETFLOAT(&list_out2[1], columns); + outlet_anything(mtx_sort_obj->list_outlet2, gensym("matrix"), + mtx_sort_obj->size+2, list_out2); +} + +void mtx_sort_setup (void) +{ + mtx_sort_class = class_new + (gensym("mtx_sort"), + (t_newmethod) newMTXSort, + (t_method) deleteMTXSort, + sizeof (MTXSort), + CLASS_DEFAULT, A_GIMME, 0); + class_addbang (mtx_sort_class, (t_method) mTXSortBang); + class_addmethod (mtx_sort_class, (t_method) mTXSortMatrix, gensym("matrix"), A_GIMME,0); + class_addmethod (mtx_sort_class, (t_method) mTXSetSortDimension, gensym("dimension"), A_DEFFLOAT,0); + class_addmethod (mtx_sort_class, (t_method) mTXSetSortDirection, gensym("direction"), A_DEFFLOAT,0); + class_sethelpsymbol (mtx_sort_class, gensym("iemmatrix/mtx_sort")); +} + +void iemtx_sort_setup(void){ + mtx_sort_setup(); +} -- cgit v1.2.1