aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFranz Zotter <fzotter@users.sourceforge.net>2005-09-26 11:01:28 +0000
committerFranz Zotter <fzotter@users.sourceforge.net>2005-09-26 11:01:28 +0000
commitdf4f70b90bbc9ee6ef23c81cb143d92c61e4d759 (patch)
tree50b9a104c19daa8ffcb1598f6c57b4edca055a9a
parentb810cd1f4f95524debe30fe8805565aedfb151a3 (diff)
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
-rw-r--r--src/iemmatrix_sources.c3
-rw-r--r--src/iemmatrix_sources.h3
-rw-r--r--src/mtx_concat.c182
3 files changed, 186 insertions, 2 deletions
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_size<size) {
+ post("mtx_concat: sparse matrix not yet supported: use \"mtx_check\"");
+ return;
+ }
+ mtx_in1->row = 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();
+}