Mercurial > hg > octave-lyh
annotate liboctave/mx-op-defs.h @ 7875:bff8dbc1be11
mlock: doc fix
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 06 Jun 2008 11:35:10 -0400 |
parents | 82be108cc558 |
children | 935be827eaf8 |
rev | line source |
---|---|
2829 | 1 /* |
2 | |
7017 | 3 Copyright (C) 1996, 1997, 1998, 2000, 2001, 2003, 2004, 2005, 2006, |
4 2007 John W. Eaton | |
2829 | 5 |
6 This file is part of Octave. | |
7 | |
8 Octave is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
7016 | 10 Free Software Foundation; either version 3 of the License, or (at your |
11 option) any later version. | |
2829 | 12 |
13 Octave is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
7016 | 19 along with Octave; see the file COPYING. If not, see |
20 <http://www.gnu.org/licenses/>. | |
2829 | 21 |
22 */ | |
23 | |
24 #if !defined (octave_mx_op_defs_h) | |
25 #define octave_mx_op_defs_h 1 | |
26 | |
27 #include "mx-inlines.cc" | |
28 | |
6708 | 29 #define BIN_OP_DECL(R, OP, X, Y, API) \ |
30 extern API R OP (const X&, const Y&) | |
2829 | 31 |
2870 | 32 class boolMatrix; |
4543 | 33 class boolNDArray; |
2870 | 34 |
6708 | 35 #define CMP_OP_DECL(OP, X, Y, API) \ |
36 extern API boolMatrix OP (const X&, const Y&) | |
2870 | 37 |
6708 | 38 #define NDCMP_OP_DECL(OP, X, Y, API) \ |
39 extern API boolNDArray OP (const X&, const Y&) | |
4543 | 40 |
6708 | 41 #define BOOL_OP_DECL(OP, X, Y, API) \ |
42 extern API boolMatrix OP (const X&, const Y&) | |
2870 | 43 |
6708 | 44 #define NDBOOL_OP_DECL(OP, X, Y, API) \ |
45 extern API boolNDArray OP (const X&, const Y&) | |
4543 | 46 |
2870 | 47 // vector by scalar operations. |
48 | |
6708 | 49 #define VS_BIN_OP_DECLS(R, V, S, API) \ |
50 BIN_OP_DECL (R, operator +, V, S, API); \ | |
51 BIN_OP_DECL (R, operator -, V, S, API); \ | |
52 BIN_OP_DECL (R, operator *, V, S, API); \ | |
53 BIN_OP_DECL (R, operator /, V, S, API); | |
2870 | 54 |
55 #define VS_BIN_OP(R, F, OP, V, S) \ | |
56 R \ | |
57 F (const V& v, const S& s) \ | |
58 { \ | |
59 int len = v.length (); \ | |
60 \ | |
61 R r (len); \ | |
62 \ | |
3582 | 63 for (int i = 0; i < len; i++) \ |
2870 | 64 r.elem(i) = v.elem(i) OP s; \ |
65 \ | |
66 return r; \ | |
67 } | |
68 | |
69 #define VS_BIN_OPS(R, V, S) \ | |
70 VS_BIN_OP (R, operator +, +, V, S) \ | |
71 VS_BIN_OP (R, operator -, -, V, S) \ | |
72 VS_BIN_OP (R, operator *, *, V, S) \ | |
73 VS_BIN_OP (R, operator /, /, V, S) | |
74 | |
6708 | 75 #define VS_OP_DECLS(R, V, S, API) \ |
76 VS_BIN_OP_DECLS(R, V, S, API) | |
3582 | 77 |
2870 | 78 // scalar by vector by operations. |
79 | |
6708 | 80 #define SV_BIN_OP_DECLS(R, S, V, API) \ |
81 BIN_OP_DECL (R, operator +, S, V, API); \ | |
82 BIN_OP_DECL (R, operator -, S, V, API); \ | |
83 BIN_OP_DECL (R, operator *, S, V, API); \ | |
84 BIN_OP_DECL (R, operator /, S, V, API); | |
2870 | 85 |
86 #define SV_BIN_OP(R, F, OP, S, V) \ | |
87 R \ | |
88 F (const S& s, const V& v) \ | |
89 { \ | |
90 int len = v.length (); \ | |
91 \ | |
92 R r (len); \ | |
93 \ | |
3582 | 94 for (int i = 0; i < len; i++) \ |
2870 | 95 r.elem(i) = s OP v.elem(i); \ |
96 \ | |
97 return r; \ | |
98 } | |
99 | |
100 #define SV_BIN_OPS(R, S, V) \ | |
101 SV_BIN_OP (R, operator +, +, S, V) \ | |
102 SV_BIN_OP (R, operator -, -, S, V) \ | |
103 SV_BIN_OP (R, operator *, *, S, V) \ | |
104 SV_BIN_OP (R, operator /, /, S, V) | |
105 | |
6708 | 106 #define SV_OP_DECLS(R, S, V, API) \ |
107 SV_BIN_OP_DECLS(R, S, V, API) | |
3582 | 108 |
2870 | 109 // vector by vector operations. |
110 | |
6708 | 111 #define VV_BIN_OP_DECLS(R, V1, V2, API) \ |
112 BIN_OP_DECL (R, operator +, V1, V2, API); \ | |
113 BIN_OP_DECL (R, operator -, V1, V2, API); \ | |
114 BIN_OP_DECL (R, product, V1, V2, API); \ | |
115 BIN_OP_DECL (R, quotient, V1, V2, API); | |
2870 | 116 |
117 #define VV_BIN_OP(R, F, OP, V1, V2) \ | |
118 R \ | |
119 F (const V1& v1, const V2& v2) \ | |
120 { \ | |
121 R r; \ | |
122 \ | |
123 int v1_len = v1.length (); \ | |
124 int v2_len = v2.length (); \ | |
125 \ | |
126 if (v1_len != v2_len) \ | |
127 gripe_nonconformant (#OP, v1_len, v2_len); \ | |
128 else \ | |
129 { \ | |
130 r.resize (v1_len); \ | |
131 \ | |
3582 | 132 for (int i = 0; i < v1_len; i++) \ |
2870 | 133 r.elem(i) = v1.elem(i) OP v2.elem(i); \ |
134 } \ | |
135 \ | |
136 return r; \ | |
137 } | |
138 | |
139 #define VV_BIN_OPS(R, V1, V2) \ | |
140 VV_BIN_OP (R, operator +, +, V1, V2) \ | |
141 VV_BIN_OP (R, operator -, -, V1, V2) \ | |
142 VV_BIN_OP (R, product, *, V1, V2) \ | |
143 VV_BIN_OP (R, quotient, /, V1, V2) | |
144 | |
6708 | 145 #define VV_OP_DECLS(R, V1, V2, API) \ |
146 VV_BIN_OP_DECLS(R, V1, V2, API) | |
2870 | 147 |
148 // matrix by scalar operations. | |
149 | |
6708 | 150 #define MS_BIN_OP_DECLS(R, M, S, API) \ |
151 BIN_OP_DECL (R, operator +, M, S, API); \ | |
152 BIN_OP_DECL (R, operator -, M, S, API); \ | |
153 BIN_OP_DECL (R, operator *, M, S, API); \ | |
154 BIN_OP_DECL (R, operator /, M, S, API); | |
2829 | 155 |
2870 | 156 #define MS_BIN_OP(R, OP, M, S, F) \ |
2829 | 157 R \ |
158 OP (const M& m, const S& s) \ | |
159 { \ | |
160 int nr = m.rows (); \ | |
161 int nc = m.cols (); \ | |
162 \ | |
163 R r (nr, nc); \ | |
164 \ | |
165 if (nr > 0 && nc > 0) \ | |
166 F ## _vs (r.fortran_vec (), m.data (), nr * nc, s); \ | |
167 \ | |
168 return r; \ | |
169 } | |
170 | |
2870 | 171 #define MS_BIN_OPS(R, M, S) \ |
3769 | 172 MS_BIN_OP (R, operator +, M, S, mx_inline_add) \ |
173 MS_BIN_OP (R, operator -, M, S, mx_inline_subtract) \ | |
174 MS_BIN_OP (R, operator *, M, S, mx_inline_multiply) \ | |
175 MS_BIN_OP (R, operator /, M, S, mx_inline_divide) | |
2870 | 176 |
6708 | 177 #define MS_CMP_OP_DECLS(M, S, API) \ |
178 CMP_OP_DECL (mx_el_lt, M, S, API); \ | |
179 CMP_OP_DECL (mx_el_le, M, S, API); \ | |
180 CMP_OP_DECL (mx_el_ge, M, S, API); \ | |
181 CMP_OP_DECL (mx_el_gt, M, S, API); \ | |
182 CMP_OP_DECL (mx_el_eq, M, S, API); \ | |
183 CMP_OP_DECL (mx_el_ne, M, S, API); | |
2870 | 184 |
4826 | 185 #define MS_CMP_OP(F, OP, M, MC, S, SC) \ |
2870 | 186 boolMatrix \ |
187 F (const M& m, const S& s) \ | |
188 { \ | |
189 boolMatrix r; \ | |
190 \ | |
191 int nr = m.rows (); \ | |
192 int nc = m.cols (); \ | |
193 \ | |
4826 | 194 r.resize (nr, nc); \ |
195 \ | |
196 if (nr > 0 && nc > 0) \ | |
2870 | 197 { \ |
198 for (int j = 0; j < nc; j++) \ | |
199 for (int i = 0; i < nr; i++) \ | |
200 r.elem(i, j) = MC (m.elem(i, j)) OP SC (s); \ | |
201 } \ | |
202 \ | |
203 return r; \ | |
204 } | |
2829 | 205 |
2870 | 206 #define MS_CMP_OPS(M, CM, S, CS) \ |
4826 | 207 MS_CMP_OP (mx_el_lt, <, M, CM, S, CS) \ |
208 MS_CMP_OP (mx_el_le, <=, M, CM, S, CS) \ | |
209 MS_CMP_OP (mx_el_ge, >=, M, CM, S, CS) \ | |
210 MS_CMP_OP (mx_el_gt, >, M, CM, S, CS) \ | |
211 MS_CMP_OP (mx_el_eq, ==, M, , S, ) \ | |
212 MS_CMP_OP (mx_el_ne, !=, M, , S, ) | |
2870 | 213 |
6708 | 214 #define MS_BOOL_OP_DECLS(M, S, API) \ |
215 BOOL_OP_DECL (mx_el_and, M, S, API); \ | |
216 BOOL_OP_DECL (mx_el_or, M, S, API); \ | |
2870 | 217 |
5030 | 218 #define MS_BOOL_OP(F, OP, M, S, LHS_ZERO, RHS_ZERO) \ |
2870 | 219 boolMatrix \ |
220 F (const M& m, const S& s) \ | |
221 { \ | |
222 boolMatrix r; \ | |
223 \ | |
224 int nr = m.rows (); \ | |
225 int nc = m.cols (); \ | |
226 \ | |
227 if (nr != 0 && nc != 0) \ | |
228 { \ | |
229 r.resize (nr, nc); \ | |
230 \ | |
231 for (int j = 0; j < nc; j++) \ | |
232 for (int i = 0; i < nr; i++) \ | |
5030 | 233 r.elem(i, j) = (m.elem(i, j) != LHS_ZERO) OP (s != RHS_ZERO); \ |
2870 | 234 } \ |
235 \ | |
236 return r; \ | |
237 } | |
238 | |
5030 | 239 #define MS_BOOL_OPS2(M, S, LHS_ZERO, RHS_ZERO) \ |
240 MS_BOOL_OP (mx_el_and, &&, M, S, LHS_ZERO, RHS_ZERO) \ | |
241 MS_BOOL_OP (mx_el_or, ||, M, S, LHS_ZERO, RHS_ZERO) | |
242 | |
3504 | 243 #define MS_BOOL_OPS(M, S, ZERO) \ |
5030 | 244 MS_BOOL_OPS2(M, S, ZERO, ZERO) |
2870 | 245 |
6708 | 246 #define MS_OP_DECLS(R, M, S, API) \ |
247 MS_BIN_OP_DECLS (R, M, S, API) \ | |
248 MS_CMP_OP_DECLS (M, S, API) \ | |
249 MS_BOOL_OP_DECLS (M, S, API) \ | |
2870 | 250 |
251 // scalar by matrix operations. | |
252 | |
6708 | 253 #define SM_BIN_OP_DECLS(R, S, M, API) \ |
254 BIN_OP_DECL (R, operator +, S, M, API); \ | |
255 BIN_OP_DECL (R, operator -, S, M, API); \ | |
256 BIN_OP_DECL (R, operator *, S, M, API); \ | |
257 BIN_OP_DECL (R, operator /, S, M, API); | |
2870 | 258 |
259 #define SM_BIN_OP(R, OP, S, M, F) \ | |
2829 | 260 R \ |
261 OP (const S& s, const M& m) \ | |
262 { \ | |
263 int nr = m.rows (); \ | |
264 int nc = m.cols (); \ | |
265 \ | |
266 R r (nr, nc); \ | |
267 \ | |
268 if (nr > 0 && nc > 0) \ | |
269 F ## _sv (r.fortran_vec (), s, m.data (), nr * nc); \ | |
270 \ | |
271 return r; \ | |
272 } | |
273 | |
2870 | 274 #define SM_BIN_OPS(R, S, M) \ |
3769 | 275 SM_BIN_OP (R, operator +, S, M, mx_inline_add) \ |
276 SM_BIN_OP (R, operator -, S, M, mx_inline_subtract) \ | |
277 SM_BIN_OP (R, operator *, S, M, mx_inline_multiply) \ | |
278 SM_BIN_OP (R, operator /, S, M, mx_inline_divide) | |
2870 | 279 |
6708 | 280 #define SM_CMP_OP_DECLS(S, M, API) \ |
281 CMP_OP_DECL (mx_el_lt, S, M, API); \ | |
282 CMP_OP_DECL (mx_el_le, S, M, API); \ | |
283 CMP_OP_DECL (mx_el_ge, S, M, API); \ | |
284 CMP_OP_DECL (mx_el_gt, S, M, API); \ | |
285 CMP_OP_DECL (mx_el_eq, S, M, API); \ | |
286 CMP_OP_DECL (mx_el_ne, S, M, API); | |
2870 | 287 |
4826 | 288 #define SM_CMP_OP(F, OP, S, SC, M, MC) \ |
2870 | 289 boolMatrix \ |
290 F (const S& s, const M& m) \ | |
291 { \ | |
292 boolMatrix r; \ | |
293 \ | |
294 int nr = m.rows (); \ | |
295 int nc = m.cols (); \ | |
296 \ | |
4826 | 297 r.resize (nr, nc); \ |
298 \ | |
299 if (nr > 0 && nc > 0) \ | |
2870 | 300 { \ |
301 for (int j = 0; j < nc; j++) \ | |
302 for (int i = 0; i < nr; i++) \ | |
303 r.elem(i, j) = SC (s) OP MC (m.elem(i, j)); \ | |
304 } \ | |
305 \ | |
306 return r; \ | |
307 } | |
2829 | 308 |
2870 | 309 #define SM_CMP_OPS(S, CS, M, CM) \ |
4826 | 310 SM_CMP_OP (mx_el_lt, <, S, CS, M, CM) \ |
311 SM_CMP_OP (mx_el_le, <=, S, CS, M, CM) \ | |
312 SM_CMP_OP (mx_el_ge, >=, S, CS, M, CM) \ | |
313 SM_CMP_OP (mx_el_gt, >, S, CS, M, CM) \ | |
314 SM_CMP_OP (mx_el_eq, ==, S, , M, ) \ | |
315 SM_CMP_OP (mx_el_ne, !=, S, , M, ) | |
2870 | 316 |
6708 | 317 #define SM_BOOL_OP_DECLS(S, M, API) \ |
318 BOOL_OP_DECL (mx_el_and, S, M, API); \ | |
319 BOOL_OP_DECL (mx_el_or, S, M, API); \ | |
2870 | 320 |
5030 | 321 #define SM_BOOL_OP(F, OP, S, M, LHS_ZERO, RHS_ZERO) \ |
2870 | 322 boolMatrix \ |
323 F (const S& s, const M& m) \ | |
324 { \ | |
325 boolMatrix r; \ | |
326 \ | |
327 int nr = m.rows (); \ | |
328 int nc = m.cols (); \ | |
329 \ | |
330 if (nr != 0 && nc != 0) \ | |
331 { \ | |
332 r.resize (nr, nc); \ | |
333 \ | |
334 for (int j = 0; j < nc; j++) \ | |
335 for (int i = 0; i < nr; i++) \ | |
5030 | 336 r.elem(i, j) = (s != LHS_ZERO) OP (m.elem(i, j) != RHS_ZERO); \ |
2870 | 337 } \ |
338 \ | |
339 return r; \ | |
340 } | |
341 | |
5030 | 342 #define SM_BOOL_OPS2(S, M, LHS_ZERO, RHS_ZERO) \ |
343 SM_BOOL_OP (mx_el_and, &&, S, M, LHS_ZERO, RHS_ZERO) \ | |
344 SM_BOOL_OP (mx_el_or, ||, S, M, LHS_ZERO, RHS_ZERO) | |
345 | |
3504 | 346 #define SM_BOOL_OPS(S, M, ZERO) \ |
5030 | 347 SM_BOOL_OPS2(S, M, ZERO, ZERO) |
2870 | 348 |
6708 | 349 #define SM_OP_DECLS(R, S, M, API) \ |
350 SM_BIN_OP_DECLS (R, S, M, API) \ | |
351 SM_CMP_OP_DECLS (S, M, API) \ | |
352 SM_BOOL_OP_DECLS (S, M, API) \ | |
2870 | 353 |
354 // matrix by matrix operations. | |
355 | |
6708 | 356 #define MM_BIN_OP_DECLS(R, M1, M2, API) \ |
357 BIN_OP_DECL (R, operator +, M1, M2, API); \ | |
358 BIN_OP_DECL (R, operator -, M1, M2, API); \ | |
359 BIN_OP_DECL (R, product, M1, M2, API); \ | |
360 BIN_OP_DECL (R, quotient, M1, M2, API); | |
2870 | 361 |
362 #define MM_BIN_OP(R, OP, M1, M2, F) \ | |
2829 | 363 R \ |
364 OP (const M1& m1, const M2& m2) \ | |
365 { \ | |
366 R r; \ | |
367 \ | |
368 int m1_nr = m1.rows (); \ | |
369 int m1_nc = m1.cols (); \ | |
370 \ | |
371 int m2_nr = m2.rows (); \ | |
372 int m2_nc = m2.cols (); \ | |
373 \ | |
374 if (m1_nr != m2_nr || m1_nc != m2_nc) \ | |
375 gripe_nonconformant (#OP, m1_nr, m1_nc, m2_nr, m2_nc); \ | |
376 else \ | |
377 { \ | |
378 r.resize (m1_nr, m1_nc); \ | |
379 \ | |
380 if (m1_nr > 0 && m1_nc > 0) \ | |
381 F ## _vv (r.fortran_vec (), m1.data (), m2.data (), m1_nr * m1_nc); \ | |
382 } \ | |
383 \ | |
384 return r; \ | |
385 } | |
386 | |
2870 | 387 #define MM_BIN_OPS(R, M1, M2) \ |
3769 | 388 MM_BIN_OP (R, operator +, M1, M2, mx_inline_add) \ |
389 MM_BIN_OP (R, operator -, M1, M2, mx_inline_subtract) \ | |
390 MM_BIN_OP (R, product, M1, M2, mx_inline_multiply) \ | |
391 MM_BIN_OP (R, quotient, M1, M2, mx_inline_divide) | |
2870 | 392 |
6708 | 393 #define MM_CMP_OP_DECLS(M1, M2, API) \ |
394 CMP_OP_DECL (mx_el_lt, M1, M2, API); \ | |
395 CMP_OP_DECL (mx_el_le, M1, M2, API); \ | |
396 CMP_OP_DECL (mx_el_ge, M1, M2, API); \ | |
397 CMP_OP_DECL (mx_el_gt, M1, M2, API); \ | |
398 CMP_OP_DECL (mx_el_eq, M1, M2, API); \ | |
399 CMP_OP_DECL (mx_el_ne, M1, M2, API); | |
2870 | 400 |
4826 | 401 #define MM_CMP_OP(F, OP, M1, C1, M2, C2) \ |
2870 | 402 boolMatrix \ |
403 F (const M1& m1, const M2& m2) \ | |
404 { \ | |
405 boolMatrix r; \ | |
406 \ | |
407 int m1_nr = m1.rows (); \ | |
408 int m1_nc = m1.cols (); \ | |
409 \ | |
410 int m2_nr = m2.rows (); \ | |
411 int m2_nc = m2.cols (); \ | |
412 \ | |
413 if (m1_nr == m2_nr && m1_nc == m2_nc) \ | |
414 { \ | |
4826 | 415 r.resize (m1_nr, m1_nc); \ |
2870 | 416 \ |
4826 | 417 for (int j = 0; j < m1_nc; j++) \ |
418 for (int i = 0; i < m1_nr; i++) \ | |
419 r.elem(i, j) = C1 (m1.elem(i, j)) OP C2 (m2.elem(i, j)); \ | |
2870 | 420 } \ |
421 else \ | |
4826 | 422 gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \ |
2870 | 423 \ |
424 return r; \ | |
425 } | |
2829 | 426 |
2870 | 427 #define MM_CMP_OPS(M1, C1, M2, C2) \ |
4826 | 428 MM_CMP_OP (mx_el_lt, <, M1, C1, M2, C2) \ |
429 MM_CMP_OP (mx_el_le, <=, M1, C1, M2, C2) \ | |
430 MM_CMP_OP (mx_el_ge, >=, M1, C1, M2, C2) \ | |
431 MM_CMP_OP (mx_el_gt, >, M1, C1, M2, C2) \ | |
432 MM_CMP_OP (mx_el_eq, ==, M1, , M2, ) \ | |
433 MM_CMP_OP (mx_el_ne, !=, M1, , M2, ) | |
2870 | 434 |
6708 | 435 #define MM_BOOL_OP_DECLS(M1, M2, API) \ |
436 BOOL_OP_DECL (mx_el_and, M1, M2, API); \ | |
437 BOOL_OP_DECL (mx_el_or, M1, M2, API); | |
2870 | 438 |
5030 | 439 #define MM_BOOL_OP(F, OP, M1, M2, LHS_ZERO, RHS_ZERO) \ |
2870 | 440 boolMatrix \ |
441 F (const M1& m1, const M2& m2) \ | |
442 { \ | |
443 boolMatrix r; \ | |
444 \ | |
445 int m1_nr = m1.rows (); \ | |
446 int m1_nc = m1.cols (); \ | |
447 \ | |
448 int m2_nr = m2.rows (); \ | |
449 int m2_nc = m2.cols (); \ | |
450 \ | |
451 if (m1_nr == m2_nr && m1_nc == m2_nc) \ | |
452 { \ | |
453 if (m1_nr != 0 || m1_nc != 0) \ | |
454 { \ | |
455 r.resize (m1_nr, m1_nc); \ | |
456 \ | |
457 for (int j = 0; j < m1_nc; j++) \ | |
458 for (int i = 0; i < m1_nr; i++) \ | |
5030 | 459 r.elem(i, j) = (m1.elem(i, j) != LHS_ZERO) \ |
460 OP (m2.elem(i, j) != RHS_ZERO); \ | |
2870 | 461 } \ |
462 } \ | |
463 else \ | |
464 { \ | |
465 if ((m1_nr != 0 || m1_nc != 0) && (m2_nr != 0 || m2_nc != 0)) \ | |
466 gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \ | |
467 } \ | |
468 \ | |
469 return r; \ | |
470 } | |
471 | |
5030 | 472 #define MM_BOOL_OPS2(M1, M2, LHS_ZERO, RHS_ZERO) \ |
473 MM_BOOL_OP (mx_el_and, &&, M1, M2, LHS_ZERO, RHS_ZERO) \ | |
474 MM_BOOL_OP (mx_el_or, ||, M1, M2, LHS_ZERO, RHS_ZERO) | |
475 | |
3504 | 476 #define MM_BOOL_OPS(M1, M2, ZERO) \ |
5030 | 477 MM_BOOL_OPS2(M1, M2, ZERO, ZERO) |
2870 | 478 |
6708 | 479 #define MM_OP_DECLS(R, M1, M2, API) \ |
480 MM_BIN_OP_DECLS (R, M1, M2, API) \ | |
481 MM_CMP_OP_DECLS (M1, M2, API) \ | |
482 MM_BOOL_OP_DECLS (M1, M2, API) | |
2870 | 483 |
4543 | 484 // N-d matrix by scalar operations. |
485 | |
6708 | 486 #define NDS_BIN_OP_DECLS(R, ND, S, API) \ |
487 BIN_OP_DECL (R, operator +, ND, S, API); \ | |
488 BIN_OP_DECL (R, operator -, ND, S, API); \ | |
489 BIN_OP_DECL (R, operator *, ND, S, API); \ | |
490 BIN_OP_DECL (R, operator /, ND, S, API); | |
4543 | 491 |
492 #define NDS_BIN_OP(R, OP, ND, S, F) \ | |
493 R \ | |
494 OP (const ND& m, const S& s) \ | |
495 { \ | |
496 R r (m.dims ()); \ | |
497 \ | |
498 int len = m.length (); \ | |
499 \ | |
500 if (len > 0) \ | |
501 F ## _vs (r.fortran_vec (), m.data (), len, s); \ | |
502 \ | |
503 return r; \ | |
504 } | |
505 | |
506 #define NDS_BIN_OPS(R, ND, S) \ | |
507 NDS_BIN_OP (R, operator +, ND, S, mx_inline_add) \ | |
508 NDS_BIN_OP (R, operator -, ND, S, mx_inline_subtract) \ | |
509 NDS_BIN_OP (R, operator *, ND, S, mx_inline_multiply) \ | |
510 NDS_BIN_OP (R, operator /, ND, S, mx_inline_divide) | |
511 | |
6708 | 512 #define NDS_CMP_OP_DECLS(ND, S, API) \ |
513 NDCMP_OP_DECL (mx_el_lt, ND, S, API); \ | |
514 NDCMP_OP_DECL (mx_el_le, ND, S, API); \ | |
515 NDCMP_OP_DECL (mx_el_ge, ND, S, API); \ | |
516 NDCMP_OP_DECL (mx_el_gt, ND, S, API); \ | |
517 NDCMP_OP_DECL (mx_el_eq, ND, S, API); \ | |
518 NDCMP_OP_DECL (mx_el_ne, ND, S, API); | |
4543 | 519 |
4826 | 520 #define NDS_CMP_OP(F, OP, ND, NDC, S, SC) \ |
4543 | 521 boolNDArray \ |
522 F (const ND& m, const S& s) \ | |
523 { \ | |
524 boolNDArray r; \ | |
525 \ | |
526 int len = m.length (); \ | |
527 \ | |
4826 | 528 r.resize (m.dims ()); \ |
4543 | 529 \ |
4826 | 530 for (int i = 0; i < len; i++) \ |
531 r.elem(i) = NDC (m.elem(i)) OP SC (s); \ | |
4543 | 532 \ |
533 return r; \ | |
534 } | |
535 | |
536 #define NDS_CMP_OPS(ND, NDC, S, SC) \ | |
4826 | 537 NDS_CMP_OP (mx_el_lt, <, ND, NDC, S, SC) \ |
538 NDS_CMP_OP (mx_el_le, <=, ND, NDC, S, SC) \ | |
539 NDS_CMP_OP (mx_el_ge, >=, ND, NDC, S, SC) \ | |
540 NDS_CMP_OP (mx_el_gt, >, ND, NDC, S, SC) \ | |
541 NDS_CMP_OP (mx_el_eq, ==, ND, , S, ) \ | |
542 NDS_CMP_OP (mx_el_ne, !=, ND, , S, ) | |
4543 | 543 |
6119 | 544 #define NDS_CMP_OP1(F, OP, ND, NDC, S, SC, SPEC) \ |
545 boolNDArray \ | |
546 F (const ND& m, const S& s) \ | |
547 { \ | |
548 boolNDArray r; \ | |
549 \ | |
550 int len = m.length (); \ | |
551 \ | |
552 r.resize (m.dims ()); \ | |
553 \ | |
554 for (int i = 0; i < len; i++) \ | |
555 r.elem(i) = operator OP <SPEC> (NDC (m.elem(i)), SC (s)); \ | |
556 \ | |
557 return r; \ | |
558 } | |
559 | |
560 #define NDS_CMP_OPS1(ND, NDC, S, SC, SPEC) \ | |
561 NDS_CMP_OP1 (mx_el_lt, <, ND, NDC, S, SC, SPEC) \ | |
562 NDS_CMP_OP1 (mx_el_le, <=, ND, NDC, S, SC, SPEC) \ | |
563 NDS_CMP_OP1 (mx_el_ge, >=, ND, NDC, S, SC, SPEC) \ | |
564 NDS_CMP_OP1 (mx_el_gt, >, ND, NDC, S, SC, SPEC) \ | |
565 NDS_CMP_OP1 (mx_el_eq, ==, ND, , S, , SPEC) \ | |
566 NDS_CMP_OP1 (mx_el_ne, !=, ND, , S, , SPEC) | |
567 | |
568 #define NDS_CMP_OP2(F, OP, ND, NDC, S, SC, SPEC1, SPEC2) \ | |
569 boolNDArray \ | |
570 F (const ND& m, const S& s) \ | |
571 { \ | |
572 boolNDArray r; \ | |
573 \ | |
574 int len = m.length (); \ | |
575 \ | |
576 r.resize (m.dims ()); \ | |
577 \ | |
578 for (int i = 0; i < len; i++) \ | |
579 r.elem(i) = operator OP <SPEC1,SPEC2> (NDC (m.elem(i)), SC (s)); \ | |
580 \ | |
581 return r; \ | |
582 } | |
583 | |
584 #define NDS_CMP_OPS2(ND, NDC, S, SC, SPEC1, SPEC2) \ | |
585 NDS_CMP_OP2 (mx_el_lt, <, ND, NDC, S, SC, SPEC1, SPEC2) \ | |
586 NDS_CMP_OP2 (mx_el_le, <=, ND, NDC, S, SC, SPEC1, SPEC2) \ | |
587 NDS_CMP_OP2 (mx_el_ge, >=, ND, NDC, S, SC, SPEC1, SPEC2) \ | |
588 NDS_CMP_OP2 (mx_el_gt, >, ND, NDC, S, SC, SPEC1, SPEC2) \ | |
589 NDS_CMP_OP2 (mx_el_eq, ==, ND, , S, , SPEC1, SPEC2) \ | |
590 NDS_CMP_OP2 (mx_el_ne, !=, ND, , S, , SPEC1, SPEC2) | |
591 | |
6708 | 592 #define NDS_BOOL_OP_DECLS(ND, S, API) \ |
593 NDBOOL_OP_DECL (mx_el_and, ND, S, API); \ | |
594 NDBOOL_OP_DECL (mx_el_or, ND, S, API); | |
4543 | 595 |
5030 | 596 #define NDS_BOOL_OP(F, OP, ND, S, LHS_ZERO, RHS_ZERO) \ |
4543 | 597 boolNDArray \ |
598 F (const ND& m, const S& s) \ | |
599 { \ | |
600 boolNDArray r; \ | |
601 \ | |
602 int len = m.length (); \ | |
603 \ | |
604 if (len > 0) \ | |
605 { \ | |
606 r.resize (m.dims ()); \ | |
607 \ | |
608 for (int i = 0; i < len; i++) \ | |
5030 | 609 r.elem(i) = (m.elem(i) != LHS_ZERO) OP (s != RHS_ZERO); \ |
4543 | 610 } \ |
611 \ | |
612 return r; \ | |
613 } | |
614 | |
5030 | 615 #define NDS_BOOL_OPS2(ND, S, LHS_ZERO, RHS_ZERO) \ |
616 NDS_BOOL_OP (mx_el_and, &&, ND, S, LHS_ZERO, RHS_ZERO) \ | |
617 NDS_BOOL_OP (mx_el_or, ||, ND, S, LHS_ZERO, RHS_ZERO) | |
618 | |
4543 | 619 #define NDS_BOOL_OPS(ND, S, ZERO) \ |
5030 | 620 NDS_BOOL_OPS2(ND, S, ZERO, ZERO) |
4543 | 621 |
6708 | 622 #define NDS_OP_DECLS(R, ND, S, API) \ |
623 NDS_BIN_OP_DECLS (R, ND, S, API) \ | |
624 NDS_CMP_OP_DECLS (ND, S, API) \ | |
625 NDS_BOOL_OP_DECLS (ND, S, API) | |
4543 | 626 |
627 // scalar by N-d matrix operations. | |
628 | |
6708 | 629 #define SND_BIN_OP_DECLS(R, S, ND, API) \ |
630 BIN_OP_DECL (R, operator +, S, ND, API); \ | |
631 BIN_OP_DECL (R, operator -, S, ND, API); \ | |
632 BIN_OP_DECL (R, operator *, S, ND, API); \ | |
633 BIN_OP_DECL (R, operator /, S, ND, API); | |
4543 | 634 |
635 #define SND_BIN_OP(R, OP, S, ND, F) \ | |
636 R \ | |
637 OP (const S& s, const ND& m) \ | |
638 { \ | |
639 R r (m.dims ()); \ | |
640 \ | |
641 int len = m.length (); \ | |
642 \ | |
643 if (len > 0) \ | |
644 F ## _sv (r.fortran_vec (), s, m.data (), len); \ | |
645 \ | |
646 return r; \ | |
647 } | |
648 | |
649 #define SND_BIN_OPS(R, S, ND) \ | |
650 SND_BIN_OP (R, operator +, S, ND, mx_inline_add) \ | |
651 SND_BIN_OP (R, operator -, S, ND, mx_inline_subtract) \ | |
652 SND_BIN_OP (R, operator *, S, ND, mx_inline_multiply) \ | |
653 SND_BIN_OP (R, operator /, S, ND, mx_inline_divide) | |
654 | |
6708 | 655 #define SND_CMP_OP_DECLS(S, ND, API) \ |
656 NDCMP_OP_DECL (mx_el_lt, S, ND, API); \ | |
657 NDCMP_OP_DECL (mx_el_le, S, ND, API); \ | |
658 NDCMP_OP_DECL (mx_el_ge, S, ND, API); \ | |
659 NDCMP_OP_DECL (mx_el_gt, S, ND, API); \ | |
660 NDCMP_OP_DECL (mx_el_eq, S, ND, API); \ | |
661 NDCMP_OP_DECL (mx_el_ne, S, ND, API); | |
4543 | 662 |
4826 | 663 #define SND_CMP_OP(F, OP, S, SC, ND, NDC) \ |
4543 | 664 boolNDArray \ |
665 F (const S& s, const ND& m) \ | |
666 { \ | |
667 boolNDArray r; \ | |
668 \ | |
669 int len = m.length (); \ | |
670 \ | |
4826 | 671 r.resize (m.dims ()); \ |
4543 | 672 \ |
4826 | 673 for (int i = 0; i < len; i++) \ |
674 r.elem(i) = SC (s) OP NDC (m.elem(i)); \ | |
4543 | 675 \ |
676 return r; \ | |
677 } | |
678 | |
679 #define SND_CMP_OPS(S, CS, ND, CND) \ | |
4826 | 680 SND_CMP_OP (mx_el_lt, <, S, CS, ND, CND) \ |
681 SND_CMP_OP (mx_el_le, <=, S, CS, ND, CND) \ | |
682 SND_CMP_OP (mx_el_ge, >=, S, CS, ND, CND) \ | |
683 SND_CMP_OP (mx_el_gt, >, S, CS, ND, CND) \ | |
684 SND_CMP_OP (mx_el_eq, ==, S, , ND, ) \ | |
685 SND_CMP_OP (mx_el_ne, !=, S, , ND, ) | |
4543 | 686 |
6119 | 687 #define SND_CMP_OP1(F, OP, S, SC, ND, NDC, SPEC) \ |
688 boolNDArray \ | |
689 F (const S& s, const ND& m) \ | |
690 { \ | |
691 boolNDArray r; \ | |
692 \ | |
693 int len = m.length (); \ | |
694 \ | |
695 r.resize (m.dims ()); \ | |
696 \ | |
697 for (int i = 0; i < len; i++) \ | |
698 r.elem(i) = operator OP <SPEC> (SC (s), NDC (m.elem(i))); \ | |
699 \ | |
700 return r; \ | |
701 } | |
702 | |
703 #define SND_CMP_OPS1(S, CS, ND, CND, SPEC) \ | |
704 SND_CMP_OP1 (mx_el_lt, <, S, CS, ND, CND, SPEC) \ | |
705 SND_CMP_OP1 (mx_el_le, <=, S, CS, ND, CND, SPEC) \ | |
706 SND_CMP_OP1 (mx_el_ge, >=, S, CS, ND, CND, SPEC) \ | |
707 SND_CMP_OP1 (mx_el_gt, >, S, CS, ND, CND, SPEC) \ | |
708 SND_CMP_OP1 (mx_el_eq, ==, S, , ND, , SPEC) \ | |
709 SND_CMP_OP1 (mx_el_ne, !=, S, , ND, , SPEC) | |
710 | |
711 #define SND_CMP_OP2(F, OP, S, SC, ND, NDC, SPEC1, SPEC2) \ | |
712 boolNDArray \ | |
713 F (const S& s, const ND& m) \ | |
714 { \ | |
715 boolNDArray r; \ | |
716 \ | |
717 int len = m.length (); \ | |
718 \ | |
719 r.resize (m.dims ()); \ | |
720 \ | |
721 for (int i = 0; i < len; i++) \ | |
722 r.elem(i) = operator OP <SPEC1, SPEC2> (SC (s), NDC (m.elem(i))); \ | |
723 \ | |
724 return r; \ | |
725 } | |
726 | |
727 #define SND_CMP_OPS2(S, CS, ND, CND, SPEC1, SPEC2) \ | |
728 SND_CMP_OP2 (mx_el_lt, <, S, CS, ND, CND, SPEC1, SPEC2) \ | |
729 SND_CMP_OP2 (mx_el_le, <=, S, CS, ND, CND, SPEC1, SPEC2) \ | |
730 SND_CMP_OP2 (mx_el_ge, >=, S, CS, ND, CND, SPEC1, SPEC2) \ | |
731 SND_CMP_OP2 (mx_el_gt, >, S, CS, ND, CND, SPEC1, SPEC2) \ | |
732 SND_CMP_OP2 (mx_el_eq, ==, S, , ND, , SPEC1, SPEC2) \ | |
733 SND_CMP_OP2 (mx_el_ne, !=, S, , ND, , SPEC1, SPEC2) | |
734 | |
6708 | 735 #define SND_BOOL_OP_DECLS(S, ND, API) \ |
736 NDBOOL_OP_DECL (mx_el_and, S, ND, API); \ | |
737 NDBOOL_OP_DECL (mx_el_or, S, ND, API); | |
4543 | 738 |
5030 | 739 #define SND_BOOL_OP(F, OP, S, ND, LHS_ZERO, RHS_ZERO) \ |
4543 | 740 boolNDArray \ |
741 F (const S& s, const ND& m) \ | |
742 { \ | |
743 boolNDArray r; \ | |
744 \ | |
745 int len = m.length (); \ | |
746 \ | |
747 if (len > 0) \ | |
748 { \ | |
749 r.resize (m.dims ()); \ | |
750 \ | |
751 for (int i = 0; i < len; i++) \ | |
5030 | 752 r.elem(i) = (s != LHS_ZERO) OP (m.elem(i) != RHS_ZERO); \ |
4543 | 753 } \ |
754 \ | |
755 return r; \ | |
756 } | |
757 | |
5030 | 758 #define SND_BOOL_OPS2(S, ND, LHS_ZERO, RHS_ZERO) \ |
759 SND_BOOL_OP (mx_el_and, &&, S, ND, LHS_ZERO, RHS_ZERO) \ | |
760 SND_BOOL_OP (mx_el_or, ||, S, ND, LHS_ZERO, RHS_ZERO) | |
761 | |
4543 | 762 #define SND_BOOL_OPS(S, ND, ZERO) \ |
5030 | 763 SND_BOOL_OPS2(S, ND, ZERO, ZERO) |
4543 | 764 |
6708 | 765 #define SND_OP_DECLS(R, S, ND, API) \ |
766 SND_BIN_OP_DECLS (R, S, ND, API) \ | |
767 SND_CMP_OP_DECLS (S, ND, API) \ | |
768 SND_BOOL_OP_DECLS (S, ND, API) | |
4543 | 769 |
770 // N-d matrix by N-d matrix operations. | |
771 | |
6708 | 772 #define NDND_BIN_OP_DECLS(R, ND1, ND2, API) \ |
773 BIN_OP_DECL (R, operator +, ND1, ND2, API); \ | |
774 BIN_OP_DECL (R, operator -, ND1, ND2, API); \ | |
775 BIN_OP_DECL (R, product, ND1, ND2, API); \ | |
776 BIN_OP_DECL (R, quotient, ND1, ND2, API); | |
4543 | 777 |
778 #define NDND_BIN_OP(R, OP, ND1, ND2, F) \ | |
779 R \ | |
780 OP (const ND1& m1, const ND2& m2) \ | |
781 { \ | |
782 R r; \ | |
783 \ | |
784 dim_vector m1_dims = m1.dims (); \ | |
785 dim_vector m2_dims = m2.dims (); \ | |
786 \ | |
787 if (m1_dims != m2_dims) \ | |
788 gripe_nonconformant (#OP, m1_dims, m2_dims); \ | |
789 else \ | |
790 { \ | |
791 r.resize (m1_dims); \ | |
792 \ | |
793 int len = m1.length (); \ | |
794 \ | |
795 if (len > 0) \ | |
796 F ## _vv (r.fortran_vec (), m1.data (), m2.data (), len); \ | |
797 } \ | |
798 \ | |
799 return r; \ | |
800 } | |
801 | |
802 #define NDND_BIN_OPS(R, ND1, ND2) \ | |
803 NDND_BIN_OP (R, operator +, ND1, ND2, mx_inline_add) \ | |
804 NDND_BIN_OP (R, operator -, ND1, ND2, mx_inline_subtract) \ | |
805 NDND_BIN_OP (R, product, ND1, ND2, mx_inline_multiply) \ | |
806 NDND_BIN_OP (R, quotient, ND1, ND2, mx_inline_divide) | |
807 | |
6708 | 808 #define NDND_CMP_OP_DECLS(ND1, ND2, API) \ |
809 NDCMP_OP_DECL (mx_el_lt, ND1, ND2, API); \ | |
810 NDCMP_OP_DECL (mx_el_le, ND1, ND2, API); \ | |
811 NDCMP_OP_DECL (mx_el_ge, ND1, ND2, API); \ | |
812 NDCMP_OP_DECL (mx_el_gt, ND1, ND2, API); \ | |
813 NDCMP_OP_DECL (mx_el_eq, ND1, ND2, API); \ | |
814 NDCMP_OP_DECL (mx_el_ne, ND1, ND2, API); | |
4543 | 815 |
4826 | 816 #define NDND_CMP_OP(F, OP, ND1, C1, ND2, C2) \ |
4543 | 817 boolNDArray \ |
818 F (const ND1& m1, const ND2& m2) \ | |
819 { \ | |
820 boolNDArray r; \ | |
821 \ | |
822 dim_vector m1_dims = m1.dims (); \ | |
823 dim_vector m2_dims = m2.dims (); \ | |
824 \ | |
825 if (m1_dims == m2_dims) \ | |
826 { \ | |
4826 | 827 r.resize (m1_dims); \ |
4543 | 828 \ |
4826 | 829 for (int i = 0; i < m1.length (); i++) \ |
830 r.elem(i) = C1 (m1.elem(i)) OP C2 (m2.elem(i)); \ | |
4543 | 831 } \ |
832 else \ | |
4826 | 833 gripe_nonconformant (#F, m1_dims, m2_dims); \ |
4543 | 834 \ |
835 return r; \ | |
836 } | |
837 | |
838 #define NDND_CMP_OPS(ND1, C1, ND2, C2) \ | |
4826 | 839 NDND_CMP_OP (mx_el_lt, <, ND1, C1, ND2, C2) \ |
840 NDND_CMP_OP (mx_el_le, <=, ND1, C1, ND2, C2) \ | |
841 NDND_CMP_OP (mx_el_ge, >=, ND1, C1, ND2, C2) \ | |
842 NDND_CMP_OP (mx_el_gt, >, ND1, C1, ND2, C2) \ | |
843 NDND_CMP_OP (mx_el_eq, ==, ND1, , ND2, ) \ | |
844 NDND_CMP_OP (mx_el_ne, !=, ND1, , ND2, ) | |
4543 | 845 |
6708 | 846 #define NDND_BOOL_OP_DECLS(ND1, ND2, API) \ |
847 NDBOOL_OP_DECL (mx_el_and, ND1, ND2, API); \ | |
848 NDBOOL_OP_DECL (mx_el_or, ND1, ND2, API); | |
4543 | 849 |
5030 | 850 #define NDND_BOOL_OP(F, OP, ND1, ND2, LHS_ZERO, RHS_ZERO) \ |
4543 | 851 boolNDArray \ |
852 F (const ND1& m1, const ND2& m2) \ | |
853 { \ | |
854 boolNDArray r; \ | |
855 \ | |
856 dim_vector m1_dims = m1.dims (); \ | |
857 dim_vector m2_dims = m2.dims (); \ | |
858 \ | |
859 if (m1_dims == m2_dims) \ | |
860 { \ | |
861 if (! m1_dims.all_zero ()) \ | |
862 { \ | |
863 r.resize (m1_dims); \ | |
864 \ | |
865 for (int i = 0; i < m1.length (); i++) \ | |
5030 | 866 r.elem(i) = (m1.elem(i) != LHS_ZERO) OP (m2.elem(i) != RHS_ZERO); \ |
4543 | 867 } \ |
868 } \ | |
869 else \ | |
870 gripe_nonconformant (#F, m1_dims, m2_dims); \ | |
871 \ | |
872 return r; \ | |
873 } | |
874 | |
5030 | 875 #define NDND_BOOL_OPS2(ND1, ND2, LHS_ZERO, RHS_ZERO) \ |
876 NDND_BOOL_OP (mx_el_and, &&, ND1, ND2, LHS_ZERO, RHS_ZERO) \ | |
877 NDND_BOOL_OP (mx_el_or, ||, ND1, ND2, LHS_ZERO, RHS_ZERO) | |
878 | |
4543 | 879 #define NDND_BOOL_OPS(ND1, ND2, ZERO) \ |
5030 | 880 NDND_BOOL_OPS2(ND1, ND2, ZERO, ZERO) |
4543 | 881 |
6708 | 882 #define NDND_OP_DECLS(R, ND1, ND2, API) \ |
883 NDND_BIN_OP_DECLS (R, ND1, ND2, API) \ | |
884 NDND_CMP_OP_DECLS (ND1, ND2, API) \ | |
885 NDND_BOOL_OP_DECLS (ND1, ND2, API) | |
4543 | 886 |
2870 | 887 // scalar by diagonal matrix operations. |
888 | |
6708 | 889 #define SDM_BIN_OP_DECLS(R, S, DM, API) \ |
890 BIN_OP_DECL (R, operator +, S, DM, API); \ | |
891 BIN_OP_DECL (R, operator -, S, DM, API); | |
2870 | 892 |
893 #define SDM_BIN_OP(R, OP, S, DM, OPEQ) \ | |
2829 | 894 R \ |
895 OP (const S& s, const DM& dm) \ | |
896 { \ | |
897 int nr = dm.rows (); \ | |
898 int nc = dm.cols (); \ | |
899 \ | |
900 R r (nr, nc, s); \ | |
901 \ | |
4543 | 902 for (int i = 0; i < dm.length (); i++) \ |
2870 | 903 r.elem(i, i) OPEQ dm.elem(i, i); \ |
2829 | 904 \ |
905 return r; \ | |
906 } | |
907 | |
2870 | 908 #define SDM_BIN_OPS(R, S, DM) \ |
909 SDM_BIN_OP (R, operator +, S, DM, +=) \ | |
910 SDM_BIN_OP (R, operator -, S, DM, -=) | |
911 | |
6708 | 912 #define SDM_OP_DECLS(R, S, DM, API) \ |
913 SDM_BIN_OP_DECLS(R, S, DM, API) | |
2829 | 914 |
2870 | 915 // diagonal matrix by scalar operations. |
916 | |
6708 | 917 #define DMS_BIN_OP_DECLS(R, DM, S, API) \ |
918 BIN_OP_DECL (R, operator +, DM, S, API); \ | |
919 BIN_OP_DECL (R, operator -, DM, S, API); | |
2870 | 920 |
921 #define DMS_BIN_OP(R, OP, DM, S, SGN) \ | |
2829 | 922 R \ |
923 OP (const DM& dm, const S& s) \ | |
924 { \ | |
925 int nr = dm.rows (); \ | |
926 int nc = dm.cols (); \ | |
927 \ | |
928 R r (nr, nc, SGN s); \ | |
929 \ | |
4543 | 930 for (int i = 0; i < dm.length (); i++) \ |
2870 | 931 r.elem(i, i) += dm.elem(i, i); \ |
2829 | 932 \ |
933 return r; \ | |
934 } | |
935 | |
2870 | 936 #define DMS_BIN_OPS(R, DM, S) \ |
937 DMS_BIN_OP (R, operator +, DM, S, ) \ | |
938 DMS_BIN_OP (R, operator -, DM, S, -) | |
939 | |
6708 | 940 #define DMS_OP_DECLS(R, DM, S, API) \ |
941 DMS_BIN_OP_DECLS(R, DM, S, API) | |
2829 | 942 |
2870 | 943 // matrix by diagonal matrix operations. |
944 | |
6708 | 945 #define MDM_BIN_OP_DECLS(R, M, DM, API) \ |
946 BIN_OP_DECL (R, operator +, M, DM, API); \ | |
947 BIN_OP_DECL (R, operator -, M, DM, API); \ | |
948 BIN_OP_DECL (R, operator *, M, DM, API); | |
2870 | 949 |
950 #define MDM_BIN_OP(R, OP, M, DM, OPEQ) \ | |
2829 | 951 R \ |
952 OP (const M& m, const DM& dm) \ | |
953 { \ | |
954 R r; \ | |
955 \ | |
956 int m_nr = m.rows (); \ | |
957 int m_nc = m.cols (); \ | |
958 \ | |
959 int dm_nr = dm.rows (); \ | |
960 int dm_nc = dm.cols (); \ | |
961 \ | |
962 if (m_nr != dm_nr || m_nc != dm_nc) \ | |
963 gripe_nonconformant (#OP, m_nr, m_nc, dm_nr, dm_nc); \ | |
964 else \ | |
965 { \ | |
966 r.resize (m_nr, m_nc); \ | |
967 \ | |
968 if (m_nr > 0 && m_nc > 0) \ | |
969 { \ | |
3585 | 970 r = R (m); \ |
2829 | 971 \ |
972 int len = dm.length (); \ | |
973 \ | |
974 for (int i = 0; i < len; i++) \ | |
2870 | 975 r.elem(i, i) OPEQ dm.elem(i, i); \ |
2829 | 976 } \ |
977 } \ | |
978 \ | |
979 return r; \ | |
980 } | |
981 | |
5030 | 982 #define MDM_MULTIPLY_OP(R, M, DM, R_ZERO) \ |
2829 | 983 R \ |
984 operator * (const M& m, const DM& dm) \ | |
985 { \ | |
986 R r; \ | |
987 \ | |
988 int m_nr = m.rows (); \ | |
989 int m_nc = m.cols (); \ | |
990 \ | |
991 int dm_nr = dm.rows (); \ | |
992 int dm_nc = dm.cols (); \ | |
993 \ | |
994 if (m_nc != dm_nr) \ | |
995 gripe_nonconformant ("operator *", m_nr, m_nc, dm_nr, dm_nc); \ | |
996 else \ | |
997 { \ | |
5030 | 998 r.resize (m_nr, dm_nc, R_ZERO); \ |
2829 | 999 \ |
3176 | 1000 if (m_nr > 0 && m_nc > 0 && dm_nc > 0) \ |
2829 | 1001 { \ |
4543 | 1002 int len = dm.length (); \ |
1003 \ | |
1004 for (int j = 0; j < len; j++) \ | |
2829 | 1005 { \ |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7189
diff
changeset
|
1006 for (int i = 0; i < m_nr; i++) \ |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7189
diff
changeset
|
1007 r.elem(i, j) = dm.elem(j, j) * m.elem(i, j); \ |
2829 | 1008 } \ |
1009 } \ | |
1010 } \ | |
1011 \ | |
1012 return r; \ | |
1013 } | |
1014 | |
5030 | 1015 #define MDM_BIN_OPS(R, M, DM, R_ZERO) \ |
2870 | 1016 MDM_BIN_OP (R, operator +, M, DM, +=) \ |
1017 MDM_BIN_OP (R, operator -, M, DM, -=) \ | |
5030 | 1018 MDM_MULTIPLY_OP (R, M, DM, R_ZERO) |
2829 | 1019 |
6708 | 1020 #define MDM_OP_DECLS(R, M, DM, API) \ |
1021 MDM_BIN_OP_DECLS(R, M, DM, API) | |
2870 | 1022 |
1023 // diagonal matrix by matrix operations. | |
1024 | |
6708 | 1025 #define DMM_BIN_OP_DECLS(R, DM, M, API) \ |
1026 BIN_OP_DECL (R, operator +, DM, M, API); \ | |
1027 BIN_OP_DECL (R, operator -, DM, M, API); \ | |
1028 BIN_OP_DECL (R, operator *, DM, M, API); | |
2870 | 1029 |
3585 | 1030 #define DMM_BIN_OP(R, OP, DM, M, OPEQ, PREOP) \ |
2829 | 1031 R \ |
1032 OP (const DM& dm, const M& m) \ | |
1033 { \ | |
1034 R r; \ | |
1035 \ | |
1036 int dm_nr = dm.rows (); \ | |
1037 int dm_nc = dm.cols (); \ | |
1038 \ | |
1039 int m_nr = m.rows (); \ | |
1040 int m_nc = m.cols (); \ | |
1041 \ | |
1042 if (dm_nr != m_nr || dm_nc != m_nc) \ | |
1043 gripe_nonconformant (#OP, dm_nr, dm_nc, m_nr, m_nc); \ | |
1044 else \ | |
1045 { \ | |
1046 if (m_nr > 0 && m_nc > 0) \ | |
1047 { \ | |
3585 | 1048 r = R (PREOP m); \ |
2829 | 1049 \ |
1050 int len = dm.length (); \ | |
1051 \ | |
1052 for (int i = 0; i < len; i++) \ | |
2870 | 1053 r.elem(i, i) OPEQ dm.elem(i, i); \ |
2829 | 1054 } \ |
1055 else \ | |
1056 r.resize (m_nr, m_nc); \ | |
1057 } \ | |
1058 \ | |
1059 return r; \ | |
1060 } | |
1061 | |
5030 | 1062 #define DMM_MULTIPLY_OP(R, DM, M, R_ZERO) \ |
2829 | 1063 R \ |
1064 operator * (const DM& dm, const M& m) \ | |
1065 { \ | |
1066 R r; \ | |
1067 \ | |
1068 int dm_nr = dm.rows (); \ | |
1069 int dm_nc = dm.cols (); \ | |
1070 \ | |
1071 int m_nr = m.rows (); \ | |
1072 int m_nc = m.cols (); \ | |
1073 \ | |
1074 if (dm_nc != m_nr) \ | |
1075 gripe_nonconformant ("operator *", dm_nr, dm_nc, m_nr, m_nc); \ | |
1076 else \ | |
1077 { \ | |
5030 | 1078 r.resize (dm_nr, m_nc, R_ZERO); \ |
2829 | 1079 \ |
1080 if (dm_nr > 0 && dm_nc > 0 && m_nc > 0) \ | |
1081 { \ | |
4543 | 1082 int len = dm.length (); \ |
1083 \ | |
1084 for (int i = 0; i < len; i++) \ | |
2829 | 1085 { \ |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7189
diff
changeset
|
1086 for (int j = 0; j < m_nc; j++) \ |
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7189
diff
changeset
|
1087 r.elem(i, j) = dm.elem(i, i) * m.elem(i, j); \ |
2829 | 1088 } \ |
1089 } \ | |
1090 } \ | |
1091 \ | |
1092 return r; \ | |
1093 } | |
1094 | |
5030 | 1095 #define DMM_BIN_OPS(R, DM, M, R_ZERO) \ |
3585 | 1096 DMM_BIN_OP (R, operator +, DM, M, +=, ) \ |
1097 DMM_BIN_OP (R, operator -, DM, M, +=, -) \ | |
5030 | 1098 DMM_MULTIPLY_OP (R, DM, M, R_ZERO) |
2829 | 1099 |
6708 | 1100 #define DMM_OP_DECLS(R, DM, M, API) \ |
1101 DMM_BIN_OP_DECLS(R, DM, M, API) | |
2870 | 1102 |
1103 // diagonal matrix by diagonal matrix operations. | |
2829 | 1104 |
6708 | 1105 #define DMDM_BIN_OP_DECLS(R, DM1, DM2, API) \ |
1106 BIN_OP_DECL (R, operator +, DM1, DM2, API); \ | |
1107 BIN_OP_DECL (R, operator -, DM1, DM2, API); \ | |
1108 BIN_OP_DECL (R, product, DM1, DM2, API); | |
2870 | 1109 |
1110 #define DMDM_BIN_OP(R, OP, DM1, DM2, F) \ | |
2829 | 1111 R \ |
1112 OP (const DM1& dm1, const DM2& dm2) \ | |
1113 { \ | |
1114 R r; \ | |
1115 \ | |
1116 int dm1_nr = dm1.rows (); \ | |
1117 int dm1_nc = dm1.cols (); \ | |
1118 \ | |
1119 int dm2_nr = dm2.rows (); \ | |
1120 int dm2_nc = dm2.cols (); \ | |
1121 \ | |
1122 if (dm1_nr != dm2_nr || dm1_nc != dm2_nc) \ | |
1123 gripe_nonconformant (#OP, dm1_nr, dm1_nc, dm2_nr, dm2_nc); \ | |
1124 else \ | |
1125 { \ | |
1126 r.resize (dm1_nr, dm1_nc); \ | |
1127 \ | |
1128 if (dm1_nr > 0 && dm1_nc > 0) \ | |
1129 F ## _vv (r.fortran_vec (), dm1.data (), dm2.data (), \ | |
1130 dm1_nr * dm2_nc); \ | |
1131 } \ | |
1132 \ | |
1133 return r; \ | |
1134 } | |
1135 | |
2870 | 1136 #define DMDM_BIN_OPS(R, DM1, DM2) \ |
3769 | 1137 DMDM_BIN_OP (R, operator +, DM1, DM2, mx_inline_add) \ |
1138 DMDM_BIN_OP (R, operator -, DM1, DM2, mx_inline_subtract) \ | |
1139 DMDM_BIN_OP (R, product, DM1, DM2, mx_inline_multiply) | |
2870 | 1140 |
6708 | 1141 #define DMDM_OP_DECLS(R, DM1, DM2, API) \ |
1142 DMDM_BIN_OP_DECLS (R, DM1, DM2, API) | |
2829 | 1143 |
3582 | 1144 #endif |
1145 | |
7189 | 1146 #define SND_MINMAX_FCN(FCN, OP, T) \ |
1147 T ## NDArray \ | |
1148 FCN (octave_ ## T d, const T ## NDArray& m) \ | |
1149 { \ | |
1150 dim_vector dv = m.dims (); \ | |
1151 octave_idx_type nel = dv.numel (); \ | |
1152 \ | |
1153 if (nel == 0) \ | |
1154 return T ## NDArray (dv); \ | |
1155 \ | |
1156 T ## NDArray result (dv); \ | |
1157 \ | |
1158 for (octave_idx_type i = 0; i < nel; i++) \ | |
1159 { \ | |
1160 OCTAVE_QUIT; \ | |
1161 result (i) = d OP m (i) ? d : m(i); \ | |
1162 } \ | |
1163 \ | |
1164 return result; \ | |
1165 } | |
1166 | |
1167 #define NDS_MINMAX_FCN(FCN, OP, T) \ | |
1168 T ## NDArray \ | |
1169 FCN (const T ## NDArray& m, octave_ ## T d) \ | |
1170 { \ | |
1171 dim_vector dv = m.dims (); \ | |
1172 octave_idx_type nel = dv.numel (); \ | |
1173 \ | |
1174 if (nel == 0) \ | |
1175 return T ## NDArray (dv); \ | |
1176 \ | |
1177 T ## NDArray result (dv); \ | |
1178 \ | |
1179 for (octave_idx_type i = 0; i < nel; i++) \ | |
1180 { \ | |
1181 OCTAVE_QUIT; \ | |
1182 result (i) = m (i) OP d ? m(i) : d; \ | |
1183 } \ | |
1184 \ | |
1185 return result; \ | |
1186 } | |
1187 | |
1188 #define NDND_MINMAX_FCN(FCN, OP, T) \ | |
1189 T ## NDArray \ | |
1190 FCN (const T ## NDArray& a, const T ## NDArray& b) \ | |
1191 { \ | |
1192 dim_vector dv = a.dims (); \ | |
1193 octave_idx_type nel = dv.numel (); \ | |
1194 \ | |
1195 if (dv != b.dims ()) \ | |
1196 { \ | |
1197 (*current_liboctave_error_handler) \ | |
1198 ("two-arg min expecting args of same size"); \ | |
1199 return T ## NDArray (); \ | |
1200 } \ | |
1201 \ | |
1202 if (nel == 0) \ | |
1203 return T ## NDArray (dv); \ | |
1204 \ | |
1205 T ## NDArray result (dv); \ | |
1206 \ | |
1207 for (octave_idx_type i = 0; i < nel; i++) \ | |
1208 { \ | |
1209 OCTAVE_QUIT; \ | |
1210 result (i) = a(i) OP b(i) ? a(i) : b(i); \ | |
1211 } \ | |
1212 \ | |
1213 return result; \ | |
1214 } | |
1215 | |
1216 #define MINMAX_FCNS(T) \ | |
1217 SND_MINMAX_FCN (min, <, T) \ | |
1218 NDS_MINMAX_FCN (min, <, T) \ | |
1219 NDND_MINMAX_FCN (min, <, T) \ | |
1220 SND_MINMAX_FCN (max, >, T) \ | |
1221 NDS_MINMAX_FCN (max, >, T) \ | |
1222 NDND_MINMAX_FCN (max, >, T) | |
1223 | |
1224 #define MINMAX_DECLS(T) \ | |
1225 extern OCTAVE_API T ## NDArray min (octave_ ## T d, const T ## NDArray& m); \ | |
1226 extern OCTAVE_API T ## NDArray min (const T ## NDArray& m, octave_ ## T d); \ | |
1227 extern OCTAVE_API T ## NDArray min (const T ## NDArray& a, \ | |
1228 const T ## NDArray& b); \ | |
1229 extern OCTAVE_API T ## NDArray max (octave_ ## T d, const T ## NDArray& m); \ | |
1230 extern OCTAVE_API T ## NDArray max (const T ## NDArray& m, octave_ ## T d); \ | |
1231 extern OCTAVE_API T ## NDArray max (const T ## NDArray& a, \ | |
1232 const T ## NDArray& b); | |
1233 | |
1234 | |
2829 | 1235 /* |
1236 ;;; Local Variables: *** | |
1237 ;;; mode: C++ *** | |
1238 ;;; End: *** | |
1239 */ |