Update of /cvsroot/pure-data/externals/iem/iemmatrix/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19682
Modified Files: iemmatrix.h Added Files: iemmatrix_binops.c iemmatrix_utility.c matrix.c Log Message: adopted iemmatrix to the new buildsystem
--- NEW FILE: iemmatrix_binops.c --- /* * 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"
/* -------------------------------------------------------------- */ /* matrix math */
void mtx_bin_matrix2(t_mtx_binmtx *x, t_symbol *s, int argc, t_atom *argv) { int row = atom_getfloat(argv); int col = atom_getfloat(argv+1); if (argc<2){post("mtx_bin2: crippled matrix"); return;} if ((col<1)||(row<1)) {post("mtx_bin2: invalid dimensions %dx%d", row,col); return;} if (col*row+2>argc){ post("mtx_bin2: sparse matrix not yet supported : use "mtx_check""); return;}
if (row*col!=x->m2.row*x->m2.col) { freebytes(x->m2.atombuffer, (x->m2.row*x->m2.col+2)*sizeof(t_atom)); x->m2.atombuffer=copybytes(argv,(row*col+2)*sizeof(t_atom)); }else memcpy(x->m2.atombuffer, argv, (row*col+2)*sizeof(t_atom)); setdimen(&x->m2, row, col); }
void mtx_binmtx_bang(t_mtx_binmtx *x) { if((&x->m)&&(x->m.atombuffer)) outlet_anything(x->x_obj.ob_outlet, gensym("matrix"), x->m.col*x->m.row+2, x->m.atombuffer); }
void mtx_binmtx_free(t_mtx_binmtx *x) { matrix_free(&x->m); matrix_free(&x->m2); } void mtx_binscalar_bang(t_mtx_binscalar *x) { if((&x->m)&&(x->m.atombuffer)) outlet_anything(x->x_obj.ob_outlet, gensym("matrix"), x->m.col*x->m.row+2, x->m.atombuffer); } void mtx_binscalar_free(t_mtx_binscalar *x) { matrix_free(&x->m); }
void iemtx_binops_setup(void) { }
Index: iemmatrix.h =================================================================== RCS file: /cvsroot/pure-data/externals/iem/iemmatrix/src/iemmatrix.h,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** iemmatrix.h 15 Dec 2006 13:04:06 -0000 1.12 --- iemmatrix.h 11 Jan 2007 19:41:20 -0000 1.13 *************** *** 122,125 **** --- 122,130 ----
+ /* + G.Holzmann: the following is now implemented + in iemmatrix_utility.c + */ + void matrix_free(t_matrix*x);
*************** *** 150,153 **** --- 155,162 ----
+ /* + in iemmatrix_binops.c + */ + void mtx_bin_matrix2(t_mtx_binmtx *x, t_symbol *s, int argc, t_atom *argv); void mtx_binmtx_bang(t_mtx_binmtx *x);
--- NEW FILE: matrix.c --- /* * 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. * */
/* matrix : basic object : create and store matrices mtx : alias for matrix */
#include "iemmatrix.h" #include <stdio.h> #ifdef _WIN32 /* or should we use the security enhanced _snprintf_s() ?? */ # define snprintf _snprintf #endif
/* -------------------- matrix ------------------------------ */ /* G.Holzmann: see iemmatrix_utility.c for the functions you don't find here ... ;) */
static t_class *matrix_class;
static void matrix_matrix(t_matrix *x, t_symbol *s, int argc, t_atom *argv) { int row, col;
if (argc<2){ post("matrix : corrupt matrix passed"); return; } row = atom_getfloat(argv); col = atom_getfloat(argv+1); if ((row<1)||(col<1)){ post("matrix : corrupt matrix passed"); return; } if (row*col > argc-2){ post("matrix: sparse matrices not yet supported : use "mtx_check""); return; }
matrix_matrix2(x, s, argc, argv); matrix_bang(x); }
static void matrix_float(t_matrix *x, t_float f) { matrix_set(x, f); matrix_bang(x); }
static void matrix_size(t_matrix *x, t_symbol *s, int argc, t_atom *argv) { int col, row;
switch(argc) { case 0: /* size */ if (x->row*x->col) outlet_list(x->x_obj.ob_outlet, gensym("size"), 2, x->atombuffer); break; case 1: row=atom_getfloat(argv); adjustsize(x, row, row); matrix_set(x, 0); break; default: row=atom_getfloat(argv++); col=atom_getfloat(argv); adjustsize(x, row, col); matrix_set(x, 0); } }
/* ------------- file I/O ------------------ */
static void matrix_read(t_matrix *x, t_symbol *filename) { t_binbuf *bbuf = binbuf_new(); t_atom *ap; int n;
if (binbuf_read_via_path(bbuf, filename->s_name, canvas_getdir(x->x_canvas)->s_name, 0)) pd_error(x,"matrix: failed to read %128s", filename->s_name);
ap=binbuf_getvec(bbuf); n =binbuf_getnatom(bbuf)-1;
if ((ap->a_type == A_SYMBOL) && (!strcmp(ap->a_w.w_symbol->s_name,"matrix") || !strcmp(ap->a_w.w_symbol->s_name,"#matrix")) ){ matrix_matrix2(x, gensym("matrix"), n, ap+1); }
binbuf_free(bbuf); }
static void matrix_write(t_matrix *x, t_symbol *filename) { t_atom *ap=x->atombuffer+2; char *filnam = (char*)getbytes(sizeof(char)*MAXPDSTRING); int rows = x->row, cols = x->col; FILE *f=0;
sys_bashfilename(filename->s_name, filnam);
/* open file */ if (!(f = fopen(filnam, "w"))) { pd_error(x,"matrix : failed to open %128s", filnam); } else { char *text=(char *)getbytes(sizeof(char)*MAXPDSTRING); int textlen;
/* header: * we now write "#matrix" instead of "matrix", * so that these files can easily read by other * applications such as octave */ snprintf(text, MAXPDSTRING, "#matrix %d %d\n", rows, cols); text[MAXPDSTRING-1]=0; textlen = strlen(text); if (fwrite(text, textlen*sizeof(char), 1, f) < 1) { pd_error(x,"matrix : failed to write %128s", filnam); goto end; }
while(rows--) { int c = cols; while (c--) { t_float val = atom_getfloat(ap++); snprintf(text, MAXPDSTRING, "%.15f ", val); text[MAXPDSTRING-1]=0; textlen=strlen(text); if (fwrite(text, textlen*sizeof(char), 1, f) < 1) { pd_error(x,"matrix : failed to write %128s", filnam); goto end; } } if (fwrite("\n", sizeof(char), 1, f) < 1) { pd_error(x, "matrix : failed to write %128s", filnam); goto end; } } freebytes(text, sizeof(char)*MAXPDSTRING); }
end: /* close file */ if (f) fclose(f); if(filnam)freebytes(filnam, sizeof(char)*MAXPDSTRING); }
static void matrix_list(t_matrix *x, t_symbol *s, int argc, t_atom *argv) { /* like matrix, but without col/row information, so the previous size is kept */ int row=x->row, col=x->col;
if(!row*col){ post("matrix : unknown matrix dimensions"); return; } if (argc<row*col){ post("matrix: sparse matrices not yet supported : use "mtx_check" !"); return; }
memcpy(x->atombuffer+2, argv, row*col*sizeof(t_atom)); matrix_bang(x); }
static void *matrix_new(t_symbol *s, int argc, t_atom *argv) { t_matrix *x = (t_matrix *)pd_new(matrix_class); int row, col;
inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("matrix"), gensym("")); outlet_new(&x->x_obj, 0);
x->atombuffer = 0; x->x_canvas = canvas_getcurrent();
switch (argc) { case 0: row = col = 0; break; case 1: if (argv->a_type == A_SYMBOL) { matrix_read(x, argv->a_w.w_symbol); return(x); } row = col = atom_getfloat(argv); break; default: row = atom_getfloat(argv++); col = atom_getfloat(argv++); }
if(row*col){ adjustsize(x, row, col); matrix_set(x, 0); }
return (x); }
void matrix_setup(void) { matrix_class = class_new(gensym("matrix"), (t_newmethod)matrix_new, (t_method)matrix_free, sizeof(t_matrix), 0, A_GIMME, 0); class_addcreator((t_newmethod)matrix_new, gensym("mtx"), A_GIMME, 0);
/* the core : functions for matrices */ class_addmethod (matrix_class, (t_method)matrix_matrix, gensym("matrix"), A_GIMME, 0); class_addmethod (matrix_class, (t_method)matrix_matrix2, gensym(""), A_GIMME, 0);
/* the basics : functions for creation */ class_addmethod (matrix_class, (t_method)matrix_size, gensym("size"), A_GIMME, 0); class_addmethod (matrix_class, (t_method)matrix_eye, gensym("eye"), A_GIMME, 0); class_addmethod (matrix_class, (t_method)matrix_diag, gensym("diag"), A_GIMME, 0); class_addmethod (matrix_class, (t_method)matrix_ones, gensym("ones"), A_GIMME, 0); class_addmethod (matrix_class, (t_method)matrix_zeros, gensym("zeros"), A_GIMME, 0); class_addmethod (matrix_class, (t_method)matrix_egg, gensym("egg"), A_GIMME, 0); class_addmethod (matrix_class, (t_method)matrix_diegg, gensym("diegg"), A_GIMME, 0);
/* the rest : functions for anything */ class_addbang (matrix_class, matrix_bang); class_addfloat (matrix_class, matrix_float); class_addlist (matrix_class, matrix_list); class_addmethod (matrix_class, (t_method)matrix_row, gensym("row"), A_GIMME, 0); class_addmethod (matrix_class, (t_method)matrix_col, gensym("column"), A_GIMME, 0); class_addmethod (matrix_class, (t_method)matrix_col, gensym("col"), A_GIMME, 0); class_addmethod (matrix_class, (t_method)matrix_element, gensym("element"), A_GIMME, 0);
/* the file functions */ class_addmethod (matrix_class, (t_method)matrix_write, gensym("write"), A_SYMBOL, 0); class_addmethod (matrix_class, (t_method)matrix_read , gensym("read") , A_SYMBOL, 0); }
void iemtx_matrix_setup(void){ matrix_setup(); }
void mtx_matrix_setup(void){ matrix_setup(); }
--- NEW FILE: iemmatrix_utility.c --- /* * iemmatrix_utility * * 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. * */
/* G.Holzmann: this has been in mtx_matrix.c before now here should be the shared code !!! */
#include "iemmatrix.h"
/* utility functions */
void setdimen(t_matrix *x, int row, int col) { x->col = col; x->row = row; SETFLOAT(x->atombuffer, row); SETFLOAT(x->atombuffer+1, col); }
void adjustsize(t_matrix *x, int desiredRow, int desiredCol) { int col=x->col, row=x->row;
if (desiredRow<1){ post("cannot make less than 1 rows"); desiredRow=1; } if (desiredCol<1){ post("cannot make less than 1 columns"); desiredCol=1; }
if (col*row!=desiredRow*desiredCol){ if(x->atombuffer)freebytes(x->atombuffer, (col*row+2)*sizeof(t_atom)); x->atombuffer=(t_atom *)getbytes((desiredCol*desiredRow+2)*sizeof(t_atom)); }
setdimen(x, desiredRow, desiredCol); return; }
void debugmtx(int argc, t_float *buf, int id) { int i=argc; while(i--){ int j=argc; startpost("debug%d: ", id); while(j--) startpost("%f ", *buf++); endpost(); } }
t_matrixfloat *matrix2float(t_atom *ap) { int row = atom_getfloat(ap++); int col=atom_getfloat(ap++); int length = row * col; t_matrixfloat *buffer = (t_matrixfloat *)getbytes(sizeof(t_matrixfloat)*length); t_matrixfloat *buf = buffer; while(length--)*buf++=atom_getfloat(ap++); return buffer; }
void float2matrix(t_atom *ap, t_matrixfloat *buffer) { int row=atom_getfloat(ap++); int col=atom_getfloat(ap++); int length = row * col; t_matrixfloat*buf= buffer; while(length--){ SETFLOAT(ap, *buf++); ap++; } freebytes(buffer, row*col*sizeof(t_matrixfloat)); }
/* core functions */ void matrix_bang(t_matrix *x) { /* output the matrix */ if (x->atombuffer)outlet_anything(x->x_obj.ob_outlet, gensym("matrix"), x->col*x->row+2, x->atombuffer); }
void matrix_matrix2(t_matrix *x, t_symbol *s, int argc, t_atom *argv) { int row, col;
if (argc<2){ post("matrix : corrupt matrix passed"); return; } row = atom_getfloat(argv); col = atom_getfloat(argv+1); if ((row<1)||(col<1)){ post("matrix : corrupt matrix passed"); return; } if (row*col > argc-2){ post("matrix: sparse matrices not yet supported : use "mtx_check""); return; }
/* this is fast and dirty, MAYBE make it slow and clean */ /* or, to clean matrices, use the mtx_check object */ if (row*col != x->row*x->col) { freebytes(x->atombuffer, x->row*x->col*sizeof(t_atom)); x->atombuffer = copybytes(argv, (row*col+2)*sizeof(t_atom)); } else memcpy(x->atombuffer, argv, (row*col+2)*sizeof(t_atom));
setdimen(x, row, col); }
/* set data */
void matrix_set(t_matrix *x, t_float f) { int size = x->col * x->row; t_atom *buf=x->atombuffer+2; if(x->atombuffer)while(size--)SETFLOAT(&buf[size], f); }
void matrix_zeros(t_matrix *x, t_symbol *s, int argc, t_atom *argv) { int col, row;
switch(argc) { case 0: /* zero out the actual matrix */ matrix_set(x, 0); break; case 1: row=atom_getfloat(argv); adjustsize(x, row, row); matrix_set(x, 0); break; default: row=atom_getfloat(argv++); col=atom_getfloat(argv); adjustsize(x, row, col);
matrix_set(x, 0); }
matrix_bang(x); }
void matrix_ones(t_matrix *x, t_symbol *s, int argc, t_atom *argv) { int col, row;
switch(argc) { case 0: /* zero out the actual matrix */ matrix_set(x, 1); break; case 1: row=atom_getfloat(argv); adjustsize(x, row, row); matrix_set(x, 1); break; default: row=atom_getfloat(argv++); col=atom_getfloat(argv); adjustsize(x, row, col);
matrix_set(x, 1); }
matrix_bang(x); }
void matrix_eye(t_matrix *x, t_symbol *s, int argc, t_atom *argv) { int col, row; int n;
switch(argc) { case 0: /* zero out the actual matrix */ matrix_set(x, 0); break; case 1: row=atom_getfloat(argv); adjustsize(x, row, row); matrix_set(x, 0); break; default: row=atom_getfloat(argv++); col=atom_getfloat(argv); adjustsize(x, row, col); matrix_set(x, 0); }
col=x->col; row=x->row; n = (col<row)?col:row; while(n--)SETFLOAT(x->atombuffer+2+n*(1+col), 1);
matrix_bang(x); }
void matrix_egg(t_matrix *x, t_symbol *s, int argc, t_atom *argv) { int col, row; int n;
switch(argc) { case 0: /* zero out the actual matrix */ matrix_set(x, 0); break; case 1: row=atom_getfloat(argv); adjustsize(x, row, row); matrix_set(x, 0); break; default: row=atom_getfloat(argv++); col=atom_getfloat(argv); adjustsize(x, row, col); matrix_set(x, 0); }
col=x->col; row=x->row; n = (col<row)?col:row; while(n--)SETFLOAT(x->atombuffer+2+(n+1)*(col-1), 1);
matrix_bang(x); }
void matrix_diag(t_matrix *x, t_symbol *s, int argc, t_atom *argv) { int col=argc; argv+=argc-1; if (argc<1) { post("matrix: no diagonale present"); return; } adjustsize(x, argc, argc); matrix_set(x, 0);
while(argc--)SETFLOAT(x->atombuffer+2+argc*(1+col), atom_getfloat(argv--));
matrix_bang(x); }
void matrix_diegg(t_matrix *x, t_symbol *s, int argc, t_atom *argv) { int col=argc; argv+=argc-1; if (argc<1) { post("matrix: no dieggonale present"); return; } adjustsize(x, argc, argc); matrix_set(x, 0);
while(argc--){ t_atom *ap=x->atombuffer+2+(argc+1)*(col-1); SETFLOAT(ap, atom_getfloat(argv--)); }
matrix_bang(x); }
/* the rest */
void matrix_row(t_matrix *x, t_symbol *s, int argc, t_atom *argv) { t_atom *ap; int row=x->row, col=x->col; int r; t_float f;
switch (argc){ case 0: for (r=0;r<row;r++)outlet_list(x->x_obj.ob_outlet, gensym("row"), col, x->atombuffer+r*col+2); break; case 1: r=atom_getfloat(argv)-1; if ((r<0)||(r>=row)){ post("matrix: row index %d is out of range", r+1); return; } outlet_list(x->x_obj.ob_outlet, gensym("row"), col, x->atombuffer+r*col+2); break; case 2: r=atom_getfloat(argv)-1; f=atom_getfloat(argv+1); if ((r<0)||(r>=row)){ post("matrix: row index %d is out of range", r+1); return; }
default: r=atom_getfloat(argv++)-1; if (argc--<col){ post("matrix: sparse rows not yet supported : use "mtx_check""); return; } if ((r<0)||(r>=row)){ post("matrix: row index %d is out of range", r+1); return; } if (r==row) { } else { ap=x->atombuffer+2+col*r; memcpy(ap, argv, col*sizeof(t_atom)); } } }
void matrix_col(t_matrix *x, t_symbol *s, int argc, t_atom *argv) { t_atom *ap; int row=x->row, col=x->col; int c, r;
switch (argc){ case 0: ap=(t_atom *)getbytes(row*sizeof(t_atom)); for (c=0;c<col;c++) { for (r=0;r<row;r++)SETFLOAT(&ap[r], atom_getfloat(x->atombuffer+2+c+col*r)); outlet_list(x->x_obj.ob_outlet, gensym("col"), row, ap); } freebytes(ap, row*sizeof(t_atom)); break; case 1: ap=(t_atom *)getbytes(row*sizeof(t_atom)); c=atom_getfloat(argv)-1; if ((c<0)||(c>=col)){ post("matrix: col index %d is out of range", c+1); return; } for (r=0;r<row;r++)SETFLOAT(&ap[r], atom_getfloat(x->atombuffer+2+c+col*r)); outlet_list(x->x_obj.ob_outlet, gensym("col"), row, ap); freebytes(ap, row*sizeof(t_atom)); break; default: c=atom_getfloat(argv++)-1; if (argc--<row){ post("matrix: sparse cols not yet supported : use "mtx_check""); return; } if ((c<0)||(c>=col)){ post("matrix: col index %d is out of range", c+1); return; } argv+=argc-1; if (argc>row)argc=row; while(argc--){ ap=x->atombuffer+2+c+col*argc; SETFLOAT(ap, atom_getfloat(argv--)); } } }
void matrix_element(t_matrix *x, t_symbol *s, int argc, t_atom *argv) { t_atom *ap=x->atombuffer+2; int row=x->row, col=x->col; int r, c, i=row*col;
switch (argc){ case 0: while(i--)outlet_float(x->x_obj.ob_outlet, atom_getfloat(ap++)); break; case 1: r=c=atom_getfloat(argv)-1; if ((r<0)||(r>=row)){ post("matrix: row index %d is out of range", r+1); return; } if ((c<0)||(c>=col)){ post("matrix: col index %d is out of range", c+1); return; } outlet_float(x->x_obj.ob_outlet, atom_getfloat(x->atombuffer+2+c+r*col)); break; case 2: r=atom_getfloat(argv++)-1; c=atom_getfloat(argv++)-1; if ((r<0)||(r>=row)){ post("matrix: row index %d is out of range", r+1); return; } if ((c<0)||(c>=col)){ post("matrix: col index %d is out of range", c+1); return; } outlet_float(x->x_obj.ob_outlet, atom_getfloat(x->atombuffer+2+c+r*col)); break; default: r=atom_getfloat(argv++)-1; c=atom_getfloat(argv++)-1; if ((r<0)||(r>=row)){ post("matrix: row index %d is out of range", r+1); return; } if ((c<0)||(c>=col)){ post("matrix: col index %d is out of range", c+1); return; } SETFLOAT(x->atombuffer+2+c+r*col, atom_getfloat(argv)); } }
/* destructor */
void matrix_free(t_matrix *x) { freebytes(x->atombuffer, (x->col*x->row+2)*sizeof(t_atom)); x->atombuffer=0; x->col=x->row=0; }