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 }
|