Update of /cvsroot/pure-data/externals/iem/iemmatrix/src
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5954
Modified Files:
iemmatrix_sources.c iemmatrix_sources.h
Added Files:
mtx_colon.c mtx_conv.c mtx_cumsum.c mtx_diff.c mtx_fill.c
mtx_find.c mtx_index.c mtx_minmax.c mtx_not.c mtx_repmat.c
mtx_reverse.c mtx_sort.c
Log Message:
added a bunch of new objects (from f.zotter);
some of them are unstable, some are likely to change in their behaviour (read: not yet for use)
Index: iemmatrix_sources.c
===================================================================
RCS file: /cvsroot/pure-data/externals/iem/iemmatrix/src/iemmatrix_sources.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** iemmatrix_sources.c 19 Sep 2005 13:28:51 -0000 1.2
--- iemmatrix_sources.c 19 Sep 2005 14:47:48 -0000 1.3
***************
*** 19,26 ****
--- 19,30 ----
iemtx_cholesky_setup(); /* mtx_cholesky.c */
iemtx_col_setup(); /* mtx_col.c */
+ iemtx_colon_setup(); /* mtx_colon.c */
+ iemtx_conv_setup(); /* mtx_conv.c */
iemtx_cos_setup(); /* mtx_cos.c */
+ iemtx_cumsum_setup(); /* mtx_cumsum.c */
iemtx_dbtorms_setup(); /* mtx_dbtorms.c */
iemtx_diag_setup(); /* mtx_diag.c */
iemtx_diegg_setup(); /* mtx_diegg.c */
+ iemtx_diff_setup(); /* mtx_diff.c */
iemtx_distance2_setup(); /* mtx_distance2.c */
iemtx_egg_setup(); /* mtx_egg.c */
***************
*** 29,35 ****
--- 33,42 ----
iemtx_exp_setup(); /* mtx_exp.c */
iemtx_eye_setup(); /* mtx_eye.c */
+ iemtx_fill_setup(); /* mtx_fill.c */
+ iemtx_find_setup(); /* mtx_find.c */
iemtx_gauss_setup(); /* mtx_gauss.c */
iemtx_ge_setup(); /* mtx_ge.c */
iemtx_gt_setup(); /* mtx_gt.c */
+ iemtx_index_setup(); /* mtx_index.c */
iemtx_int_setup(); /* mtx_int.c */
iemtx_inverse_setup(); /* mtx_inverse.c */
***************
*** 41,47 ****
--- 48,56 ----
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_neq_setup(); /* mtx_neq.c */
+ iemtx_not_setup(); /* mtx_not.c */
iemtx_ones_setup(); /* mtx_ones.c */
iemtx_or_setup(); /* mtx_or.c */
***************
*** 51,55 ****
--- 60,66 ----
iemtx_prod_setup(); /* mtx_prod.c */
iemtx_rand_setup(); /* mtx_rand.c */
+ iemtx_repmat_setup(); /* mtx_repmat.c */
iemtx_resize_setup(); /* mtx_resize.c */
+ iemtx_reverse_setup(); /* mtx_reverse.c */
iemtx_rmstodb_setup(); /* mtx_rmstodb.c */
iemtx_roll_setup(); /* mtx_roll.c */
***************
*** 58,61 ****
--- 69,73 ----
iemtx_sin_setup(); /* mtx_sin.c */
iemtx_size_setup(); /* mtx_size.c */
+ iemtx_sort_setup(); /* mtx_sort.c */
iemtx_sub_setup(); /* mtx_sub.c */
iemtx_sum_setup(); /* mtx_sum.c */
--- NEW FILE: mtx_index.c ---
/*
* 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_index_class;
typedef struct _MTXindex_ MTXindex;
struct _MTXindex_
{
t_object x_obj;
int index_size;
int index_rows;
int index_columns;
t_float fill_value;
int max_index;
int *index_in;
t_outlet *list_outlet;
t_atom *list_out;
t_atom *list_in;
};
static void deleteMTXIndex (MTXindex *mtx_index_obj)
{
if (mtx_index_obj->index_in)
freebytes (mtx_index_obj->index_in, sizeof(int)*(mtx_index_obj->index_size+2));
if (mtx_index_obj->list_out)
freebytes (mtx_index_obj->list_out, sizeof(t_atom)*(mtx_index_obj->index_size+2));
}
static void *newMTXIndex (t_symbol *s, int argc, t_atom *argv)
{
MTXindex *mtx_index_obj = (MTXindex *) pd_new (mtx_index_class);
t_atom fill_atom;
SETFLOAT(&fill_atom,0);
switch ((argc>1)?1:argc) {
case 1:
fill_atom = *argv;
}
if (atom_getsymbol(&fill_atom) == gensym("nan"))
mtx_index_obj->fill_value = 0.0f/0.0f;
else
mtx_index_obj->fill_value = atom_getfloat(&fill_atom);
mtx_index_obj->list_outlet = outlet_new (&mtx_index_obj->x_obj, gensym("matrix"));
inlet_new(&mtx_index_obj->x_obj, &mtx_index_obj->x_obj.ob_pd, gensym("matrix"),gensym(""));
error("[mtx_index]: this object is likely to change! not really for use yet");
return ((void *) mtx_index_obj);
}
static void mTXIndexBang (MTXindex *mtx_index_obj)
{
if (mtx_index_obj->list_out)
outlet_anything(mtx_index_obj->list_outlet, gensym("matrix"),
mtx_index_obj->index_size+2, mtx_index_obj->list_out);
}
/*
static void copyList (int size, t_atom *x, t_atom *y)
{
while(size--)
*y++=*x++;
}
*/
static int copyAtomToIntegerArrayMax (int n, t_atom *x, int *y)
{
int max = atom_getint(x);
for (;n--;x++,y++) {
*y = atom_getint (x);
max = (*y > max)?*y:max;
}
return max;
}
static void setAtomListConstFloat (int n, t_atom *x, t_float f)
{
for (;n--;x++)
SETFLOAT(x,f);
}
static void writeIndexedValuesIntoList (int n, int *index, t_atom *x, t_atom *y)
{
for (;n--;index++,y++)
if (*index)
*y = x[*index-1];
}
static void mTXIndexRightMatrix (MTXindex *mtx_index_obj, t_symbol *s,
int argc, t_atom *argv)
{
int rows = atom_getint (argv++);
int columns = atom_getint (argv++);
int size = rows * columns;
int list_size = argc - 2;
t_atom *list_in = argv;
t_atom *list_out = mtx_index_obj->list_out;
int *index_in = mtx_index_obj->index_in;
int max;
// size check
if (!size) {
post("mtx_index: invalid dimensions");
return;
}
else if (list_size<size) {
post("mtx_index: sparse matrix not yet supported: use \"mtx_check\"");
return;
}
if (size != mtx_index_obj->index_size) {
if (!index_in)
index_in = (int *) getbytes (sizeof (int) * (size + 2));
else
index_in = (int *) resizebytes (index_in,
sizeof (int) * (mtx_index_obj->index_size+2),
sizeof (int) * (size + 2));
if (!list_out)
list_out = (t_atom *) getbytes (sizeof (t_atom) * (size + 2));
else
list_out = (t_atom *) resizebytes (list_out,
sizeof (t_atom) * (mtx_index_obj->index_size+2),
sizeof (t_atom) * (size + 2));
}
mtx_index_obj->index_size = size;
mtx_index_obj->index_columns = columns;
mtx_index_obj->index_rows = rows;
mtx_index_obj->list_out = list_out;
mtx_index_obj->index_in = index_in;
max = copyAtomToIntegerArrayMax (size, list_in, index_in);
mtx_index_obj->max_index = max;
}
static void mTXIndexMatrix (MTXindex *mtx_index_obj, t_symbol *s,
int argc, t_atom *argv)
{
int rows = atom_getint (argv++);
int columns = atom_getint (argv++);
int size = rows * columns;
int list_size = argc - 2;
t_atom *list_in = argv;
t_atom *list_out = mtx_index_obj->list_out;
int count;
int index_rows = mtx_index_obj->index_rows;
int index_columns = mtx_index_obj->index_columns;
int *index = mtx_index_obj->index_in;
// size check
if (!size) {
post("mtx_index: invalid dimensions");
return;
}
else if (list_size<size) {
post("mtx_index: sparse matrix not yet supported: use \"mtx_check\"");
return;
}
if (size < mtx_index_obj->max_index) {
post("mtx_index: index exceeds matrix dimensions");
return;
}
if ((!index)||(mtx_index_obj->index_size == 0)) {
post("mtx_index: index with what? no right matrix defined");
return;
}
// main part
list_out += 2;
setAtomListConstFloat (mtx_index_obj->index_size, list_out, mtx_index_obj->fill_value);
writeIndexedValuesIntoList (mtx_index_obj->index_size, index,list_in,list_out);
list_out = mtx_index_obj->list_out;
SETSYMBOL(list_out, gensym("matrix"));
SETFLOAT(list_out, index_rows);
SETFLOAT(&list_out[1], index_columns);
outlet_anything(mtx_index_obj->list_outlet, gensym("matrix"),
mtx_index_obj->index_size+2, list_out);
}
void mtx_index_setup (void)
{
mtx_index_class = class_new
(gensym("mtx_index"),
(t_newmethod) newMTXIndex,
(t_method) deleteMTXIndex,
sizeof (MTXindex),
CLASS_DEFAULT, A_GIMME, 0);
class_addbang (mtx_index_class, (t_method) mTXIndexBang);
class_addmethod (mtx_index_class, (t_method) mTXIndexMatrix, gensym("matrix"), A_GIMME,0);
class_addmethod (mtx_index_class, (t_method) mTXIndexRightMatrix, gensym(""), A_GIMME,0);
class_sethelpsymbol (mtx_index_class, gensym("iemmatrix/mtx_index"));
}
void iemtx_index_setup(void){
mtx_index_setup();
}
--- NEW FILE: mtx_sort.c ---
/*
* 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_sort_class;
typedef struct _MTXSort_ MTXSort;
struct _MTXSort_
{
t_object x_obj;
int rows;
int columns;
int size;
int sort_dimension;
int sort_direction;
t_outlet *list_outlet1;
t_outlet *list_outlet2;
t_atom *list_out1;
t_atom *list_out2;
t_atom *list_in;
t_float *x;
// t_float *y;
t_float *i;
};
static void deleteMTXSort (MTXSort *mtx_sort_obj)
{
if (mtx_sort_obj->list_out1)
freebytes (mtx_sort_obj->list_out1, sizeof(t_atom)*(mtx_sort_obj->size+2));
if (mtx_sort_obj->list_out2)
freebytes (mtx_sort_obj->list_out2, sizeof(t_atom)*(mtx_sort_obj->size+2));
if (mtx_sort_obj->x)
freebytes (mtx_sort_obj->x, sizeof(t_float)*(mtx_sort_obj->size));
//if (mtx_sort_obj->y)
// freebytes (mtx_sort_obj->y, sizeof(t_float)*(mtx_sort_obj->size));
if (mtx_sort_obj->i)
freebytes (mtx_sort_obj->i, sizeof(t_float)*(mtx_sort_obj->size));
}
static void mTXSetSortDirection (MTXSort *mtx_sort_obj, t_float s_dir)
{
int direction = (int) s_dir;
mtx_sort_obj->sort_direction = (direction==-1)?direction:1;
}
static void mTXSetSortDimension (MTXSort *mtx_sort_obj, t_float s_dim)
{
int dimension = (int) s_dim;
dimension = (dimension<2)?dimension:2;
dimension = (dimension>0)?dimension:0;
mtx_sort_obj->sort_dimension = dimension;
}
static void *newMTXSort (t_symbol *s, int argc, t_atom *argv)
{
MTXSort *mtx_sort_obj = (MTXSort *) pd_new (mtx_sort_class);
int c_dir = 1;
int c_dim = 1;
mtx_sort_obj->sort_dimension = c_dim;
switch ((argc>2)?2:argc) {
case 2:
c_dir = atom_getint(argv+1);
case 1:
c_dim = atom_getint(argv);
}
mTXSetSortDirection (mtx_sort_obj, (t_float) c_dir);
mTXSetSortDimension (mtx_sort_obj, (t_float) c_dim);
mtx_sort_obj->list_outlet1 = outlet_new (&mtx_sort_obj->x_obj, gensym("matrix"));
mtx_sort_obj->list_outlet2 = outlet_new (&mtx_sort_obj->x_obj, gensym("matrix"));
return ((void *) mtx_sort_obj);
}
static void mTXSortBang (MTXSort *mtx_sort_obj)
{
if (mtx_sort_obj->list_out1)
outlet_anything(mtx_sort_obj->list_outlet1, gensym("matrix"),
mtx_sort_obj->size+2, mtx_sort_obj->list_out1);
if (mtx_sort_obj->list_out2)
outlet_anything(mtx_sort_obj->list_outlet2, gensym("matrix"),
mtx_sort_obj->size+2, mtx_sort_obj->list_out2);
}
static void writeFloatIntoList (int n, t_atom *l, t_float *f)
{
for (;n--;f++, l++)
SETFLOAT (l, *f);
}
static void readFloatFromList (int n, t_atom *l, t_float *f)
{
while (n--)
*f++ = atom_getfloat (l++);
}
static void readFloatFromListModulo (int n, int m, t_atom *l, t_float *f)
{
t_atom *ptr = l;
int count1, count2;
n /= m;
count1 = m;
while (count1--)
for (count2 = n, ptr = l++; count2--; ptr += m, f++)
*f = atom_getfloat (ptr);
}
static void writeFloatIntoListModulo (int n, int m, t_atom *l, t_float *f)
{
t_atom *ptr = l;
int count1, count2;
n /= m;
count1 = m;
while (count1--)
for (count2 = n, ptr = l++; count2--; ptr += m, f++)
SETFLOAT(ptr,*f);
}
static void sortVector (int n, t_float *x, t_float *i, int direction)
{
int step = n;
int size = n;
int k, loops = 1;
int i_tmp;
t_float x_tmp;
switch (direction) {
case -1:
while (step > 1) {
step = (step % 2)?(step+1)/2:step/2;
k = loops;
loops += 2;
while(k--) { /* there might be some optimization in here */
for (n=0; n<(size-step); n++)
if (x[n] < x[n+step]) {
i_tmp = i[n];
x_tmp = x[n];
x[n] = x[n+step];
x[n+step] = x_tmp;
i[n] = i[n+step];
i[n+step] = i_tmp;
}
}
}
break;
default:
case 1:
while (step > 1) {
step = (step % 2)?(step+1)/2:step/2;
k = loops;
loops += 2;
while(k--) { /* there might be some optimization in here */
for (n=0; n<(size-step); n++)
if (x[n] > x[n+step]) {
i_tmp = i[n];
x_tmp = x[n];
x[n] = x[n+step];
x[n+step] = x_tmp;
i[n] = i[n+step];
i[n+step] = i_tmp;
}
}
}
}
}
static void indexingVector (int n, int m, int dimension, t_float *i)
{
int count;
int count2;
int idx = n;
t_float *ptr;
i += n;
switch (dimension) {
case 2:
n /= m;
for (count = m; count--;) {
ptr = --i;
for (count2 = n; count2--; ptr -= m)
*ptr = idx--;
}
break;
default:
case 1:
for (; idx;)
*--i = idx--;
}
}
static void mTXSortMatrix (MTXSort *mtx_sort_obj, t_symbol *s,
int argc, t_atom *argv)
{
int rows = atom_getint (argv++);
int columns = atom_getint (argv++);
int size = rows * columns;
int list_size = argc - 2;
t_atom *list_ptr = argv;
t_atom *list_out1 = mtx_sort_obj->list_out1;
t_atom *list_out2 = mtx_sort_obj->list_out2;
t_float *x = mtx_sort_obj->x;
//t_float *y = mtx_sort_obj->y;
t_float *i = mtx_sort_obj->i;
int count;
// size check
if (!size) {
post("mtx_sort: invalid dimensions");
return;
}
else if (list_size<size) {
post("mtx_sort: sparse matrix not yet supported: use \"mtx_check\"");
return;
}
else if ((!x)||(!list_out1)||(!list_out2)/*||(!y)*/) {
if (!x)
x = (t_float *) getbytes (sizeof (t_float) * (size));
//if (!y)
// y = (t_float *) getbytes (sizeof (t_float) * (size));
if (!i)
i = (t_float *) getbytes (sizeof (t_float) * (size));
if (!list_out1)
list_out1 = (t_atom *) getbytes (sizeof (t_atom) * (size+2));
if (!list_out2)
list_out2 = (t_atom *) getbytes (sizeof (t_atom) * (size+2));
}
else if (size != mtx_sort_obj->size) {
x = (t_float *) resizebytes (x,
sizeof (t_float) * (mtx_sort_obj->size),
sizeof (t_float) * (size));
//y = (t_float *) resizebytes (y,
// sizeof (t_float) * (mtx_sort_obj->size),
// sizeof (t_float) * (size));
i = (t_float *) resizebytes (i,
sizeof (t_float) * (mtx_sort_obj->size),
sizeof (t_float) * (size));
list_out1 = (t_atom *) resizebytes (list_out1,
sizeof (t_atom) * (mtx_sort_obj->size+2),
sizeof (t_atom) * (size + 2));
list_out2 = (t_atom *) resizebytes (list_out2,
sizeof (t_atom) * (mtx_sort_obj->size+2),
sizeof (t_atom) * (size + 2));
}
mtx_sort_obj->list_out1 = list_out1;
mtx_sort_obj->list_out2 = list_out2;
mtx_sort_obj->x = x;
// mtx_sort_obj->y = y;
mtx_sort_obj->i = i;
mtx_sort_obj->size = size;
mtx_sort_obj->rows = rows;
mtx_sort_obj->columns = columns;
// generating indexing vector
indexingVector (size, columns, mtx_sort_obj->sort_dimension, i);
// main part
// reading matrix from inlet
if (mtx_sort_obj->sort_dimension == 2) {
readFloatFromListModulo (size, columns, list_ptr, x);
columns = mtx_sort_obj->rows;
rows = mtx_sort_obj->columns;
}
else
readFloatFromList (size, list_ptr, x);
// calculating sort
if (mtx_sort_obj->sort_dimension == 0)
sortVector (size,x,i,mtx_sort_obj->sort_direction);
else
for (count = rows; count--;x+=columns,i+=columns)
sortVector (columns,x,i,mtx_sort_obj->sort_direction);
x = mtx_sort_obj->x;
i = mtx_sort_obj->i;
// writing matrix to outlet
if (mtx_sort_obj->sort_dimension == 2) {
columns = mtx_sort_obj->columns;
rows = mtx_sort_obj->rows;
writeFloatIntoListModulo (size, columns, list_out1+2, x);
writeFloatIntoListModulo (size, columns, list_out2+2, i);
}
else {
writeFloatIntoList (size, list_out1+2, x);
writeFloatIntoList (size, list_out2+2, i);
}
SETSYMBOL(list_out1, gensym("matrix"));
SETFLOAT(list_out1, rows);
SETFLOAT(&list_out1[1], columns);
outlet_anything(mtx_sort_obj->list_outlet1, gensym("matrix"),
mtx_sort_obj->size+2, list_out1);
SETSYMBOL(list_out2, gensym("matrix"));
SETFLOAT(list_out2, rows);
SETFLOAT(&list_out2[1], columns);
outlet_anything(mtx_sort_obj->list_outlet2, gensym("matrix"),
mtx_sort_obj->size+2, list_out2);
}
void mtx_sort_setup (void)
{
mtx_sort_class = class_new
(gensym("mtx_sort"),
(t_newmethod) newMTXSort,
(t_method) deleteMTXSort,
sizeof (MTXSort),
CLASS_DEFAULT, A_GIMME, 0);
class_addbang (mtx_sort_class, (t_method) mTXSortBang);
class_addmethod (mtx_sort_class, (t_method) mTXSortMatrix, gensym("matrix"), A_GIMME,0);
class_addmethod (mtx_sort_class, (t_method) mTXSetSortDimension, gensym("dimension"), A_DEFFLOAT,0);
class_addmethod (mtx_sort_class, (t_method) mTXSetSortDirection, gensym("direction"), A_DEFFLOAT,0);
class_sethelpsymbol (mtx_sort_class, gensym("iemmatrix/mtx_sort"));
}
void iemtx_sort_setup(void){
mtx_sort_setup();
}
--- NEW FILE: mtx_colon.c ---
/*
* 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_colon_class;
typedef struct _MTXColon_ MTXColon;
struct _MTXColon_
{
t_object x_obj;
int size;
t_atom *list_out;
t_outlet *list_outlet;
};
static void deleteMTXColon (MTXColon *mtx_colon_obj)
{
if (mtx_colon_obj->list_out)
freebytes (mtx_colon_obj->list_out, sizeof(t_atom)*(mtx_colon_obj->size+2));
}
static void *newMTXColon (t_symbol *s, int argc, t_atom *argv)
{
MTXColon *mtx_colon_obj = (MTXColon *) pd_new (mtx_colon_class);
mtx_colon_obj->list_outlet = outlet_new (&mtx_colon_obj->x_obj, gensym("matrix"));
return ((void *) mtx_colon_obj);
}
static void mTXColonBang (MTXColon *mtx_colon_obj)
{
if (mtx_colon_obj->list_out)
outlet_anything(mtx_colon_obj->list_outlet, gensym("matrix"),
mtx_colon_obj->size+2, mtx_colon_obj->list_out);
}
static void mTXColonList (MTXColon *mtx_colon_obj, t_symbol *s,
int argc, t_atom *argv)
{
int size;
t_float startval;
t_float stopval;
t_float step;
t_atom *list_out = mtx_colon_obj->list_out;
if (argc == 3) {
startval = atom_getfloat(argv++);
step = atom_getfloat(argv++);
stopval = atom_getfloat(argv++);
}
else if (argc == 2) {
startval = atom_getfloat(argv++);
stopval = atom_getfloat(argv++);
step = 1.0f;
}
else {
post("mtx_colon: wrong number of input arguments");
return;
}
size = (int)((stopval- startval + step) / step);
//post("startval %f stopval %f step %f, size %d",startval, stopval, step, size);
if (size) {
if (size!=mtx_colon_obj->size) {
if (list_out)
list_out = (t_atom *) resizebytes (list_out,
sizeof(t_atom)*(mtx_colon_obj->size+2),
sizeof(t_atom)*(size+2));
else
list_out = (t_atom*) getbytes (sizeof(t_atom)*(size+2));
mtx_colon_obj->size = size;
}
mtx_colon_obj->list_out = list_out;
SETFLOAT (&list_out[0],1.0f);
SETFLOAT (&list_out[1],(t_float)size);
list_out += 2;
for (;size--;list_out++,startval+=step)
SETFLOAT(list_out,startval);
mTXColonBang (mtx_colon_obj);
}
}
void mtx_colon_setup (void)
{
mtx_colon_class = class_new
(gensym("mtx_colon"),
(t_newmethod) newMTXColon,
(t_method) deleteMTXColon,
sizeof (MTXColon),
CLASS_DEFAULT, A_GIMME, 0);
class_addbang (mtx_colon_class, (t_method) mTXColonBang);
class_addlist (mtx_colon_class, (t_method) mTXColonList);
class_addcreator ((t_newmethod) newMTXColon, gensym("mtx_:"), A_GIMME, 0);
class_sethelpsymbol (mtx_colon_class, gensym("iemmatrix/mtx_colon"));
}
void iemtx_colon_setup(void){
mtx_colon_setup();
}
Index: iemmatrix_sources.h
===================================================================
RCS file: /cvsroot/pure-data/externals/iem/iemmatrix/src/iemmatrix_sources.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** iemmatrix_sources.h 19 Sep 2005 13:28:51 -0000 1.2
--- iemmatrix_sources.h 19 Sep 2005 14:47:49 -0000 1.3
***************
*** 17,24 ****
--- 17,28 ----
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_conv_setup(void); /* mtx_conv.c */
void iemtx_cos_setup(void); /* mtx_cos.c */
+ void iemtx_cumsum_setup(void); /* mtx_cumsum.c */
void iemtx_dbtorms_setup(void); /* mtx_dbtorms.c */
void iemtx_diag_setup(void); /* mtx_diag.c */
void iemtx_diegg_setup(void); /* mtx_diegg.c */
+ void iemtx_diff_setup(void); /* mtx_diff.c */
void iemtx_distance2_setup(void); /* mtx_distance2.c */
void iemtx_egg_setup(void); /* mtx_egg.c */
***************
*** 27,33 ****
--- 31,40 ----
void iemtx_exp_setup(void); /* mtx_exp.c */
void iemtx_eye_setup(void); /* mtx_eye.c */
+ void iemtx_fill_setup(void); /* mtx_fill.c */
+ void iemtx_find_setup(void); /* mtx_find.c */
void iemtx_gauss_setup(void); /* mtx_gauss.c */
void iemtx_ge_setup(void); /* mtx_ge.c */
void iemtx_gt_setup(void); /* mtx_gt.c */
+ void iemtx_index_setup(void); /* mtx_index.c */
void iemtx_int_setup(void); /* mtx_int.c */
void iemtx_inverse_setup(void); /* mtx_inverse.c */
***************
*** 39,45 ****
--- 46,54 ----
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_neq_setup(void); /* mtx_neq.c */
+ void iemtx_not_setup(void); /* mtx_not.c */
void iemtx_ones_setup(void); /* mtx_ones.c */
void iemtx_or_setup(void); /* mtx_or.c */
***************
*** 49,53 ****
--- 58,64 ----
void iemtx_prod_setup(void); /* mtx_prod.c */
void iemtx_rand_setup(void); /* mtx_rand.c */
+ void iemtx_repmat_setup(void); /* mtx_repmat.c */
void iemtx_resize_setup(void); /* mtx_resize.c */
+ void iemtx_reverse_setup(void); /* mtx_reverse.c */
void iemtx_rmstodb_setup(void); /* mtx_rmstodb.c */
void iemtx_roll_setup(void); /* mtx_roll.c */
***************
*** 56,59 ****
--- 67,71 ----
void iemtx_sin_setup(void); /* mtx_sin.c */
void iemtx_size_setup(void); /* mtx_size.c */
+ void iemtx_sort_setup(void); /* mtx_sort.c */
void iemtx_sub_setup(void); /* mtx_sub.c */
void iemtx_sum_setup(void); /* mtx_sum.c */
--- NEW FILE: mtx_not.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"
/* mtx_not: B=!A; */
#define MTX_ALMOSTZERO 1e-19
static t_class *mtx_not_class;
static void mtx_not_matrix(t_mtx_binmtx *x, t_symbol *s, int argc, t_atom *argv)
{
int row=atom_getfloat(argv++);
int col=atom_getfloat(argv++);
t_atom *m;
int n = argc-2;
if (argc<2){ post("mtx_!: crippled matrix"); return; }
if ((col<1)||(row<1)) { post("mtx_!: invalid dimensions"); return; }
if (col*row>argc-2){ post("sparse matrix not yet supported : use \"mtx_check\""); return; }
adjustsize(&x->m, row, col);
m = x->m.atombuffer+2;
while(n--){
t_float f = atom_getfloat(argv++);
SETFLOAT(m, (t_float)(f<MTX_ALMOSTZERO&&f>-MTX_ALMOSTZERO));
m++;
}
outlet_anything(x->x_obj.ob_outlet, gensym("matrix"), argc, x->m.atombuffer);
}
static void mtx_not_list(t_mtx_binscalar *x, t_symbol *s, int argc, t_atom *argv)
{
int n=argc;
t_atom *m;
t_float factor = x->f;
adjustsize(&x->m, 1, argc);
m = x->m.atombuffer;
while(n--){
m->a_type = A_FLOAT;
t_float f = atom_getfloat(argv++);
(m++)->a_w.w_float = (t_float)(f<MTX_ALMOSTZERO&&f>-MTX_ALMOSTZERO);
}
outlet_list(x->x_obj.ob_outlet, gensym("list"), argc, x->m.atombuffer);
}
static void *mtx_not_new(t_symbol *s)
{
/* element not */
t_matrix *x = (t_matrix *)pd_new(mtx_not_class);
outlet_new(&x->x_obj, 0);
x->col = x->row = 0;
x->atombuffer = 0;
return(x);
}
void mtx_not_setup(void)
{
mtx_not_class = class_new(gensym("mtx_not"), (t_newmethod)mtx_not_new, (t_method)mtx_binmtx_free,
sizeof(t_mtx_binmtx), 0, A_GIMME, 0);
class_addcreator((t_newmethod)mtx_not_new, gensym("mtx_!"), A_GIMME,0);
class_addmethod(mtx_not_class, (t_method)mtx_not_matrix, gensym("matrix"), A_GIMME, 0);
class_addlist (mtx_not_class, mtx_not_list);
class_addbang (mtx_not_class, mtx_binmtx_bang);
class_sethelpsymbol(mtx_not_class, gensym("iemmatrix/mtx_not"));
}
void iemtx_not_setup(void)
{
mtx_not_setup();
}
--- NEW FILE: mtx_find.c ---
/*
* 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_find_class;
typedef struct _MTXfind_ MTXfind;
struct _MTXfind_
{
t_object x_obj;
int size;
int outsize;
int find_dimension;
int find_direction;
t_outlet *list_outlet;
t_atom *list_out;
t_atom *list_in;
};
static void deleteMTXFind (MTXfind *mtx_find_obj)
{
if (mtx_find_obj->list_out)
freebytes (mtx_find_obj->list_out, sizeof(t_atom)*(mtx_find_obj->size+2));
}
static void mTXSetFindDirection (MTXfind *mtx_find_obj, t_float c_dir)
{
int direction = (int) c_dir;
if ((direction != -1) && (direction != 1))
direction = 1;
mtx_find_obj->find_direction = direction;
}
static void mTXSetFindDimension (MTXfind *mtx_find_obj, t_float c_dim)
{
int dimension = (int) c_dim;
dimension = (dimension > 0)?dimension:0;
dimension = (dimension < 3)?dimension:3;
mtx_find_obj->find_dimension = dimension;
}
static void *newMTXFind (t_symbol *s, int argc, t_atom *argv)
{
MTXfind *mtx_find_obj = (MTXfind *) pd_new (mtx_find_class);
int c_dim = 0;
int c_dir = 1;
switch ((argc>2)?2:argc) {
case 2:
c_dir = atom_getint(argv+1);
case 1:
c_dim = atom_getint(argv);
}
mTXSetFindDimension (mtx_find_obj, (t_float) c_dim);
mTXSetFindDirection (mtx_find_obj, (t_float) c_dir);
mtx_find_obj->list_outlet = outlet_new (&mtx_find_obj->x_obj, gensym("matrix"));
error("[mtx_find]: this object is likely to change! not really for use yet");
return ((void *) mtx_find_obj);
}
static void mTXFindBang (MTXfind *mtx_find_obj)
{
if (mtx_find_obj->list_out)
outlet_anything(mtx_find_obj->list_outlet, gensym("matrix"),
mtx_find_obj->outsize+2, mtx_find_obj->list_out);
}
/*
static void copyList (int size, t_atom *x, t_atom *y)
{
while(size--)
*y++=*x++;
}
*/
static int findPreviousNonZero (const int n, t_atom *x, int offset)
{
x+=offset;
for (; offset > n; offset--, x--)
if (atom_getfloat(x))
return offset;
return -1;
}
static int findPreviousNonZeroStep (const int step, t_atom *x, int offset)
{
x += offset;
for (; offset > 0; offset-=step, x-=step)
if (atom_getfloat(x))
return offset;
return -1;
}
static int findNextNonZero (const int n, t_atom *x, int offset)
{
x+=offset;
for (; offset < n; offset++, x++)
if (atom_getfloat(x))
return offset;
return -1;
}
static int findNextNonZeroStep (const int n, const int step, t_atom *x, int offset)
{
x += offset;
for (; offset < n; offset+=step, x+=step)
if (atom_getfloat(x))
return offset;
return -1;
}
static void findFirstNonZeroRow (const int rows, const int columns, t_atom *x, t_atom *y)
{
int offset;
int pos;
const int size = rows*columns;
for (offset = 0; offset < size; y++, offset+=columns) {
pos = findNextNonZero(offset+columns,x,offset)+1;
SETFLOAT(y,(t_float)pos);
}
}
static void findLastNonZeroRow (const int rows, const int columns, t_atom *x, t_atom *y)
{
int offset;
int pos;
const int size = rows*columns;
for (offset = columns-1; offset < size; y++, offset+=columns) {
pos = findPreviousNonZero(offset-columns,x,offset)+1;
SETFLOAT(y,(t_float)pos);
}
}
static void findFirstNonZeroColumn (const int rows, const int columns, t_atom *x, t_atom *y)
{
int offset;
int pos;
const int size = rows*columns;
for (offset = 0; offset < columns; y++, offset++) {
pos = findNextNonZeroStep(size,columns,x,offset)+1;
SETFLOAT(y,(t_float)pos);
}
}
static void findLastNonZeroColumn (const int rows, const int columns, t_atom *x, t_atom *y)
{
int offset;
int pos;
const int size = rows*columns;
for (offset = size-columns; offset < size; y++, offset++) {
pos = findPreviousNonZeroStep(columns,x,offset)+1;
SETFLOAT(y,(t_float)pos);
}
}
static int findAllNonZeros (int n, t_atom *x, t_atom *y)
{
int outsize = 0;
int pos = 0;
while ((pos = findNextNonZero(n,x,pos)) != -1) {
pos++;
SETFLOAT(y,(t_float)pos);
y++;
outsize++;
}
return outsize;
}
static void zeroFloatList (int n, t_atom *x)
{
for (;n--;x++)
SETFLOAT(x,0);
}
static void findReplaceNonZerosWithIndex (int n, t_atom *x, t_atom *y)
{
int pos = 0;
zeroFloatList(n,y);
while ((pos = findNextNonZero(n,x,pos)) != -1) {
SETFLOAT(y+pos,(t_float)pos+1);
pos++;
}
}
static void mTXFindMatrix (MTXfind *mtx_find_obj, t_symbol *s,
int argc, t_atom *argv)
{
int rows = atom_getint (argv++);
int columns = atom_getint (argv++);
int size = rows * columns;
int list_size = argc - 2;
t_atom *list_in = argv;
t_atom *list_out = mtx_find_obj->list_out;
int count;
int rows_out;
int columns_out;
// size check
if (!size) {
post("mtx_find: invalid dimensions");
return;
}
else if (list_size<size) {
post("mtx_find: sparse matrix not yet supported: use \"mtx_check\"");
return;
}
if (size != mtx_find_obj->size) {
if (!list_out)
list_out = (t_atom *) getbytes (sizeof (t_atom) * (size + 2));
else
list_out = (t_atom *) resizebytes (list_out,
sizeof (t_atom) * (mtx_find_obj->size+2),
sizeof (t_atom) * (size + 2));
}
mtx_find_obj->size = size;
mtx_find_obj->list_out = list_out;
// main part
list_out += 2;
//copyList (size, argv, list_out);
rows_out = 1;
switch (mtx_find_obj->find_dimension) {
case 0:
columns_out = findAllNonZeros (size, list_in, list_out);
rows_out = 1;
break;
case 3:
findReplaceNonZerosWithIndex (size, list_in, list_out);
rows_out = rows;
columns_out = columns;
break;
case 2:
if (mtx_find_obj->find_direction == -1)
findLastNonZeroColumn (rows, columns, list_in, list_out);
else
findFirstNonZeroColumn (rows, columns, list_in, list_out);
columns_out = columns;
rows_out = 1;
break;
case 1:
if (mtx_find_obj->find_direction == -1)
findLastNonZeroRow (rows, columns, list_in, list_out);
else
findFirstNonZeroRow (rows, columns, list_in, list_out);
rows_out = rows;
columns_out = 1;
break;
}
mtx_find_obj->outsize = columns_out * rows_out;
list_out = mtx_find_obj->list_out;
SETSYMBOL(list_out, gensym("matrix"));
SETFLOAT(list_out, rows_out);
SETFLOAT(&list_out[1], columns_out);
outlet_anything(mtx_find_obj->list_outlet, gensym("matrix"),
mtx_find_obj->outsize+2, list_out);
}
void mtx_find_setup (void)
{
mtx_find_class = class_new
(gensym("mtx_find"),
(t_newmethod) newMTXFind,
(t_method) deleteMTXFind,
sizeof (MTXfind),
CLASS_DEFAULT, A_GIMME, 0);
class_addbang (mtx_find_class, (t_method) mTXFindBang);
class_addmethod (mtx_find_class, (t_method) mTXFindMatrix, gensym("matrix"), A_GIMME,0);
class_addmethod (mtx_find_class, (t_method) mTXSetFindDimension, gensym("dimension"), A_DEFFLOAT,0);
class_addmethod (mtx_find_class, (t_method) mTXSetFindDirection, gensym("direction"), A_DEFFLOAT,0);
class_sethelpsymbol (mtx_find_class, gensym("iemmatrix/mtx_find"));
}
void iemtx_find_setup(void){
mtx_find_setup();
}
--- NEW FILE: mtx_diff.c ---
/*
* 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_diff_class;
typedef struct _MTXdiff_ MTXdiff;
struct _MTXdiff_
{
t_object x_obj;
int rows;
int columns;
int size;
int diff_dimension;
int diff_direction;
t_outlet *list_outlet;
t_atom *list_out;
t_atom *list_in;
t_float *x;
t_float *y;
};
static void deleteMTXdiff (MTXdiff *mtx_diff_obj)
{
if (mtx_diff_obj->list_out)
freebytes (mtx_diff_obj->list_out, sizeof(t_atom)*(mtx_diff_obj->size+2));
if (mtx_diff_obj->x)
freebytes (mtx_diff_obj->x, sizeof(t_float)*(mtx_diff_obj->size));
if (mtx_diff_obj->y)
freebytes (mtx_diff_obj->y, sizeof(t_float)*(mtx_diff_obj->size));
}
static void mTXSetdiffDirection (MTXdiff *mtx_diff_obj, t_float c_dir)
{
int direction = (int) c_dir;
mtx_diff_obj->diff_direction = (direction==-1)?direction:1;
}
static void mTXSetdiffDimension (MTXdiff *mtx_diff_obj, t_float c_dim)
{
int dimension = (int) c_dim;
mtx_diff_obj->diff_dimension = (dimension==2)?dimension:1;
}
static void *newMTXdiff (t_symbol *s, int argc, t_atom *argv)
{
MTXdiff *mtx_diff_obj = (MTXdiff *) pd_new (mtx_diff_class);
int c_dir = 1;
int c_dim = 1;
mtx_diff_obj->diff_dimension = c_dim;
switch ((argc>2)?2:argc) {
case 2:
c_dir = atom_getint(argv+1);
case 1:
c_dim = atom_getint(argv);
}
mTXSetdiffDirection (mtx_diff_obj, (t_float) c_dir);
mTXSetdiffDimension (mtx_diff_obj, (t_float) c_dim);
mtx_diff_obj->list_outlet = outlet_new (&mtx_diff_obj->x_obj, gensym("matrix"));
return ((void *) mtx_diff_obj);
}
static void mTXdiffBang (MTXdiff *mtx_diff_obj)
{
if (mtx_diff_obj->list_out)
outlet_anything(mtx_diff_obj->list_outlet, gensym("matrix"),
mtx_diff_obj->size+2, mtx_diff_obj->list_out);
}
static void writeFloatIntoList (int n, t_atom *l, t_float *f)
{
for (;n--;f++, l++)
SETFLOAT (l, *f);
}
static void readFloatFromList (int n, t_atom *l, t_float *f)
{
while (n--)
*f++ = atom_getfloat (l++);
}
static void readFloatFromListModulo (int n, int m, t_atom *l, t_float *f)
{
t_atom *ptr = l;
int count1, count2;
n /= m;
count1 = m;
while (count1--)
for (count2 = n, ptr = l++; count2--; ptr += m, f++)
*f = atom_getfloat (ptr);
}
static void writeFloatIntoListModulo (int n, int m, t_atom *l, t_float *f)
{
t_atom *ptr = l;
int count1, count2;
n /= m;
count1 = m;
while (count1--)
for (count2 = n, ptr = l++; count2--; ptr += m, f++)
SETFLOAT(ptr,*f);
}
static void diff (int n, t_float *x, t_float *y)
{
*y++ = *x++;
for (;--n; x++, y++)
*y = *x - *(x-1);
}
static void diffReverse (int n, t_float *x, t_float *y)
{
*y-- = *x--;
for (;--n; x--, y--)
*y = *x - *(x+1);
}
static void mTXdiffMatrix (MTXdiff *mtx_diff_obj, t_symbol *s,
int argc, t_atom *argv)
{
int rows = atom_getint (argv++);
int columns = atom_getint (argv++);
int size = rows * columns;
int list_size = argc - 2;
t_atom *list_ptr = argv;
t_atom *list_out = mtx_diff_obj->list_out;
t_float *x = mtx_diff_obj->x;
t_float *y = mtx_diff_obj->y;
int count;
// size check
if (!size) {
post("mtx_diff: invalid dimensions");
return;
}
else if (list_size<size) {
post("mtx_diff: sparse matrix not yet supported: use \"mtx_check\"");
return;
}
else if ((!x)||(!list_out)||(!y)) {
if (!x)
x = (t_float *) getbytes (sizeof (t_float) * (size));
if (!y)
y = (t_float *) getbytes (sizeof (t_float) * (size));
if (!list_out)
list_out = (t_atom *) getbytes (sizeof (t_atom) * (size+2));
}
else if (size != mtx_diff_obj->size) {
x = (t_float *) resizebytes (x,
sizeof (t_float) * (mtx_diff_obj->size),
sizeof (t_float) * (size));
y = (t_float *) resizebytes (y,
sizeof (t_float) * (mtx_diff_obj->size),
sizeof (t_float) * (size));
list_out = (t_atom *) resizebytes (list_out,
sizeof (t_atom) * (mtx_diff_obj->size+2),
sizeof (t_atom) * (size + 2));
}
mtx_diff_obj->size = size;
mtx_diff_obj->rows = rows;
mtx_diff_obj->columns = columns;
mtx_diff_obj->list_out = list_out;
mtx_diff_obj->x = x;
mtx_diff_obj->y = y;
// main part
// reading matrix from inlet
if (mtx_diff_obj->diff_dimension == 2) {
readFloatFromListModulo (size, columns, list_ptr, x);
columns = mtx_diff_obj->rows;
rows = mtx_diff_obj->columns;
}
else
readFloatFromList (size, list_ptr, x);
// calculating diff
if (mtx_diff_obj->diff_direction == -1) {
x += columns-1;
y += columns-1;
for (count = rows; count--; x += columns, y += columns)
diffReverse (columns,x,y);
}
else
for (count = rows; count--; x += columns, y += columns)
diff (columns,x,y);
x = mtx_diff_obj->x;
y = mtx_diff_obj->y;
// writing matrix to outlet
if (mtx_diff_obj->diff_dimension == 2) {
columns = mtx_diff_obj->columns;
rows = mtx_diff_obj->rows;
writeFloatIntoListModulo (size, columns, list_out+2, y);
}
else
writeFloatIntoList (size, list_out+2, y);
SETSYMBOL(list_out, gensym("matrix"));
SETFLOAT(list_out, rows);
SETFLOAT(&list_out[1], columns);
outlet_anything(mtx_diff_obj->list_outlet, gensym("matrix"),
mtx_diff_obj->size+2, list_out);
}
void mtx_diff_setup (void)
{
mtx_diff_class = class_new
(gensym("mtx_diff"),
(t_newmethod) newMTXdiff,
(t_method) deleteMTXdiff,
sizeof (MTXdiff),
CLASS_DEFAULT, A_GIMME, 0);
class_addbang (mtx_diff_class, (t_method) mTXdiffBang);
class_addmethod (mtx_diff_class, (t_method) mTXdiffMatrix, gensym("matrix"), A_GIMME,0);
class_addmethod (mtx_diff_class, (t_method) mTXSetdiffDimension, gensym("dimension"), A_DEFFLOAT,0);
class_addmethod (mtx_diff_class, (t_method) mTXSetdiffDirection, gensym("direction"), A_DEFFLOAT,0);
class_sethelpsymbol (mtx_diff_class, gensym("iemmatrix/mtx_diff"));
}
void iemtx_diff_setup(void){
mtx_diff_setup();
}
--- NEW FILE: mtx_fill.c ---
/*
* 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"
typedef enum {
FILL_SUBMATRIX,
FILL_INDEXED_ELEMENTS
} FillStyle;
static t_class *mtx_fill_class;
typedef struct _MTXfill_ MTXfill;
struct _MTXfill_
{
t_object x_obj;
int size;
int rows;
int columns;
int fill_startcol;
int fill_startrow;
int *index;
int index_size;
int max_index;
FillStyle fill_type;
t_outlet *list_outlet;
t_atom *list_in;
t_atom *list_out;
};
static void deleteMTXFill (MTXfill *mtx_fill_obj)
{
if (mtx_fill_obj->list_in)
freebytes (mtx_fill_obj->list_in, sizeof(t_atom)*(mtx_fill_obj->size+2));
if (mtx_fill_obj->list_out)
freebytes (mtx_fill_obj->list_out, sizeof(t_atom)*(mtx_fill_obj->size+2));
if (mtx_fill_obj->index)
freebytes (mtx_fill_obj->list_out, sizeof(int)*(mtx_fill_obj->index_size));
}
static void setListConstFloat (int size, t_float f, t_atom *y)
{
for(;size--;y++)
SETFLOAT(y,f);
}
static void copyList (int size, t_atom *x, t_atom *y)
{
while(size--)
*y++=*x++;
}
static int copyNonZeroAtomsToIntegerArrayMax (int *size, t_atom *x, int *y)
{
int idx;
int n = *size;
int max = atom_getint(x);
*size = 0;
for (;n--;x++) {
idx = atom_getint (x);
if (idx) {
size[0]++;
*y++ = idx;
max = (idx > max)?idx:max;
}
}
return max;
}
static void writeIndexedValuesIntoMatrix (int n, int *index, t_atom *x, t_atom *y)
{
for (;n--;index++,x++)
if (*index)
y[*index-1] = *x;
}
static void writeFloatIndexedIntoMatrix (int n, int *index, t_float f, t_atom *y)
{
for (;n--;index++)
if (*index)
SETFLOAT(&y[*index-1], f);
}
static void mTXFillIndexMatrix (MTXfill *mtx_fill_obj, t_symbol *s,
int argc, t_atom *argv)
{
int rows = atom_getint (argv++);
int columns = atom_getint (argv++);
int size = rows * columns;
int list_size = argc - 2;
int *index = mtx_fill_obj->index;
// size check
if (!size) {
post("mtx_fill: invalid dimensions/invalid start index");
return;
}
if (list_size == 0) {
if ((rows<1) || (columns<1)){
post("mtx_fill: row and column indices must be >0");
return;
}
mtx_fill_obj->fill_startrow = rows;
mtx_fill_obj->fill_startcol = columns;
mtx_fill_obj->fill_type = FILL_SUBMATRIX;
}
else if (list_size<size) {
post("mtx_fill: sparse matrix not yet supported: use \"mtx_check\"");
return;
}
else {
if (size > mtx_fill_obj->index_size) {
if (!index)
index = (int *) getbytes (sizeof (int) * (size + 2));
else
index = (int *) resizebytes (index,
sizeof (int) * (mtx_fill_obj->index_size+2),
sizeof (t_atom) * (size + 2));
mtx_fill_obj->index_size = size;
}
mtx_fill_obj->max_index =
copyNonZeroAtomsToIntegerArrayMax (&size, argv++, index);
if (!size) {
post("mtx_fill: indexing matrix contains zero-values only!!!");
return;
}
if (size != mtx_fill_obj->index_size) {
index = (int *) resizebytes (index,
sizeof (int) * (mtx_fill_obj->index_size+2),
sizeof (t_atom) * (size + 2));
mtx_fill_obj->index_size = size;
}
mtx_fill_obj->fill_type = FILL_INDEXED_ELEMENTS;
mtx_fill_obj->index = index;
}
}
static void *newMTXFill (t_symbol *s, int argc, t_atom *argv)
{
MTXfill *mtx_fill_obj = (MTXfill *) pd_new (mtx_fill_class);
mtx_fill_obj->fill_startrow = 1;
mtx_fill_obj->fill_startcol = 1;
mtx_fill_obj->fill_type = FILL_SUBMATRIX;
if (argc) {
if (atom_getsymbol(argv)==gensym("matrix"))
mTXFillIndexMatrix (mtx_fill_obj, s, argc-1, argv+1);
else
post("mtx_fill: creation argument must be 'matrix <startrow> <startcol>' for submatrix filling or 'matrix rows columns [...]' for indexed filling with scalar/matrices");
}
mtx_fill_obj->list_outlet = outlet_new (&mtx_fill_obj->x_obj, gensym("matrix"));
inlet_new(&mtx_fill_obj->x_obj, &mtx_fill_obj->x_obj.ob_pd, gensym("matrix"),gensym("fill_mtx"));
inlet_new(&mtx_fill_obj->x_obj, &mtx_fill_obj->x_obj.ob_pd, gensym("matrix"),gensym("index"));
return ((void *) mtx_fill_obj);
}
static void mTXBigMatrix (MTXfill *mtx_fill_obj, t_symbol *s,
int argc, t_atom *argv)
{
int rows = atom_getint (argv++);
int columns = atom_getint (argv++);
int size = rows * columns;
int list_size = argc - 2;
t_atom *list_in = mtx_fill_obj->list_in;
t_atom *list_out = mtx_fill_obj->list_out;
// size check
if (!size) {
post("mtx_fill: invalid dimensions");
return;
}
else if (list_size<size) {
post("mtx_fill: sparse matrix not yet supported: use \"mtx_check\"");
return;
}
if (size != mtx_fill_obj->size) {
if (!list_out)
list_out = (t_atom *) getbytes (sizeof (t_atom) * (size + 2));
else
list_out = (t_atom *) resizebytes (list_out,
sizeof (t_atom) * (mtx_fill_obj->size+2),
sizeof (t_atom) * (size + 2));
if (!list_in)
list_in = (t_atom *) getbytes (sizeof (t_atom) * (size + 2));
else
list_in = (t_atom *) resizebytes (list_in,
sizeof (t_atom) * (mtx_fill_obj->size+2),
sizeof (t_atom) * (size + 2));
}
mtx_fill_obj->size = size;
mtx_fill_obj->columns = columns;
mtx_fill_obj->rows = rows;
mtx_fill_obj->list_out = list_out;
mtx_fill_obj->list_in = list_in;
copyList (size, argv, list_in);
}
static void mTXFillBang (MTXfill *mtx_fill_obj)
{
if (mtx_fill_obj->list_out)
outlet_anything(mtx_fill_obj->list_outlet, gensym("matrix"),
mtx_fill_obj->size+2, mtx_fill_obj->list_out);
}
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 mTXFillScalar (MTXfill *mtx_fill_obj, t_float f)
{
t_atom *list_out = mtx_fill_obj->list_out;
t_atom *list_in = mtx_fill_obj->list_in;
int rows = mtx_fill_obj->rows;
int columns = mtx_fill_obj->columns;
if (mtx_fill_obj->fill_type == FILL_INDEXED_ELEMENTS) {
if (mtx_fill_obj->max_index > mtx_fill_obj->size) {
post("mtx_fill: index matrix index exceeds matrix borders");
return;
}
else if (mtx_fill_obj->size == 0) {
post("mtx_fill: no matrix defined for filling");
return;
}
// main part
list_out += 2;
copyList (mtx_fill_obj->size, list_in, list_out);
writeFloatIndexedIntoMatrix (mtx_fill_obj->index_size,
mtx_fill_obj->index, f,list_out);
list_out = mtx_fill_obj->list_out;
SETSYMBOL(list_out, gensym("matrix"));
SETFLOAT(list_out, rows);
SETFLOAT(&list_out[1], columns);
outlet_anything(mtx_fill_obj->list_outlet, gensym("matrix"),
mtx_fill_obj->size+2, list_out);
}
else
post("mtx_fill: scalar fill for submatrices not supported yet");
}
static void mTXFillMatrix (MTXfill *mtx_fill_obj, t_symbol *s,
int argc, t_atom *argv)
{
int fill_rows = atom_getint (argv++);
int fill_columns = atom_getint (argv++);
int fill_size = fill_rows * fill_columns;
int list_size = argc - 2;
int rows = mtx_fill_obj->rows;
int columns = mtx_fill_obj->columns;
t_atom *fill_mtx = argv;
t_atom *list_in = mtx_fill_obj->list_in;
t_atom *list_out = mtx_fill_obj->list_out;
int stopcol = mtx_fill_obj->fill_startcol+fill_columns-1;
int stoprow = mtx_fill_obj->fill_startrow+fill_rows-1;
// size check
if (!list_size) {
post("mtx_fill: invalid dimensions");
return;
}
switch (mtx_fill_obj->fill_type) {
case FILL_SUBMATRIX:
if (list_size < fill_size) {
post("mtx_fill: sparse matrix not yet supported: use \"mtx_check\"");
return;
}
if ((stopcol > columns) ||
(stoprow > rows)) {
post("mtx_fill: fill matrix index exceeds matrix borders");
return;
}
break;
case FILL_INDEXED_ELEMENTS:
if (list_size > mtx_fill_obj->index_size) {
post("mtx_fill: fill matrix smaller than indexing vector");
return;
}
else if (mtx_fill_obj->max_index > mtx_fill_obj->size) {
post("mtx_fill: index matrix index exceeds matrix borders");
return;
}
break;
}
if (mtx_fill_obj->size == 0) {
post("mtx_fill: no matrix defined for filling");
return;
}
// main part
list_out += 2;
copyList (mtx_fill_obj->size, list_in, list_out);
switch (mtx_fill_obj->fill_type) {
case FILL_SUBMATRIX:
list_out += columns * (mtx_fill_obj->fill_startrow-1) +
mtx_fill_obj->fill_startcol-1;
writeFillMatrixIntoList (fill_rows, fill_columns,
columns, fill_mtx, list_out);
break;
case FILL_INDEXED_ELEMENTS:
writeIndexedValuesIntoMatrix (mtx_fill_obj->index_size,
mtx_fill_obj->index, fill_mtx,list_out);
break;
}
list_out = mtx_fill_obj->list_out;
SETSYMBOL(list_out, gensym("matrix"));
SETFLOAT(list_out, rows);
SETFLOAT(&list_out[1], columns);
outlet_anything(mtx_fill_obj->list_outlet, gensym("matrix"),
mtx_fill_obj->size+2, list_out);
}
void mtx_fill_setup (void)
{
mtx_fill_class = class_new
(gensym("mtx_fill"),
(t_newmethod) newMTXFill,
(t_method) deleteMTXFill,
sizeof (MTXfill),
CLASS_DEFAULT, A_GIMME, 0);
class_addbang (mtx_fill_class, (t_method) mTXFillBang);
class_addmethod (mtx_fill_class, (t_method) mTXFillMatrix, gensym("matrix"), A_GIMME,0);
class_addmethod (mtx_fill_class, (t_method) mTXBigMatrix, gensym("fill_mtx"), A_GIMME,0);
class_addmethod (mtx_fill_class, (t_method) mTXFillIndexMatrix, gensym("index"), A_GIMME,0);
class_addfloat (mtx_fill_class, (t_method) mTXFillScalar);
class_sethelpsymbol (mtx_fill_class, gensym("iemmatrix/mtx_fill"));
}
void iemtx_fill_setup(void){
mtx_fill_setup();
}
--- NEW FILE: mtx_minmax.c ---
/*
* 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_minmax_class;
typedef struct _MTXminmax_ MTXminmax;
struct _MTXminmax_
{
t_object x_obj;
int size;
int outsize;
int minmax_dimension;
int minmax_direction;
int operator_minimum; // 1 if we are [mtx_min], 0 if we are [mtx_max]
t_outlet *list_outlet;
t_atom *list_out;
t_atom *list_in;
};
static void deleteMTXMinMax (MTXminmax *mtx_minmax_obj)
{
if (mtx_minmax_obj->list_out)
freebytes (mtx_minmax_obj->list_out, sizeof(t_atom)*(mtx_minmax_obj->size+2));
}
static void mTXSetMinMaxDirection (MTXminmax *mtx_minmax_obj, t_float c_dir)
{
int direction = (int) c_dir;
if ((direction != -1) && (direction != 1))
direction = 1;
mtx_minmax_obj->minmax_direction = direction;
}
static void mTXSetMinMaxDimension (MTXminmax *mtx_minmax_obj, t_float c_dim)
{
int dimension = (int) c_dim;
dimension = (dimension > 0)?dimension:0;
dimension = (dimension < 3)?dimension:3;
mtx_minmax_obj->minmax_dimension = dimension;
}
static void *newMTXMin (t_symbol *s, int argc, t_atom *argv)
{
MTXminmax *mtx_minmax_obj = (MTXminmax *) pd_new (mtx_minmax_class);
int c_dim = 1;
int c_dir = 1;
switch ((argc>2)?2:argc) {
case 2:
c_dir = atom_getint(argv+1);
case 1:
c_dim = atom_getint(argv);
}
mtx_minmax_obj->operator_minimum = 1;
mTXSetMinMaxDimension (mtx_minmax_obj, (t_float) c_dim);
mTXSetMinMaxDirection (mtx_minmax_obj, (t_float) c_dir);
mtx_minmax_obj->list_outlet = outlet_new (&mtx_minmax_obj->x_obj, gensym("matrix"));
return ((void *) mtx_minmax_obj);
}
static void *newMTXMax (t_symbol *s, int argc, t_atom *argv)
{
MTXminmax *mtx_minmax_obj = (MTXminmax *) pd_new (mtx_minmax_class);
int c_dim = 1;
int c_dir = 1;
switch ((argc>2)?2:argc) {
case 2:
c_dir = atom_getint(argv+1);
case 1:
c_dim = atom_getint(argv);
}
mtx_minmax_obj->operator_minimum = 0;
mTXSetMinMaxDimension (mtx_minmax_obj, (t_float) c_dim);
mTXSetMinMaxDirection (mtx_minmax_obj, (t_float) c_dir);
mtx_minmax_obj->list_outlet = outlet_new (&mtx_minmax_obj->x_obj, gensym("matrix"));
return ((void *) mtx_minmax_obj);
}
static void mTXMinMaxBang (MTXminmax *mtx_minmax_obj)
{
if (mtx_minmax_obj->list_out)
outlet_anything(mtx_minmax_obj->list_outlet, gensym("matrix"),
mtx_minmax_obj->outsize+2, mtx_minmax_obj->list_out);
}
/*
static void copyList (int size, t_atom *x, t_atom *y)
{
while(size--)
*y++=*x++;
}
*/
static t_float minList (int n, t_atom *x)
{
t_float min=atom_getfloat(x);
t_float f;
for (;n--;x++) {
f = atom_getfloat(x);
min = (min < f)?min:f;
}
return min;
}
static t_float minListStep (int n, const int step, t_atom *x)
{
t_float min=atom_getfloat(x);
t_float f;
for (;n--;x+=step) {
f = atom_getfloat(x);
min = (min < f)?min:f;
}
return min;
}
static t_float maxList (int n, t_atom *x)
{
t_float max=atom_getfloat(x);
t_float f;
for (;n--;x++) {
f = atom_getfloat(x);
max = (max > f)?max:f;
}
return max;
}
static t_float maxListStep (int n, const int step, t_atom *x)
{
t_float max=atom_getfloat(x);
t_float f;
for (;n--;x+=step) {
f = atom_getfloat(x);
max = (max > f)?max:f;
}
return max;
}
static void minListColumns (const int rows, const int columns, t_atom *x, t_atom *y)
{
int count;
t_float f;
for (count=0; count < columns; count++, x++, y++) {
f=minListStep (rows, columns, x);
SETFLOAT(y,f);
}
}
static void minListRows (int rows, int columns, t_atom *x, t_atom *y)
{
int count;
t_float f;
for (count=0; count < rows; count++, x+=columns, y++) {
f=minList (columns, x);
SETFLOAT(y,f);
}
}
static void maxListColumns (const int rows, const int columns, t_atom *x, t_atom *y)
{
int count;
t_float f;
for (count=0; count < columns; count++, x++, y++) {
f=maxListStep (rows, columns, x);
SETFLOAT(y,f);
}
}
static void maxListRows (int rows, int columns, t_atom *x, t_atom *y)
{
int count;
t_float f;
for (count=0; count < rows; count++, x+=columns, y++) {
f=maxList (columns, x);
SETFLOAT(y,f);
}
}
static void mTXMinMaxMatrix (MTXminmax *mtx_minmax_obj, t_symbol *s,
int argc, t_atom *argv)
{
int rows = atom_getint (argv++);
int columns = atom_getint (argv++);
int size = rows * columns;
int list_size = argc - 2;
t_atom *list_in = argv;
t_atom *list_out = mtx_minmax_obj->list_out;
int count;
int rows_out;
int columns_out;
// size check
if (!size) {
post("mtx_minmax: invalid dimensions");
return;
}
else if (list_size<size) {
post("mtx_minmax: sparse matrix not yet supported: use \"mtx_check\"");
return;
}
if (size != mtx_minmax_obj->size) {
if (!list_out)
list_out = (t_atom *) getbytes (sizeof (t_atom) * (size + 2));
else
list_out = (t_atom *) resizebytes (list_out,
sizeof (t_atom) * (mtx_minmax_obj->size+2),
sizeof (t_atom) * (size + 2));
}
mtx_minmax_obj->size = size;
mtx_minmax_obj->list_out = list_out;
// main part
list_out += 2;
//copyList (size, argv, list_out);
switch (mtx_minmax_obj->minmax_dimension) {
case 0:
columns_out = 1;
rows_out = 1;
if (mtx_minmax_obj->operator_minimum)
minListRows (1, size, list_in, list_out);
else
maxListRows (1, size, list_in, list_out);
break;
case 1:
rows_out = rows;
columns_out = 1;
if (mtx_minmax_obj->operator_minimum)
minListRows (rows, columns, list_in, list_out);
else
maxListRows (rows, columns, list_in, list_out);
break;
case 2:
rows_out = 1;
columns_out = columns;
if (mtx_minmax_obj->operator_minimum)
minListColumns (rows, columns, list_in, list_out);
else
maxListColumns (rows, columns, list_in, list_out);
break;
}
mtx_minmax_obj->outsize = columns_out * rows_out;
list_out = mtx_minmax_obj->list_out;
SETSYMBOL(list_out, gensym("matrix"));
SETFLOAT(list_out, rows_out);
SETFLOAT(&list_out[1], columns_out);
outlet_anything(mtx_minmax_obj->list_outlet, gensym("matrix"),
mtx_minmax_obj->outsize+2, list_out);
}
void mtx_minmax_setup (void)
{
mtx_minmax_class = class_new
(gensym("mtx_min"),
(t_newmethod) newMTXMin,
(t_method) deleteMTXMinMax,
sizeof (MTXminmax),
CLASS_DEFAULT, A_GIMME, 0);
class_addbang (mtx_minmax_class, (t_method) mTXMinMaxBang);
class_addmethod (mtx_minmax_class, (t_method) mTXMinMaxMatrix, gensym("matrix"), A_GIMME,0);
class_addmethod (mtx_minmax_class, (t_method) mTXSetMinMaxDimension, gensym("dimension"), A_DEFFLOAT,0);
class_addmethod (mtx_minmax_class, (t_method) mTXSetMinMaxDirection, gensym("direction"), A_DEFFLOAT,0);
class_addcreator ((t_newmethod) newMTXMax, gensym("mtx_max"), A_GIMME,0);
class_sethelpsymbol (mtx_minmax_class, gensym("iemmatrix/mtx_minmax"));
}
void iemtx_minmax_setup(void){
mtx_minmax_setup();
}
--- NEW FILE: mtx_repmat.c ---
/*
* 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_repmat_class;
typedef struct _MTXrepmat_ MTXrepmat;
struct _MTXrepmat_
{
t_object x_obj;
int size;
int repeat_rows;
int repeat_cols;
t_outlet *list_outlet;
t_atom *list_out;
};
static void deleteMTXRepmat (MTXrepmat *mtx_repmat_obj)
{
if (mtx_repmat_obj->list_out)
freebytes (mtx_repmat_obj->list_out, sizeof(t_atom)*(mtx_repmat_obj->size+2));
}
static void mTXRepmatList (MTXrepmat *mtx_repmat_obj, t_symbol *s,
int argc, t_atom *argv)
{
if (argc!=2) {
post("mtx_repmat: there have to be exactly 2 arguments");
return;
}
mtx_repmat_obj->repeat_rows = atom_getint(argv++);
mtx_repmat_obj->repeat_cols = atom_getint(argv);
}
static void *newMTXRepmat (t_symbol *s, int argc, t_atom *argv)
{
MTXrepmat *mtx_repmat_obj = (MTXrepmat *) pd_new (mtx_repmat_class);
mtx_repmat_obj->repeat_cols = 1;
mtx_repmat_obj->repeat_rows = 1;
if (argc)
mTXRepmatList (mtx_repmat_obj, gensym("list"), argc, argv);
mtx_repmat_obj->list_outlet = outlet_new (&mtx_repmat_obj->x_obj, gensym("matrix"));
inlet_new(&mtx_repmat_obj->x_obj, &mtx_repmat_obj->x_obj.ob_pd, gensym("list"),gensym(""));
return ((void *) mtx_repmat_obj);
}
static void mTXRepmatBang (MTXrepmat *mtx_repmat_obj)
{
if (mtx_repmat_obj->list_out)
outlet_anything(mtx_repmat_obj->list_outlet, gensym("matrix"),
mtx_repmat_obj->size+2, mtx_repmat_obj->list_out);
}
static void copyList (int n, t_atom *x, t_atom *y)
{
while (n--)
*y++=*x++;
}
static void writeRepeatIntoMatrix (int repeat_rows, int repeat_cols, int rows, int columns, t_atom *x, t_atom *y)
{
int row_cnt;
int col_cnt;
int idx = 0;
int new_col = columns * repeat_cols;
t_atom *ptr = y;
// writing each row repeatedly (repeat_col times) into output array
// so that : row1#1 row1#2 ... row1#RN | ... | rowN#1 rowN#2 ... rowN#RN
for (row_cnt=rows;row_cnt--;x+=columns)
for(col_cnt=repeat_cols;col_cnt--;ptr+=columns)
copyList (columns, x, ptr);
// repeating the above written long lines repeat row_repeat times in output array
for (;--repeat_rows;)
for (row_cnt=rows;row_cnt--;y+=new_col,ptr+=new_col)
copyList (new_col, y, ptr);
}
static void mTXRepmatMatrix (MTXrepmat *mtx_repmat_obj, t_symbol *s,
int argc, t_atom *argv)
{
int rows = atom_getint (argv++);
int columns = atom_getint (argv++);
int rep_rows = mtx_repmat_obj->repeat_rows;
int rep_cols = mtx_repmat_obj->repeat_cols;
int mrows = rows * rep_rows;
int mcolumns = columns * rep_cols;
int size = rows * columns;
int list_size = argc - 2;
t_atom *list_in = argv;
t_atom *list_out = mtx_repmat_obj->list_out;
// size check
if (!size) {
post("mtx_repmat: invalid dimensions");
return;
}
else if (list_size<size) {
post("mtx_repmat: sparse matrix not yet supported: use \"mtx_check\"");
return;
}
mrows = rows * rep_rows;
mcolumns = columns * rep_cols;
size = mrows * mcolumns;
if (size != mtx_repmat_obj->size) {
if (list_out)
list_out = (t_atom*) resizebytes (list_out,
sizeof(t_atom)*(mtx_repmat_obj->size+2),
sizeof(t_atom)*(size+2));
else
list_out = (t_atom*) getbytes (sizeof(t_atom)*(size+2));
mtx_repmat_obj->list_out = list_out;
mtx_repmat_obj->size = size;
//post("size %d, rows %d, columns %d", size, rows, columns);
}
// main part
writeRepeatIntoMatrix (rep_rows, rep_cols, rows, columns,
list_in, list_out+2);
SETFLOAT(list_out, mrows);
SETFLOAT(&list_out[1], mcolumns);
mTXRepmatBang (mtx_repmat_obj);
}
void mtx_repmat_setup (void)
{
mtx_repmat_class = class_new
(gensym("mtx_repmat"),
(t_newmethod) newMTXRepmat,
(t_method) deleteMTXRepmat,
sizeof (MTXrepmat),
CLASS_DEFAULT, A_GIMME, 0);
class_addbang (mtx_repmat_class, (t_method) mTXRepmatBang);
class_addmethod (mtx_repmat_class, (t_method) mTXRepmatMatrix, gensym("matrix"), A_GIMME,0);
class_addmethod (mtx_repmat_class, (t_method) mTXRepmatList, gensym(""), A_GIMME,0);
class_sethelpsymbol (mtx_repmat_class, gensym("iemmatrix/mtx_repmat"));
}
void iemtx_repmat_setup(void){
mtx_repmat_setup();
}
--- NEW FILE: mtx_reverse.c ---
/*
* 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_reverse_class;
typedef struct _MTXreverse_ MTXreverse;
struct _MTXreverse_
{
t_object x_obj;
int size;
int reverse_dimension;
t_outlet *list_outlet;
t_atom *list_out;
t_atom *list_in;
};
static void deleteMTXreverse (MTXreverse *mtx_reverse_obj)
{
if (mtx_reverse_obj->list_out)
freebytes (mtx_reverse_obj->list_out, sizeof(t_atom)*(mtx_reverse_obj->size+2));
}
static void mTXSetreverseDimension (MTXreverse *mtx_reverse_obj, t_float c_dim)
{
int dimension = (int) c_dim;
dimension = (dimension > 0)?dimension:0;
dimension = (dimension < 2)?dimension:2;
mtx_reverse_obj->reverse_dimension = dimension;
}
static void *newMTXreverse (t_symbol *s, int argc, t_atom *argv)
{
MTXreverse *mtx_reverse_obj = (MTXreverse *) pd_new (mtx_reverse_class);
int c_dim = 0;
mtx_reverse_obj->reverse_dimension = c_dim;
switch ((argc>1)?1:argc) {
case 1:
c_dim = atom_getint(argv);
}
mTXSetreverseDimension (mtx_reverse_obj, (t_float) c_dim);
mtx_reverse_obj->list_outlet = outlet_new (&mtx_reverse_obj->x_obj, gensym("matrix"));
return ((void *) mtx_reverse_obj);
}
static void mTXreverseBang (MTXreverse *mtx_reverse_obj)
{
if (mtx_reverse_obj->list_out)
outlet_anything(mtx_reverse_obj->list_outlet, gensym("matrix"),
mtx_reverse_obj->size+2, mtx_reverse_obj->list_out);
}
static void copyList (int n, t_atom *x, t_atom *y)
{
for (;n--;)
*y++ = *x++;
}
static void reverseList (int n, t_atom *y)
{
t_atom *read = y;
t_atom tmp;
y += n-1;
n >>= 1;
for (;n--;) {
tmp = *y;
*y-- = *read;
*read++ = tmp;
}
}
static void reverseListStep (int n, int step, t_atom *y)
{
t_atom *read = y;
t_atom tmp;
n /= step;
y += (n-1) * step;
n >>= 1;
for (;n--; y-=step, read+=step) {
tmp = *y;
*y = *read;
*read = tmp;
}
}
static void mTXreverseMatrix (MTXreverse *mtx_reverse_obj, t_symbol *s,
int argc, t_atom *argv)
{
int rows = atom_getint (argv++);
int columns = atom_getint (argv++);
int size = rows * columns;
int list_size = argc - 2;
t_atom *list_in = argv;
t_atom *list_out = mtx_reverse_obj->list_out;
int count;
// size check
if (!size) {
post("mtx_reverse: invalid dimensions");
return;
}
else if (list_size<size) {
post("mtx_reverse: sparse matrix not yet supported: use \"mtx_check\"");
return;
}
if (size != mtx_reverse_obj->size) {
if (!list_out)
list_out = (t_atom *) getbytes (sizeof (t_atom) * (size + 2));
else
list_out = (t_atom *) resizebytes (list_out,
sizeof (t_atom) * (mtx_reverse_obj->size+2),
sizeof (t_atom) * (size + 2));
}
mtx_reverse_obj->size = size;
mtx_reverse_obj->list_out = list_out;
// main part
list_out += 2;
copyList (size, argv, list_out);
switch (mtx_reverse_obj->reverse_dimension) {
case 2:
for (count = columns; count--; list_out++)
reverseListStep (size, columns, list_out);
break;
case 1:
for (count = rows; count--; list_out += columns)
reverseList (columns, list_out);
break;
case 0:
reverseList (size, list_out);
break;
}
list_out = mtx_reverse_obj->list_out;
SETSYMBOL(list_out, gensym("matrix"));
SETFLOAT(list_out, rows);
SETFLOAT(&list_out[1], columns);
outlet_anything(mtx_reverse_obj->list_outlet, gensym("matrix"),
mtx_reverse_obj->size+2, list_out);
}
void mtx_reverse_setup (void)
{
mtx_reverse_class = class_new
(gensym("mtx_reverse"),
(t_newmethod) newMTXreverse,
(t_method) deleteMTXreverse,
sizeof (MTXreverse),
CLASS_DEFAULT, A_GIMME, 0);
class_addbang (mtx_reverse_class, (t_method) mTXreverseBang);
class_addmethod (mtx_reverse_class, (t_method) mTXreverseMatrix, gensym("matrix"), A_GIMME,0);
class_addmethod (mtx_reverse_class, (t_method) mTXSetreverseDimension, gensym("dimension"), A_DEFFLOAT,0);
class_sethelpsymbol (mtx_reverse_class, gensym("iemmatrix/mtx_reverse"));
}
void iemtx_reverse_setup(void){
mtx_reverse_setup();
}
--- NEW FILE: mtx_cumsum.c ---
/*
* 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_cumsum_class;
typedef struct _MTXCumsum_ MTXCumsum;
struct _MTXCumsum_
{
t_object x_obj;
int rows;
int columns;
int size;
int cumsum_dimension;
int cumsum_direction;
t_outlet *list_outlet;
t_atom *list_out;
t_atom *list_in;
t_float *x;
t_float *y;
};
static void deleteMTXCumsum (MTXCumsum *mtx_cumsum_obj)
{
if (mtx_cumsum_obj->list_out)
freebytes (mtx_cumsum_obj->list_out, sizeof(t_atom)*(mtx_cumsum_obj->size+2));
if (mtx_cumsum_obj->x)
freebytes (mtx_cumsum_obj->x, sizeof(t_float)*(mtx_cumsum_obj->size));
if (mtx_cumsum_obj->y)
freebytes (mtx_cumsum_obj->y, sizeof(t_float)*(mtx_cumsum_obj->size));
}
static void mTXSetCumsumDirection (MTXCumsum *mtx_cumsum_obj, t_float c_dir)
{
int direction = (int) c_dir;
mtx_cumsum_obj->cumsum_direction = (direction==-1)?direction:1;
}
static void mTXSetCumsumDimension (MTXCumsum *mtx_cumsum_obj, t_float c_dim)
{
int dimension = (int) c_dim;
mtx_cumsum_obj->cumsum_dimension = (dimension==2)?dimension:1;
}
static void *newMTXCumsum (t_symbol *s, int argc, t_atom *argv)
{
MTXCumsum *mtx_cumsum_obj = (MTXCumsum *) pd_new (mtx_cumsum_class);
int c_dir = 1;
int c_dim = 1;
mtx_cumsum_obj->cumsum_dimension = c_dim;
switch ((argc>2)?2:argc) {
case 2:
c_dir = atom_getint(argv+1);
case 1:
c_dim = atom_getint(argv);
}
mTXSetCumsumDirection (mtx_cumsum_obj, (t_float) c_dir);
mTXSetCumsumDimension (mtx_cumsum_obj, (t_float) c_dim);
mtx_cumsum_obj->list_outlet = outlet_new (&mtx_cumsum_obj->x_obj, gensym("matrix"));
return ((void *) mtx_cumsum_obj);
}
static void mTXCumsumBang (MTXCumsum *mtx_cumsum_obj)
{
if (mtx_cumsum_obj->list_out)
outlet_anything(mtx_cumsum_obj->list_outlet, gensym("matrix"),
mtx_cumsum_obj->size+2, mtx_cumsum_obj->list_out);
}
static void writeFloatIntoList (int n, t_atom *l, t_float *f)
{
for (;n--;f++, l++)
SETFLOAT (l, *f);
}
static void readFloatFromList (int n, t_atom *l, t_float *f)
{
while (n--)
*f++ = atom_getfloat (l++);
}
static void readFloatFromListModulo (int n, int m, t_atom *l, t_float *f)
{
t_atom *ptr = l;
int count1, count2;
n /= m;
count1 = m;
while (count1--)
for (count2 = n, ptr = l++; count2--; ptr += m, f++)
*f = atom_getfloat (ptr);
}
static void writeFloatIntoListModulo (int n, int m, t_atom *l, t_float *f)
{
t_atom *ptr = l;
int count1, count2;
n /= m;
count1 = m;
while (count1--)
for (count2 = n, ptr = l++; count2--; ptr += m, f++)
SETFLOAT(ptr,*f);
}
static void cumSum (int n, t_float *x, t_float *y)
{
t_float accu = 0.0f;
for (;n--; x++, y++) {
accu += *x;
*y = accu;
}
}
static void cumSumReverse (int n, t_float *x, t_float *y)
{
t_float accu = 0.0f;
for (;n--; x--, y--) {
accu += *x;
*y = accu;
}
}
static void mTXCumsumMatrix (MTXCumsum *mtx_cumsum_obj, t_symbol *s,
int argc, t_atom *argv)
{
int rows = atom_getint (argv++);
int columns = atom_getint (argv++);
int size = rows * columns;
int list_size = argc - 2;
t_atom *list_ptr = argv;
t_atom *list_out = mtx_cumsum_obj->list_out;
t_float *x = mtx_cumsum_obj->x;
t_float *y = mtx_cumsum_obj->y;
int count;
// size check
if (!size) {
post("mtx_cumsum: invalid dimensions");
return;
}
else if (list_size<size) {
post("mtx_cumsum: sparse matrix not yet supported: use \"mtx_check\"");
return;
}
else if ((!x)||(!list_out)||(!y)) {
if (!x)
x = (t_float *) getbytes (sizeof (t_float) * (size));
if (!y)
y = (t_float *) getbytes (sizeof (t_float) * (size));
if (!list_out)
list_out = (t_atom *) getbytes (sizeof (t_atom) * (size+2));
}
else if (size != mtx_cumsum_obj->size) {
x = (t_float *) resizebytes (x,
sizeof (t_float) * (mtx_cumsum_obj->size),
sizeof (t_float) * (size));
y = (t_float *) resizebytes (y,
sizeof (t_float) * (mtx_cumsum_obj->size),
sizeof (t_float) * (size));
list_out = (t_atom *) resizebytes (list_out,
sizeof (t_atom) * (mtx_cumsum_obj->size+2),
sizeof (t_atom) * (size + 2));
}
mtx_cumsum_obj->size = size;
mtx_cumsum_obj->rows = rows;
mtx_cumsum_obj->columns = columns;
mtx_cumsum_obj->list_out = list_out;
mtx_cumsum_obj->x = x;
mtx_cumsum_obj->y = y;
// main part
// reading matrix from inlet
if (mtx_cumsum_obj->cumsum_dimension == 2) {
readFloatFromListModulo (size, columns, list_ptr, x);
columns = mtx_cumsum_obj->rows;
rows = mtx_cumsum_obj->columns;
}
else
readFloatFromList (size, list_ptr, x);
// calculating cumsum
if (mtx_cumsum_obj->cumsum_direction == -1) {
x += columns-1;
y += columns-1;
for (count = rows; count--; x += columns, y += columns)
cumSumReverse (columns,x,y);
}
else
for (count = rows; count--; x += columns, y += columns)
cumSum (columns,x,y);
x = mtx_cumsum_obj->x;
y = mtx_cumsum_obj->y;
// writing matrix to outlet
if (mtx_cumsum_obj->cumsum_dimension == 2) {
columns = mtx_cumsum_obj->columns;
rows = mtx_cumsum_obj->rows;
writeFloatIntoListModulo (size, columns, list_out+2, y);
}
else
writeFloatIntoList (size, list_out+2, y);
SETSYMBOL(list_out, gensym("matrix"));
SETFLOAT(list_out, rows);
SETFLOAT(&list_out[1], columns);
outlet_anything(mtx_cumsum_obj->list_outlet, gensym("matrix"),
mtx_cumsum_obj->size+2, list_out);
}
void mtx_cumsum_setup (void)
{
mtx_cumsum_class = class_new
(gensym("mtx_cumsum"),
(t_newmethod) newMTXCumsum,
(t_method) deleteMTXCumsum,
sizeof (MTXCumsum),
CLASS_DEFAULT, A_GIMME, 0);
class_addbang (mtx_cumsum_class, (t_method) mTXCumsumBang);
class_addmethod (mtx_cumsum_class, (t_method) mTXCumsumMatrix, gensym("matrix"), A_GIMME,0);
class_addmethod (mtx_cumsum_class, (t_method) mTXSetCumsumDimension, gensym("dimension"), A_DEFFLOAT,0);
class_addmethod (mtx_cumsum_class, (t_method) mTXSetCumsumDirection, gensym("direction"), A_DEFFLOAT,0);
class_sethelpsymbol (mtx_cumsum_class, gensym("iemmatrix/mtx_cumsum"));
}
void iemtx_cumsum_setup(void){
mtx_cumsum_setup();
}
--- NEW FILE: mtx_conv.c ---
/*
* 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_conv_class;
typedef struct _MTXConv_ MTXConv;
struct _MTXConv_
{
t_object x_obj;
int size;
int rows;
int columns;
int rows_k;
int columns_k;
int size_k;
int rows_y;
int columns_y;
int size_y;
t_float renorm_fac;
t_float **x;
t_float **k;
t_float **y;
t_outlet *list_outlet;
t_atom *list;
};
static t_float **getTFloatMatrix (int rows, int columns)
{
t_float **matrix = (t_float **) getbytes
(sizeof (t_float *) * columns);
t_float **mtx = matrix;
while (columns--)
if (!(*matrix++ = (t_float *) getbytes
(sizeof (t_float) * rows)))
post("an error has occured :)");
return mtx;
}
static void deleteTFloatMatrix (t_float **matrix, int rows, int columns)
{
int n = columns;
t_float **matr = matrix;
if (matr) {
while (n--)
if (*matr)
freebytes (*matr++, sizeof(t_float) * rows);
freebytes (matrix, sizeof(t_float*) * columns);
}
}
static t_float **resizeTFloatMatrix (t_float **old, int rows_old, int columns_old,
int rows_new, int columns_new)
{
t_float **mtx = old;
int count1, count2;
post("resizing from %dx%d to %dx%d", rows_old, columns_old, rows_new, columns_new);
if ((rows_new == 0)||(columns_new == 0)) {
deleteTFloatMatrix (old, rows_old, columns_old);
old = 0;
return;
}
// 1. if rows_old>rows_new: old row disposal
if (rows_old>rows_new)
for (count1 = (rows_old - rows_new), mtx += rows_new;
count1--; mtx++)
freebytes (*mtx, sizeof(t_float) * columns_old);
// 2. resize row (double) pointer
mtx = old = (t_float **) resizebytes(old, sizeof(t_float*) * rows_old,
sizeof(t_float*) * rows_new);
// 3. resizing rows if new size is smaller
if (rows_old>rows_new)
for (count1 = rows_new; count1--; mtx++)
*mtx = (t_float *) resizebytes (*mtx, sizeof(t_float) * columns_old,
sizeof(t_float) * columns_new);
else { // 4. resizing old rows if new size is bigger, allocating new rows
for (count1 = rows_old; count1--; mtx++)
*mtx = (t_float *) resizebytes (*mtx, sizeof(t_float) * columns_old,
sizeof(t_float) * columns_new);
for (count1 = (rows_new - rows_old); count1--; mtx++)
*mtx = (t_float *) getbytes (sizeof(t_float) * columns_new);
}
post("return resize");
return old;
}
static void deleteMTXConv (MTXConv *mtx_conv_obj)
{
int count = mtx_conv_obj->rows;
deleteTFloatMatrix (mtx_conv_obj->k, mtx_conv_obj->rows_k, mtx_conv_obj->columns_k);
deleteTFloatMatrix (mtx_conv_obj->x, mtx_conv_obj->rows, mtx_conv_obj->columns);
deleteTFloatMatrix (mtx_conv_obj->y, mtx_conv_obj->rows_y, mtx_conv_obj->columns_y);
if (mtx_conv_obj->list)
freebytes (mtx_conv_obj->list, sizeof(t_float) * (mtx_conv_obj->size_y + 2));
mtx_conv_obj->k = 0;
mtx_conv_obj->x = 0;
mtx_conv_obj->y = 0;
mtx_conv_obj->list = 0;
}
static void *newMTXConv (t_symbol *s, int argc, t_atom *argv)
{
MTXConv *mtx_conv_obj = (MTXConv *) pd_new (mtx_conv_class);
mtx_conv_obj->list_outlet = outlet_new (&mtx_conv_obj->x_obj, gensym("matrix"));
inlet_new(&mtx_conv_obj->x_obj, &mtx_conv_obj->x_obj.ob_pd, gensym("matrix"),gensym(""));
mtx_conv_obj->size = 0;
mtx_conv_obj->rows = 0;
mtx_conv_obj->columns = 0;
mtx_conv_obj->size_y = 0;
mtx_conv_obj->rows_y = 0;
mtx_conv_obj->columns_y = 0;
mtx_conv_obj->size_k = 0;
mtx_conv_obj->rows_k = 0;
mtx_conv_obj->columns_k = 0;
return ((void *) mtx_conv_obj);
}
static void mTXConvBang (MTXConv *mtx_conv_obj)
{
if (mtx_conv_obj->list)
outlet_anything(mtx_conv_obj->list_outlet, gensym("matrix"), mtx_conv_obj->size+2, mtx_conv_obj->list);
}
static void zeroFloatArray (int n, t_float *f)
{
while (n--)
*f++ = 0.0f;
}
static void zeroTFloatMatrix (t_float **mtx, int rows, int columns)
{
while (rows--)
zeroFloatArray (columns, *mtx++);
}
static void writeFloatIntoList (int n, t_atom *l, t_float *f)
{
for (;n--;f++, l++)
SETFLOAT (l, *f);
}
static void readFloatFromList (int n, t_atom *l, t_float *f)
{
while (n--)
*f++ = atom_getfloat (l++);
}
static void scaleVector (int n, t_float *x, t_float *y, t_float k)
{
while (n--)
*y++ = k * *x++;
}
static void addWeightedVector (int n, t_float *x, t_float *y, t_float k)
{
while (n--)
*y++ += k * *y++;
}
static void readMatrixFromList (int rows, int columns, t_atom *l, t_float **mtx)
{
for (;rows--; l+=columns)
readFloatFromList (columns, l, *mtx++);
}
static void writeMatrixIntoList (int rows, int columns, t_atom *l, t_float **mtx)
{
for (;rows--; l+=columns)
writeFloatIntoList (columns, l, *mtx++);
}
static void mTXConvKernelMatrix (MTXConv *mtx_conv_obj, t_symbol *s, int argc,
t_atom *argv)
{
int rows_k = atom_getint (argv++);
int columns_k = atom_getint (argv++);
int in_size = argc-2;
int size_k = rows_k * columns_k;
t_float **k = mtx_conv_obj->k;
if (!size_k)
post ("mtx_conv: invalid matrix dimensions!");
else if (in_size < size_k)
post("mtx_conv: sparse matrix not yet supported: use \"mtx_check\"");
else if ((rows_k != mtx_conv_obj->rows_k) || (columns_k != mtx_conv_obj->columns_k)) {
if (k)
k = resizeTFloatMatrix (k, mtx_conv_obj->rows_k, mtx_conv_obj->columns_k,
rows_k, columns_k);
else
k = getTFloatMatrix (rows_k, columns_k);
mtx_conv_obj->rows_k = rows_k;
mtx_conv_obj->columns_k = columns_k;
readMatrixFromList (rows_k, columns_k, argv, k);
mtx_conv_obj->k = k;
mtx_conv_obj->size_k = size_k;
}
else
readMatrixFromList (rows_k, columns_k, argv, k);
}
static void convolveRow (int columns, int columns_c, t_float *x, t_float *c, t_float *y)
{
int n,k,count;
for (k = 0; k < columns_c; k++)
for (n = k, count = columns; count--; n++)
y[n] += x[n-k] * c[k];
}
static void convolveMtx (int rows, int columns, int rows_c, int columns_c,
t_float **x, t_float **c, t_float **y)
{
int n,k,count;
zeroTFloatMatrix (y, rows+rows_c-1, columns+columns_c-1);
for (k = 0; k < rows_c; k++)
for (n = k, count = rows; count--; n++)
convolveRow (columns, columns_c, x[n-k], c[k], y[n]);
}
static void mTXConvMatrix (MTXConv *mtx_conv_obj, t_symbol *s,
int argc, t_atom *argv)
{
int rows = atom_getint (argv++);
int columns = atom_getint (argv++);
int size = rows * columns;
int rows_k = mtx_conv_obj->rows_k;
int columns_k = mtx_conv_obj->columns_k;
int size_k = mtx_conv_obj->size_k;
int in_size = argc-2;
int rows_y;
int columns_y;
int size_y = mtx_conv_obj->size_y;
t_atom *list_ptr = mtx_conv_obj->list;
t_float **x = mtx_conv_obj->x;
t_float **y = mtx_conv_obj->y;
t_float **k = mtx_conv_obj->k;
t_float *ptr1;
t_float *ptr2;
int row_count;
int offset1;
int offset2;
int count;
// fftsize check
if (!size){
post("mtx_conv: invalid dimensions");
return;
} else if (in_size<size) {
post("mtx_conv: sparse matrix not yet supported: use \"mtx_check\"");
return;
} else if (!size_k) {
post("mtx_conv: no valid filter kernel defined");
return;
}
post("1");
if ((mtx_conv_obj->rows != rows)||(mtx_conv_obj->columns != columns)) {
if (x)
x = resizeTFloatMatrix (x, mtx_conv_obj->rows, mtx_conv_obj->columns,
rows, columns);
else
x = getTFloatMatrix (rows, columns);
mtx_conv_obj->x = x;
mtx_conv_obj->size = size;
mtx_conv_obj->rows = rows;
mtx_conv_obj->columns = columns;
}
post("2");
rows_y = rows+rows_k-1;
columns_y = columns+columns_k-1;
if ((mtx_conv_obj->rows_y != rows_y)||(mtx_conv_obj->columns_y != columns_y)) {
size_y = rows_y * columns_y;
if (y)
y = resizeTFloatMatrix (y, mtx_conv_obj->rows_y, mtx_conv_obj->columns_y,
rows_y, columns_y);
else
y = getTFloatMatrix (rows_y, columns_y);
if (list_ptr)
list_ptr = (t_atom *) resizebytes (list_ptr, sizeof(t_atom) * (mtx_conv_obj->size_y+2),
sizeof (t_atom) * (size_y+2));
else
list_ptr = (t_atom *) getbytes (sizeof (t_atom) * (size_y+2));
mtx_conv_obj->size_y = size_y;
mtx_conv_obj->rows_y = rows_y;
mtx_conv_obj->columns_y = columns_y;
mtx_conv_obj->y = y;
mtx_conv_obj->list = list_ptr;
}
post("3");
// main part
readMatrixFromList (rows, columns, argv, x);
post("4");
convolveMtx (rows, columns, rows_k, columns_k, x, k, y);
post("5");
writeMatrixIntoList (rows_y, columns_y, list_ptr+2, y);
post("6");
SETSYMBOL(list_ptr, gensym("matrix"));
SETFLOAT(list_ptr, rows_y);
SETFLOAT(&list_ptr[1], columns_y);
outlet_anything(mtx_conv_obj->list_outlet, gensym("matrix"),
size_y+2, list_ptr);
post("7");
}
void mtx_conv_setup (void)
{
mtx_conv_class = class_new
(gensym("mtx_conv"),
(t_newmethod) newMTXConv,
(t_method) deleteMTXConv,
sizeof (MTXConv),
CLASS_DEFAULT, A_GIMME, 0);
class_addbang (mtx_conv_class, (t_method) mTXConvBang);
class_addmethod (mtx_conv_class, (t_method) mTXConvMatrix, gensym("matrix"), A_GIMME,0);
class_addmethod (mtx_conv_class, (t_method) mTXConvKernelMatrix, gensym(""), A_GIMME,0);
class_sethelpsymbol (mtx_conv_class, gensym("iemmatrix/mtx_conv"));
}
void iemtx_conv_setup(void){
mtx_conv_setup();
}