| idamnjanovic@70 | 1 /************************************************************************** | 
| idamnjanovic@70 | 2  * | 
| idamnjanovic@70 | 3  * File name: rowlincomb.c | 
| idamnjanovic@70 | 4  * | 
| idamnjanovic@70 | 5  * Ron Rubinstein | 
| idamnjanovic@70 | 6  * Computer Science Department | 
| idamnjanovic@70 | 7  * Technion, Haifa 32000 Israel | 
| idamnjanovic@70 | 8  * ronrubin@cs | 
| idamnjanovic@70 | 9  * | 
| idamnjanovic@70 | 10  * Last Updated: 21.5.2009 | 
| idamnjanovic@70 | 11  * | 
| idamnjanovic@70 | 12  *************************************************************************/ | 
| idamnjanovic@70 | 13 | 
| idamnjanovic@70 | 14 #include "mex.h" | 
| idamnjanovic@70 | 15 | 
| idamnjanovic@70 | 16 | 
| idamnjanovic@70 | 17 /* Input Arguments */ | 
| idamnjanovic@70 | 18 | 
| idamnjanovic@70 | 19 #define	X_IN	   prhs[0] | 
| idamnjanovic@70 | 20 #define A_IN     prhs[1] | 
| idamnjanovic@70 | 21 #define ROWS_IN  prhs[2] | 
| idamnjanovic@70 | 22 #define COLS_IN  prhs[3] | 
| idamnjanovic@70 | 23 | 
| idamnjanovic@70 | 24 | 
| idamnjanovic@70 | 25 /* Output Arguments */ | 
| idamnjanovic@70 | 26 | 
| idamnjanovic@70 | 27 #define	Y_OUT	plhs[0] | 
| idamnjanovic@70 | 28 | 
| idamnjanovic@70 | 29 | 
| idamnjanovic@70 | 30 void mexFunction(int nlhs, mxArray *plhs[], | 
| idamnjanovic@70 | 31 int nrhs, const mxArray*prhs[]) | 
| idamnjanovic@70 | 32 | 
| idamnjanovic@70 | 33 { | 
| idamnjanovic@70 | 34   double *A, *x, *y, *rows, *cols; | 
| idamnjanovic@70 | 35   mwSize m,n,m1,n1,m2,n2,rownum,colnum; | 
| idamnjanovic@70 | 36   mwIndex *row_ids,*col_ids,i,j; | 
| idamnjanovic@70 | 37   int colnumspecified=0; | 
| idamnjanovic@70 | 38 | 
| idamnjanovic@70 | 39 | 
| idamnjanovic@70 | 40   /* Check for proper number of arguments */ | 
| idamnjanovic@70 | 41 | 
| idamnjanovic@70 | 42   if (nrhs!=3 && nrhs!=4) { | 
| idamnjanovic@70 | 43     mexErrMsgTxt("Invalid number of input arguments."); | 
| idamnjanovic@70 | 44   } else if (nlhs > 1) { | 
| idamnjanovic@70 | 45     mexErrMsgTxt("Too many output arguments."); | 
| idamnjanovic@70 | 46   } | 
| idamnjanovic@70 | 47 | 
| idamnjanovic@70 | 48 | 
| idamnjanovic@70 | 49   /* Check the input dimensions */ | 
| idamnjanovic@70 | 50 | 
| idamnjanovic@70 | 51   m = mxGetM(A_IN); | 
| idamnjanovic@70 | 52   n = mxGetN(A_IN); | 
| idamnjanovic@70 | 53   if (!mxIsDouble(A_IN) || mxIsComplex(A_IN) || mxGetNumberOfDimensions(A_IN)>2) { | 
| idamnjanovic@70 | 54     mexErrMsgTxt("ROWLINCOMB requires that A be a double matrix."); | 
| idamnjanovic@70 | 55   } | 
| idamnjanovic@70 | 56 | 
| idamnjanovic@70 | 57   m1 = mxGetM(ROWS_IN); | 
| idamnjanovic@70 | 58   n1 = mxGetN(ROWS_IN); | 
| idamnjanovic@70 | 59   if (!mxIsDouble(ROWS_IN) || mxIsComplex(ROWS_IN) || (m1!=1 && n1!=1)) { | 
| idamnjanovic@70 | 60     mexErrMsgTxt("ROWLINCOMB requires that ROWS be an index vector of type double."); | 
| idamnjanovic@70 | 61   } | 
| idamnjanovic@70 | 62   rownum = (m1 > n1) ? m1 : n1;   /* the number of rows in the linear combination */ | 
| idamnjanovic@70 | 63 | 
| idamnjanovic@70 | 64   m2 = mxGetM(X_IN); | 
| idamnjanovic@70 | 65   n2 = mxGetN(X_IN); | 
| idamnjanovic@70 | 66   if (!mxIsDouble(X_IN) || mxIsComplex(X_IN) || ((m2!=1) && (n2!=1))) { | 
| idamnjanovic@70 | 67     mexErrMsgTxt("ROWLINCOMB requires that X be a double vector."); | 
| idamnjanovic@70 | 68   } | 
| idamnjanovic@70 | 69 | 
| idamnjanovic@70 | 70   if (m2 != rownum && n2 != rownum) { | 
| idamnjanovic@70 | 71     mexErrMsgTxt("The length of X does not match the number of rows in ROWS."); | 
| idamnjanovic@70 | 72   } | 
| idamnjanovic@70 | 73 | 
| idamnjanovic@70 | 74   if (nrhs==4) { | 
| idamnjanovic@70 | 75     m1 = mxGetM(COLS_IN); | 
| idamnjanovic@70 | 76     n1 = mxGetN(COLS_IN); | 
| idamnjanovic@70 | 77     if (!mxIsDouble(COLS_IN) || mxIsComplex(COLS_IN) || (m1!=1 && n1!=1)) { | 
| idamnjanovic@70 | 78       mexErrMsgTxt("ROWLINCOMB requires that COLS be an index vector of type double."); | 
| idamnjanovic@70 | 79     } | 
| idamnjanovic@70 | 80     colnum = (m1 > n1) ? m1 : n1;   /* the number of columns */ | 
| idamnjanovic@70 | 81     colnumspecified = 1; | 
| idamnjanovic@70 | 82     cols = mxGetPr(COLS_IN); | 
| idamnjanovic@70 | 83 | 
| idamnjanovic@70 | 84     Y_OUT = mxCreateDoubleMatrix(1, colnum, mxREAL); | 
| idamnjanovic@70 | 85   } | 
| idamnjanovic@70 | 86   else { | 
| idamnjanovic@70 | 87     cols = 0; | 
| idamnjanovic@70 | 88     Y_OUT = mxCreateDoubleMatrix(1, n, mxREAL); | 
| idamnjanovic@70 | 89   } | 
| idamnjanovic@70 | 90 | 
| idamnjanovic@70 | 91 | 
| idamnjanovic@70 | 92   /* Assign pointers to the various parameters */ | 
| idamnjanovic@70 | 93   A = mxGetPr(A_IN); | 
| idamnjanovic@70 | 94   rows = mxGetPr(ROWS_IN); | 
| idamnjanovic@70 | 95   x = mxGetPr(X_IN); | 
| idamnjanovic@70 | 96   y = mxGetPr(Y_OUT); | 
| idamnjanovic@70 | 97 | 
| idamnjanovic@70 | 98 | 
| idamnjanovic@70 | 99   /* check row indices */ | 
| idamnjanovic@70 | 100 | 
| idamnjanovic@70 | 101   row_ids = (mwIndex*)mxMalloc(rownum*sizeof(mwIndex)); | 
| idamnjanovic@70 | 102 | 
| idamnjanovic@70 | 103   for (i=0; i<rownum; ++i) { | 
| idamnjanovic@70 | 104     row_ids[i] = (mwIndex)(rows[i]+0.1)-1; | 
| idamnjanovic@70 | 105     if (row_ids[i]<0 || row_ids[i]>=m) { | 
| idamnjanovic@70 | 106       mexErrMsgTxt("Row index in ROWS is out of range."); | 
| idamnjanovic@70 | 107     } | 
| idamnjanovic@70 | 108   } | 
| idamnjanovic@70 | 109 | 
| idamnjanovic@70 | 110 | 
| idamnjanovic@70 | 111 | 
| idamnjanovic@70 | 112   if (colnumspecified) { | 
| idamnjanovic@70 | 113 | 
| idamnjanovic@70 | 114     /* check column indices */ | 
| idamnjanovic@70 | 115     col_ids = (mwIndex*)mxMalloc(colnum*sizeof(mwIndex)); | 
| idamnjanovic@70 | 116 | 
| idamnjanovic@70 | 117     for (i=0; i<colnum; ++i) { | 
| idamnjanovic@70 | 118       col_ids[i] = (mwIndex)(cols[i]+0.1)-1; | 
| idamnjanovic@70 | 119       if (col_ids[i]<0 || col_ids[i]>=n) { | 
| idamnjanovic@70 | 120         mexErrMsgTxt("Column index in COLS is out of range."); | 
| idamnjanovic@70 | 121       } | 
| idamnjanovic@70 | 122     } | 
| idamnjanovic@70 | 123 | 
| idamnjanovic@70 | 124     /* Do the actual computation */ | 
| idamnjanovic@70 | 125     for (j=0; j<colnum; ++j) { | 
| idamnjanovic@70 | 126       for (i=0; i<rownum; ++i) { | 
| idamnjanovic@70 | 127         y[j] += A[m*col_ids[j]+row_ids[i]]*x[i]; | 
| idamnjanovic@70 | 128       } | 
| idamnjanovic@70 | 129     } | 
| idamnjanovic@70 | 130 | 
| idamnjanovic@70 | 131     mxFree(col_ids); | 
| idamnjanovic@70 | 132   } | 
| idamnjanovic@70 | 133 | 
| idamnjanovic@70 | 134   else { | 
| idamnjanovic@70 | 135 | 
| idamnjanovic@70 | 136     /* Do the actual computation */ | 
| idamnjanovic@70 | 137     for (j=0; j<n; ++j) { | 
| idamnjanovic@70 | 138       for (i=0; i<rownum; ++i) { | 
| idamnjanovic@70 | 139         y[j] += A[m*j+row_ids[i]]*x[i]; | 
| idamnjanovic@70 | 140       } | 
| idamnjanovic@70 | 141     } | 
| idamnjanovic@70 | 142   } | 
| idamnjanovic@70 | 143 | 
| idamnjanovic@70 | 144 | 
| idamnjanovic@70 | 145   mxFree(row_ids); | 
| idamnjanovic@70 | 146 | 
| idamnjanovic@70 | 147   return; | 
| idamnjanovic@70 | 148 } |