idamnjanovic@60
|
1 /**************************************************************************
|
idamnjanovic@60
|
2 *
|
idamnjanovic@60
|
3 * File name: myblas.c
|
idamnjanovic@60
|
4 *
|
idamnjanovic@60
|
5 * Ron Rubinstein
|
idamnjanovic@60
|
6 * Computer Science Department
|
idamnjanovic@60
|
7 * Technion, Haifa 32000 Israel
|
idamnjanovic@60
|
8 * ronrubin@cs
|
idamnjanovic@60
|
9 *
|
idamnjanovic@60
|
10 * Version: 1.1
|
idamnjanovic@60
|
11 * Last updated: 13.8.2009
|
idamnjanovic@60
|
12 *
|
idamnjanovic@60
|
13 *************************************************************************/
|
idamnjanovic@60
|
14
|
idamnjanovic@60
|
15
|
idamnjanovic@60
|
16 #include "myblas.h"
|
idamnjanovic@60
|
17 #include <ctype.h>
|
idamnjanovic@60
|
18
|
idamnjanovic@60
|
19
|
idamnjanovic@60
|
20 /* find maximum of absolute values */
|
idamnjanovic@60
|
21
|
idamnjanovic@60
|
22 mwIndex maxabs(double c[], mwSize m)
|
idamnjanovic@60
|
23 {
|
idamnjanovic@60
|
24 mwIndex maxid=0, k;
|
idamnjanovic@60
|
25 double absval, maxval = SQR(*c); /* use square which is quicker than absolute value */
|
idamnjanovic@60
|
26
|
idamnjanovic@60
|
27 for (k=1; k<m; ++k) {
|
idamnjanovic@60
|
28 absval = SQR(c[k]);
|
idamnjanovic@60
|
29 if (absval > maxval) {
|
idamnjanovic@60
|
30 maxval = absval;
|
idamnjanovic@60
|
31 maxid = k;
|
idamnjanovic@60
|
32 }
|
idamnjanovic@60
|
33 }
|
idamnjanovic@60
|
34 return maxid;
|
idamnjanovic@60
|
35 }
|
idamnjanovic@60
|
36
|
idamnjanovic@60
|
37
|
idamnjanovic@60
|
38 /* compute y := alpha*x + y */
|
idamnjanovic@60
|
39
|
idamnjanovic@60
|
40 void vec_sum(double alpha, double x[], double y[], mwSize n)
|
idamnjanovic@60
|
41 {
|
idamnjanovic@60
|
42 mwIndex i;
|
idamnjanovic@60
|
43
|
idamnjanovic@60
|
44 for (i=0; i<n; ++i) {
|
idamnjanovic@60
|
45 y[i] += alpha*x[i];
|
idamnjanovic@60
|
46 }
|
idamnjanovic@60
|
47 }
|
idamnjanovic@60
|
48
|
idamnjanovic@60
|
49
|
idamnjanovic@60
|
50 /* compute y := alpha*A*x */
|
idamnjanovic@60
|
51
|
idamnjanovic@60
|
52 void mat_vec(double alpha, double A[], double x[], double y[], mwSize n, mwSize m)
|
idamnjanovic@60
|
53 {
|
idamnjanovic@60
|
54 mwIndex i, j, i_n;
|
idamnjanovic@60
|
55 double *Ax;
|
idamnjanovic@60
|
56
|
idamnjanovic@60
|
57 Ax = mxCalloc(n,sizeof(double));
|
idamnjanovic@60
|
58
|
idamnjanovic@60
|
59 for (i=0; i<m; ++i) {
|
idamnjanovic@60
|
60 i_n = i*n;
|
idamnjanovic@60
|
61 for (j=0; j<n; ++j) {
|
idamnjanovic@60
|
62 Ax[j] += A[i_n+j] * x[i];
|
idamnjanovic@60
|
63 }
|
idamnjanovic@60
|
64 }
|
idamnjanovic@60
|
65
|
idamnjanovic@60
|
66 for (j=0; j<n; ++j) {
|
idamnjanovic@60
|
67 y[j] = alpha*Ax[j];
|
idamnjanovic@60
|
68 }
|
idamnjanovic@60
|
69
|
idamnjanovic@60
|
70 mxFree(Ax);
|
idamnjanovic@60
|
71 }
|
idamnjanovic@60
|
72
|
idamnjanovic@60
|
73
|
idamnjanovic@60
|
74 /* compute y := alpha*A'*x */
|
idamnjanovic@60
|
75
|
idamnjanovic@60
|
76 void matT_vec(double alpha, double A[], double x[], double y[], mwSize n, mwSize m)
|
idamnjanovic@60
|
77 {
|
idamnjanovic@60
|
78 mwIndex i, j, n_i;
|
idamnjanovic@60
|
79 double sum0, sum1, sum2, sum3;
|
idamnjanovic@60
|
80
|
idamnjanovic@60
|
81 for (j=0; j<m; ++j) {
|
idamnjanovic@60
|
82 y[j] = 0;
|
idamnjanovic@60
|
83 }
|
idamnjanovic@60
|
84
|
idamnjanovic@60
|
85 /* use loop unrolling to accelerate computation */
|
idamnjanovic@60
|
86
|
idamnjanovic@60
|
87 for (i=0; i<m; ++i) {
|
idamnjanovic@60
|
88 n_i = n*i;
|
idamnjanovic@60
|
89 sum0 = sum1 = sum2 = sum3 = 0;
|
idamnjanovic@60
|
90 for (j=0; j+4<n; j+=4) {
|
idamnjanovic@60
|
91 sum0 += A[n_i+j]*x[j];
|
idamnjanovic@60
|
92 sum1 += A[n_i+j+1]*x[j+1];
|
idamnjanovic@60
|
93 sum2 += A[n_i+j+2]*x[j+2];
|
idamnjanovic@60
|
94 sum3 += A[n_i+j+3]*x[j+3];
|
idamnjanovic@60
|
95 }
|
idamnjanovic@60
|
96 y[i] += alpha * ((sum0 + sum1) + (sum2 + sum3));
|
idamnjanovic@60
|
97 while (j<n) {
|
idamnjanovic@60
|
98 y[i] += alpha*A[n_i+j]*x[j];
|
idamnjanovic@60
|
99 j++;
|
idamnjanovic@60
|
100 }
|
idamnjanovic@60
|
101 }
|
idamnjanovic@60
|
102 }
|
idamnjanovic@60
|
103
|
idamnjanovic@60
|
104
|
idamnjanovic@60
|
105 /* compute y := alpha*A*x */
|
idamnjanovic@60
|
106
|
idamnjanovic@60
|
107 void mat_sp_vec(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double x[], double y[], mwSize n, mwSize m)
|
idamnjanovic@60
|
108 {
|
idamnjanovic@60
|
109
|
idamnjanovic@60
|
110 mwIndex i, j, j1, j2;
|
idamnjanovic@60
|
111
|
idamnjanovic@60
|
112 for (i=0; i<n; ++i) {
|
idamnjanovic@60
|
113 y[i] = 0;
|
idamnjanovic@60
|
114 }
|
idamnjanovic@60
|
115
|
idamnjanovic@60
|
116 j2 = jc[0];
|
idamnjanovic@60
|
117 for (i=0; i<m; ++i) {
|
idamnjanovic@60
|
118 j1 = j2; j2 = jc[i+1];
|
idamnjanovic@60
|
119 for (j=j1; j<j2; ++j) {
|
idamnjanovic@60
|
120 y[ir[j]] += alpha * pr[j] * x[i];
|
idamnjanovic@60
|
121 }
|
idamnjanovic@60
|
122 }
|
idamnjanovic@60
|
123
|
idamnjanovic@60
|
124 }
|
idamnjanovic@60
|
125
|
idamnjanovic@60
|
126
|
idamnjanovic@60
|
127 /* compute y := alpha*A'*x */
|
idamnjanovic@60
|
128
|
idamnjanovic@60
|
129 void matT_sp_vec(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double x[], double y[], mwSize n, mwSize m)
|
idamnjanovic@60
|
130 {
|
idamnjanovic@60
|
131
|
idamnjanovic@60
|
132 mwIndex i, j, j1, j2;
|
idamnjanovic@60
|
133
|
idamnjanovic@60
|
134 for (i=0; i<m; ++i) {
|
idamnjanovic@60
|
135 y[i] = 0;
|
idamnjanovic@60
|
136 }
|
idamnjanovic@60
|
137
|
idamnjanovic@60
|
138 j2 = jc[0];
|
idamnjanovic@60
|
139 for (i=0; i<m; ++i) {
|
idamnjanovic@60
|
140 j1 = j2; j2 = jc[i+1];
|
idamnjanovic@60
|
141 for (j=j1; j<j2; ++j) {
|
idamnjanovic@60
|
142 y[i] += alpha * pr[j] * x[ir[j]];
|
idamnjanovic@60
|
143 }
|
idamnjanovic@60
|
144 }
|
idamnjanovic@60
|
145
|
idamnjanovic@60
|
146 }
|
idamnjanovic@60
|
147
|
idamnjanovic@60
|
148
|
idamnjanovic@60
|
149 /* compute y := alpha*A*x */
|
idamnjanovic@60
|
150
|
idamnjanovic@60
|
151 void mat_vec_sp(double alpha, double A[], double pr[], mwIndex ir[], mwIndex jc[], double y[], mwSize n, mwSize m)
|
idamnjanovic@60
|
152 {
|
idamnjanovic@60
|
153
|
idamnjanovic@60
|
154 mwIndex i, j, j_n, k, kend;
|
idamnjanovic@60
|
155
|
idamnjanovic@60
|
156 for (i=0; i<n; ++i) {
|
idamnjanovic@60
|
157 y[i] = 0;
|
idamnjanovic@60
|
158 }
|
idamnjanovic@60
|
159
|
idamnjanovic@60
|
160 kend = jc[1];
|
idamnjanovic@60
|
161 if (kend==0) { /* x is empty */
|
idamnjanovic@60
|
162 return;
|
idamnjanovic@60
|
163 }
|
idamnjanovic@60
|
164
|
idamnjanovic@60
|
165 for (k=0; k<kend; ++k) {
|
idamnjanovic@60
|
166 j = ir[k];
|
idamnjanovic@60
|
167 j_n = j*n;
|
idamnjanovic@60
|
168 for (i=0; i<n; ++i) {
|
idamnjanovic@60
|
169 y[i] += alpha * A[i+j_n] * pr[k];
|
idamnjanovic@60
|
170 }
|
idamnjanovic@60
|
171 }
|
idamnjanovic@60
|
172
|
idamnjanovic@60
|
173 }
|
idamnjanovic@60
|
174
|
idamnjanovic@60
|
175
|
idamnjanovic@60
|
176 /* compute y := alpha*A'*x */
|
idamnjanovic@60
|
177
|
idamnjanovic@60
|
178 void matT_vec_sp(double alpha, double A[], double pr[], mwIndex ir[], mwIndex jc[], double y[], mwSize n, mwSize m)
|
idamnjanovic@60
|
179 {
|
idamnjanovic@60
|
180
|
idamnjanovic@60
|
181 mwIndex i, j, j_n, k, kend;
|
idamnjanovic@60
|
182
|
idamnjanovic@60
|
183 for (i=0; i<m; ++i) {
|
idamnjanovic@60
|
184 y[i] = 0;
|
idamnjanovic@60
|
185 }
|
idamnjanovic@60
|
186
|
idamnjanovic@60
|
187 kend = jc[1];
|
idamnjanovic@60
|
188 if (kend==0) { /* x is empty */
|
idamnjanovic@60
|
189 return;
|
idamnjanovic@60
|
190 }
|
idamnjanovic@60
|
191
|
idamnjanovic@60
|
192 for (j=0; j<m; ++j) {
|
idamnjanovic@60
|
193 j_n = j*n;
|
idamnjanovic@60
|
194 for (k=0; k<kend; ++k) {
|
idamnjanovic@60
|
195 i = ir[k];
|
idamnjanovic@60
|
196 y[j] += alpha * A[i+j_n] * pr[k];
|
idamnjanovic@60
|
197 }
|
idamnjanovic@60
|
198 }
|
idamnjanovic@60
|
199
|
idamnjanovic@60
|
200 }
|
idamnjanovic@60
|
201
|
idamnjanovic@60
|
202
|
idamnjanovic@60
|
203 /* compute y := alpha*A*x */
|
idamnjanovic@60
|
204
|
idamnjanovic@60
|
205 void mat_sp_vec_sp(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double prx[], mwIndex irx[], mwIndex jcx[], double y[], mwSize n, mwSize m)
|
idamnjanovic@60
|
206 {
|
idamnjanovic@60
|
207
|
idamnjanovic@60
|
208 mwIndex i, j, k, kend, j1, j2;
|
idamnjanovic@60
|
209
|
idamnjanovic@60
|
210 for (i=0; i<n; ++i) {
|
idamnjanovic@60
|
211 y[i] = 0;
|
idamnjanovic@60
|
212 }
|
idamnjanovic@60
|
213
|
idamnjanovic@60
|
214 kend = jcx[1];
|
idamnjanovic@60
|
215 if (kend==0) { /* x is empty */
|
idamnjanovic@60
|
216 return;
|
idamnjanovic@60
|
217 }
|
idamnjanovic@60
|
218
|
idamnjanovic@60
|
219 for (k=0; k<kend; ++k) {
|
idamnjanovic@60
|
220 i = irx[k];
|
idamnjanovic@60
|
221 j1 = jc[i]; j2 = jc[i+1];
|
idamnjanovic@60
|
222 for (j=j1; j<j2; ++j) {
|
idamnjanovic@60
|
223 y[ir[j]] += alpha * pr[j] * prx[k];
|
idamnjanovic@60
|
224 }
|
idamnjanovic@60
|
225 }
|
idamnjanovic@60
|
226
|
idamnjanovic@60
|
227 }
|
idamnjanovic@60
|
228
|
idamnjanovic@60
|
229
|
idamnjanovic@60
|
230 /* compute y := alpha*A'*x */
|
idamnjanovic@60
|
231
|
idamnjanovic@60
|
232 void matT_sp_vec_sp(double alpha, double pr[], mwIndex ir[], mwIndex jc[], double prx[], mwIndex irx[], mwIndex jcx[], double y[], mwSize n, mwSize m)
|
idamnjanovic@60
|
233 {
|
idamnjanovic@60
|
234
|
idamnjanovic@60
|
235 mwIndex i, j, k, jend, kend, jadd, kadd, delta;
|
idamnjanovic@60
|
236
|
idamnjanovic@60
|
237 for (i=0; i<m; ++i) {
|
idamnjanovic@60
|
238 y[i] = 0;
|
idamnjanovic@60
|
239 }
|
idamnjanovic@60
|
240
|
idamnjanovic@60
|
241 kend = jcx[1];
|
idamnjanovic@60
|
242 if (kend==0) { /* x is empty */
|
idamnjanovic@60
|
243 return;
|
idamnjanovic@60
|
244 }
|
idamnjanovic@60
|
245
|
idamnjanovic@60
|
246 for (i=0; i<m; ++i) {
|
idamnjanovic@60
|
247 j = jc[i];
|
idamnjanovic@60
|
248 jend = jc[i+1];
|
idamnjanovic@60
|
249 k = 0;
|
idamnjanovic@60
|
250 while (j<jend && k<kend) {
|
idamnjanovic@60
|
251
|
idamnjanovic@60
|
252 delta = ir[j] - irx[k];
|
idamnjanovic@60
|
253
|
idamnjanovic@60
|
254 if (delta) { /* if indices differ - increment the smaller one */
|
idamnjanovic@60
|
255 jadd = delta<0;
|
idamnjanovic@60
|
256 kadd = 1-jadd;
|
idamnjanovic@60
|
257 j += jadd;
|
idamnjanovic@60
|
258 k += kadd;
|
idamnjanovic@60
|
259 }
|
idamnjanovic@60
|
260
|
idamnjanovic@60
|
261 else { /* indices are equal - add to result and increment both */
|
idamnjanovic@60
|
262 y[i] += alpha * pr[j] * prx[k];
|
idamnjanovic@60
|
263 j++; k++;
|
idamnjanovic@60
|
264 }
|
idamnjanovic@60
|
265 }
|
idamnjanovic@60
|
266 }
|
idamnjanovic@60
|
267
|
idamnjanovic@60
|
268 }
|
idamnjanovic@60
|
269
|
idamnjanovic@60
|
270
|
idamnjanovic@60
|
271 /* matrix-matrix multiplication */
|
idamnjanovic@60
|
272
|
idamnjanovic@60
|
273 void mat_mat(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k)
|
idamnjanovic@60
|
274 {
|
idamnjanovic@60
|
275 mwIndex i1, i2, i3, iX, iA, i2_n;
|
idamnjanovic@60
|
276 double b;
|
idamnjanovic@60
|
277
|
idamnjanovic@60
|
278 for (i1=0; i1<n*k; i1++) {
|
idamnjanovic@60
|
279 X[i1] = 0;
|
idamnjanovic@60
|
280 }
|
idamnjanovic@60
|
281
|
idamnjanovic@60
|
282 for (i2=0; i2<m; ++i2) {
|
idamnjanovic@60
|
283 i2_n = i2*n;
|
idamnjanovic@60
|
284 iX = 0;
|
idamnjanovic@60
|
285 for (i3=0; i3<k; ++i3) {
|
idamnjanovic@60
|
286 iA = i2_n;
|
idamnjanovic@60
|
287 b = B[i2+i3*m];
|
idamnjanovic@60
|
288 for (i1=0; i1<n; ++i1) {
|
idamnjanovic@60
|
289 X[iX++] += A[iA++]*b;
|
idamnjanovic@60
|
290 }
|
idamnjanovic@60
|
291 }
|
idamnjanovic@60
|
292 }
|
idamnjanovic@60
|
293
|
idamnjanovic@60
|
294 for (i1=0; i1<n*k; i1++) {
|
idamnjanovic@60
|
295 X[i1] *= alpha;
|
idamnjanovic@60
|
296 }
|
idamnjanovic@60
|
297 }
|
idamnjanovic@60
|
298
|
idamnjanovic@60
|
299
|
idamnjanovic@60
|
300 /* matrix-transpose-matrix multiplication */
|
idamnjanovic@60
|
301
|
idamnjanovic@60
|
302 void matT_mat(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k)
|
idamnjanovic@60
|
303 {
|
idamnjanovic@60
|
304 mwIndex i1, i2, i3, iX, iA, i2_n;
|
idamnjanovic@60
|
305 double *x, sum0, sum1, sum2, sum3;
|
idamnjanovic@60
|
306
|
idamnjanovic@60
|
307 for (i2=0; i2<m; ++i2) {
|
idamnjanovic@60
|
308 for (i3=0; i3<k; ++i3) {
|
idamnjanovic@60
|
309 sum0 = sum1 = sum2 = sum3 = 0;
|
idamnjanovic@60
|
310 for (i1=0; i1+4<n; i1+=4) {
|
idamnjanovic@60
|
311 sum0 += A[i1+0+i2*n]*B[i1+0+i3*n];
|
idamnjanovic@60
|
312 sum1 += A[i1+1+i2*n]*B[i1+1+i3*n];
|
idamnjanovic@60
|
313 sum2 += A[i1+2+i2*n]*B[i1+2+i3*n];
|
idamnjanovic@60
|
314 sum3 += A[i1+3+i2*n]*B[i1+3+i3*n];
|
idamnjanovic@60
|
315 }
|
idamnjanovic@60
|
316 X[i2+i3*m] = (sum0+sum1) + (sum2+sum3);
|
idamnjanovic@60
|
317 while(i1<n) {
|
idamnjanovic@60
|
318 X[i2+i3*m] += A[i1+i2*n]*B[i1+i3*n];
|
idamnjanovic@60
|
319 i1++;
|
idamnjanovic@60
|
320 }
|
idamnjanovic@60
|
321 }
|
idamnjanovic@60
|
322 }
|
idamnjanovic@60
|
323
|
idamnjanovic@60
|
324 for (i1=0; i1<m*k; i1++) {
|
idamnjanovic@60
|
325 X[i1] *= alpha;
|
idamnjanovic@60
|
326 }
|
idamnjanovic@60
|
327 }
|
idamnjanovic@60
|
328
|
idamnjanovic@60
|
329
|
idamnjanovic@60
|
330 /* tensor-matrix product */
|
idamnjanovic@60
|
331
|
idamnjanovic@60
|
332 void tens_mat(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k, mwSize l)
|
idamnjanovic@60
|
333 {
|
idamnjanovic@60
|
334 mwIndex i1, i2, i3, i4, i2_n, nml;
|
idamnjanovic@60
|
335 double b;
|
idamnjanovic@60
|
336
|
idamnjanovic@60
|
337 nml = n*m*l;
|
idamnjanovic@60
|
338 for (i1=0; i1<nml; ++i1) {
|
idamnjanovic@60
|
339 X[i1] = 0;
|
idamnjanovic@60
|
340 }
|
idamnjanovic@60
|
341
|
idamnjanovic@60
|
342 for (i2=0; i2<m; ++i2) {
|
idamnjanovic@60
|
343 i2_n = i2*n;
|
idamnjanovic@60
|
344 for (i3=0; i3<k; ++i3) {
|
idamnjanovic@60
|
345 for (i4=0; i4<l; ++i4) {
|
idamnjanovic@60
|
346 b = B[i4+i3*l];
|
idamnjanovic@60
|
347 for (i1=0; i1<n; ++i1) {
|
idamnjanovic@60
|
348 X[i1 + i2_n + i4*n*m] += A[i1 + i2_n + i3*n*m] * b;
|
idamnjanovic@60
|
349 }
|
idamnjanovic@60
|
350 }
|
idamnjanovic@60
|
351 }
|
idamnjanovic@60
|
352 }
|
idamnjanovic@60
|
353
|
idamnjanovic@60
|
354 for (i1=0; i1<nml; ++i1) {
|
idamnjanovic@60
|
355 X[i1] *= alpha;
|
idamnjanovic@60
|
356 }
|
idamnjanovic@60
|
357 }
|
idamnjanovic@60
|
358
|
idamnjanovic@60
|
359
|
idamnjanovic@60
|
360 /* tensor-matrix-transpose product */
|
idamnjanovic@60
|
361
|
idamnjanovic@60
|
362 void tens_matT(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k, mwSize l)
|
idamnjanovic@60
|
363 {
|
idamnjanovic@60
|
364 mwIndex i1, i2, i3, i4, i2_n, nml;
|
idamnjanovic@60
|
365 double b;
|
idamnjanovic@60
|
366
|
idamnjanovic@60
|
367 nml = n*m*l;
|
idamnjanovic@60
|
368 for (i1=0; i1<nml; ++i1) {
|
idamnjanovic@60
|
369 X[i1] = 0;
|
idamnjanovic@60
|
370 }
|
idamnjanovic@60
|
371
|
idamnjanovic@60
|
372 for (i2=0; i2<m; ++i2) {
|
idamnjanovic@60
|
373 i2_n = i2*n;
|
idamnjanovic@60
|
374 for (i4=0; i4<l; ++i4) {
|
idamnjanovic@60
|
375 for (i3=0; i3<k; ++i3) {
|
idamnjanovic@60
|
376 b = B[i3+i4*k];
|
idamnjanovic@60
|
377 for (i1=0; i1<n; ++i1) {
|
idamnjanovic@60
|
378 X[i1 + i2_n + i4*n*m] += A[i1 + i2_n + i3*n*m] * b;
|
idamnjanovic@60
|
379 }
|
idamnjanovic@60
|
380 }
|
idamnjanovic@60
|
381 }
|
idamnjanovic@60
|
382 }
|
idamnjanovic@60
|
383
|
idamnjanovic@60
|
384 for (i1=0; i1<nml; ++i1) {
|
idamnjanovic@60
|
385 X[i1] *= alpha;
|
idamnjanovic@60
|
386 }
|
idamnjanovic@60
|
387 }
|
idamnjanovic@60
|
388
|
idamnjanovic@60
|
389
|
idamnjanovic@60
|
390 /* dot product */
|
idamnjanovic@60
|
391
|
idamnjanovic@60
|
392 double dotprod(double a[], double b[], mwSize n)
|
idamnjanovic@60
|
393 {
|
idamnjanovic@60
|
394 double sum = 0;
|
idamnjanovic@60
|
395 mwIndex i;
|
idamnjanovic@60
|
396 for (i=0; i<n; ++i)
|
idamnjanovic@60
|
397 sum += a[i]*b[i];
|
idamnjanovic@60
|
398 return sum;
|
idamnjanovic@60
|
399 }
|
idamnjanovic@60
|
400
|
idamnjanovic@60
|
401
|
idamnjanovic@60
|
402 /* find maximum of vector */
|
idamnjanovic@60
|
403
|
idamnjanovic@60
|
404 mwIndex maxpos(double c[], mwSize m)
|
idamnjanovic@60
|
405 {
|
idamnjanovic@60
|
406 mwIndex maxid=0, k;
|
idamnjanovic@60
|
407 double val, maxval = *c;
|
idamnjanovic@60
|
408
|
idamnjanovic@60
|
409 for (k=1; k<m; ++k) {
|
idamnjanovic@60
|
410 val = c[k];
|
idamnjanovic@60
|
411 if (val > maxval) {
|
idamnjanovic@60
|
412 maxval = val;
|
idamnjanovic@60
|
413 maxid = k;
|
idamnjanovic@60
|
414 }
|
idamnjanovic@60
|
415 }
|
idamnjanovic@60
|
416 return maxid;
|
idamnjanovic@60
|
417 }
|
idamnjanovic@60
|
418
|
idamnjanovic@60
|
419
|
idamnjanovic@60
|
420 /* solve L*x = b */
|
idamnjanovic@60
|
421
|
idamnjanovic@60
|
422 void backsubst_L(double L[], double b[], double x[], mwSize n, mwSize k)
|
idamnjanovic@60
|
423 {
|
idamnjanovic@60
|
424 mwIndex i, j;
|
idamnjanovic@60
|
425 double rhs;
|
idamnjanovic@60
|
426
|
idamnjanovic@60
|
427 for (i=0; i<k; ++i) {
|
idamnjanovic@60
|
428 rhs = b[i];
|
idamnjanovic@60
|
429 for (j=0; j<i; ++j) {
|
idamnjanovic@60
|
430 rhs -= L[j*n+i]*x[j];
|
idamnjanovic@60
|
431 }
|
idamnjanovic@60
|
432 x[i] = rhs/L[i*n+i];
|
idamnjanovic@60
|
433 }
|
idamnjanovic@60
|
434 }
|
idamnjanovic@60
|
435
|
idamnjanovic@60
|
436
|
idamnjanovic@60
|
437 /* solve L'*x = b */
|
idamnjanovic@60
|
438
|
idamnjanovic@60
|
439 void backsubst_Lt(double L[], double b[], double x[], mwSize n, mwSize k)
|
idamnjanovic@60
|
440 {
|
idamnjanovic@60
|
441 mwIndex i, j;
|
idamnjanovic@60
|
442 double rhs;
|
idamnjanovic@60
|
443
|
idamnjanovic@60
|
444 for (i=k; i>=1; --i) {
|
idamnjanovic@60
|
445 rhs = b[i-1];
|
idamnjanovic@60
|
446 for (j=i; j<k; ++j) {
|
idamnjanovic@60
|
447 rhs -= L[(i-1)*n+j]*x[j];
|
idamnjanovic@60
|
448 }
|
idamnjanovic@60
|
449 x[i-1] = rhs/L[(i-1)*n+i-1];
|
idamnjanovic@60
|
450 }
|
idamnjanovic@60
|
451 }
|
idamnjanovic@60
|
452
|
idamnjanovic@60
|
453
|
idamnjanovic@60
|
454 /* solve U*x = b */
|
idamnjanovic@60
|
455
|
idamnjanovic@60
|
456 void backsubst_U(double U[], double b[], double x[], mwSize n, mwSize k)
|
idamnjanovic@60
|
457 {
|
idamnjanovic@60
|
458 mwIndex i, j;
|
idamnjanovic@60
|
459 double rhs;
|
idamnjanovic@60
|
460
|
idamnjanovic@60
|
461 for (i=k; i>=1; --i) {
|
idamnjanovic@60
|
462 rhs = b[i-1];
|
idamnjanovic@60
|
463 for (j=i; j<k; ++j) {
|
idamnjanovic@60
|
464 rhs -= U[j*n+i-1]*x[j];
|
idamnjanovic@60
|
465 }
|
idamnjanovic@60
|
466 x[i-1] = rhs/U[(i-1)*n+i-1];
|
idamnjanovic@60
|
467 }
|
idamnjanovic@60
|
468 }
|
idamnjanovic@60
|
469
|
idamnjanovic@60
|
470
|
idamnjanovic@60
|
471 /* solve U'*x = b */
|
idamnjanovic@60
|
472
|
idamnjanovic@60
|
473 void backsubst_Ut(double U[], double b[], double x[], mwSize n, mwSize k)
|
idamnjanovic@60
|
474 {
|
idamnjanovic@60
|
475 mwIndex i, j;
|
idamnjanovic@60
|
476 double rhs;
|
idamnjanovic@60
|
477
|
idamnjanovic@60
|
478 for (i=0; i<k; ++i) {
|
idamnjanovic@60
|
479 rhs = b[i];
|
idamnjanovic@60
|
480 for (j=0; j<i; ++j) {
|
idamnjanovic@60
|
481 rhs -= U[i*n+j]*x[j];
|
idamnjanovic@60
|
482 }
|
idamnjanovic@60
|
483 x[i] = rhs/U[i*n+i];
|
idamnjanovic@60
|
484 }
|
idamnjanovic@60
|
485 }
|
idamnjanovic@60
|
486
|
idamnjanovic@60
|
487
|
idamnjanovic@60
|
488 /* back substitution solver */
|
idamnjanovic@60
|
489
|
idamnjanovic@60
|
490 void backsubst(char ul, double A[], double b[], double x[], mwSize n, mwSize k)
|
idamnjanovic@60
|
491 {
|
idamnjanovic@60
|
492 if (tolower(ul) == 'u') {
|
idamnjanovic@60
|
493 backsubst_U(A, b, x, n, k);
|
idamnjanovic@60
|
494 }
|
idamnjanovic@60
|
495 else if (tolower(ul) == 'l') {
|
idamnjanovic@60
|
496 backsubst_L(A, b, x, n, k);
|
idamnjanovic@60
|
497 }
|
idamnjanovic@60
|
498 else {
|
idamnjanovic@60
|
499 mexErrMsgTxt("Invalid triangular matrix type: must be ''U'' or ''L''");
|
idamnjanovic@60
|
500 }
|
idamnjanovic@60
|
501 }
|
idamnjanovic@60
|
502
|
idamnjanovic@60
|
503
|
idamnjanovic@60
|
504 /* solve equation set using cholesky decomposition */
|
idamnjanovic@60
|
505
|
idamnjanovic@60
|
506 void cholsolve(char ul, double A[], double b[], double x[], mwSize n, mwSize k)
|
idamnjanovic@60
|
507 {
|
idamnjanovic@60
|
508 double *tmp;
|
idamnjanovic@60
|
509
|
idamnjanovic@60
|
510 tmp = mxMalloc(k*sizeof(double));
|
idamnjanovic@60
|
511
|
idamnjanovic@60
|
512 if (tolower(ul) == 'l') {
|
idamnjanovic@60
|
513 backsubst_L(A, b, tmp, n, k);
|
idamnjanovic@60
|
514 backsubst_Lt(A, tmp, x, n, k);
|
idamnjanovic@60
|
515 }
|
idamnjanovic@60
|
516 else if (tolower(ul) == 'u') {
|
idamnjanovic@60
|
517 backsubst_Ut(A, b, tmp, n, k);
|
idamnjanovic@60
|
518 backsubst_U(A, tmp, x, n, k);
|
idamnjanovic@60
|
519 }
|
idamnjanovic@60
|
520 else {
|
idamnjanovic@60
|
521 mexErrMsgTxt("Invalid triangular matrix type: must be either ''U'' or ''L''");
|
idamnjanovic@60
|
522 }
|
idamnjanovic@60
|
523
|
idamnjanovic@60
|
524 mxFree(tmp);
|
idamnjanovic@60
|
525 }
|
idamnjanovic@60
|
526
|
idamnjanovic@60
|
527
|
idamnjanovic@60
|
528 /* perform a permutation assignment y := x(ind(1:k)) */
|
idamnjanovic@60
|
529
|
idamnjanovic@60
|
530 void vec_assign(double y[], double x[], mwIndex ind[], mwSize k)
|
idamnjanovic@60
|
531 {
|
idamnjanovic@60
|
532 mwIndex i;
|
idamnjanovic@60
|
533
|
idamnjanovic@60
|
534 for (i=0; i<k; ++i)
|
idamnjanovic@60
|
535 y[i] = x[ind[i]];
|
idamnjanovic@60
|
536 }
|
idamnjanovic@60
|
537
|
idamnjanovic@60
|
538
|
idamnjanovic@60
|
539 /* matrix transpose */
|
idamnjanovic@60
|
540
|
idamnjanovic@60
|
541 void transpose(double X[], double Y[], mwSize n, mwSize m)
|
idamnjanovic@60
|
542 {
|
idamnjanovic@60
|
543 mwIndex i, j, i_m, j_n;
|
idamnjanovic@60
|
544
|
idamnjanovic@60
|
545 if (n<m) {
|
idamnjanovic@60
|
546 for (j=0; j<m; ++j) {
|
idamnjanovic@60
|
547 j_n = j*n;
|
idamnjanovic@60
|
548 for (i=0; i<n; ++i) {
|
idamnjanovic@60
|
549 Y[j+i*m] = X[i+j_n];
|
idamnjanovic@60
|
550 }
|
idamnjanovic@60
|
551 }
|
idamnjanovic@60
|
552 }
|
idamnjanovic@60
|
553 else {
|
idamnjanovic@60
|
554 for (i=0; i<n; ++i) {
|
idamnjanovic@60
|
555 i_m = i*m;
|
idamnjanovic@60
|
556 for (j=0; j<m; ++j) {
|
idamnjanovic@60
|
557 Y[j+i_m] = X[i+j*n];
|
idamnjanovic@60
|
558 }
|
idamnjanovic@60
|
559 }
|
idamnjanovic@60
|
560 }
|
idamnjanovic@60
|
561 }
|
idamnjanovic@60
|
562
|
idamnjanovic@60
|
563
|
idamnjanovic@60
|
564 /* print contents of matrix */
|
idamnjanovic@60
|
565
|
idamnjanovic@60
|
566 void printmat(double A[], int n, int m, char* matname)
|
idamnjanovic@60
|
567 {
|
idamnjanovic@60
|
568 int i, j;
|
idamnjanovic@60
|
569 mexPrintf("\n%s = \n\n", matname);
|
idamnjanovic@60
|
570
|
idamnjanovic@60
|
571 if (n*m==0) {
|
idamnjanovic@60
|
572 mexPrintf(" Empty matrix: %d-by-%d\n\n", n, m);
|
idamnjanovic@60
|
573 return;
|
idamnjanovic@60
|
574 }
|
idamnjanovic@60
|
575
|
idamnjanovic@60
|
576 for (i=0; i<n; ++i) {
|
idamnjanovic@60
|
577 for (j=0; j<m; ++j)
|
idamnjanovic@60
|
578 mexPrintf(" %lf", A[j*n+i]);
|
idamnjanovic@60
|
579 mexPrintf("\n");
|
idamnjanovic@60
|
580 }
|
idamnjanovic@60
|
581 mexPrintf("\n");
|
idamnjanovic@60
|
582 }
|
idamnjanovic@60
|
583
|
idamnjanovic@60
|
584
|
idamnjanovic@60
|
585 /* print contents of sparse matrix */
|
idamnjanovic@60
|
586
|
idamnjanovic@60
|
587 void printspmat(mxArray *a, char* matname)
|
idamnjanovic@60
|
588 {
|
idamnjanovic@60
|
589 mwIndex *aJc = mxGetJc(a);
|
idamnjanovic@60
|
590 mwIndex *aIr = mxGetIr(a);
|
idamnjanovic@60
|
591 double *aPr = mxGetPr(a);
|
idamnjanovic@60
|
592
|
idamnjanovic@60
|
593 int i;
|
idamnjanovic@60
|
594
|
idamnjanovic@60
|
595 mexPrintf("\n%s = \n\n", matname);
|
idamnjanovic@60
|
596
|
idamnjanovic@60
|
597 for (i=0; i<aJc[1]; ++i)
|
idamnjanovic@60
|
598 printf(" (%d,1) = %lf\n", aIr[i]+1,aPr[i]);
|
idamnjanovic@60
|
599
|
idamnjanovic@60
|
600 mexPrintf("\n");
|
idamnjanovic@60
|
601 }
|
idamnjanovic@60
|
602
|
idamnjanovic@60
|
603
|
idamnjanovic@60
|
604
|
idamnjanovic@60
|
605 /* matrix multiplication using Winograd's algorithm */
|
idamnjanovic@60
|
606
|
idamnjanovic@60
|
607 /*
|
idamnjanovic@60
|
608 void mat_mat2(double alpha, double A[], double B[], double X[], mwSize n, mwSize m, mwSize k)
|
idamnjanovic@60
|
609 {
|
idamnjanovic@60
|
610
|
idamnjanovic@60
|
611 mwIndex i1, i2, i3, iX, iA, i2_n;
|
idamnjanovic@60
|
612 double b, *AA, *BB;
|
idamnjanovic@60
|
613
|
idamnjanovic@60
|
614 AA = mxCalloc(n,sizeof(double));
|
idamnjanovic@60
|
615 BB = mxCalloc(k,sizeof(double));
|
idamnjanovic@60
|
616
|
idamnjanovic@60
|
617 for (i1=0; i1<n*k; i1++) {
|
idamnjanovic@60
|
618 X[i1] = 0;
|
idamnjanovic@60
|
619 }
|
idamnjanovic@60
|
620
|
idamnjanovic@60
|
621 for (i1=0; i1<n; ++i1) {
|
idamnjanovic@60
|
622 for (i2=0; i2<m/2; ++i2) {
|
idamnjanovic@60
|
623 AA[i1] += A[i1+2*i2*n]*A[i1+(2*i2+1)*n];
|
idamnjanovic@60
|
624 }
|
idamnjanovic@60
|
625 }
|
idamnjanovic@60
|
626
|
idamnjanovic@60
|
627 for (i2=0; i2<k; ++i2) {
|
idamnjanovic@60
|
628 for (i1=0; i1<m/2; ++i1) {
|
idamnjanovic@60
|
629 BB[i2] += B[2*i1+i2*m]*B[2*i1+1+i2*m];
|
idamnjanovic@60
|
630 }
|
idamnjanovic@60
|
631 }
|
idamnjanovic@60
|
632
|
idamnjanovic@60
|
633 for (i2=0; i2<k; ++i2) {
|
idamnjanovic@60
|
634 for (i3=0; i3<m/2; ++i3) {
|
idamnjanovic@60
|
635 for (i1=0; i1<n; ++i1) {
|
idamnjanovic@60
|
636 X[i1+i2*n] += (A[i1+(2*i3)*n]+B[2*i3+1+i2*m])*(A[i1+(2*i3+1)*n]+B[2*i3+i2*m]);
|
idamnjanovic@60
|
637 }
|
idamnjanovic@60
|
638 }
|
idamnjanovic@60
|
639 }
|
idamnjanovic@60
|
640
|
idamnjanovic@60
|
641 if (m%2) {
|
idamnjanovic@60
|
642 for (i2=0; i2<k; ++i2) {
|
idamnjanovic@60
|
643 for (i1=0; i1<n; ++i1) {
|
idamnjanovic@60
|
644 X[i1+i2*n] += A[i1+(m-1)*n]*B[m-1+i2*m];
|
idamnjanovic@60
|
645 }
|
idamnjanovic@60
|
646 }
|
idamnjanovic@60
|
647 }
|
idamnjanovic@60
|
648
|
idamnjanovic@60
|
649 for (i2=0; i2<k; ++i2) {
|
idamnjanovic@60
|
650 for (i1=0; i1<n; ++i1) {
|
idamnjanovic@60
|
651 X[i1+i2*n] -= (AA[i1] + BB[i2]);
|
idamnjanovic@60
|
652 X[i1+i2*n] *= alpha;
|
idamnjanovic@60
|
653 }
|
idamnjanovic@60
|
654 }
|
idamnjanovic@60
|
655
|
idamnjanovic@60
|
656 mxFree(AA);
|
idamnjanovic@60
|
657 mxFree(BB);
|
idamnjanovic@60
|
658 }
|
idamnjanovic@60
|
659 */
|
idamnjanovic@60
|
660
|
idamnjanovic@60
|
661
|
idamnjanovic@60
|
662
|
idamnjanovic@60
|
663
|