diff options
author | IOhannes m zmölnig <zmoelnig@users.sourceforge.net> | 2005-09-20 08:12:38 +0000 |
---|---|---|
committer | IOhannes m zmölnig <zmoelnig@users.sourceforge.net> | 2005-09-20 08:12:38 +0000 |
commit | 59a57d6fd293f9ff9bfe86cf2da90a890495c16b (patch) | |
tree | a52e24b949fbc1f45968c6a8fdc2b8887ac9bdf4 /src/mtx_slice.c | |
parent | 208200ef713d588a1cb5c4d125b2bfccc9a7e2ce (diff) |
added more objects by fz
svn path=/trunk/externals/iem/iemmatrix/; revision=3600
Diffstat (limited to 'src/mtx_slice.c')
-rw-r--r-- | src/mtx_slice.c | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/src/mtx_slice.c b/src/mtx_slice.c new file mode 100644 index 0000000..7dc1042 --- /dev/null +++ b/src/mtx_slice.c @@ -0,0 +1,215 @@ +/* + * 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_slice_class; + +typedef struct _MTXslice_ MTXslice; +struct _MTXslice_ +{ + t_object x_obj; + int slice_size; + int slice_startcol; + int slice_startrow; + int slice_stopcol; + int slice_stoprow; + + t_outlet *list_outlet; + + t_atom *list_out; +}; + +static void deleteMTXSlice (MTXslice *mtx_slice_obj) +{ + if (mtx_slice_obj->list_out) + freebytes (mtx_slice_obj->list_out, sizeof(t_atom)*(mtx_slice_obj->slice_size+2)); +} + +static void mTXSliceIndexList (MTXslice *mtx_slice_obj, t_symbol *s, + int argc, t_atom *argv) +{ + int startcol; + int startrow; + int stopcol; + int stoprow; + t_symbol *endsym = gensym("end"); + t_atom *list_out = mtx_slice_obj->list_out; + + if (argc<4) { + post("mtx_slice: invalid index vector: <startrow><startcol><stoprow><stopcol>"); + return; + } + startrow = atom_getint(&argv[0]); + startcol = atom_getint(&argv[1]); + stoprow = atom_getint(&argv[2]); + stopcol = atom_getint(&argv[3]); + if (atom_getsymbol(&argv[0])==endsym) { + startrow = -1; + } + if (atom_getsymbol(&argv[1])==endsym) { + startcol = -1; + } + if (atom_getsymbol(&argv[2])==endsym) { + stoprow = -1; + } + if (atom_getsymbol(&argv[3])==endsym) { + stopcol = -1; + } + + if (((startrow<1) && (atom_getsymbol(&argv[0])!=endsym)) || + ((startcol<1) && (atom_getsymbol(&argv[1])!=endsym))) { + post("mtx_slice: row and column indices must be >0, or misused \"end\" keyword"); + return; + } + + if (((startrow>stoprow) && (atom_getsymbol(&argv[2])!=endsym)) || + ((startcol>stopcol) && (atom_getsymbol (&argv[3])!=endsym))) { + post("mtx_slice: start_index<stop_index for rows and columns, or misused \"end\" keyword"); + return; + } + + mtx_slice_obj->slice_startrow = startrow; + mtx_slice_obj->slice_startcol = startcol; + mtx_slice_obj->slice_stoprow = stoprow; + mtx_slice_obj->slice_stopcol = stopcol; +} + +static void *newMTXSlice (t_symbol *s, int argc, t_atom *argv) +{ + MTXslice *mtx_slice_obj = (MTXslice *) pd_new (mtx_slice_class); + if (argc==4) + mTXSliceIndexList (mtx_slice_obj, gensym("list"),argc,argv); + else { + mtx_slice_obj->slice_startrow = 1; + mtx_slice_obj->slice_startcol = 1; + mtx_slice_obj->slice_stopcol = -1; + mtx_slice_obj->slice_stoprow = -1; + } + mtx_slice_obj->list_outlet = outlet_new (&mtx_slice_obj->x_obj, gensym("matrix")); + inlet_new(&mtx_slice_obj->x_obj, &mtx_slice_obj->x_obj.ob_pd, gensym("list"),gensym("")); + return ((void *) mtx_slice_obj); +} + +static void mTXSliceBang (MTXslice *mtx_slice_obj) +{ + if (mtx_slice_obj->list_out) + outlet_anything(mtx_slice_obj->list_outlet, gensym("matrix"), + mtx_slice_obj->slice_size+2, mtx_slice_obj->list_out); +} +/* + static void copyList (int size, t_atom *x, t_atom *y) + { + while(size--) + *y++=*x++; + } +*/ + +static void writeVectorIntoList (int n, t_atom *x, t_atom *y) +{ + for (;n--;x++,y++) + *y = *x; +} + +static void writeSliceIntoList (int slicerows, const int slicecols, int columns, t_atom *x, t_atom *y) +{ + for (;slicerows--;x+=columns,y+=slicecols) + writeVectorIntoList(slicecols, x, y); +} + +static void mTXSliceMatrix (MTXslice *mtx_slice_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_slice_obj->list_out; + int stopcol = mtx_slice_obj->slice_stopcol; + int stoprow = mtx_slice_obj->slice_stoprow; + int startrow = mtx_slice_obj->slice_startrow; + int startcol = mtx_slice_obj->slice_startcol; + int slicecols, slicerows, slicesize; + + // size check + if (!size) { + post("mtx_slice: invalid dimensions"); + return; + } + else if (list_size<size) { + post("mtx_slice: sparse matrix not yet supported: use \"mtx_check\""); + return; + } + startrow = (startrow==-1)?rows:startrow; + startcol = (startcol==-1)?columns:startcol; + stoprow = (stoprow==-1)?rows:stoprow; + stopcol = (stopcol==-1)?columns:stopcol; + if ((!startrow)||(!startcol)) { + post("mtx_slice: indices must be >0"); + return; + } + if ((stopcol > columns) || + (stoprow > rows)) { + post("mtx_slice: slice index exceeds matrix dimensions"); + return; + } + if ((stoprow<startrow) || (stopcol<startcol)) { + post("mtx_slice: start_index<stop_index for rows and columns, or misused \"end\" keyword"); + return; + } + slicerows = stoprow-startrow+1; + slicecols = stopcol-startcol+1; + slicesize = slicerows*slicecols; + + // main part + if (slicesize != mtx_slice_obj->slice_size) { + if (!list_out) + list_out = (t_atom *) getbytes (sizeof (t_atom) * (slicesize + 2)); + else + list_out = (t_atom *) resizebytes (list_out, + sizeof (t_atom) * (mtx_slice_obj->slice_size+2), + sizeof (t_atom) * (slicesize + 2)); + mtx_slice_obj->slice_size = slicesize; + mtx_slice_obj->list_out = list_out; + } + list_out += 2; + list_in += columns * (startrow-1) + startcol-1; + writeSliceIntoList (slicerows, slicecols, + columns, list_in,list_out); + list_out = mtx_slice_obj->list_out; + SETSYMBOL(list_out, gensym("matrix")); + SETFLOAT(list_out, slicerows); + SETFLOAT(&list_out[1], slicecols); + outlet_anything(mtx_slice_obj->list_outlet, gensym("matrix"), + slicesize+2, list_out); +} + +void mtx_slice_setup (void) +{ + mtx_slice_class = class_new + (gensym("mtx_slice"), + (t_newmethod) newMTXSlice, + (t_method) deleteMTXSlice, + sizeof (MTXslice), + CLASS_DEFAULT, A_GIMME, 0); + class_addbang (mtx_slice_class, (t_method) mTXSliceBang); + class_addmethod (mtx_slice_class, (t_method) mTXSliceMatrix, gensym("matrix"), A_GIMME,0); + class_addmethod (mtx_slice_class, (t_method) mTXSliceIndexList, gensym(""), A_GIMME,0); + class_sethelpsymbol (mtx_slice_class, gensym("iemmatrix/mtx_slice")); +} + +void iemtx_slice_setup(void){ + mtx_slice_setup(); +} |