: $Id: matrix.mod,v 1.32 2003/09/05 18:52:54 billl Exp $ :* COMMENT COMMENT NB: only minimal error checking done NB: no dynamic allocation - eg m1.transpose(m1) will give a wrong result NB: matrix and vec sizes must be correct before using: use .resize() ================ USAGE ================ objref mat mat = new Vector(rows*cols) mat.mprintf(M,N) // print out as M rows and N columns mat2.transpose(mat) // transpose of matrix y.mmult(mat,x) // y = mat*x y.spmult(pre,post,mat,x) // y = mat*x using "sparse matrix" w.spget(pre,post,row,col) // ie pre,post,post,pre!! spidget(pre,post,prid,poid ...) // match vals in 4 vecs to 4 vals wt.mkspcp/chkspcp(pre,post) // copy the indices into integer arrays mat.outprod(x,y) // mat = outer product of vectors x and y mat.mget(i,j,cols) // i=row#; j=col# mat.mset(i,j,cols,val) y.mrow(mat,i,cols) y.mcol(mat,j,cols) y.msetrow(mat,i,cols) y.msetcol(mat,j,cols) ================================================================ ENDCOMMENT NEURON { SUFFIX nothing } VERBATIM #ifndef NRN_VERSION_GTEQ_8_2_0 extern double hoc_call_func(Symbol*, int narg); #endif ENDVERBATIM PARAMETER { MATRIX_INSTALLED=0 } :* mat.outprod(x,y) // mat = outer product of vectors x and y VERBATIM static double outprod(void* vv) { int i, j, nx, ny, nz; double *x, *y, *z; /* this will be the outer product */ nx = vector_instance_px(vv, &x); /* these are the two vectors that make it up */ ny = vector_arg_px(1, &y); // will be number of columns nz = vector_arg_px(2, &z); // will be number of rows if (nx != ny*nz) { hoc_execerror("Vector size mismatch", 0); } for (i=0;i= nx) { hoc_execerror("Indices out of bounds", 0); } return x[i*cols+j]; } ENDVERBATIM :* mrow(mat,i,cols) VERBATIM static double mrow(void* vv) { int i, j, nx, ny, rows, cols; double *x, *y; nx = vector_instance_px(vv, &x); ny = vector_arg_px(1, &y); i = (int)*getarg(2); cols = (int)*getarg(3); rows=ny/cols; if (cols!=nx) { nx=vector_buffer_size((IvocVect*)vv); if (cols<=nx) { vector_resize((IvocVect*)vv, cols); nx=cols; } else { printf("%d > %d :: \n",cols,nx); hoc_execerror("Vector max capacity too small in mrow", 0); } } if (i>=rows) { hoc_execerror("Indices out of bounds", 0); } for (j=0;j %d :: ",rows,nx); hoc_execerror("Vector max capacity too small in mcol ", 0); } } if (j>=cols) { hoc_execerror("Indices out of bounds", 0); } for (i=0;i=ny/cols) { hoc_execerror("Indices out of bounds", 0); } for (j=0;j=cols) { hoc_execerror("Indices out of bounds", 0); } for (i=0;i= nx) { hoc_execerror("Indices out of bounds", 0); } return (x[i*cols+j]=val); } ENDVERBATIM :* PROCEDURE install_matrix() PROCEDURE install_matrix() { MATRIX_INSTALLED=1 VERBATIM /* the list of additional methods */ install_vector_method("outprod", outprod); install_vector_method("mmult", mmult); install_vector_method("spmult", spmult); install_vector_method("spget", spget); install_vector_method("mkspcp", mkspcp); install_vector_method("chkspcp", chkspcp); install_vector_method("spltp", spltp); install_vector_method("transpose", transpose); install_vector_method("mprintf", mprintf); install_vector_method("mget", mget); install_vector_method("mset", mset); install_vector_method("mrow", mrow); install_vector_method("mcol", mcol); install_vector_method("msetrow", msetrow); install_vector_method("msetcol", msetcol); ENDVERBATIM }