Update of /cvsroot/pure-data/externals/iem/iemmatrix/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5954
Modified Files: iemmatrix_sources.c iemmatrix_sources.h Added Files: mtx_colon.c mtx_conv.c mtx_cumsum.c mtx_diff.c mtx_fill.c mtx_find.c mtx_index.c mtx_minmax.c mtx_not.c mtx_repmat.c mtx_reverse.c mtx_sort.c Log Message: 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)
Index: iemmatrix_sources.c =================================================================== RCS file: /cvsroot/pure-data/externals/iem/iemmatrix/src/iemmatrix_sources.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** iemmatrix_sources.c 19 Sep 2005 13:28:51 -0000 1.2 --- iemmatrix_sources.c 19 Sep 2005 14:47:48 -0000 1.3 *************** *** 19,26 **** --- 19,30 ---- iemtx_cholesky_setup(); /* mtx_cholesky.c */ iemtx_col_setup(); /* mtx_col.c */ + iemtx_colon_setup(); /* mtx_colon.c */ + iemtx_conv_setup(); /* mtx_conv.c */ iemtx_cos_setup(); /* mtx_cos.c */ + iemtx_cumsum_setup(); /* mtx_cumsum.c */ iemtx_dbtorms_setup(); /* mtx_dbtorms.c */ iemtx_diag_setup(); /* mtx_diag.c */ iemtx_diegg_setup(); /* mtx_diegg.c */ + iemtx_diff_setup(); /* mtx_diff.c */ iemtx_distance2_setup(); /* mtx_distance2.c */ iemtx_egg_setup(); /* mtx_egg.c */ *************** *** 29,35 **** --- 33,42 ---- iemtx_exp_setup(); /* mtx_exp.c */ iemtx_eye_setup(); /* mtx_eye.c */ + iemtx_fill_setup(); /* mtx_fill.c */ + iemtx_find_setup(); /* mtx_find.c */ iemtx_gauss_setup(); /* mtx_gauss.c */ iemtx_ge_setup(); /* mtx_ge.c */ iemtx_gt_setup(); /* mtx_gt.c */ + iemtx_index_setup(); /* mtx_index.c */ iemtx_int_setup(); /* mtx_int.c */ iemtx_inverse_setup(); /* mtx_inverse.c */ *************** *** 41,47 **** --- 48,56 ---- iemtx_mean_setup(); /* mtx_mean.c */ iemtx_min2_setup(); /* mtx_min2.c */ + iemtx_minmax_setup(); /* mtx_minmax.c */ iemtx_mul_setup(); /* mtx_mul.c */ iemtx_mul__setup(); /* mtx_mul~.c */ iemtx_neq_setup(); /* mtx_neq.c */ + iemtx_not_setup(); /* mtx_not.c */ iemtx_ones_setup(); /* mtx_ones.c */ iemtx_or_setup(); /* mtx_or.c */ *************** *** 51,55 **** --- 60,66 ---- iemtx_prod_setup(); /* mtx_prod.c */ iemtx_rand_setup(); /* mtx_rand.c */ + iemtx_repmat_setup(); /* mtx_repmat.c */ iemtx_resize_setup(); /* mtx_resize.c */ + iemtx_reverse_setup(); /* mtx_reverse.c */ iemtx_rmstodb_setup(); /* mtx_rmstodb.c */ iemtx_roll_setup(); /* mtx_roll.c */ *************** *** 58,61 **** --- 69,73 ---- iemtx_sin_setup(); /* mtx_sin.c */ iemtx_size_setup(); /* mtx_size.c */ + iemtx_sort_setup(); /* mtx_sort.c */ iemtx_sub_setup(); /* mtx_sub.c */ iemtx_sum_setup(); /* mtx_sum.c */
--- NEW FILE: mtx_index.c --- /* * 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_index_class;
typedef struct _MTXindex_ MTXindex; struct _MTXindex_ { t_object x_obj; int index_size; int index_rows; int index_columns; t_float fill_value; int max_index; int *index_in;
t_outlet *list_outlet;
t_atom *list_out; t_atom *list_in; };
static void deleteMTXIndex (MTXindex *mtx_index_obj) { if (mtx_index_obj->index_in) freebytes (mtx_index_obj->index_in, sizeof(int)*(mtx_index_obj->index_size+2)); if (mtx_index_obj->list_out) freebytes (mtx_index_obj->list_out, sizeof(t_atom)*(mtx_index_obj->index_size+2)); }
static void *newMTXIndex (t_symbol *s, int argc, t_atom *argv) { MTXindex *mtx_index_obj = (MTXindex *) pd_new (mtx_index_class); t_atom fill_atom;
SETFLOAT(&fill_atom,0); switch ((argc>1)?1:argc) { case 1: fill_atom = *argv; } if (atom_getsymbol(&fill_atom) == gensym("nan")) mtx_index_obj->fill_value = 0.0f/0.0f; else mtx_index_obj->fill_value = atom_getfloat(&fill_atom);
mtx_index_obj->list_outlet = outlet_new (&mtx_index_obj->x_obj, gensym("matrix")); inlet_new(&mtx_index_obj->x_obj, &mtx_index_obj->x_obj.ob_pd, gensym("matrix"),gensym(""));
error("[mtx_index]: this object is likely to change! not really for use yet");
return ((void *) mtx_index_obj); }
static void mTXIndexBang (MTXindex *mtx_index_obj) { if (mtx_index_obj->list_out) outlet_anything(mtx_index_obj->list_outlet, gensym("matrix"), mtx_index_obj->index_size+2, mtx_index_obj->list_out); } /* static void copyList (int size, t_atom *x, t_atom *y) { while(size--) *y++=*x++; } */
static int copyAtomToIntegerArrayMax (int n, t_atom *x, int *y) { int max = atom_getint(x); for (;n--;x++,y++) { *y = atom_getint (x); max = (*y > max)?*y:max; } return max; }
static void setAtomListConstFloat (int n, t_atom *x, t_float f) { for (;n--;x++) SETFLOAT(x,f); }
static void writeIndexedValuesIntoList (int n, int *index, t_atom *x, t_atom *y) { for (;n--;index++,y++) if (*index) *y = x[*index-1]; }
static void mTXIndexRightMatrix (MTXindex *mtx_index_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_in = argv; t_atom *list_out = mtx_index_obj->list_out; int *index_in = mtx_index_obj->index_in; int max;
// size check if (!size) { post("mtx_index: invalid dimensions"); return; } else if (list_size<size) { post("mtx_index: sparse matrix not yet supported: use "mtx_check""); return; }
if (size != mtx_index_obj->index_size) { if (!index_in) index_in = (int *) getbytes (sizeof (int) * (size + 2)); else index_in = (int *) resizebytes (index_in, sizeof (int) * (mtx_index_obj->index_size+2), sizeof (int) * (size + 2)); if (!list_out) list_out = (t_atom *) getbytes (sizeof (t_atom) * (size + 2)); else list_out = (t_atom *) resizebytes (list_out, sizeof (t_atom) * (mtx_index_obj->index_size+2), sizeof (t_atom) * (size + 2)); }
mtx_index_obj->index_size = size; mtx_index_obj->index_columns = columns; mtx_index_obj->index_rows = rows; mtx_index_obj->list_out = list_out; mtx_index_obj->index_in = index_in;
max = copyAtomToIntegerArrayMax (size, list_in, index_in); mtx_index_obj->max_index = max;
}
static void mTXIndexMatrix (MTXindex *mtx_index_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_in = argv; t_atom *list_out = mtx_index_obj->list_out; int count; int index_rows = mtx_index_obj->index_rows; int index_columns = mtx_index_obj->index_columns; int *index = mtx_index_obj->index_in;
// size check if (!size) { post("mtx_index: invalid dimensions"); return; } else if (list_size<size) { post("mtx_index: sparse matrix not yet supported: use "mtx_check""); return; }
if (size < mtx_index_obj->max_index) { post("mtx_index: index exceeds matrix dimensions"); return; } if ((!index)||(mtx_index_obj->index_size == 0)) { post("mtx_index: index with what? no right matrix defined"); return; } // main part list_out += 2; setAtomListConstFloat (mtx_index_obj->index_size, list_out, mtx_index_obj->fill_value); writeIndexedValuesIntoList (mtx_index_obj->index_size, index,list_in,list_out); list_out = mtx_index_obj->list_out; SETSYMBOL(list_out, gensym("matrix")); SETFLOAT(list_out, index_rows); SETFLOAT(&list_out[1], index_columns); outlet_anything(mtx_index_obj->list_outlet, gensym("matrix"), mtx_index_obj->index_size+2, list_out); }
void mtx_index_setup (void) { mtx_index_class = class_new (gensym("mtx_index"), (t_newmethod) newMTXIndex, (t_method) deleteMTXIndex, sizeof (MTXindex), CLASS_DEFAULT, A_GIMME, 0); class_addbang (mtx_index_class, (t_method) mTXIndexBang); class_addmethod (mtx_index_class, (t_method) mTXIndexMatrix, gensym("matrix"), A_GIMME,0); class_addmethod (mtx_index_class, (t_method) mTXIndexRightMatrix, gensym(""), A_GIMME,0); class_sethelpsymbol (mtx_index_class, gensym("iemmatrix/mtx_index")); }
void iemtx_index_setup(void){ mtx_index_setup(); }
--- NEW FILE: mtx_sort.c --- /* * 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_size<size) { post("mtx_sort: sparse matrix not yet supported: use "mtx_check""); return; } else if ((!x)||(!list_out1)||(!list_out2)/*||(!y)*/) { if (!x) x = (t_float *) getbytes (sizeof (t_float) * (size)); //if (!y) // y = (t_float *) getbytes (sizeof (t_float) * (size)); if (!i) i = (t_float *) getbytes (sizeof (t_float) * (size)); if (!list_out1) list_out1 = (t_atom *) getbytes (sizeof (t_atom) * (size+2)); if (!list_out2) list_out2 = (t_atom *) getbytes (sizeof (t_atom) * (size+2)); } else if (size != mtx_sort_obj->size) { 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(); }
--- NEW FILE: mtx_colon.c --- /* * 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_colon_class;
typedef struct _MTXColon_ MTXColon; struct _MTXColon_ { t_object x_obj; int size;
t_atom *list_out; t_outlet *list_outlet; };
static void deleteMTXColon (MTXColon *mtx_colon_obj) { if (mtx_colon_obj->list_out) freebytes (mtx_colon_obj->list_out, sizeof(t_atom)*(mtx_colon_obj->size+2)); }
static void *newMTXColon (t_symbol *s, int argc, t_atom *argv) { MTXColon *mtx_colon_obj = (MTXColon *) pd_new (mtx_colon_class);
mtx_colon_obj->list_outlet = outlet_new (&mtx_colon_obj->x_obj, gensym("matrix")); return ((void *) mtx_colon_obj); }
static void mTXColonBang (MTXColon *mtx_colon_obj) { if (mtx_colon_obj->list_out) outlet_anything(mtx_colon_obj->list_outlet, gensym("matrix"), mtx_colon_obj->size+2, mtx_colon_obj->list_out); }
static void mTXColonList (MTXColon *mtx_colon_obj, t_symbol *s, int argc, t_atom *argv) { int size; t_float startval; t_float stopval; t_float step; t_atom *list_out = mtx_colon_obj->list_out; if (argc == 3) { startval = atom_getfloat(argv++); step = atom_getfloat(argv++); stopval = atom_getfloat(argv++); } else if (argc == 2) { startval = atom_getfloat(argv++); stopval = atom_getfloat(argv++); step = 1.0f; } else { post("mtx_colon: wrong number of input arguments"); return; }
size = (int)((stopval- startval + step) / step); //post("startval %f stopval %f step %f, size %d",startval, stopval, step, size); if (size) { if (size!=mtx_colon_obj->size) { if (list_out) list_out = (t_atom *) resizebytes (list_out, sizeof(t_atom)*(mtx_colon_obj->size+2), sizeof(t_atom)*(size+2)); else list_out = (t_atom*) getbytes (sizeof(t_atom)*(size+2)); mtx_colon_obj->size = size; } mtx_colon_obj->list_out = list_out;
SETFLOAT (&list_out[0],1.0f); SETFLOAT (&list_out[1],(t_float)size); list_out += 2; for (;size--;list_out++,startval+=step) SETFLOAT(list_out,startval);
mTXColonBang (mtx_colon_obj); } }
void mtx_colon_setup (void) { mtx_colon_class = class_new (gensym("mtx_colon"), (t_newmethod) newMTXColon, (t_method) deleteMTXColon, sizeof (MTXColon), CLASS_DEFAULT, A_GIMME, 0); class_addbang (mtx_colon_class, (t_method) mTXColonBang); class_addlist (mtx_colon_class, (t_method) mTXColonList); class_addcreator ((t_newmethod) newMTXColon, gensym("mtx_:"), A_GIMME, 0); class_sethelpsymbol (mtx_colon_class, gensym("iemmatrix/mtx_colon")); }
void iemtx_colon_setup(void){ mtx_colon_setup(); }
Index: iemmatrix_sources.h =================================================================== RCS file: /cvsroot/pure-data/externals/iem/iemmatrix/src/iemmatrix_sources.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** iemmatrix_sources.h 19 Sep 2005 13:28:51 -0000 1.2 --- iemmatrix_sources.h 19 Sep 2005 14:47:49 -0000 1.3 *************** *** 17,24 **** --- 17,28 ---- void iemtx_cholesky_setup(void); /* mtx_cholesky.c */ void iemtx_col_setup(void); /* mtx_col.c */ + void iemtx_colon_setup(void); /* mtx_colon.c */ + void iemtx_conv_setup(void); /* mtx_conv.c */ void iemtx_cos_setup(void); /* mtx_cos.c */ + void iemtx_cumsum_setup(void); /* mtx_cumsum.c */ void iemtx_dbtorms_setup(void); /* mtx_dbtorms.c */ void iemtx_diag_setup(void); /* mtx_diag.c */ void iemtx_diegg_setup(void); /* mtx_diegg.c */ + void iemtx_diff_setup(void); /* mtx_diff.c */ void iemtx_distance2_setup(void); /* mtx_distance2.c */ void iemtx_egg_setup(void); /* mtx_egg.c */ *************** *** 27,33 **** --- 31,40 ---- void iemtx_exp_setup(void); /* mtx_exp.c */ void iemtx_eye_setup(void); /* mtx_eye.c */ + void iemtx_fill_setup(void); /* mtx_fill.c */ + void iemtx_find_setup(void); /* mtx_find.c */ void iemtx_gauss_setup(void); /* mtx_gauss.c */ void iemtx_ge_setup(void); /* mtx_ge.c */ void iemtx_gt_setup(void); /* mtx_gt.c */ + void iemtx_index_setup(void); /* mtx_index.c */ void iemtx_int_setup(void); /* mtx_int.c */ void iemtx_inverse_setup(void); /* mtx_inverse.c */ *************** *** 39,45 **** --- 46,54 ---- void iemtx_mean_setup(void); /* mtx_mean.c */ void iemtx_min2_setup(void); /* mtx_min2.c */ + void iemtx_minmax_setup(void); /* mtx_minmax.c */ void iemtx_mul_setup(void); /* mtx_mul.c */ void iemtx_mul__setup(void); /* mtx_mul~.c */ void iemtx_neq_setup(void); /* mtx_neq.c */ + void iemtx_not_setup(void); /* mtx_not.c */ void iemtx_ones_setup(void); /* mtx_ones.c */ void iemtx_or_setup(void); /* mtx_or.c */ *************** *** 49,53 **** --- 58,64 ---- void iemtx_prod_setup(void); /* mtx_prod.c */ void iemtx_rand_setup(void); /* mtx_rand.c */ + void iemtx_repmat_setup(void); /* mtx_repmat.c */ void iemtx_resize_setup(void); /* mtx_resize.c */ + void iemtx_reverse_setup(void); /* mtx_reverse.c */ void iemtx_rmstodb_setup(void); /* mtx_rmstodb.c */ void iemtx_roll_setup(void); /* mtx_roll.c */ *************** *** 56,59 **** --- 67,71 ---- void iemtx_sin_setup(void); /* mtx_sin.c */ void iemtx_size_setup(void); /* mtx_size.c */ + void iemtx_sort_setup(void); /* mtx_sort.c */ void iemtx_sub_setup(void); /* mtx_sub.c */ void iemtx_sum_setup(void); /* mtx_sum.c */
--- NEW FILE: mtx_not.c --- /* * iemmatrix * * objects for manipulating simple matrices * mostly refering to matlab/octave matrix functions * * Copyright (c) IOhannes m zmölnig, forum::für::umläute * 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"
/* mtx_not: B=!A; */
#define MTX_ALMOSTZERO 1e-19
static t_class *mtx_not_class;
static void mtx_not_matrix(t_mtx_binmtx *x, t_symbol *s, int argc, t_atom *argv) { int row=atom_getfloat(argv++); int col=atom_getfloat(argv++); t_atom *m; int n = argc-2;
if (argc<2){ post("mtx_!: crippled matrix"); return; } if ((col<1)||(row<1)) { post("mtx_!: invalid dimensions"); return; } if (col*row>argc-2){ post("sparse matrix not yet supported : use "mtx_check""); return; }
adjustsize(&x->m, row, col); m = x->m.atombuffer+2;
while(n--){ t_float f = atom_getfloat(argv++); SETFLOAT(m, (t_float)(f<MTX_ALMOSTZERO&&f>-MTX_ALMOSTZERO)); m++; }
outlet_anything(x->x_obj.ob_outlet, gensym("matrix"), argc, x->m.atombuffer); }
static void mtx_not_list(t_mtx_binscalar *x, t_symbol *s, int argc, t_atom *argv) { int n=argc; t_atom *m; t_float factor = x->f;
adjustsize(&x->m, 1, argc); m = x->m.atombuffer;
while(n--){ m->a_type = A_FLOAT; t_float f = atom_getfloat(argv++); (m++)->a_w.w_float = (t_float)(f<MTX_ALMOSTZERO&&f>-MTX_ALMOSTZERO); }
outlet_list(x->x_obj.ob_outlet, gensym("list"), argc, x->m.atombuffer); }
static void *mtx_not_new(t_symbol *s) { /* element not */ t_matrix *x = (t_matrix *)pd_new(mtx_not_class); outlet_new(&x->x_obj, 0); x->col = x->row = 0; x->atombuffer = 0; return(x); }
void mtx_not_setup(void) { mtx_not_class = class_new(gensym("mtx_not"), (t_newmethod)mtx_not_new, (t_method)mtx_binmtx_free, sizeof(t_mtx_binmtx), 0, A_GIMME, 0); class_addcreator((t_newmethod)mtx_not_new, gensym("mtx_!"), A_GIMME,0); class_addmethod(mtx_not_class, (t_method)mtx_not_matrix, gensym("matrix"), A_GIMME, 0); class_addlist (mtx_not_class, mtx_not_list); class_addbang (mtx_not_class, mtx_binmtx_bang);
class_sethelpsymbol(mtx_not_class, gensym("iemmatrix/mtx_not")); }
void iemtx_not_setup(void) { mtx_not_setup(); }
--- NEW FILE: mtx_find.c --- /* * 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_find_class;
typedef struct _MTXfind_ MTXfind; struct _MTXfind_ { t_object x_obj; int size; int outsize; int find_dimension; int find_direction;
t_outlet *list_outlet;
t_atom *list_out; t_atom *list_in; };
static void deleteMTXFind (MTXfind *mtx_find_obj) { if (mtx_find_obj->list_out) freebytes (mtx_find_obj->list_out, sizeof(t_atom)*(mtx_find_obj->size+2)); }
static void mTXSetFindDirection (MTXfind *mtx_find_obj, t_float c_dir) { int direction = (int) c_dir; if ((direction != -1) && (direction != 1)) direction = 1; mtx_find_obj->find_direction = direction; }
static void mTXSetFindDimension (MTXfind *mtx_find_obj, t_float c_dim) { int dimension = (int) c_dim; dimension = (dimension > 0)?dimension:0; dimension = (dimension < 3)?dimension:3; mtx_find_obj->find_dimension = dimension; }
static void *newMTXFind (t_symbol *s, int argc, t_atom *argv) { MTXfind *mtx_find_obj = (MTXfind *) pd_new (mtx_find_class); int c_dim = 0; int c_dir = 1;
switch ((argc>2)?2:argc) { case 2: c_dir = atom_getint(argv+1); case 1: c_dim = atom_getint(argv); } mTXSetFindDimension (mtx_find_obj, (t_float) c_dim); mTXSetFindDirection (mtx_find_obj, (t_float) c_dir);
mtx_find_obj->list_outlet = outlet_new (&mtx_find_obj->x_obj, gensym("matrix"));
error("[mtx_find]: this object is likely to change! not really for use yet"); return ((void *) mtx_find_obj); }
static void mTXFindBang (MTXfind *mtx_find_obj) { if (mtx_find_obj->list_out) outlet_anything(mtx_find_obj->list_outlet, gensym("matrix"), mtx_find_obj->outsize+2, mtx_find_obj->list_out); } /* static void copyList (int size, t_atom *x, t_atom *y) { while(size--) *y++=*x++; } */ static int findPreviousNonZero (const int n, t_atom *x, int offset) { x+=offset; for (; offset > n; offset--, x--) if (atom_getfloat(x)) return offset; return -1; } static int findPreviousNonZeroStep (const int step, t_atom *x, int offset) { x += offset; for (; offset > 0; offset-=step, x-=step) if (atom_getfloat(x)) return offset; return -1; } static int findNextNonZero (const int n, t_atom *x, int offset) { x+=offset; for (; offset < n; offset++, x++) if (atom_getfloat(x)) return offset; return -1; } static int findNextNonZeroStep (const int n, const int step, t_atom *x, int offset) { x += offset; for (; offset < n; offset+=step, x+=step) if (atom_getfloat(x)) return offset; return -1; }
static void findFirstNonZeroRow (const int rows, const int columns, t_atom *x, t_atom *y) { int offset; int pos; const int size = rows*columns; for (offset = 0; offset < size; y++, offset+=columns) { pos = findNextNonZero(offset+columns,x,offset)+1; SETFLOAT(y,(t_float)pos); } } static void findLastNonZeroRow (const int rows, const int columns, t_atom *x, t_atom *y) { int offset; int pos; const int size = rows*columns; for (offset = columns-1; offset < size; y++, offset+=columns) { pos = findPreviousNonZero(offset-columns,x,offset)+1; SETFLOAT(y,(t_float)pos); } } static void findFirstNonZeroColumn (const int rows, const int columns, t_atom *x, t_atom *y) { int offset; int pos; const int size = rows*columns; for (offset = 0; offset < columns; y++, offset++) { pos = findNextNonZeroStep(size,columns,x,offset)+1; SETFLOAT(y,(t_float)pos); } } static void findLastNonZeroColumn (const int rows, const int columns, t_atom *x, t_atom *y) { int offset; int pos; const int size = rows*columns; for (offset = size-columns; offset < size; y++, offset++) { pos = findPreviousNonZeroStep(columns,x,offset)+1; SETFLOAT(y,(t_float)pos); } }
static int findAllNonZeros (int n, t_atom *x, t_atom *y) { int outsize = 0; int pos = 0; while ((pos = findNextNonZero(n,x,pos)) != -1) { pos++; SETFLOAT(y,(t_float)pos); y++; outsize++; } return outsize; }
static void zeroFloatList (int n, t_atom *x) { for (;n--;x++) SETFLOAT(x,0); } static void findReplaceNonZerosWithIndex (int n, t_atom *x, t_atom *y) { int pos = 0; zeroFloatList(n,y); while ((pos = findNextNonZero(n,x,pos)) != -1) { SETFLOAT(y+pos,(t_float)pos+1); pos++; } }
static void mTXFindMatrix (MTXfind *mtx_find_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_in = argv; t_atom *list_out = mtx_find_obj->list_out; int count; int rows_out; int columns_out;
// size check if (!size) { post("mtx_find: invalid dimensions"); return; } else if (list_size<size) { post("mtx_find: sparse matrix not yet supported: use "mtx_check""); return; }
if (size != mtx_find_obj->size) { if (!list_out) list_out = (t_atom *) getbytes (sizeof (t_atom) * (size + 2)); else list_out = (t_atom *) resizebytes (list_out, sizeof (t_atom) * (mtx_find_obj->size+2), sizeof (t_atom) * (size + 2)); }
mtx_find_obj->size = size; mtx_find_obj->list_out = list_out;
// main part list_out += 2; //copyList (size, argv, list_out); rows_out = 1; switch (mtx_find_obj->find_dimension) { case 0: columns_out = findAllNonZeros (size, list_in, list_out); rows_out = 1; break; case 3: findReplaceNonZerosWithIndex (size, list_in, list_out); rows_out = rows; columns_out = columns; break; case 2: if (mtx_find_obj->find_direction == -1) findLastNonZeroColumn (rows, columns, list_in, list_out); else findFirstNonZeroColumn (rows, columns, list_in, list_out); columns_out = columns; rows_out = 1; break; case 1: if (mtx_find_obj->find_direction == -1) findLastNonZeroRow (rows, columns, list_in, list_out); else findFirstNonZeroRow (rows, columns, list_in, list_out); rows_out = rows; columns_out = 1; break; } mtx_find_obj->outsize = columns_out * rows_out; list_out = mtx_find_obj->list_out;
SETSYMBOL(list_out, gensym("matrix")); SETFLOAT(list_out, rows_out); SETFLOAT(&list_out[1], columns_out); outlet_anything(mtx_find_obj->list_outlet, gensym("matrix"), mtx_find_obj->outsize+2, list_out); }
void mtx_find_setup (void) { mtx_find_class = class_new (gensym("mtx_find"), (t_newmethod) newMTXFind, (t_method) deleteMTXFind, sizeof (MTXfind), CLASS_DEFAULT, A_GIMME, 0); class_addbang (mtx_find_class, (t_method) mTXFindBang); class_addmethod (mtx_find_class, (t_method) mTXFindMatrix, gensym("matrix"), A_GIMME,0); class_addmethod (mtx_find_class, (t_method) mTXSetFindDimension, gensym("dimension"), A_DEFFLOAT,0); class_addmethod (mtx_find_class, (t_method) mTXSetFindDirection, gensym("direction"), A_DEFFLOAT,0); class_sethelpsymbol (mtx_find_class, gensym("iemmatrix/mtx_find")); }
void iemtx_find_setup(void){ mtx_find_setup(); }
--- NEW FILE: mtx_diff.c --- /* * 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_diff_class;
typedef struct _MTXdiff_ MTXdiff; struct _MTXdiff_ { t_object x_obj; int rows; int columns; int size; int diff_dimension; int diff_direction;
t_outlet *list_outlet;
t_atom *list_out; t_atom *list_in; t_float *x; t_float *y; };
static void deleteMTXdiff (MTXdiff *mtx_diff_obj) { if (mtx_diff_obj->list_out) freebytes (mtx_diff_obj->list_out, sizeof(t_atom)*(mtx_diff_obj->size+2)); if (mtx_diff_obj->x) freebytes (mtx_diff_obj->x, sizeof(t_float)*(mtx_diff_obj->size)); if (mtx_diff_obj->y) freebytes (mtx_diff_obj->y, sizeof(t_float)*(mtx_diff_obj->size)); }
static void mTXSetdiffDirection (MTXdiff *mtx_diff_obj, t_float c_dir) { int direction = (int) c_dir; mtx_diff_obj->diff_direction = (direction==-1)?direction:1; } static void mTXSetdiffDimension (MTXdiff *mtx_diff_obj, t_float c_dim) { int dimension = (int) c_dim; mtx_diff_obj->diff_dimension = (dimension==2)?dimension:1; }
static void *newMTXdiff (t_symbol *s, int argc, t_atom *argv) { MTXdiff *mtx_diff_obj = (MTXdiff *) pd_new (mtx_diff_class); int c_dir = 1; int c_dim = 1;
mtx_diff_obj->diff_dimension = c_dim; switch ((argc>2)?2:argc) { case 2: c_dir = atom_getint(argv+1); case 1: c_dim = atom_getint(argv); } mTXSetdiffDirection (mtx_diff_obj, (t_float) c_dir); mTXSetdiffDimension (mtx_diff_obj, (t_float) c_dim);
mtx_diff_obj->list_outlet = outlet_new (&mtx_diff_obj->x_obj, gensym("matrix")); return ((void *) mtx_diff_obj); }
static void mTXdiffBang (MTXdiff *mtx_diff_obj) { if (mtx_diff_obj->list_out) outlet_anything(mtx_diff_obj->list_outlet, gensym("matrix"), mtx_diff_obj->size+2, mtx_diff_obj->list_out); }
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 diff (int n, t_float *x, t_float *y) { *y++ = *x++; for (;--n; x++, y++) *y = *x - *(x-1); } static void diffReverse (int n, t_float *x, t_float *y) { *y-- = *x--; for (;--n; x--, y--) *y = *x - *(x+1); }
static void mTXdiffMatrix (MTXdiff *mtx_diff_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_out = mtx_diff_obj->list_out; t_float *x = mtx_diff_obj->x; t_float *y = mtx_diff_obj->y; int count;
// size check if (!size) { post("mtx_diff: invalid dimensions"); return; } else if (list_size<size) { post("mtx_diff: sparse matrix not yet supported: use "mtx_check""); return; } else if ((!x)||(!list_out)||(!y)) { if (!x) x = (t_float *) getbytes (sizeof (t_float) * (size)); if (!y) y = (t_float *) getbytes (sizeof (t_float) * (size)); if (!list_out) list_out = (t_atom *) getbytes (sizeof (t_atom) * (size+2)); } else if (size != mtx_diff_obj->size) { x = (t_float *) resizebytes (x, sizeof (t_float) * (mtx_diff_obj->size), sizeof (t_float) * (size)); y = (t_float *) resizebytes (y, sizeof (t_float) * (mtx_diff_obj->size), sizeof (t_float) * (size)); list_out = (t_atom *) resizebytes (list_out, sizeof (t_atom) * (mtx_diff_obj->size+2), sizeof (t_atom) * (size + 2)); } mtx_diff_obj->size = size; mtx_diff_obj->rows = rows; mtx_diff_obj->columns = columns; mtx_diff_obj->list_out = list_out; mtx_diff_obj->x = x; mtx_diff_obj->y = y;
// main part // reading matrix from inlet if (mtx_diff_obj->diff_dimension == 2) { readFloatFromListModulo (size, columns, list_ptr, x); columns = mtx_diff_obj->rows; rows = mtx_diff_obj->columns; } else readFloatFromList (size, list_ptr, x);
// calculating diff if (mtx_diff_obj->diff_direction == -1) { x += columns-1; y += columns-1; for (count = rows; count--; x += columns, y += columns) diffReverse (columns,x,y); } else for (count = rows; count--; x += columns, y += columns) diff (columns,x,y); x = mtx_diff_obj->x; y = mtx_diff_obj->y;
// writing matrix to outlet if (mtx_diff_obj->diff_dimension == 2) { columns = mtx_diff_obj->columns; rows = mtx_diff_obj->rows; writeFloatIntoListModulo (size, columns, list_out+2, y); } else writeFloatIntoList (size, list_out+2, y);
SETSYMBOL(list_out, gensym("matrix")); SETFLOAT(list_out, rows); SETFLOAT(&list_out[1], columns); outlet_anything(mtx_diff_obj->list_outlet, gensym("matrix"), mtx_diff_obj->size+2, list_out); }
void mtx_diff_setup (void) { mtx_diff_class = class_new (gensym("mtx_diff"), (t_newmethod) newMTXdiff, (t_method) deleteMTXdiff, sizeof (MTXdiff), CLASS_DEFAULT, A_GIMME, 0); class_addbang (mtx_diff_class, (t_method) mTXdiffBang); class_addmethod (mtx_diff_class, (t_method) mTXdiffMatrix, gensym("matrix"), A_GIMME,0); class_addmethod (mtx_diff_class, (t_method) mTXSetdiffDimension, gensym("dimension"), A_DEFFLOAT,0); class_addmethod (mtx_diff_class, (t_method) mTXSetdiffDirection, gensym("direction"), A_DEFFLOAT,0); class_sethelpsymbol (mtx_diff_class, gensym("iemmatrix/mtx_diff")); }
void iemtx_diff_setup(void){ mtx_diff_setup(); }
--- NEW FILE: mtx_fill.c --- /* * 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"
typedef enum { FILL_SUBMATRIX, FILL_INDEXED_ELEMENTS } FillStyle;
static t_class *mtx_fill_class;
typedef struct _MTXfill_ MTXfill; struct _MTXfill_ { t_object x_obj; int size; int rows; int columns;
int fill_startcol; int fill_startrow;
int *index; int index_size; int max_index;
FillStyle fill_type;
t_outlet *list_outlet;
t_atom *list_in; t_atom *list_out; };
static void deleteMTXFill (MTXfill *mtx_fill_obj) { if (mtx_fill_obj->list_in) freebytes (mtx_fill_obj->list_in, sizeof(t_atom)*(mtx_fill_obj->size+2)); if (mtx_fill_obj->list_out) freebytes (mtx_fill_obj->list_out, sizeof(t_atom)*(mtx_fill_obj->size+2)); if (mtx_fill_obj->index) freebytes (mtx_fill_obj->list_out, sizeof(int)*(mtx_fill_obj->index_size)); }
static void setListConstFloat (int size, t_float f, t_atom *y) { for(;size--;y++) SETFLOAT(y,f); } static void copyList (int size, t_atom *x, t_atom *y) { while(size--) *y++=*x++; } static int copyNonZeroAtomsToIntegerArrayMax (int *size, t_atom *x, int *y) { int idx; int n = *size; int max = atom_getint(x); *size = 0; for (;n--;x++) { idx = atom_getint (x); if (idx) { size[0]++; *y++ = idx; max = (idx > max)?idx:max; } } return max; }
static void writeIndexedValuesIntoMatrix (int n, int *index, t_atom *x, t_atom *y) { for (;n--;index++,x++) if (*index) y[*index-1] = *x; } static void writeFloatIndexedIntoMatrix (int n, int *index, t_float f, t_atom *y) { for (;n--;index++) if (*index) SETFLOAT(&y[*index-1], f); }
static void mTXFillIndexMatrix (MTXfill *mtx_fill_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; int *index = mtx_fill_obj->index;
// size check if (!size) { post("mtx_fill: invalid dimensions/invalid start index"); return; }
if (list_size == 0) { if ((rows<1) || (columns<1)){ post("mtx_fill: row and column indices must be >0"); return; } mtx_fill_obj->fill_startrow = rows; mtx_fill_obj->fill_startcol = columns; mtx_fill_obj->fill_type = FILL_SUBMATRIX; } else if (list_size<size) { post("mtx_fill: sparse matrix not yet supported: use "mtx_check""); return; } else { if (size > mtx_fill_obj->index_size) { if (!index) index = (int *) getbytes (sizeof (int) * (size + 2)); else index = (int *) resizebytes (index, sizeof (int) * (mtx_fill_obj->index_size+2), sizeof (t_atom) * (size + 2)); mtx_fill_obj->index_size = size; } mtx_fill_obj->max_index = copyNonZeroAtomsToIntegerArrayMax (&size, argv++, index); if (!size) { post("mtx_fill: indexing matrix contains zero-values only!!!"); return; } if (size != mtx_fill_obj->index_size) { index = (int *) resizebytes (index, sizeof (int) * (mtx_fill_obj->index_size+2), sizeof (t_atom) * (size + 2)); mtx_fill_obj->index_size = size; } mtx_fill_obj->fill_type = FILL_INDEXED_ELEMENTS; mtx_fill_obj->index = index; } }
static void *newMTXFill (t_symbol *s, int argc, t_atom *argv) { MTXfill *mtx_fill_obj = (MTXfill *) pd_new (mtx_fill_class);
mtx_fill_obj->fill_startrow = 1; mtx_fill_obj->fill_startcol = 1; mtx_fill_obj->fill_type = FILL_SUBMATRIX; if (argc) { if (atom_getsymbol(argv)==gensym("matrix")) mTXFillIndexMatrix (mtx_fill_obj, s, argc-1, argv+1); else post("mtx_fill: creation argument must be 'matrix <startrow> <startcol>' for submatrix filling or 'matrix rows columns [...]' for indexed filling with scalar/matrices"); }
mtx_fill_obj->list_outlet = outlet_new (&mtx_fill_obj->x_obj, gensym("matrix")); inlet_new(&mtx_fill_obj->x_obj, &mtx_fill_obj->x_obj.ob_pd, gensym("matrix"),gensym("fill_mtx")); inlet_new(&mtx_fill_obj->x_obj, &mtx_fill_obj->x_obj.ob_pd, gensym("matrix"),gensym("index")); return ((void *) mtx_fill_obj); }
static void mTXBigMatrix (MTXfill *mtx_fill_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_in = mtx_fill_obj->list_in; t_atom *list_out = mtx_fill_obj->list_out;
// size check if (!size) { post("mtx_fill: invalid dimensions"); return; } else if (list_size<size) { post("mtx_fill: sparse matrix not yet supported: use "mtx_check""); return; }
if (size != mtx_fill_obj->size) { if (!list_out) list_out = (t_atom *) getbytes (sizeof (t_atom) * (size + 2)); else list_out = (t_atom *) resizebytes (list_out, sizeof (t_atom) * (mtx_fill_obj->size+2), sizeof (t_atom) * (size + 2)); if (!list_in) list_in = (t_atom *) getbytes (sizeof (t_atom) * (size + 2)); else list_in = (t_atom *) resizebytes (list_in, sizeof (t_atom) * (mtx_fill_obj->size+2), sizeof (t_atom) * (size + 2)); }
mtx_fill_obj->size = size; mtx_fill_obj->columns = columns; mtx_fill_obj->rows = rows; mtx_fill_obj->list_out = list_out; mtx_fill_obj->list_in = list_in;
copyList (size, argv, list_in); }
static void mTXFillBang (MTXfill *mtx_fill_obj) { if (mtx_fill_obj->list_out) outlet_anything(mtx_fill_obj->list_outlet, gensym("matrix"), mtx_fill_obj->size+2, mtx_fill_obj->list_out); }
static void writeFillMatrixIntoList (int fillrows, const int fillcols, int columns, t_atom *x, t_atom *y) { for (;fillrows--;x+=fillcols,y+=columns) copyList(fillcols, x, y); }
static void mTXFillScalar (MTXfill *mtx_fill_obj, t_float f) { t_atom *list_out = mtx_fill_obj->list_out; t_atom *list_in = mtx_fill_obj->list_in; int rows = mtx_fill_obj->rows; int columns = mtx_fill_obj->columns; if (mtx_fill_obj->fill_type == FILL_INDEXED_ELEMENTS) { if (mtx_fill_obj->max_index > mtx_fill_obj->size) { post("mtx_fill: index matrix index exceeds matrix borders"); return; } else if (mtx_fill_obj->size == 0) { post("mtx_fill: no matrix defined for filling"); return; }
// main part list_out += 2; copyList (mtx_fill_obj->size, list_in, list_out);
writeFloatIndexedIntoMatrix (mtx_fill_obj->index_size, mtx_fill_obj->index, f,list_out); list_out = mtx_fill_obj->list_out; SETSYMBOL(list_out, gensym("matrix")); SETFLOAT(list_out, rows); SETFLOAT(&list_out[1], columns); outlet_anything(mtx_fill_obj->list_outlet, gensym("matrix"), mtx_fill_obj->size+2, list_out); } else post("mtx_fill: scalar fill for submatrices not supported yet"); }
static void mTXFillMatrix (MTXfill *mtx_fill_obj, t_symbol *s, int argc, t_atom *argv) { int fill_rows = atom_getint (argv++); int fill_columns = atom_getint (argv++); int fill_size = fill_rows * fill_columns; int list_size = argc - 2; int rows = mtx_fill_obj->rows; int columns = mtx_fill_obj->columns; t_atom *fill_mtx = argv; t_atom *list_in = mtx_fill_obj->list_in; t_atom *list_out = mtx_fill_obj->list_out; int stopcol = mtx_fill_obj->fill_startcol+fill_columns-1; int stoprow = mtx_fill_obj->fill_startrow+fill_rows-1;
// size check if (!list_size) { post("mtx_fill: invalid dimensions"); return; } switch (mtx_fill_obj->fill_type) { case FILL_SUBMATRIX: if (list_size < fill_size) { post("mtx_fill: sparse matrix not yet supported: use "mtx_check""); return; } if ((stopcol > columns) || (stoprow > rows)) { post("mtx_fill: fill matrix index exceeds matrix borders"); return; } break; case FILL_INDEXED_ELEMENTS: if (list_size > mtx_fill_obj->index_size) { post("mtx_fill: fill matrix smaller than indexing vector"); return; } else if (mtx_fill_obj->max_index > mtx_fill_obj->size) { post("mtx_fill: index matrix index exceeds matrix borders"); return; } break; } if (mtx_fill_obj->size == 0) { post("mtx_fill: no matrix defined for filling"); return; }
// main part list_out += 2; copyList (mtx_fill_obj->size, list_in, list_out);
switch (mtx_fill_obj->fill_type) { case FILL_SUBMATRIX: list_out += columns * (mtx_fill_obj->fill_startrow-1) + mtx_fill_obj->fill_startcol-1; writeFillMatrixIntoList (fill_rows, fill_columns, columns, fill_mtx, list_out); break; case FILL_INDEXED_ELEMENTS: writeIndexedValuesIntoMatrix (mtx_fill_obj->index_size, mtx_fill_obj->index, fill_mtx,list_out); break; } list_out = mtx_fill_obj->list_out; SETSYMBOL(list_out, gensym("matrix")); SETFLOAT(list_out, rows); SETFLOAT(&list_out[1], columns); outlet_anything(mtx_fill_obj->list_outlet, gensym("matrix"), mtx_fill_obj->size+2, list_out); }
void mtx_fill_setup (void) { mtx_fill_class = class_new (gensym("mtx_fill"), (t_newmethod) newMTXFill, (t_method) deleteMTXFill, sizeof (MTXfill), CLASS_DEFAULT, A_GIMME, 0); class_addbang (mtx_fill_class, (t_method) mTXFillBang); class_addmethod (mtx_fill_class, (t_method) mTXFillMatrix, gensym("matrix"), A_GIMME,0); class_addmethod (mtx_fill_class, (t_method) mTXBigMatrix, gensym("fill_mtx"), A_GIMME,0); class_addmethod (mtx_fill_class, (t_method) mTXFillIndexMatrix, gensym("index"), A_GIMME,0); class_addfloat (mtx_fill_class, (t_method) mTXFillScalar); class_sethelpsymbol (mtx_fill_class, gensym("iemmatrix/mtx_fill")); }
void iemtx_fill_setup(void){ mtx_fill_setup(); }
--- NEW FILE: mtx_minmax.c --- /* * 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_minmax_class;
typedef struct _MTXminmax_ MTXminmax; struct _MTXminmax_ { t_object x_obj; int size; int outsize; int minmax_dimension; int minmax_direction; int operator_minimum; // 1 if we are [mtx_min], 0 if we are [mtx_max]
t_outlet *list_outlet;
t_atom *list_out; t_atom *list_in; };
static void deleteMTXMinMax (MTXminmax *mtx_minmax_obj) { if (mtx_minmax_obj->list_out) freebytes (mtx_minmax_obj->list_out, sizeof(t_atom)*(mtx_minmax_obj->size+2)); }
static void mTXSetMinMaxDirection (MTXminmax *mtx_minmax_obj, t_float c_dir) { int direction = (int) c_dir; if ((direction != -1) && (direction != 1)) direction = 1; mtx_minmax_obj->minmax_direction = direction; }
static void mTXSetMinMaxDimension (MTXminmax *mtx_minmax_obj, t_float c_dim) { int dimension = (int) c_dim; dimension = (dimension > 0)?dimension:0; dimension = (dimension < 3)?dimension:3; mtx_minmax_obj->minmax_dimension = dimension; }
static void *newMTXMin (t_symbol *s, int argc, t_atom *argv) { MTXminmax *mtx_minmax_obj = (MTXminmax *) pd_new (mtx_minmax_class); int c_dim = 1; int c_dir = 1;
switch ((argc>2)?2:argc) { case 2: c_dir = atom_getint(argv+1); case 1: c_dim = atom_getint(argv); } mtx_minmax_obj->operator_minimum = 1; mTXSetMinMaxDimension (mtx_minmax_obj, (t_float) c_dim); mTXSetMinMaxDirection (mtx_minmax_obj, (t_float) c_dir);
mtx_minmax_obj->list_outlet = outlet_new (&mtx_minmax_obj->x_obj, gensym("matrix")); return ((void *) mtx_minmax_obj); } static void *newMTXMax (t_symbol *s, int argc, t_atom *argv) { MTXminmax *mtx_minmax_obj = (MTXminmax *) pd_new (mtx_minmax_class); int c_dim = 1; int c_dir = 1;
switch ((argc>2)?2:argc) { case 2: c_dir = atom_getint(argv+1); case 1: c_dim = atom_getint(argv); } mtx_minmax_obj->operator_minimum = 0; mTXSetMinMaxDimension (mtx_minmax_obj, (t_float) c_dim); mTXSetMinMaxDirection (mtx_minmax_obj, (t_float) c_dir);
mtx_minmax_obj->list_outlet = outlet_new (&mtx_minmax_obj->x_obj, gensym("matrix")); return ((void *) mtx_minmax_obj); }
static void mTXMinMaxBang (MTXminmax *mtx_minmax_obj) { if (mtx_minmax_obj->list_out) outlet_anything(mtx_minmax_obj->list_outlet, gensym("matrix"), mtx_minmax_obj->outsize+2, mtx_minmax_obj->list_out); } /* static void copyList (int size, t_atom *x, t_atom *y) { while(size--) *y++=*x++; } */
static t_float minList (int n, t_atom *x) { t_float min=atom_getfloat(x); t_float f; for (;n--;x++) { f = atom_getfloat(x); min = (min < f)?min:f; } return min; }
static t_float minListStep (int n, const int step, t_atom *x) { t_float min=atom_getfloat(x); t_float f; for (;n--;x+=step) { f = atom_getfloat(x); min = (min < f)?min:f; } return min; }
static t_float maxList (int n, t_atom *x) { t_float max=atom_getfloat(x); t_float f; for (;n--;x++) { f = atom_getfloat(x); max = (max > f)?max:f; } return max; } static t_float maxListStep (int n, const int step, t_atom *x) { t_float max=atom_getfloat(x); t_float f; for (;n--;x+=step) { f = atom_getfloat(x); max = (max > f)?max:f; } return max; }
static void minListColumns (const int rows, const int columns, t_atom *x, t_atom *y) { int count; t_float f; for (count=0; count < columns; count++, x++, y++) { f=minListStep (rows, columns, x); SETFLOAT(y,f); } } static void minListRows (int rows, int columns, t_atom *x, t_atom *y) { int count; t_float f; for (count=0; count < rows; count++, x+=columns, y++) { f=minList (columns, x); SETFLOAT(y,f); } } static void maxListColumns (const int rows, const int columns, t_atom *x, t_atom *y) { int count; t_float f; for (count=0; count < columns; count++, x++, y++) { f=maxListStep (rows, columns, x); SETFLOAT(y,f); } } static void maxListRows (int rows, int columns, t_atom *x, t_atom *y) { int count; t_float f; for (count=0; count < rows; count++, x+=columns, y++) { f=maxList (columns, x); SETFLOAT(y,f); } }
static void mTXMinMaxMatrix (MTXminmax *mtx_minmax_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_in = argv; t_atom *list_out = mtx_minmax_obj->list_out; int count; int rows_out; int columns_out;
// size check if (!size) { post("mtx_minmax: invalid dimensions"); return; } else if (list_size<size) { post("mtx_minmax: sparse matrix not yet supported: use "mtx_check""); return; }
if (size != mtx_minmax_obj->size) { if (!list_out) list_out = (t_atom *) getbytes (sizeof (t_atom) * (size + 2)); else list_out = (t_atom *) resizebytes (list_out, sizeof (t_atom) * (mtx_minmax_obj->size+2), sizeof (t_atom) * (size + 2)); }
mtx_minmax_obj->size = size; mtx_minmax_obj->list_out = list_out;
// main part list_out += 2; //copyList (size, argv, list_out); switch (mtx_minmax_obj->minmax_dimension) { case 0: columns_out = 1; rows_out = 1; if (mtx_minmax_obj->operator_minimum) minListRows (1, size, list_in, list_out); else maxListRows (1, size, list_in, list_out); break; case 1: rows_out = rows; columns_out = 1; if (mtx_minmax_obj->operator_minimum) minListRows (rows, columns, list_in, list_out); else maxListRows (rows, columns, list_in, list_out); break; case 2: rows_out = 1; columns_out = columns; if (mtx_minmax_obj->operator_minimum) minListColumns (rows, columns, list_in, list_out); else maxListColumns (rows, columns, list_in, list_out); break; } mtx_minmax_obj->outsize = columns_out * rows_out; list_out = mtx_minmax_obj->list_out;
SETSYMBOL(list_out, gensym("matrix")); SETFLOAT(list_out, rows_out); SETFLOAT(&list_out[1], columns_out); outlet_anything(mtx_minmax_obj->list_outlet, gensym("matrix"), mtx_minmax_obj->outsize+2, list_out); }
void mtx_minmax_setup (void) { mtx_minmax_class = class_new (gensym("mtx_min"), (t_newmethod) newMTXMin, (t_method) deleteMTXMinMax, sizeof (MTXminmax), CLASS_DEFAULT, A_GIMME, 0); class_addbang (mtx_minmax_class, (t_method) mTXMinMaxBang); class_addmethod (mtx_minmax_class, (t_method) mTXMinMaxMatrix, gensym("matrix"), A_GIMME,0); class_addmethod (mtx_minmax_class, (t_method) mTXSetMinMaxDimension, gensym("dimension"), A_DEFFLOAT,0); class_addmethod (mtx_minmax_class, (t_method) mTXSetMinMaxDirection, gensym("direction"), A_DEFFLOAT,0); class_addcreator ((t_newmethod) newMTXMax, gensym("mtx_max"), A_GIMME,0); class_sethelpsymbol (mtx_minmax_class, gensym("iemmatrix/mtx_minmax")); }
void iemtx_minmax_setup(void){ mtx_minmax_setup(); }
--- NEW FILE: mtx_repmat.c --- /* * 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_repmat_class;
typedef struct _MTXrepmat_ MTXrepmat; struct _MTXrepmat_ { t_object x_obj; int size; int repeat_rows; int repeat_cols;
t_outlet *list_outlet;
t_atom *list_out; };
static void deleteMTXRepmat (MTXrepmat *mtx_repmat_obj) { if (mtx_repmat_obj->list_out) freebytes (mtx_repmat_obj->list_out, sizeof(t_atom)*(mtx_repmat_obj->size+2)); } static void mTXRepmatList (MTXrepmat *mtx_repmat_obj, t_symbol *s, int argc, t_atom *argv) { if (argc!=2) { post("mtx_repmat: there have to be exactly 2 arguments"); return; } mtx_repmat_obj->repeat_rows = atom_getint(argv++); mtx_repmat_obj->repeat_cols = atom_getint(argv); }
static void *newMTXRepmat (t_symbol *s, int argc, t_atom *argv) { MTXrepmat *mtx_repmat_obj = (MTXrepmat *) pd_new (mtx_repmat_class); mtx_repmat_obj->repeat_cols = 1; mtx_repmat_obj->repeat_rows = 1;
if (argc) mTXRepmatList (mtx_repmat_obj, gensym("list"), argc, argv);
mtx_repmat_obj->list_outlet = outlet_new (&mtx_repmat_obj->x_obj, gensym("matrix")); inlet_new(&mtx_repmat_obj->x_obj, &mtx_repmat_obj->x_obj.ob_pd, gensym("list"),gensym("")); return ((void *) mtx_repmat_obj); }
static void mTXRepmatBang (MTXrepmat *mtx_repmat_obj) { if (mtx_repmat_obj->list_out) outlet_anything(mtx_repmat_obj->list_outlet, gensym("matrix"), mtx_repmat_obj->size+2, mtx_repmat_obj->list_out); }
static void copyList (int n, t_atom *x, t_atom *y) { while (n--) *y++=*x++; }
static void writeRepeatIntoMatrix (int repeat_rows, int repeat_cols, int rows, int columns, t_atom *x, t_atom *y) { int row_cnt; int col_cnt; int idx = 0; int new_col = columns * repeat_cols; t_atom *ptr = y;
// writing each row repeatedly (repeat_col times) into output array // so that : row1#1 row1#2 ... row1#RN | ... | rowN#1 rowN#2 ... rowN#RN for (row_cnt=rows;row_cnt--;x+=columns) for(col_cnt=repeat_cols;col_cnt--;ptr+=columns) copyList (columns, x, ptr);
// repeating the above written long lines repeat row_repeat times in output array for (;--repeat_rows;) for (row_cnt=rows;row_cnt--;y+=new_col,ptr+=new_col) copyList (new_col, y, ptr);
} static void mTXRepmatMatrix (MTXrepmat *mtx_repmat_obj, t_symbol *s, int argc, t_atom *argv) { int rows = atom_getint (argv++); int columns = atom_getint (argv++); int rep_rows = mtx_repmat_obj->repeat_rows; int rep_cols = mtx_repmat_obj->repeat_cols; int mrows = rows * rep_rows; int mcolumns = columns * rep_cols; int size = rows * columns; int list_size = argc - 2; t_atom *list_in = argv; t_atom *list_out = mtx_repmat_obj->list_out;
// size check if (!size) { post("mtx_repmat: invalid dimensions"); return; } else if (list_size<size) { post("mtx_repmat: sparse matrix not yet supported: use "mtx_check""); return; }
mrows = rows * rep_rows; mcolumns = columns * rep_cols; size = mrows * mcolumns;
if (size != mtx_repmat_obj->size) { if (list_out) list_out = (t_atom*) resizebytes (list_out, sizeof(t_atom)*(mtx_repmat_obj->size+2), sizeof(t_atom)*(size+2)); else list_out = (t_atom*) getbytes (sizeof(t_atom)*(size+2)); mtx_repmat_obj->list_out = list_out; mtx_repmat_obj->size = size; //post("size %d, rows %d, columns %d", size, rows, columns); } // main part
writeRepeatIntoMatrix (rep_rows, rep_cols, rows, columns, list_in, list_out+2); SETFLOAT(list_out, mrows); SETFLOAT(&list_out[1], mcolumns);
mTXRepmatBang (mtx_repmat_obj); }
void mtx_repmat_setup (void) { mtx_repmat_class = class_new (gensym("mtx_repmat"), (t_newmethod) newMTXRepmat, (t_method) deleteMTXRepmat, sizeof (MTXrepmat), CLASS_DEFAULT, A_GIMME, 0); class_addbang (mtx_repmat_class, (t_method) mTXRepmatBang); class_addmethod (mtx_repmat_class, (t_method) mTXRepmatMatrix, gensym("matrix"), A_GIMME,0); class_addmethod (mtx_repmat_class, (t_method) mTXRepmatList, gensym(""), A_GIMME,0); class_sethelpsymbol (mtx_repmat_class, gensym("iemmatrix/mtx_repmat")); }
void iemtx_repmat_setup(void){ mtx_repmat_setup(); }
--- NEW FILE: mtx_reverse.c --- /* * 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_reverse_class;
typedef struct _MTXreverse_ MTXreverse; struct _MTXreverse_ { t_object x_obj; int size; int reverse_dimension;
t_outlet *list_outlet;
t_atom *list_out; t_atom *list_in; };
static void deleteMTXreverse (MTXreverse *mtx_reverse_obj) { if (mtx_reverse_obj->list_out) freebytes (mtx_reverse_obj->list_out, sizeof(t_atom)*(mtx_reverse_obj->size+2)); }
static void mTXSetreverseDimension (MTXreverse *mtx_reverse_obj, t_float c_dim) { int dimension = (int) c_dim; dimension = (dimension > 0)?dimension:0; dimension = (dimension < 2)?dimension:2; mtx_reverse_obj->reverse_dimension = dimension; }
static void *newMTXreverse (t_symbol *s, int argc, t_atom *argv) { MTXreverse *mtx_reverse_obj = (MTXreverse *) pd_new (mtx_reverse_class); int c_dim = 0;
mtx_reverse_obj->reverse_dimension = c_dim; switch ((argc>1)?1:argc) { case 1: c_dim = atom_getint(argv); } mTXSetreverseDimension (mtx_reverse_obj, (t_float) c_dim);
mtx_reverse_obj->list_outlet = outlet_new (&mtx_reverse_obj->x_obj, gensym("matrix")); return ((void *) mtx_reverse_obj); }
static void mTXreverseBang (MTXreverse *mtx_reverse_obj) { if (mtx_reverse_obj->list_out) outlet_anything(mtx_reverse_obj->list_outlet, gensym("matrix"), mtx_reverse_obj->size+2, mtx_reverse_obj->list_out); }
static void copyList (int n, t_atom *x, t_atom *y) { for (;n--;) *y++ = *x++; } static void reverseList (int n, t_atom *y) { t_atom *read = y; t_atom tmp; y += n-1; n >>= 1; for (;n--;) { tmp = *y; *y-- = *read; *read++ = tmp; } } static void reverseListStep (int n, int step, t_atom *y) { t_atom *read = y; t_atom tmp; n /= step; y += (n-1) * step; n >>= 1; for (;n--; y-=step, read+=step) { tmp = *y; *y = *read; *read = tmp; } }
static void mTXreverseMatrix (MTXreverse *mtx_reverse_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_in = argv; t_atom *list_out = mtx_reverse_obj->list_out; int count;
// size check if (!size) { post("mtx_reverse: invalid dimensions"); return; } else if (list_size<size) { post("mtx_reverse: sparse matrix not yet supported: use "mtx_check""); return; }
if (size != mtx_reverse_obj->size) { if (!list_out) list_out = (t_atom *) getbytes (sizeof (t_atom) * (size + 2)); else list_out = (t_atom *) resizebytes (list_out, sizeof (t_atom) * (mtx_reverse_obj->size+2), sizeof (t_atom) * (size + 2)); }
mtx_reverse_obj->size = size; mtx_reverse_obj->list_out = list_out;
// main part list_out += 2; copyList (size, argv, list_out); switch (mtx_reverse_obj->reverse_dimension) { case 2: for (count = columns; count--; list_out++) reverseListStep (size, columns, list_out); break; case 1: for (count = rows; count--; list_out += columns) reverseList (columns, list_out); break; case 0: reverseList (size, list_out); break; } list_out = mtx_reverse_obj->list_out;
SETSYMBOL(list_out, gensym("matrix")); SETFLOAT(list_out, rows); SETFLOAT(&list_out[1], columns); outlet_anything(mtx_reverse_obj->list_outlet, gensym("matrix"), mtx_reverse_obj->size+2, list_out); }
void mtx_reverse_setup (void) { mtx_reverse_class = class_new (gensym("mtx_reverse"), (t_newmethod) newMTXreverse, (t_method) deleteMTXreverse, sizeof (MTXreverse), CLASS_DEFAULT, A_GIMME, 0); class_addbang (mtx_reverse_class, (t_method) mTXreverseBang); class_addmethod (mtx_reverse_class, (t_method) mTXreverseMatrix, gensym("matrix"), A_GIMME,0); class_addmethod (mtx_reverse_class, (t_method) mTXSetreverseDimension, gensym("dimension"), A_DEFFLOAT,0); class_sethelpsymbol (mtx_reverse_class, gensym("iemmatrix/mtx_reverse")); }
void iemtx_reverse_setup(void){ mtx_reverse_setup(); }
--- NEW FILE: mtx_cumsum.c --- /* * 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_cumsum_class;
typedef struct _MTXCumsum_ MTXCumsum; struct _MTXCumsum_ { t_object x_obj; int rows; int columns; int size; int cumsum_dimension; int cumsum_direction;
t_outlet *list_outlet;
t_atom *list_out; t_atom *list_in; t_float *x; t_float *y; };
static void deleteMTXCumsum (MTXCumsum *mtx_cumsum_obj) { if (mtx_cumsum_obj->list_out) freebytes (mtx_cumsum_obj->list_out, sizeof(t_atom)*(mtx_cumsum_obj->size+2)); if (mtx_cumsum_obj->x) freebytes (mtx_cumsum_obj->x, sizeof(t_float)*(mtx_cumsum_obj->size)); if (mtx_cumsum_obj->y) freebytes (mtx_cumsum_obj->y, sizeof(t_float)*(mtx_cumsum_obj->size)); }
static void mTXSetCumsumDirection (MTXCumsum *mtx_cumsum_obj, t_float c_dir) { int direction = (int) c_dir; mtx_cumsum_obj->cumsum_direction = (direction==-1)?direction:1; } static void mTXSetCumsumDimension (MTXCumsum *mtx_cumsum_obj, t_float c_dim) { int dimension = (int) c_dim; mtx_cumsum_obj->cumsum_dimension = (dimension==2)?dimension:1; }
static void *newMTXCumsum (t_symbol *s, int argc, t_atom *argv) { MTXCumsum *mtx_cumsum_obj = (MTXCumsum *) pd_new (mtx_cumsum_class); int c_dir = 1; int c_dim = 1;
mtx_cumsum_obj->cumsum_dimension = c_dim; switch ((argc>2)?2:argc) { case 2: c_dir = atom_getint(argv+1); case 1: c_dim = atom_getint(argv); } mTXSetCumsumDirection (mtx_cumsum_obj, (t_float) c_dir); mTXSetCumsumDimension (mtx_cumsum_obj, (t_float) c_dim);
mtx_cumsum_obj->list_outlet = outlet_new (&mtx_cumsum_obj->x_obj, gensym("matrix")); return ((void *) mtx_cumsum_obj); }
static void mTXCumsumBang (MTXCumsum *mtx_cumsum_obj) { if (mtx_cumsum_obj->list_out) outlet_anything(mtx_cumsum_obj->list_outlet, gensym("matrix"), mtx_cumsum_obj->size+2, mtx_cumsum_obj->list_out); }
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 cumSum (int n, t_float *x, t_float *y) { t_float accu = 0.0f; for (;n--; x++, y++) { accu += *x; *y = accu; } } static void cumSumReverse (int n, t_float *x, t_float *y) { t_float accu = 0.0f; for (;n--; x--, y--) { accu += *x; *y = accu; } }
static void mTXCumsumMatrix (MTXCumsum *mtx_cumsum_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_out = mtx_cumsum_obj->list_out; t_float *x = mtx_cumsum_obj->x; t_float *y = mtx_cumsum_obj->y; int count;
// size check if (!size) { post("mtx_cumsum: invalid dimensions"); return; } else if (list_size<size) { post("mtx_cumsum: sparse matrix not yet supported: use "mtx_check""); return; } else if ((!x)||(!list_out)||(!y)) { if (!x) x = (t_float *) getbytes (sizeof (t_float) * (size)); if (!y) y = (t_float *) getbytes (sizeof (t_float) * (size)); if (!list_out) list_out = (t_atom *) getbytes (sizeof (t_atom) * (size+2)); } else if (size != mtx_cumsum_obj->size) { x = (t_float *) resizebytes (x, sizeof (t_float) * (mtx_cumsum_obj->size), sizeof (t_float) * (size)); y = (t_float *) resizebytes (y, sizeof (t_float) * (mtx_cumsum_obj->size), sizeof (t_float) * (size)); list_out = (t_atom *) resizebytes (list_out, sizeof (t_atom) * (mtx_cumsum_obj->size+2), sizeof (t_atom) * (size + 2)); } mtx_cumsum_obj->size = size; mtx_cumsum_obj->rows = rows; mtx_cumsum_obj->columns = columns; mtx_cumsum_obj->list_out = list_out; mtx_cumsum_obj->x = x; mtx_cumsum_obj->y = y;
// main part // reading matrix from inlet if (mtx_cumsum_obj->cumsum_dimension == 2) { readFloatFromListModulo (size, columns, list_ptr, x); columns = mtx_cumsum_obj->rows; rows = mtx_cumsum_obj->columns; } else readFloatFromList (size, list_ptr, x);
// calculating cumsum if (mtx_cumsum_obj->cumsum_direction == -1) { x += columns-1; y += columns-1; for (count = rows; count--; x += columns, y += columns) cumSumReverse (columns,x,y); } else for (count = rows; count--; x += columns, y += columns) cumSum (columns,x,y); x = mtx_cumsum_obj->x; y = mtx_cumsum_obj->y;
// writing matrix to outlet if (mtx_cumsum_obj->cumsum_dimension == 2) { columns = mtx_cumsum_obj->columns; rows = mtx_cumsum_obj->rows; writeFloatIntoListModulo (size, columns, list_out+2, y); } else writeFloatIntoList (size, list_out+2, y);
SETSYMBOL(list_out, gensym("matrix")); SETFLOAT(list_out, rows); SETFLOAT(&list_out[1], columns); outlet_anything(mtx_cumsum_obj->list_outlet, gensym("matrix"), mtx_cumsum_obj->size+2, list_out); }
void mtx_cumsum_setup (void) { mtx_cumsum_class = class_new (gensym("mtx_cumsum"), (t_newmethod) newMTXCumsum, (t_method) deleteMTXCumsum, sizeof (MTXCumsum), CLASS_DEFAULT, A_GIMME, 0); class_addbang (mtx_cumsum_class, (t_method) mTXCumsumBang); class_addmethod (mtx_cumsum_class, (t_method) mTXCumsumMatrix, gensym("matrix"), A_GIMME,0); class_addmethod (mtx_cumsum_class, (t_method) mTXSetCumsumDimension, gensym("dimension"), A_DEFFLOAT,0); class_addmethod (mtx_cumsum_class, (t_method) mTXSetCumsumDirection, gensym("direction"), A_DEFFLOAT,0); class_sethelpsymbol (mtx_cumsum_class, gensym("iemmatrix/mtx_cumsum")); }
void iemtx_cumsum_setup(void){ mtx_cumsum_setup(); }
--- NEW FILE: mtx_conv.c --- /* * 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_conv_class;
typedef struct _MTXConv_ MTXConv; struct _MTXConv_ { t_object x_obj; int size; int rows; int columns; int rows_k; int columns_k; int size_k; int rows_y; int columns_y; int size_y; t_float renorm_fac;
t_float **x; t_float **k; t_float **y;
t_outlet *list_outlet;
t_atom *list; };
static t_float **getTFloatMatrix (int rows, int columns) { t_float **matrix = (t_float **) getbytes (sizeof (t_float *) * columns); t_float **mtx = matrix;
while (columns--) if (!(*matrix++ = (t_float *) getbytes (sizeof (t_float) * rows))) post("an error has occured :)"); return mtx; }
static void deleteTFloatMatrix (t_float **matrix, int rows, int columns) { int n = columns; t_float **matr = matrix; if (matr) { while (n--) if (*matr) freebytes (*matr++, sizeof(t_float) * rows); freebytes (matrix, sizeof(t_float*) * columns); } }
static t_float **resizeTFloatMatrix (t_float **old, int rows_old, int columns_old, int rows_new, int columns_new) { t_float **mtx = old; int count1, count2; post("resizing from %dx%d to %dx%d", rows_old, columns_old, rows_new, columns_new);
if ((rows_new == 0)||(columns_new == 0)) { deleteTFloatMatrix (old, rows_old, columns_old); old = 0; return; } // 1. if rows_old>rows_new: old row disposal if (rows_old>rows_new) for (count1 = (rows_old - rows_new), mtx += rows_new; count1--; mtx++) freebytes (*mtx, sizeof(t_float) * columns_old); // 2. resize row (double) pointer mtx = old = (t_float **) resizebytes(old, sizeof(t_float*) * rows_old, sizeof(t_float*) * rows_new); // 3. resizing rows if new size is smaller if (rows_old>rows_new) for (count1 = rows_new; count1--; mtx++) *mtx = (t_float *) resizebytes (*mtx, sizeof(t_float) * columns_old, sizeof(t_float) * columns_new); else { // 4. resizing old rows if new size is bigger, allocating new rows for (count1 = rows_old; count1--; mtx++) *mtx = (t_float *) resizebytes (*mtx, sizeof(t_float) * columns_old, sizeof(t_float) * columns_new); for (count1 = (rows_new - rows_old); count1--; mtx++) *mtx = (t_float *) getbytes (sizeof(t_float) * columns_new); } post("return resize"); return old; }
static void deleteMTXConv (MTXConv *mtx_conv_obj) { int count = mtx_conv_obj->rows; deleteTFloatMatrix (mtx_conv_obj->k, mtx_conv_obj->rows_k, mtx_conv_obj->columns_k); deleteTFloatMatrix (mtx_conv_obj->x, mtx_conv_obj->rows, mtx_conv_obj->columns); deleteTFloatMatrix (mtx_conv_obj->y, mtx_conv_obj->rows_y, mtx_conv_obj->columns_y); if (mtx_conv_obj->list) freebytes (mtx_conv_obj->list, sizeof(t_float) * (mtx_conv_obj->size_y + 2));
mtx_conv_obj->k = 0; mtx_conv_obj->x = 0; mtx_conv_obj->y = 0; mtx_conv_obj->list = 0; }
static void *newMTXConv (t_symbol *s, int argc, t_atom *argv) { MTXConv *mtx_conv_obj = (MTXConv *) pd_new (mtx_conv_class); mtx_conv_obj->list_outlet = outlet_new (&mtx_conv_obj->x_obj, gensym("matrix")); inlet_new(&mtx_conv_obj->x_obj, &mtx_conv_obj->x_obj.ob_pd, gensym("matrix"),gensym("")); mtx_conv_obj->size = 0; mtx_conv_obj->rows = 0; mtx_conv_obj->columns = 0; mtx_conv_obj->size_y = 0; mtx_conv_obj->rows_y = 0; mtx_conv_obj->columns_y = 0; mtx_conv_obj->size_k = 0; mtx_conv_obj->rows_k = 0; mtx_conv_obj->columns_k = 0; return ((void *) mtx_conv_obj); }
static void mTXConvBang (MTXConv *mtx_conv_obj) { if (mtx_conv_obj->list) outlet_anything(mtx_conv_obj->list_outlet, gensym("matrix"), mtx_conv_obj->size+2, mtx_conv_obj->list); }
static void zeroFloatArray (int n, t_float *f) { while (n--) *f++ = 0.0f; } static void zeroTFloatMatrix (t_float **mtx, int rows, int columns) { while (rows--) zeroFloatArray (columns, *mtx++); }
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 scaleVector (int n, t_float *x, t_float *y, t_float k) { while (n--) *y++ = k * *x++; } static void addWeightedVector (int n, t_float *x, t_float *y, t_float k) { while (n--) *y++ += k * *y++; } static void readMatrixFromList (int rows, int columns, t_atom *l, t_float **mtx) { for (;rows--; l+=columns) readFloatFromList (columns, l, *mtx++); } static void writeMatrixIntoList (int rows, int columns, t_atom *l, t_float **mtx) { for (;rows--; l+=columns) writeFloatIntoList (columns, l, *mtx++); }
static void mTXConvKernelMatrix (MTXConv *mtx_conv_obj, t_symbol *s, int argc, t_atom *argv) { int rows_k = atom_getint (argv++); int columns_k = atom_getint (argv++); int in_size = argc-2; int size_k = rows_k * columns_k; t_float **k = mtx_conv_obj->k;
if (!size_k) post ("mtx_conv: invalid matrix dimensions!"); else if (in_size < size_k) post("mtx_conv: sparse matrix not yet supported: use "mtx_check""); else if ((rows_k != mtx_conv_obj->rows_k) || (columns_k != mtx_conv_obj->columns_k)) { if (k) k = resizeTFloatMatrix (k, mtx_conv_obj->rows_k, mtx_conv_obj->columns_k, rows_k, columns_k); else k = getTFloatMatrix (rows_k, columns_k);
mtx_conv_obj->rows_k = rows_k; mtx_conv_obj->columns_k = columns_k;
readMatrixFromList (rows_k, columns_k, argv, k);
mtx_conv_obj->k = k; mtx_conv_obj->size_k = size_k; } else readMatrixFromList (rows_k, columns_k, argv, k); } static void convolveRow (int columns, int columns_c, t_float *x, t_float *c, t_float *y) { int n,k,count; for (k = 0; k < columns_c; k++) for (n = k, count = columns; count--; n++) y[n] += x[n-k] * c[k]; }
static void convolveMtx (int rows, int columns, int rows_c, int columns_c, t_float **x, t_float **c, t_float **y) { int n,k,count; zeroTFloatMatrix (y, rows+rows_c-1, columns+columns_c-1); for (k = 0; k < rows_c; k++) for (n = k, count = rows; count--; n++) convolveRow (columns, columns_c, x[n-k], c[k], y[n]); }
static void mTXConvMatrix (MTXConv *mtx_conv_obj, t_symbol *s, int argc, t_atom *argv) { int rows = atom_getint (argv++); int columns = atom_getint (argv++); int size = rows * columns; int rows_k = mtx_conv_obj->rows_k; int columns_k = mtx_conv_obj->columns_k; int size_k = mtx_conv_obj->size_k; int in_size = argc-2; int rows_y; int columns_y; int size_y = mtx_conv_obj->size_y; t_atom *list_ptr = mtx_conv_obj->list; t_float **x = mtx_conv_obj->x; t_float **y = mtx_conv_obj->y; t_float **k = mtx_conv_obj->k; t_float *ptr1; t_float *ptr2; int row_count; int offset1; int offset2; int count;
// fftsize check if (!size){ post("mtx_conv: invalid dimensions"); return; } else if (in_size<size) { post("mtx_conv: sparse matrix not yet supported: use "mtx_check""); return; } else if (!size_k) { post("mtx_conv: no valid filter kernel defined"); return; }
post("1");
if ((mtx_conv_obj->rows != rows)||(mtx_conv_obj->columns != columns)) { if (x) x = resizeTFloatMatrix (x, mtx_conv_obj->rows, mtx_conv_obj->columns, rows, columns); else x = getTFloatMatrix (rows, columns); mtx_conv_obj->x = x; mtx_conv_obj->size = size; mtx_conv_obj->rows = rows; mtx_conv_obj->columns = columns; } post("2"); rows_y = rows+rows_k-1; columns_y = columns+columns_k-1; if ((mtx_conv_obj->rows_y != rows_y)||(mtx_conv_obj->columns_y != columns_y)) { size_y = rows_y * columns_y; if (y) y = resizeTFloatMatrix (y, mtx_conv_obj->rows_y, mtx_conv_obj->columns_y, rows_y, columns_y); else y = getTFloatMatrix (rows_y, columns_y); if (list_ptr) list_ptr = (t_atom *) resizebytes (list_ptr, sizeof(t_atom) * (mtx_conv_obj->size_y+2), sizeof (t_atom) * (size_y+2)); else list_ptr = (t_atom *) getbytes (sizeof (t_atom) * (size_y+2)); mtx_conv_obj->size_y = size_y; mtx_conv_obj->rows_y = rows_y; mtx_conv_obj->columns_y = columns_y; mtx_conv_obj->y = y; mtx_conv_obj->list = list_ptr; } post("3"); // main part readMatrixFromList (rows, columns, argv, x); post("4"); convolveMtx (rows, columns, rows_k, columns_k, x, k, y); post("5"); writeMatrixIntoList (rows_y, columns_y, list_ptr+2, y); post("6"); SETSYMBOL(list_ptr, gensym("matrix")); SETFLOAT(list_ptr, rows_y); SETFLOAT(&list_ptr[1], columns_y); outlet_anything(mtx_conv_obj->list_outlet, gensym("matrix"), size_y+2, list_ptr); post("7"); }
void mtx_conv_setup (void) { mtx_conv_class = class_new (gensym("mtx_conv"), (t_newmethod) newMTXConv, (t_method) deleteMTXConv, sizeof (MTXConv), CLASS_DEFAULT, A_GIMME, 0); class_addbang (mtx_conv_class, (t_method) mTXConvBang); class_addmethod (mtx_conv_class, (t_method) mTXConvMatrix, gensym("matrix"), A_GIMME,0); class_addmethod (mtx_conv_class, (t_method) mTXConvKernelMatrix, gensym(""), A_GIMME,0); class_sethelpsymbol (mtx_conv_class, gensym("iemmatrix/mtx_conv")); }
void iemtx_conv_setup(void){ mtx_conv_setup(); }