summaryrefslogtreecommitdiffstats
path: root/SD-VBS/common/toolbox/toolbox_basic/spmtimesd.c
diff options
context:
space:
mode:
Diffstat (limited to 'SD-VBS/common/toolbox/toolbox_basic/spmtimesd.c')
-rwxr-xr-xSD-VBS/common/toolbox/toolbox_basic/spmtimesd.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/SD-VBS/common/toolbox/toolbox_basic/spmtimesd.c b/SD-VBS/common/toolbox/toolbox_basic/spmtimesd.c
new file mode 100755
index 0000000..a98dc0a
--- /dev/null
+++ b/SD-VBS/common/toolbox/toolbox_basic/spmtimesd.c
@@ -0,0 +1,141 @@
1/*================================================================
2* spmtimesd.c
3* This routine computes a sparse matrix times a diagonal matrix
4* whose diagonal entries are stored in a full vector.
5*
6* Examples:
7* spmtimesd(m,d,[]) = diag(d) * m,
8* spmtimesd(m,[],d) = m * diag(d)
9* spmtimesd(m,d1,d2) = diag(d1) * m * diag(d2)
10* m could be complex, but d is assumed real
11*
12* Stella X. Yu's first MEX function, Nov 9, 2001.
13
14% test sequence:
15
16m = 1000;
17n = 2000;
18a=sparse(rand(m,n));
19d1 = rand(m,1);
20d2 = rand(n,1);
21tic; b=spmtimesd(a,d1,d2); toc
22tic; bb = spdiags(d1,0,m,m) * a * spdiags(d2,0,n,n); toc
23e = (bb-b);
24max(abs(e(:)))
25
26*=================================================================*/
27
28# include "mex.h"
29
30void mexFunction(
31 int nargout,
32 mxArray *out[],
33 int nargin,
34 const mxArray *in[]
35)
36{
37 /* declare variables */
38 int i, j, k, m, n, nzmax, cmplx, xm, yn;
39 int *pir, *pjc, *qir, *qjc;
40 double *x, *y, *pr, *pi, *qr, *qi;
41
42 /* check argument */
43 if (nargin != 3) {
44 mexErrMsgTxt("Three input arguments required");
45 }
46 if (nargout>1) {
47 mexErrMsgTxt("Too many output arguments.");
48 }
49 if (!(mxIsSparse(in[0]))) {
50 mexErrMsgTxt("Input argument #1 must be of type sparse");
51 }
52 if ( mxIsSparse(in[1]) || mxIsSparse(in[2]) ) {
53 mexErrMsgTxt("Input argument #2 & #3 must be of type full");
54 }
55
56 /* computation starts */
57 m = mxGetM(in[0]);
58 n = mxGetN(in[0]);
59 pr = mxGetPr(in[0]);
60 pi = mxGetPi(in[0]);
61 pir = mxGetIr(in[0]);
62 pjc = mxGetJc(in[0]);
63
64 i = mxGetM(in[1]);
65 j = mxGetN(in[1]);
66 xm = ((i>j)? i: j);
67
68 i = mxGetM(in[2]);
69 j = mxGetN(in[2]);
70 yn = ((i>j)? i: j);
71
72 if ( xm>0 && xm != m) {
73 mexErrMsgTxt("Row multiplication dimension mismatch.");
74 }
75 if ( yn>0 && yn != n) {
76 mexErrMsgTxt("Column multiplication dimension mismatch.");
77 }
78
79
80 nzmax = mxGetNzmax(in[0]);
81 cmplx = (pi==NULL ? 0 : 1);
82 out[0] = mxCreateSparse(m,n,nzmax,cmplx);
83 if (out[0]==NULL) {
84 mexErrMsgTxt("Not enough space for the output matrix.");
85 }
86
87 qr = mxGetPr(out[0]);
88 qi = mxGetPi(out[0]);
89 qir = mxGetIr(out[0]);
90 qjc = mxGetJc(out[0]);
91
92 /* left multiplication */
93 x = mxGetPr(in[1]);
94 if (yn==0) {
95 for (j=0; j<n; j++) {
96 qjc[j] = pjc[j];
97 for (k=pjc[j]; k<pjc[j+1]; k++) {
98 i = pir[k];
99 qir[k] = i;
100 qr[k] = x[i] * pr[k];
101 if (cmplx) {
102 qi[k] = x[i] * pi[k];
103 }
104 }
105 }
106 qjc[n] = k;
107 return;
108 }
109
110 /* right multiplication */
111 y = mxGetPr(in[2]);
112 if (xm==0) {
113 for (j=0; j<n; j++) {
114 qjc[j] = pjc[j];
115 for (k=pjc[j]; k<pjc[j+1]; k++) {
116 qir[k] = pir[k];
117 qr[k] = pr[k] * y[j];
118 if (cmplx) {
119 qi[k] = qi[k] * y[j];
120 }
121 }
122 }
123 qjc[n] = k;
124 return;
125 }
126
127 /* both sides */
128 for (j=0; j<n; j++) {
129 qjc[j] = pjc[j];
130 for (k=pjc[j]; k<pjc[j+1]; k++) {
131 i = pir[k];
132 qir[k]= i;
133 qr[k] = x[i] * pr[k] * y[j];
134 if (cmplx) {
135 qi[k] = x[i] * qi[k] * y[j];
136 }
137 }
138 qjc[n] = k;
139 }
140
141}