aboutsummaryrefslogtreecommitdiff
path: root/src/mtx_concat.c
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 /src/mtx_concat.c
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
Diffstat (limited to 'src/mtx_concat.c')
-rw-r--r--src/mtx_concat.c182
1 files changed, 182 insertions, 0 deletions
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();
+}