/* * 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_pivot */ static t_class *mtx_pivot_class; typedef struct _mtx_pivot { t_object x_obj; t_matrix m; // the output matrix t_matrix m_pre; // the pre -multiply matrix t_matrix m_post; // the post-multiply matrix t_outlet *pivo, *pre, *post; t_int ascending; } t_mtx_pivot; static void mtx_pivot_matrix(t_mtx_pivot *x, t_symbol *s, int argc, t_atom *argv) { int row=atom_getfloat(argv); int col=atom_getfloat(argv+1); t_atom *m_pre, *m_post; int i, j, k; int min_rowcol = (rowascending); if (argc<2){ post("mtx_pivot: crippled matrix"); return; } if ((col<1)||(row<1)){ post("mtx_pivot: invalid dimensions"); return; } if (col*row>argc-2){ post("sparse matrix not yet supported : use \"mtx_check\""); return; } adjustsize(&x->m, row, col); adjustsize(&x->m_pre, row, row); adjustsize(&x->m_post,col, col); matrix_set(&x->m_pre, 0); matrix_set(&x->m_post, 0); buffer = matrix2float(argv); i_pre = (int *)getbytes(sizeof(int)*row); i_post = (int *)getbytes(sizeof(int)*col); /* clear pre&post matrices */ i=row; i_buf=i_pre; while(i--)*i_buf++=row-i-1; i=col; i_buf=i_post; while(i--)*i_buf++=col-i-1; /* do the pivot thing */ for (k=0; ktmp) || (!ascending && fm.atombuffer, buffer); i=col; m_post = x->m_post.atombuffer+2; while(i--){ SETFLOAT(m_post+i_post[i]*col+i, 1); } i=row; m_pre = x->m_pre.atombuffer+2; while(i--){ SETFLOAT(m_pre+i_pre[i]+i*row, 1); } outlet_anything(x->post, gensym("matrix"), 2+col*col, x->m_post.atombuffer); outlet_anything(x->pre, gensym("matrix"), 2+row*row, x->m_pre.atombuffer); outlet_anything(x->pivo , gensym("matrix"), 2+row*col, x->m.atombuffer ); } static void mtx_pivot_free(t_mtx_pivot *x) { matrix_free(&x->m); matrix_free(&x->m_pre); matrix_free(&x->m_post); } static void *mtx_pivot_new(t_floatarg f) { t_mtx_pivot *x = (t_mtx_pivot *)pd_new(mtx_pivot_class); x->pivo = outlet_new(&x->x_obj, 0); x->pre = outlet_new(&x->x_obj, 0); x->post = outlet_new(&x->x_obj, 0); x->ascending = (f < 0.f)?0:1; x->m.atombuffer = x->m_pre.atombuffer = x->m_post.atombuffer = 0; x->m.row = x->m.col = x->m_pre.row = x->m_pre.col = x->m_post.row = x->m_post.col = 0; return(x); } void mtx_pivot_setup(void) { mtx_pivot_class = class_new(gensym("mtx_pivot"), (t_newmethod)mtx_pivot_new, (t_method)mtx_pivot_free, sizeof(t_mtx_pivot), 0, A_DEFFLOAT, 0); class_addmethod(mtx_pivot_class, (t_method)mtx_pivot_matrix, gensym("matrix"), A_GIMME, 0); class_sethelpsymbol(mtx_pivot_class, gensym("iemmatrix/mtx_transpose")); } void iemtx_pivot_setup(void) { mtx_pivot_setup(); }