From df4f70b90bbc9ee6ef23c81cb143d92c61e4d759 Mon Sep 17 00:00:00 2001 From: Franz Zotter Date: Mon, 26 Sep 2005 11:01:28 +0000 Subject: adding matrix concatenation external. two matrices can be concatenated to one bigger matrix. you can select if the second matrix is appended in row or in column direction. svn path=/trunk/externals/iem/iemmatrix/; revision=3635 --- src/iemmatrix_sources.c | 3 +- src/iemmatrix_sources.h | 3 +- src/mtx_concat.c | 182 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+), 2 deletions(-) create mode 100644 src/mtx_concat.c diff --git a/src/iemmatrix_sources.c b/src/iemmatrix_sources.c index 7684656..1d6ed9c 100644 --- a/src/iemmatrix_sources.c +++ b/src/iemmatrix_sources.c @@ -19,6 +19,7 @@ void iemmatrix_sources_setup(void) iemtx_cholesky_setup(); /* mtx_cholesky.c */ iemtx_col_setup(); /* mtx_col.c */ iemtx_colon_setup(); /* mtx_colon.c */ + iemtx_concat_setup(); /* mtx_concat.c */ iemtx_conv_setup(); /* mtx_conv.c */ iemtx_cos_setup(); /* mtx_cos.c */ iemtx_cumsum_setup(); /* mtx_cumsum.c */ @@ -49,8 +50,8 @@ void iemmatrix_sources_setup(void) 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_mul_setup(); /* mtx_mul.c */ iemtx_neq_setup(); /* mtx_neq.c */ iemtx_not_setup(); /* mtx_not.c */ iemtx_ones_setup(); /* mtx_ones.c */ diff --git a/src/iemmatrix_sources.h b/src/iemmatrix_sources.h index afd6a24..fce8a0f 100644 --- a/src/iemmatrix_sources.h +++ b/src/iemmatrix_sources.h @@ -17,6 +17,7 @@ void iemtx_check_setup(void); /* mtx_check.c */ 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_concat_setup(void); /* mtx_concat.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 */ @@ -47,8 +48,8 @@ void iemtx_max2_setup(void); /* mtx_max2.c */ 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_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 */ diff --git a/src/mtx_concat.c b/src/mtx_concat.c new file mode 100644 index 0000000..98647a5 --- /dev/null +++ b/src/mtx_concat.c @@ -0,0 +1,182 @@ +/* + * 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_concat_class; +static t_symbol *row_sym; + +typedef struct _MTXconcat_ MTXconcat; +struct _MTXconcat_ +{ + t_object x_obj; + int size; + t_symbol *concat_mode; + t_matrix mtx_in1; + t_matrix mtx_in2; + t_matrix mtx_out; + + t_outlet *outl; +}; + +static void deleteMTXConcat (MTXconcat *mtx_concat_obj) +{ + matrix_free(&mtx_concat_obj->mtx_in2); + matrix_free(&mtx_concat_obj->mtx_out); +} + +static void mTXSetConcatMode (MTXconcat *mtx_concat_obj, t_symbol *c_mode) +{ + mtx_concat_obj->concat_mode = c_mode; +} + +static void *newMTXConcat (t_symbol *s, int argc, t_atom *argv) +{ + MTXconcat *mtx_concat_obj = (MTXconcat *) pd_new (mtx_concat_class); + + mTXSetConcatMode (mtx_concat_obj, gensym(":")); + if ((argc>=1)) + mTXSetConcatMode (mtx_concat_obj, atom_getsymbol(argv)); + + mtx_concat_obj->outl = mtx_concat_obj->mtx_out.x_outlet = outlet_new (&mtx_concat_obj->x_obj, gensym("matrix")); + inlet_new(&mtx_concat_obj->x_obj, &mtx_concat_obj->x_obj.ob_pd, gensym("matrix"),gensym("")); + return ((void *) mtx_concat_obj); +} + +static void mTXConcatBang (MTXconcat *mtx_concat_obj) +{ + outlet_anything(mtx_concat_obj->outl, gensym("matrix"), + mtx_concat_obj->mtx_out.row * mtx_concat_obj->mtx_out.col + 2, + mtx_concat_obj->mtx_out.atombuffer); +} + +static void copyList (int n, t_atom *x, t_atom *y) +{ + while (n--) + *y++=*x++; +} + +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 mTXConcatMatrix2 (MTXconcat *mtx_concat_obj, t_symbol *s, + int argc, t_atom *argv) +{ + matrix_matrix2 (&mtx_concat_obj->mtx_in2, s, argc, argv); +} + +static void mTXConcatDoRowConcatenation (MTXconcat *mtx_concat_obj, + t_matrix *mtx1, t_matrix *mtx2, t_matrix *mtx_out) +{ + int mcols = mtx1->col + mtx2->col; + int cnt; + t_atom *ptr_in1 = mtx1->atombuffer+2; + t_atom *ptr_in2 = mtx2->atombuffer+2; + t_atom *ptr_out; + + if (mtx1->row != mtx2->row) { + post("mtx_concat: row-mode: matrices must have same number of rows!"); + return; + } + adjustsize (mtx_out, mtx1->row, mcols); + ptr_out = mtx_out->atombuffer+2; + for (cnt=mtx1->row; cnt--; ptr_in1 += mtx1->col, + ptr_in2 += mtx2->col, ptr_out += mtx_out->col) { + memcpy (ptr_out, ptr_in1, mtx1->col * sizeof(t_atom)); + memcpy (ptr_out+mtx1->col, ptr_in2, mtx2->col * sizeof(t_atom)); + } + mTXConcatBang(mtx_concat_obj); +} +static void mTXConcatDoColConcatenation (MTXconcat *mtx_concat_obj, + t_matrix *mtx1, t_matrix *mtx2, t_matrix *mtx_out) +{ + int mrows = mtx1->row + mtx2->row; + int cnt; + t_atom *ptr_in1 = mtx1->atombuffer+2; + t_atom *ptr_in2 = mtx2->atombuffer+2; + t_atom *ptr_out; + + if (mtx1->col != mtx2->col) { + post("mtx_concat: col-mode: matrices must have same number of columns!"); + return; + } + adjustsize (mtx_out, mrows, mtx1->col); + ptr_out = mtx_out->atombuffer+2; + for (cnt=mtx1->row; cnt--; ptr_in1 += mtx1->col, + ptr_out += mtx_out->col) { + memcpy (ptr_out, ptr_in1, mtx1->col * sizeof(t_atom)); + } + for (cnt=mtx2->row; cnt--; ptr_in2 += mtx2->col, + ptr_out += mtx_out->col) { + memcpy (ptr_out, ptr_in2, mtx2->col * sizeof(t_atom)); + } + + mTXConcatBang(mtx_concat_obj); +} +static void mTXConcatMatrix (MTXconcat *mtx_concat_obj, t_symbol *s, + int argc, t_atom *argv) +{ + int rows = atom_getint (argv); + int columns = atom_getint (argv+1); + int size = rows * columns; + int list_size = argc-2; + t_matrix *mtx_in1 = &mtx_concat_obj->mtx_in1; + t_matrix *mtx_in2 = &mtx_concat_obj->mtx_in2; + t_matrix *mtx_out = &mtx_concat_obj->mtx_out; + + // size check + if (!size) { + post("mtx_concat: invalid dimensions"); + return; + } + else if (list_sizerow = rows; + mtx_in1->col = columns; + mtx_in1->atombuffer = argv; +// alternatively to the above: +// matrix_matrix2 (mtx_in1, s, argc, argv); + + if (mtx_concat_obj->concat_mode == row_sym) { + mTXConcatDoRowConcatenation(mtx_concat_obj, mtx_in1, mtx_in2, mtx_out); + } + else { + mTXConcatDoColConcatenation(mtx_concat_obj, mtx_in1, mtx_in2, mtx_out); + } +} + +void mtx_concat_setup (void) +{ + mtx_concat_class = class_new + (gensym("mtx_concat"), + (t_newmethod) newMTXConcat, + (t_method) deleteMTXConcat, + sizeof (MTXconcat), + CLASS_DEFAULT, A_GIMME, 0); + class_addbang (mtx_concat_class, (t_method) mTXConcatBang); + class_addmethod (mtx_concat_class, (t_method) mTXConcatMatrix, gensym("matrix"), A_GIMME,0); + class_addmethod (mtx_concat_class, (t_method) mTXConcatMatrix2, gensym(""), A_GIMME,0); + class_addmethod (mtx_concat_class, (t_method) mTXSetConcatMode, gensym("mode"), A_DEFSYMBOL,0); + class_sethelpsymbol (mtx_concat_class, gensym("iemmatrix/mtx_concat")); + row_sym = gensym("row"); +} + +void iemtx_concat_setup(void){ + mtx_concat_setup(); +} -- cgit v1.2.1