Mercurial > hg > octave-lyh
annotate liboctave/mx-op-defs.h @ 8367:445d27d79f4e
support permutation matrix objects
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Thu, 04 Dec 2008 08:31:56 +0100 |
parents | 8b1a2555c4e2 |
children | e3c9102431a9 |
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 \ | |
7922
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
231 if (xisnan (s)) \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
232 gripe_nan_to_logical_conversion (); \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
233 else \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
234 { \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
235 \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
236 for (int j = 0; j < nc; j++) \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
237 for (int i = 0; i < nr; i++) \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
238 if (xisnan (m.elem(i, j))) \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
239 { \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
240 gripe_nan_to_logical_conversion (); \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
241 return r; \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
242 } \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
243 else \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
244 r.elem(i, j) = (m.elem(i, j) != LHS_ZERO) OP (s != RHS_ZERO); \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
245 } \ |
2870 | 246 } \ |
247 \ | |
248 return r; \ | |
249 } | |
250 | |
5030 | 251 #define MS_BOOL_OPS2(M, S, LHS_ZERO, RHS_ZERO) \ |
252 MS_BOOL_OP (mx_el_and, &&, M, S, LHS_ZERO, RHS_ZERO) \ | |
253 MS_BOOL_OP (mx_el_or, ||, M, S, LHS_ZERO, RHS_ZERO) | |
254 | |
3504 | 255 #define MS_BOOL_OPS(M, S, ZERO) \ |
5030 | 256 MS_BOOL_OPS2(M, S, ZERO, ZERO) |
2870 | 257 |
6708 | 258 #define MS_OP_DECLS(R, M, S, API) \ |
259 MS_BIN_OP_DECLS (R, M, S, API) \ | |
260 MS_CMP_OP_DECLS (M, S, API) \ | |
261 MS_BOOL_OP_DECLS (M, S, API) \ | |
2870 | 262 |
263 // scalar by matrix operations. | |
264 | |
6708 | 265 #define SM_BIN_OP_DECLS(R, S, M, API) \ |
266 BIN_OP_DECL (R, operator +, S, M, API); \ | |
267 BIN_OP_DECL (R, operator -, S, M, API); \ | |
268 BIN_OP_DECL (R, operator *, S, M, API); \ | |
269 BIN_OP_DECL (R, operator /, S, M, API); | |
2870 | 270 |
271 #define SM_BIN_OP(R, OP, S, M, F) \ | |
2829 | 272 R \ |
273 OP (const S& s, const M& m) \ | |
274 { \ | |
275 int nr = m.rows (); \ | |
276 int nc = m.cols (); \ | |
277 \ | |
278 R r (nr, nc); \ | |
279 \ | |
280 if (nr > 0 && nc > 0) \ | |
281 F ## _sv (r.fortran_vec (), s, m.data (), nr * nc); \ | |
282 \ | |
283 return r; \ | |
284 } | |
285 | |
2870 | 286 #define SM_BIN_OPS(R, S, M) \ |
3769 | 287 SM_BIN_OP (R, operator +, S, M, mx_inline_add) \ |
288 SM_BIN_OP (R, operator -, S, M, mx_inline_subtract) \ | |
289 SM_BIN_OP (R, operator *, S, M, mx_inline_multiply) \ | |
290 SM_BIN_OP (R, operator /, S, M, mx_inline_divide) | |
2870 | 291 |
6708 | 292 #define SM_CMP_OP_DECLS(S, M, API) \ |
293 CMP_OP_DECL (mx_el_lt, S, M, API); \ | |
294 CMP_OP_DECL (mx_el_le, S, M, API); \ | |
295 CMP_OP_DECL (mx_el_ge, S, M, API); \ | |
296 CMP_OP_DECL (mx_el_gt, S, M, API); \ | |
297 CMP_OP_DECL (mx_el_eq, S, M, API); \ | |
298 CMP_OP_DECL (mx_el_ne, S, M, API); | |
2870 | 299 |
4826 | 300 #define SM_CMP_OP(F, OP, S, SC, M, MC) \ |
2870 | 301 boolMatrix \ |
302 F (const S& s, const M& m) \ | |
303 { \ | |
304 boolMatrix r; \ | |
305 \ | |
306 int nr = m.rows (); \ | |
307 int nc = m.cols (); \ | |
308 \ | |
4826 | 309 r.resize (nr, nc); \ |
310 \ | |
311 if (nr > 0 && nc > 0) \ | |
2870 | 312 { \ |
313 for (int j = 0; j < nc; j++) \ | |
314 for (int i = 0; i < nr; i++) \ | |
315 r.elem(i, j) = SC (s) OP MC (m.elem(i, j)); \ | |
316 } \ | |
317 \ | |
318 return r; \ | |
319 } | |
2829 | 320 |
2870 | 321 #define SM_CMP_OPS(S, CS, M, CM) \ |
4826 | 322 SM_CMP_OP (mx_el_lt, <, S, CS, M, CM) \ |
323 SM_CMP_OP (mx_el_le, <=, S, CS, M, CM) \ | |
324 SM_CMP_OP (mx_el_ge, >=, S, CS, M, CM) \ | |
325 SM_CMP_OP (mx_el_gt, >, S, CS, M, CM) \ | |
326 SM_CMP_OP (mx_el_eq, ==, S, , M, ) \ | |
327 SM_CMP_OP (mx_el_ne, !=, S, , M, ) | |
2870 | 328 |
6708 | 329 #define SM_BOOL_OP_DECLS(S, M, API) \ |
330 BOOL_OP_DECL (mx_el_and, S, M, API); \ | |
331 BOOL_OP_DECL (mx_el_or, S, M, API); \ | |
2870 | 332 |
5030 | 333 #define SM_BOOL_OP(F, OP, S, M, LHS_ZERO, RHS_ZERO) \ |
2870 | 334 boolMatrix \ |
335 F (const S& s, const M& m) \ | |
336 { \ | |
337 boolMatrix r; \ | |
338 \ | |
339 int nr = m.rows (); \ | |
340 int nc = m.cols (); \ | |
341 \ | |
342 if (nr != 0 && nc != 0) \ | |
343 { \ | |
344 r.resize (nr, nc); \ | |
345 \ | |
7922
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
346 if (xisnan (s)) \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
347 gripe_nan_to_logical_conversion (); \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
348 else \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
349 { \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
350 for (int j = 0; j < nc; j++) \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
351 for (int i = 0; i < nr; i++) \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
352 if (xisnan (m.elem(i, j))) \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
353 { \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
354 gripe_nan_to_logical_conversion (); \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
355 return r; \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
356 } \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
357 else \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
358 r.elem(i, j) = (s != LHS_ZERO) OP (m.elem(i, j) != RHS_ZERO); \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
359 } \ |
2870 | 360 } \ |
361 \ | |
362 return r; \ | |
363 } | |
364 | |
5030 | 365 #define SM_BOOL_OPS2(S, M, LHS_ZERO, RHS_ZERO) \ |
366 SM_BOOL_OP (mx_el_and, &&, S, M, LHS_ZERO, RHS_ZERO) \ | |
367 SM_BOOL_OP (mx_el_or, ||, S, M, LHS_ZERO, RHS_ZERO) | |
368 | |
3504 | 369 #define SM_BOOL_OPS(S, M, ZERO) \ |
5030 | 370 SM_BOOL_OPS2(S, M, ZERO, ZERO) |
2870 | 371 |
6708 | 372 #define SM_OP_DECLS(R, S, M, API) \ |
373 SM_BIN_OP_DECLS (R, S, M, API) \ | |
374 SM_CMP_OP_DECLS (S, M, API) \ | |
375 SM_BOOL_OP_DECLS (S, M, API) \ | |
2870 | 376 |
377 // matrix by matrix operations. | |
378 | |
6708 | 379 #define MM_BIN_OP_DECLS(R, M1, M2, API) \ |
380 BIN_OP_DECL (R, operator +, M1, M2, API); \ | |
381 BIN_OP_DECL (R, operator -, M1, M2, API); \ | |
382 BIN_OP_DECL (R, product, M1, M2, API); \ | |
383 BIN_OP_DECL (R, quotient, M1, M2, API); | |
2870 | 384 |
385 #define MM_BIN_OP(R, OP, M1, M2, F) \ | |
2829 | 386 R \ |
387 OP (const M1& m1, const M2& m2) \ | |
388 { \ | |
389 R r; \ | |
390 \ | |
391 int m1_nr = m1.rows (); \ | |
392 int m1_nc = m1.cols (); \ | |
393 \ | |
394 int m2_nr = m2.rows (); \ | |
395 int m2_nc = m2.cols (); \ | |
396 \ | |
397 if (m1_nr != m2_nr || m1_nc != m2_nc) \ | |
398 gripe_nonconformant (#OP, m1_nr, m1_nc, m2_nr, m2_nc); \ | |
399 else \ | |
400 { \ | |
401 r.resize (m1_nr, m1_nc); \ | |
402 \ | |
403 if (m1_nr > 0 && m1_nc > 0) \ | |
404 F ## _vv (r.fortran_vec (), m1.data (), m2.data (), m1_nr * m1_nc); \ | |
405 } \ | |
406 \ | |
407 return r; \ | |
408 } | |
409 | |
2870 | 410 #define MM_BIN_OPS(R, M1, M2) \ |
3769 | 411 MM_BIN_OP (R, operator +, M1, M2, mx_inline_add) \ |
412 MM_BIN_OP (R, operator -, M1, M2, mx_inline_subtract) \ | |
413 MM_BIN_OP (R, product, M1, M2, mx_inline_multiply) \ | |
414 MM_BIN_OP (R, quotient, M1, M2, mx_inline_divide) | |
2870 | 415 |
6708 | 416 #define MM_CMP_OP_DECLS(M1, M2, API) \ |
417 CMP_OP_DECL (mx_el_lt, M1, M2, API); \ | |
418 CMP_OP_DECL (mx_el_le, M1, M2, API); \ | |
419 CMP_OP_DECL (mx_el_ge, M1, M2, API); \ | |
420 CMP_OP_DECL (mx_el_gt, M1, M2, API); \ | |
421 CMP_OP_DECL (mx_el_eq, M1, M2, API); \ | |
422 CMP_OP_DECL (mx_el_ne, M1, M2, API); | |
2870 | 423 |
4826 | 424 #define MM_CMP_OP(F, OP, M1, C1, M2, C2) \ |
2870 | 425 boolMatrix \ |
426 F (const M1& m1, const M2& m2) \ | |
427 { \ | |
428 boolMatrix r; \ | |
429 \ | |
430 int m1_nr = m1.rows (); \ | |
431 int m1_nc = m1.cols (); \ | |
432 \ | |
433 int m2_nr = m2.rows (); \ | |
434 int m2_nc = m2.cols (); \ | |
435 \ | |
436 if (m1_nr == m2_nr && m1_nc == m2_nc) \ | |
437 { \ | |
4826 | 438 r.resize (m1_nr, m1_nc); \ |
2870 | 439 \ |
4826 | 440 for (int j = 0; j < m1_nc; j++) \ |
441 for (int i = 0; i < m1_nr; i++) \ | |
442 r.elem(i, j) = C1 (m1.elem(i, j)) OP C2 (m2.elem(i, j)); \ | |
2870 | 443 } \ |
444 else \ | |
4826 | 445 gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \ |
2870 | 446 \ |
447 return r; \ | |
448 } | |
2829 | 449 |
2870 | 450 #define MM_CMP_OPS(M1, C1, M2, C2) \ |
4826 | 451 MM_CMP_OP (mx_el_lt, <, M1, C1, M2, C2) \ |
452 MM_CMP_OP (mx_el_le, <=, M1, C1, M2, C2) \ | |
453 MM_CMP_OP (mx_el_ge, >=, M1, C1, M2, C2) \ | |
454 MM_CMP_OP (mx_el_gt, >, M1, C1, M2, C2) \ | |
455 MM_CMP_OP (mx_el_eq, ==, M1, , M2, ) \ | |
456 MM_CMP_OP (mx_el_ne, !=, M1, , M2, ) | |
2870 | 457 |
6708 | 458 #define MM_BOOL_OP_DECLS(M1, M2, API) \ |
459 BOOL_OP_DECL (mx_el_and, M1, M2, API); \ | |
460 BOOL_OP_DECL (mx_el_or, M1, M2, API); | |
2870 | 461 |
5030 | 462 #define MM_BOOL_OP(F, OP, M1, M2, LHS_ZERO, RHS_ZERO) \ |
2870 | 463 boolMatrix \ |
464 F (const M1& m1, const M2& m2) \ | |
465 { \ | |
466 boolMatrix r; \ | |
467 \ | |
468 int m1_nr = m1.rows (); \ | |
469 int m1_nc = m1.cols (); \ | |
470 \ | |
471 int m2_nr = m2.rows (); \ | |
472 int m2_nc = m2.cols (); \ | |
473 \ | |
474 if (m1_nr == m2_nr && m1_nc == m2_nc) \ | |
475 { \ | |
476 if (m1_nr != 0 || m1_nc != 0) \ | |
477 { \ | |
478 r.resize (m1_nr, m1_nc); \ | |
479 \ | |
480 for (int j = 0; j < m1_nc; j++) \ | |
481 for (int i = 0; i < m1_nr; i++) \ | |
7922
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
482 if (xisnan (m1.elem(i, j)) || xisnan (m2.elem(i, j))) \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
483 { \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
484 gripe_nan_to_logical_conversion (); \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
485 return r; \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
486 } \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
487 else \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
488 r.elem(i, j) = (m1.elem(i, j) != LHS_ZERO) \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
489 OP (m2.elem(i, j) != RHS_ZERO); \ |
2870 | 490 } \ |
491 } \ | |
492 else \ | |
493 { \ | |
494 if ((m1_nr != 0 || m1_nc != 0) && (m2_nr != 0 || m2_nc != 0)) \ | |
495 gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \ | |
496 } \ | |
497 \ | |
498 return r; \ | |
499 } | |
500 | |
5030 | 501 #define MM_BOOL_OPS2(M1, M2, LHS_ZERO, RHS_ZERO) \ |
502 MM_BOOL_OP (mx_el_and, &&, M1, M2, LHS_ZERO, RHS_ZERO) \ | |
503 MM_BOOL_OP (mx_el_or, ||, M1, M2, LHS_ZERO, RHS_ZERO) | |
504 | |
3504 | 505 #define MM_BOOL_OPS(M1, M2, ZERO) \ |
5030 | 506 MM_BOOL_OPS2(M1, M2, ZERO, ZERO) |
2870 | 507 |
6708 | 508 #define MM_OP_DECLS(R, M1, M2, API) \ |
509 MM_BIN_OP_DECLS (R, M1, M2, API) \ | |
510 MM_CMP_OP_DECLS (M1, M2, API) \ | |
511 MM_BOOL_OP_DECLS (M1, M2, API) | |
2870 | 512 |
4543 | 513 // N-d matrix by scalar operations. |
514 | |
6708 | 515 #define NDS_BIN_OP_DECLS(R, ND, S, API) \ |
516 BIN_OP_DECL (R, operator +, ND, S, API); \ | |
517 BIN_OP_DECL (R, operator -, ND, S, API); \ | |
518 BIN_OP_DECL (R, operator *, ND, S, API); \ | |
519 BIN_OP_DECL (R, operator /, ND, S, API); | |
4543 | 520 |
521 #define NDS_BIN_OP(R, OP, ND, S, F) \ | |
522 R \ | |
523 OP (const ND& m, const S& s) \ | |
524 { \ | |
525 R r (m.dims ()); \ | |
526 \ | |
527 int len = m.length (); \ | |
528 \ | |
529 if (len > 0) \ | |
530 F ## _vs (r.fortran_vec (), m.data (), len, s); \ | |
531 \ | |
532 return r; \ | |
533 } | |
534 | |
535 #define NDS_BIN_OPS(R, ND, S) \ | |
536 NDS_BIN_OP (R, operator +, ND, S, mx_inline_add) \ | |
537 NDS_BIN_OP (R, operator -, ND, S, mx_inline_subtract) \ | |
538 NDS_BIN_OP (R, operator *, ND, S, mx_inline_multiply) \ | |
539 NDS_BIN_OP (R, operator /, ND, S, mx_inline_divide) | |
540 | |
6708 | 541 #define NDS_CMP_OP_DECLS(ND, S, API) \ |
542 NDCMP_OP_DECL (mx_el_lt, ND, S, API); \ | |
543 NDCMP_OP_DECL (mx_el_le, ND, S, API); \ | |
544 NDCMP_OP_DECL (mx_el_ge, ND, S, API); \ | |
545 NDCMP_OP_DECL (mx_el_gt, ND, S, API); \ | |
546 NDCMP_OP_DECL (mx_el_eq, ND, S, API); \ | |
547 NDCMP_OP_DECL (mx_el_ne, ND, S, API); | |
4543 | 548 |
4826 | 549 #define NDS_CMP_OP(F, OP, ND, NDC, S, SC) \ |
4543 | 550 boolNDArray \ |
551 F (const ND& m, const S& s) \ | |
552 { \ | |
553 boolNDArray r; \ | |
554 \ | |
555 int len = m.length (); \ | |
556 \ | |
4826 | 557 r.resize (m.dims ()); \ |
4543 | 558 \ |
4826 | 559 for (int i = 0; i < len; i++) \ |
560 r.elem(i) = NDC (m.elem(i)) OP SC (s); \ | |
4543 | 561 \ |
562 return r; \ | |
563 } | |
564 | |
565 #define NDS_CMP_OPS(ND, NDC, S, SC) \ | |
4826 | 566 NDS_CMP_OP (mx_el_lt, <, ND, NDC, S, SC) \ |
567 NDS_CMP_OP (mx_el_le, <=, ND, NDC, S, SC) \ | |
568 NDS_CMP_OP (mx_el_ge, >=, ND, NDC, S, SC) \ | |
569 NDS_CMP_OP (mx_el_gt, >, ND, NDC, S, SC) \ | |
570 NDS_CMP_OP (mx_el_eq, ==, ND, , S, ) \ | |
571 NDS_CMP_OP (mx_el_ne, !=, ND, , S, ) | |
4543 | 572 |
6119 | 573 #define NDS_CMP_OP1(F, OP, ND, NDC, S, SC, SPEC) \ |
574 boolNDArray \ | |
575 F (const ND& m, const S& s) \ | |
576 { \ | |
577 boolNDArray r; \ | |
578 \ | |
579 int len = m.length (); \ | |
580 \ | |
581 r.resize (m.dims ()); \ | |
582 \ | |
583 for (int i = 0; i < len; i++) \ | |
584 r.elem(i) = operator OP <SPEC> (NDC (m.elem(i)), SC (s)); \ | |
585 \ | |
586 return r; \ | |
587 } | |
588 | |
589 #define NDS_CMP_OPS1(ND, NDC, S, SC, SPEC) \ | |
590 NDS_CMP_OP1 (mx_el_lt, <, ND, NDC, S, SC, SPEC) \ | |
591 NDS_CMP_OP1 (mx_el_le, <=, ND, NDC, S, SC, SPEC) \ | |
592 NDS_CMP_OP1 (mx_el_ge, >=, ND, NDC, S, SC, SPEC) \ | |
593 NDS_CMP_OP1 (mx_el_gt, >, ND, NDC, S, SC, SPEC) \ | |
594 NDS_CMP_OP1 (mx_el_eq, ==, ND, , S, , SPEC) \ | |
595 NDS_CMP_OP1 (mx_el_ne, !=, ND, , S, , SPEC) | |
596 | |
597 #define NDS_CMP_OP2(F, OP, ND, NDC, S, SC, SPEC1, SPEC2) \ | |
598 boolNDArray \ | |
599 F (const ND& m, const S& s) \ | |
600 { \ | |
601 boolNDArray r; \ | |
602 \ | |
603 int len = m.length (); \ | |
604 \ | |
605 r.resize (m.dims ()); \ | |
606 \ | |
607 for (int i = 0; i < len; i++) \ | |
608 r.elem(i) = operator OP <SPEC1,SPEC2> (NDC (m.elem(i)), SC (s)); \ | |
609 \ | |
610 return r; \ | |
611 } | |
612 | |
613 #define NDS_CMP_OPS2(ND, NDC, S, SC, SPEC1, SPEC2) \ | |
614 NDS_CMP_OP2 (mx_el_lt, <, ND, NDC, S, SC, SPEC1, SPEC2) \ | |
615 NDS_CMP_OP2 (mx_el_le, <=, ND, NDC, S, SC, SPEC1, SPEC2) \ | |
616 NDS_CMP_OP2 (mx_el_ge, >=, ND, NDC, S, SC, SPEC1, SPEC2) \ | |
617 NDS_CMP_OP2 (mx_el_gt, >, ND, NDC, S, SC, SPEC1, SPEC2) \ | |
618 NDS_CMP_OP2 (mx_el_eq, ==, ND, , S, , SPEC1, SPEC2) \ | |
619 NDS_CMP_OP2 (mx_el_ne, !=, ND, , S, , SPEC1, SPEC2) | |
620 | |
6708 | 621 #define NDS_BOOL_OP_DECLS(ND, S, API) \ |
622 NDBOOL_OP_DECL (mx_el_and, ND, S, API); \ | |
623 NDBOOL_OP_DECL (mx_el_or, ND, S, API); | |
4543 | 624 |
5030 | 625 #define NDS_BOOL_OP(F, OP, ND, S, LHS_ZERO, RHS_ZERO) \ |
4543 | 626 boolNDArray \ |
627 F (const ND& m, const S& s) \ | |
628 { \ | |
629 boolNDArray r; \ | |
630 \ | |
631 int len = m.length (); \ | |
632 \ | |
633 if (len > 0) \ | |
634 { \ | |
635 r.resize (m.dims ()); \ | |
636 \ | |
7922
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
637 if (xisnan (s)) \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
638 gripe_nan_to_logical_conversion (); \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
639 else \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
640 { \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
641 for (int i = 0; i < len; i++) \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
642 if (xisnan (m.elem(i))) \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
643 { \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
644 gripe_nan_to_logical_conversion (); \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
645 return r; \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
646 } \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
647 else \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
648 r.elem(i) = (m.elem(i) != LHS_ZERO) OP (s != RHS_ZERO); \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
649 } \ |
4543 | 650 } \ |
651 \ | |
652 return r; \ | |
653 } | |
654 | |
5030 | 655 #define NDS_BOOL_OPS2(ND, S, LHS_ZERO, RHS_ZERO) \ |
656 NDS_BOOL_OP (mx_el_and, &&, ND, S, LHS_ZERO, RHS_ZERO) \ | |
657 NDS_BOOL_OP (mx_el_or, ||, ND, S, LHS_ZERO, RHS_ZERO) | |
658 | |
4543 | 659 #define NDS_BOOL_OPS(ND, S, ZERO) \ |
5030 | 660 NDS_BOOL_OPS2(ND, S, ZERO, ZERO) |
4543 | 661 |
6708 | 662 #define NDS_OP_DECLS(R, ND, S, API) \ |
663 NDS_BIN_OP_DECLS (R, ND, S, API) \ | |
664 NDS_CMP_OP_DECLS (ND, S, API) \ | |
665 NDS_BOOL_OP_DECLS (ND, S, API) | |
4543 | 666 |
667 // scalar by N-d matrix operations. | |
668 | |
6708 | 669 #define SND_BIN_OP_DECLS(R, S, ND, API) \ |
670 BIN_OP_DECL (R, operator +, S, ND, API); \ | |
671 BIN_OP_DECL (R, operator -, S, ND, API); \ | |
672 BIN_OP_DECL (R, operator *, S, ND, API); \ | |
673 BIN_OP_DECL (R, operator /, S, ND, API); | |
4543 | 674 |
675 #define SND_BIN_OP(R, OP, S, ND, F) \ | |
676 R \ | |
677 OP (const S& s, const ND& m) \ | |
678 { \ | |
679 R r (m.dims ()); \ | |
680 \ | |
681 int len = m.length (); \ | |
682 \ | |
683 if (len > 0) \ | |
684 F ## _sv (r.fortran_vec (), s, m.data (), len); \ | |
685 \ | |
686 return r; \ | |
687 } | |
688 | |
689 #define SND_BIN_OPS(R, S, ND) \ | |
690 SND_BIN_OP (R, operator +, S, ND, mx_inline_add) \ | |
691 SND_BIN_OP (R, operator -, S, ND, mx_inline_subtract) \ | |
692 SND_BIN_OP (R, operator *, S, ND, mx_inline_multiply) \ | |
693 SND_BIN_OP (R, operator /, S, ND, mx_inline_divide) | |
694 | |
6708 | 695 #define SND_CMP_OP_DECLS(S, ND, API) \ |
696 NDCMP_OP_DECL (mx_el_lt, S, ND, API); \ | |
697 NDCMP_OP_DECL (mx_el_le, S, ND, API); \ | |
698 NDCMP_OP_DECL (mx_el_ge, S, ND, API); \ | |
699 NDCMP_OP_DECL (mx_el_gt, S, ND, API); \ | |
700 NDCMP_OP_DECL (mx_el_eq, S, ND, API); \ | |
701 NDCMP_OP_DECL (mx_el_ne, S, ND, API); | |
4543 | 702 |
4826 | 703 #define SND_CMP_OP(F, OP, S, SC, ND, NDC) \ |
4543 | 704 boolNDArray \ |
705 F (const S& s, const ND& m) \ | |
706 { \ | |
707 boolNDArray r; \ | |
708 \ | |
709 int len = m.length (); \ | |
710 \ | |
4826 | 711 r.resize (m.dims ()); \ |
4543 | 712 \ |
4826 | 713 for (int i = 0; i < len; i++) \ |
714 r.elem(i) = SC (s) OP NDC (m.elem(i)); \ | |
4543 | 715 \ |
716 return r; \ | |
717 } | |
718 | |
719 #define SND_CMP_OPS(S, CS, ND, CND) \ | |
4826 | 720 SND_CMP_OP (mx_el_lt, <, S, CS, ND, CND) \ |
721 SND_CMP_OP (mx_el_le, <=, S, CS, ND, CND) \ | |
722 SND_CMP_OP (mx_el_ge, >=, S, CS, ND, CND) \ | |
723 SND_CMP_OP (mx_el_gt, >, S, CS, ND, CND) \ | |
724 SND_CMP_OP (mx_el_eq, ==, S, , ND, ) \ | |
725 SND_CMP_OP (mx_el_ne, !=, S, , ND, ) | |
4543 | 726 |
6119 | 727 #define SND_CMP_OP1(F, OP, S, SC, ND, NDC, SPEC) \ |
728 boolNDArray \ | |
729 F (const S& s, const ND& m) \ | |
730 { \ | |
731 boolNDArray r; \ | |
732 \ | |
733 int len = m.length (); \ | |
734 \ | |
735 r.resize (m.dims ()); \ | |
736 \ | |
737 for (int i = 0; i < len; i++) \ | |
738 r.elem(i) = operator OP <SPEC> (SC (s), NDC (m.elem(i))); \ | |
739 \ | |
740 return r; \ | |
741 } | |
742 | |
743 #define SND_CMP_OPS1(S, CS, ND, CND, SPEC) \ | |
744 SND_CMP_OP1 (mx_el_lt, <, S, CS, ND, CND, SPEC) \ | |
745 SND_CMP_OP1 (mx_el_le, <=, S, CS, ND, CND, SPEC) \ | |
746 SND_CMP_OP1 (mx_el_ge, >=, S, CS, ND, CND, SPEC) \ | |
747 SND_CMP_OP1 (mx_el_gt, >, S, CS, ND, CND, SPEC) \ | |
748 SND_CMP_OP1 (mx_el_eq, ==, S, , ND, , SPEC) \ | |
749 SND_CMP_OP1 (mx_el_ne, !=, S, , ND, , SPEC) | |
750 | |
751 #define SND_CMP_OP2(F, OP, S, SC, ND, NDC, SPEC1, SPEC2) \ | |
752 boolNDArray \ | |
753 F (const S& s, const ND& m) \ | |
754 { \ | |
755 boolNDArray r; \ | |
756 \ | |
757 int len = m.length (); \ | |
758 \ | |
759 r.resize (m.dims ()); \ | |
760 \ | |
761 for (int i = 0; i < len; i++) \ | |
762 r.elem(i) = operator OP <SPEC1, SPEC2> (SC (s), NDC (m.elem(i))); \ | |
763 \ | |
764 return r; \ | |
765 } | |
766 | |
767 #define SND_CMP_OPS2(S, CS, ND, CND, SPEC1, SPEC2) \ | |
768 SND_CMP_OP2 (mx_el_lt, <, S, CS, ND, CND, SPEC1, SPEC2) \ | |
769 SND_CMP_OP2 (mx_el_le, <=, S, CS, ND, CND, SPEC1, SPEC2) \ | |
770 SND_CMP_OP2 (mx_el_ge, >=, S, CS, ND, CND, SPEC1, SPEC2) \ | |
771 SND_CMP_OP2 (mx_el_gt, >, S, CS, ND, CND, SPEC1, SPEC2) \ | |
772 SND_CMP_OP2 (mx_el_eq, ==, S, , ND, , SPEC1, SPEC2) \ | |
773 SND_CMP_OP2 (mx_el_ne, !=, S, , ND, , SPEC1, SPEC2) | |
774 | |
6708 | 775 #define SND_BOOL_OP_DECLS(S, ND, API) \ |
776 NDBOOL_OP_DECL (mx_el_and, S, ND, API); \ | |
777 NDBOOL_OP_DECL (mx_el_or, S, ND, API); | |
4543 | 778 |
5030 | 779 #define SND_BOOL_OP(F, OP, S, ND, LHS_ZERO, RHS_ZERO) \ |
4543 | 780 boolNDArray \ |
781 F (const S& s, const ND& m) \ | |
782 { \ | |
783 boolNDArray r; \ | |
784 \ | |
785 int len = m.length (); \ | |
786 \ | |
787 if (len > 0) \ | |
788 { \ | |
789 r.resize (m.dims ()); \ | |
790 \ | |
7922
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
791 if (xisnan (s)) \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
792 gripe_nan_to_logical_conversion (); \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
793 else \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
794 { \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
795 for (int i = 0; i < len; i++) \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
796 if (xisnan (m.elem(i))) \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
797 { \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
798 gripe_nan_to_logical_conversion (); \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
799 return r; \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
800 } \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
801 else \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
802 r.elem(i) = (s != LHS_ZERO) OP (m.elem(i) != RHS_ZERO); \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
803 } \ |
4543 | 804 } \ |
805 \ | |
806 return r; \ | |
807 } | |
808 | |
5030 | 809 #define SND_BOOL_OPS2(S, ND, LHS_ZERO, RHS_ZERO) \ |
810 SND_BOOL_OP (mx_el_and, &&, S, ND, LHS_ZERO, RHS_ZERO) \ | |
811 SND_BOOL_OP (mx_el_or, ||, S, ND, LHS_ZERO, RHS_ZERO) | |
812 | |
4543 | 813 #define SND_BOOL_OPS(S, ND, ZERO) \ |
5030 | 814 SND_BOOL_OPS2(S, ND, ZERO, ZERO) |
4543 | 815 |
6708 | 816 #define SND_OP_DECLS(R, S, ND, API) \ |
817 SND_BIN_OP_DECLS (R, S, ND, API) \ | |
818 SND_CMP_OP_DECLS (S, ND, API) \ | |
819 SND_BOOL_OP_DECLS (S, ND, API) | |
4543 | 820 |
821 // N-d matrix by N-d matrix operations. | |
822 | |
6708 | 823 #define NDND_BIN_OP_DECLS(R, ND1, ND2, API) \ |
824 BIN_OP_DECL (R, operator +, ND1, ND2, API); \ | |
825 BIN_OP_DECL (R, operator -, ND1, ND2, API); \ | |
826 BIN_OP_DECL (R, product, ND1, ND2, API); \ | |
827 BIN_OP_DECL (R, quotient, ND1, ND2, API); | |
4543 | 828 |
829 #define NDND_BIN_OP(R, OP, ND1, ND2, F) \ | |
830 R \ | |
831 OP (const ND1& m1, const ND2& m2) \ | |
832 { \ | |
833 R r; \ | |
834 \ | |
835 dim_vector m1_dims = m1.dims (); \ | |
836 dim_vector m2_dims = m2.dims (); \ | |
837 \ | |
838 if (m1_dims != m2_dims) \ | |
839 gripe_nonconformant (#OP, m1_dims, m2_dims); \ | |
840 else \ | |
841 { \ | |
842 r.resize (m1_dims); \ | |
843 \ | |
844 int len = m1.length (); \ | |
845 \ | |
846 if (len > 0) \ | |
847 F ## _vv (r.fortran_vec (), m1.data (), m2.data (), len); \ | |
848 } \ | |
849 \ | |
850 return r; \ | |
851 } | |
852 | |
853 #define NDND_BIN_OPS(R, ND1, ND2) \ | |
854 NDND_BIN_OP (R, operator +, ND1, ND2, mx_inline_add) \ | |
855 NDND_BIN_OP (R, operator -, ND1, ND2, mx_inline_subtract) \ | |
856 NDND_BIN_OP (R, product, ND1, ND2, mx_inline_multiply) \ | |
857 NDND_BIN_OP (R, quotient, ND1, ND2, mx_inline_divide) | |
858 | |
6708 | 859 #define NDND_CMP_OP_DECLS(ND1, ND2, API) \ |
860 NDCMP_OP_DECL (mx_el_lt, ND1, ND2, API); \ | |
861 NDCMP_OP_DECL (mx_el_le, ND1, ND2, API); \ | |
862 NDCMP_OP_DECL (mx_el_ge, ND1, ND2, API); \ | |
863 NDCMP_OP_DECL (mx_el_gt, ND1, ND2, API); \ | |
864 NDCMP_OP_DECL (mx_el_eq, ND1, ND2, API); \ | |
865 NDCMP_OP_DECL (mx_el_ne, ND1, ND2, API); | |
4543 | 866 |
4826 | 867 #define NDND_CMP_OP(F, OP, ND1, C1, ND2, C2) \ |
4543 | 868 boolNDArray \ |
869 F (const ND1& m1, const ND2& m2) \ | |
870 { \ | |
871 boolNDArray r; \ | |
872 \ | |
873 dim_vector m1_dims = m1.dims (); \ | |
874 dim_vector m2_dims = m2.dims (); \ | |
875 \ | |
876 if (m1_dims == m2_dims) \ | |
877 { \ | |
4826 | 878 r.resize (m1_dims); \ |
4543 | 879 \ |
4826 | 880 for (int i = 0; i < m1.length (); i++) \ |
881 r.elem(i) = C1 (m1.elem(i)) OP C2 (m2.elem(i)); \ | |
4543 | 882 } \ |
883 else \ | |
4826 | 884 gripe_nonconformant (#F, m1_dims, m2_dims); \ |
4543 | 885 \ |
886 return r; \ | |
887 } | |
888 | |
889 #define NDND_CMP_OPS(ND1, C1, ND2, C2) \ | |
4826 | 890 NDND_CMP_OP (mx_el_lt, <, ND1, C1, ND2, C2) \ |
891 NDND_CMP_OP (mx_el_le, <=, ND1, C1, ND2, C2) \ | |
892 NDND_CMP_OP (mx_el_ge, >=, ND1, C1, ND2, C2) \ | |
893 NDND_CMP_OP (mx_el_gt, >, ND1, C1, ND2, C2) \ | |
894 NDND_CMP_OP (mx_el_eq, ==, ND1, , ND2, ) \ | |
895 NDND_CMP_OP (mx_el_ne, !=, ND1, , ND2, ) | |
4543 | 896 |
6708 | 897 #define NDND_BOOL_OP_DECLS(ND1, ND2, API) \ |
898 NDBOOL_OP_DECL (mx_el_and, ND1, ND2, API); \ | |
899 NDBOOL_OP_DECL (mx_el_or, ND1, ND2, API); | |
4543 | 900 |
5030 | 901 #define NDND_BOOL_OP(F, OP, ND1, ND2, LHS_ZERO, RHS_ZERO) \ |
4543 | 902 boolNDArray \ |
903 F (const ND1& m1, const ND2& m2) \ | |
904 { \ | |
905 boolNDArray r; \ | |
906 \ | |
907 dim_vector m1_dims = m1.dims (); \ | |
908 dim_vector m2_dims = m2.dims (); \ | |
909 \ | |
910 if (m1_dims == m2_dims) \ | |
911 { \ | |
912 if (! m1_dims.all_zero ()) \ | |
913 { \ | |
914 r.resize (m1_dims); \ | |
915 \ | |
916 for (int i = 0; i < m1.length (); i++) \ | |
7922
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
917 if (xisnan (m1.elem(i)) || xisnan (m2.elem(i))) \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
918 { \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
919 gripe_nan_to_logical_conversion (); \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
920 return r; \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
921 } \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
922 else \ |
935be827eaf8
error for NaN values in & and | expressions
John W. Eaton <jwe@octave.org>
parents:
7789
diff
changeset
|
923 r.elem(i) = (m1.elem(i) != LHS_ZERO) OP (m2.elem(i) != RHS_ZERO); \ |
4543 | 924 } \ |
925 } \ | |
926 else \ | |
927 gripe_nonconformant (#F, m1_dims, m2_dims); \ | |
928 \ | |
929 return r; \ | |
930 } | |
931 | |
5030 | 932 #define NDND_BOOL_OPS2(ND1, ND2, LHS_ZERO, RHS_ZERO) \ |
933 NDND_BOOL_OP (mx_el_and, &&, ND1, ND2, LHS_ZERO, RHS_ZERO) \ | |
934 NDND_BOOL_OP (mx_el_or, ||, ND1, ND2, LHS_ZERO, RHS_ZERO) | |
935 | |
4543 | 936 #define NDND_BOOL_OPS(ND1, ND2, ZERO) \ |
5030 | 937 NDND_BOOL_OPS2(ND1, ND2, ZERO, ZERO) |
4543 | 938 |
6708 | 939 #define NDND_OP_DECLS(R, ND1, ND2, API) \ |
940 NDND_BIN_OP_DECLS (R, ND1, ND2, API) \ | |
941 NDND_CMP_OP_DECLS (ND1, ND2, API) \ | |
942 NDND_BOOL_OP_DECLS (ND1, ND2, API) | |
4543 | 943 |
2870 | 944 // scalar by diagonal matrix operations. |
945 | |
6708 | 946 #define SDM_BIN_OP_DECLS(R, S, DM, API) \ |
947 BIN_OP_DECL (R, operator +, S, DM, API); \ | |
948 BIN_OP_DECL (R, operator -, S, DM, API); | |
2870 | 949 |
950 #define SDM_BIN_OP(R, OP, S, DM, OPEQ) \ | |
2829 | 951 R \ |
952 OP (const S& s, const DM& dm) \ | |
953 { \ | |
954 int nr = dm.rows (); \ | |
955 int nc = dm.cols (); \ | |
956 \ | |
957 R r (nr, nc, s); \ | |
958 \ | |
4543 | 959 for (int i = 0; i < dm.length (); i++) \ |
2870 | 960 r.elem(i, i) OPEQ dm.elem(i, i); \ |
2829 | 961 \ |
962 return r; \ | |
963 } | |
964 | |
2870 | 965 #define SDM_BIN_OPS(R, S, DM) \ |
966 SDM_BIN_OP (R, operator +, S, DM, +=) \ | |
967 SDM_BIN_OP (R, operator -, S, DM, -=) | |
968 | |
6708 | 969 #define SDM_OP_DECLS(R, S, DM, API) \ |
970 SDM_BIN_OP_DECLS(R, S, DM, API) | |
2829 | 971 |
2870 | 972 // diagonal matrix by scalar operations. |
973 | |
6708 | 974 #define DMS_BIN_OP_DECLS(R, DM, S, API) \ |
975 BIN_OP_DECL (R, operator +, DM, S, API); \ | |
976 BIN_OP_DECL (R, operator -, DM, S, API); | |
2870 | 977 |
978 #define DMS_BIN_OP(R, OP, DM, S, SGN) \ | |
2829 | 979 R \ |
980 OP (const DM& dm, const S& s) \ | |
981 { \ | |
982 int nr = dm.rows (); \ | |
983 int nc = dm.cols (); \ | |
984 \ | |
985 R r (nr, nc, SGN s); \ | |
986 \ | |
4543 | 987 for (int i = 0; i < dm.length (); i++) \ |
2870 | 988 r.elem(i, i) += dm.elem(i, i); \ |
2829 | 989 \ |
990 return r; \ | |
991 } | |
992 | |
2870 | 993 #define DMS_BIN_OPS(R, DM, S) \ |
994 DMS_BIN_OP (R, operator +, DM, S, ) \ | |
995 DMS_BIN_OP (R, operator -, DM, S, -) | |
996 | |
6708 | 997 #define DMS_OP_DECLS(R, DM, S, API) \ |
998 DMS_BIN_OP_DECLS(R, DM, S, API) | |
2829 | 999 |
2870 | 1000 // matrix by diagonal matrix operations. |
1001 | |
6708 | 1002 #define MDM_BIN_OP_DECLS(R, M, DM, API) \ |
1003 BIN_OP_DECL (R, operator +, M, DM, API); \ | |
1004 BIN_OP_DECL (R, operator -, M, DM, API); \ | |
1005 BIN_OP_DECL (R, operator *, M, DM, API); | |
2870 | 1006 |
1007 #define MDM_BIN_OP(R, OP, M, DM, OPEQ) \ | |
2829 | 1008 R \ |
1009 OP (const M& m, const DM& dm) \ | |
1010 { \ | |
1011 R r; \ | |
1012 \ | |
1013 int m_nr = m.rows (); \ | |
1014 int m_nc = m.cols (); \ | |
1015 \ | |
1016 int dm_nr = dm.rows (); \ | |
1017 int dm_nc = dm.cols (); \ | |
1018 \ | |
1019 if (m_nr != dm_nr || m_nc != dm_nc) \ | |
1020 gripe_nonconformant (#OP, m_nr, m_nc, dm_nr, dm_nc); \ | |
1021 else \ | |
1022 { \ | |
1023 r.resize (m_nr, m_nc); \ | |
1024 \ | |
1025 if (m_nr > 0 && m_nc > 0) \ | |
1026 { \ | |
3585 | 1027 r = R (m); \ |
2829 | 1028 \ |
1029 int len = dm.length (); \ | |
1030 \ | |
1031 for (int i = 0; i < len; i++) \ | |
2870 | 1032 r.elem(i, i) OPEQ dm.elem(i, i); \ |
2829 | 1033 } \ |
1034 } \ | |
1035 \ | |
1036 return r; \ | |
1037 } | |
1038 | |
5030 | 1039 #define MDM_MULTIPLY_OP(R, M, DM, R_ZERO) \ |
2829 | 1040 R \ |
1041 operator * (const M& m, const DM& dm) \ | |
1042 { \ | |
1043 R r; \ | |
1044 \ | |
1045 int m_nr = m.rows (); \ | |
1046 int m_nc = m.cols (); \ | |
1047 \ | |
1048 int dm_nr = dm.rows (); \ | |
1049 int dm_nc = dm.cols (); \ | |
1050 \ | |
1051 if (m_nc != dm_nr) \ | |
1052 gripe_nonconformant ("operator *", m_nr, m_nc, dm_nr, dm_nc); \ | |
1053 else \ | |
1054 { \ | |
8366
8b1a2555c4e2
implement diagonal matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
7922
diff
changeset
|
1055 r = R (m_nr, dm_nc); \ |
2829 | 1056 \ |
3176 | 1057 if (m_nr > 0 && m_nc > 0 && dm_nc > 0) \ |
2829 | 1058 { \ |
4543 | 1059 int len = dm.length (); \ |
1060 \ | |
1061 for (int j = 0; j < len; j++) \ | |
2829 | 1062 { \ |
8366
8b1a2555c4e2
implement diagonal matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
7922
diff
changeset
|
1063 const DM::element_type djj = dm.elem (j, j); \ |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7189
diff
changeset
|
1064 for (int i = 0; i < m_nr; i++) \ |
8366
8b1a2555c4e2
implement diagonal matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
7922
diff
changeset
|
1065 r.xelem (i, j) = djj * m.elem (i, j); \ |
2829 | 1066 } \ |
1067 } \ | |
1068 } \ | |
1069 \ | |
1070 return r; \ | |
1071 } | |
1072 | |
5030 | 1073 #define MDM_BIN_OPS(R, M, DM, R_ZERO) \ |
2870 | 1074 MDM_BIN_OP (R, operator +, M, DM, +=) \ |
1075 MDM_BIN_OP (R, operator -, M, DM, -=) \ | |
5030 | 1076 MDM_MULTIPLY_OP (R, M, DM, R_ZERO) |
2829 | 1077 |
6708 | 1078 #define MDM_OP_DECLS(R, M, DM, API) \ |
1079 MDM_BIN_OP_DECLS(R, M, DM, API) | |
2870 | 1080 |
1081 // diagonal matrix by matrix operations. | |
1082 | |
6708 | 1083 #define DMM_BIN_OP_DECLS(R, DM, M, API) \ |
1084 BIN_OP_DECL (R, operator +, DM, M, API); \ | |
1085 BIN_OP_DECL (R, operator -, DM, M, API); \ | |
1086 BIN_OP_DECL (R, operator *, DM, M, API); | |
2870 | 1087 |
3585 | 1088 #define DMM_BIN_OP(R, OP, DM, M, OPEQ, PREOP) \ |
2829 | 1089 R \ |
1090 OP (const DM& dm, const M& m) \ | |
1091 { \ | |
1092 R r; \ | |
1093 \ | |
1094 int dm_nr = dm.rows (); \ | |
1095 int dm_nc = dm.cols (); \ | |
1096 \ | |
1097 int m_nr = m.rows (); \ | |
1098 int m_nc = m.cols (); \ | |
1099 \ | |
1100 if (dm_nr != m_nr || dm_nc != m_nc) \ | |
1101 gripe_nonconformant (#OP, dm_nr, dm_nc, m_nr, m_nc); \ | |
1102 else \ | |
1103 { \ | |
1104 if (m_nr > 0 && m_nc > 0) \ | |
1105 { \ | |
3585 | 1106 r = R (PREOP m); \ |
2829 | 1107 \ |
1108 int len = dm.length (); \ | |
1109 \ | |
1110 for (int i = 0; i < len; i++) \ | |
2870 | 1111 r.elem(i, i) OPEQ dm.elem(i, i); \ |
2829 | 1112 } \ |
1113 else \ | |
1114 r.resize (m_nr, m_nc); \ | |
1115 } \ | |
1116 \ | |
1117 return r; \ | |
1118 } | |
1119 | |
5030 | 1120 #define DMM_MULTIPLY_OP(R, DM, M, R_ZERO) \ |
2829 | 1121 R \ |
1122 operator * (const DM& dm, const M& m) \ | |
1123 { \ | |
1124 R r; \ | |
1125 \ | |
1126 int dm_nr = dm.rows (); \ | |
1127 int dm_nc = dm.cols (); \ | |
1128 \ | |
1129 int m_nr = m.rows (); \ | |
1130 int m_nc = m.cols (); \ | |
1131 \ | |
1132 if (dm_nc != m_nr) \ | |
1133 gripe_nonconformant ("operator *", dm_nr, dm_nc, m_nr, m_nc); \ | |
1134 else \ | |
1135 { \ | |
8366
8b1a2555c4e2
implement diagonal matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
7922
diff
changeset
|
1136 r = R (dm_nr, m_nc); \ |
2829 | 1137 \ |
1138 if (dm_nr > 0 && dm_nc > 0 && m_nc > 0) \ | |
1139 { \ | |
4543 | 1140 int len = dm.length (); \ |
1141 \ | |
1142 for (int i = 0; i < len; i++) \ | |
2829 | 1143 { \ |
7789
82be108cc558
First attempt at single precision tyeps
David Bateman <dbateman@free.fr>
parents:
7189
diff
changeset
|
1144 for (int j = 0; j < m_nc; j++) \ |
8366
8b1a2555c4e2
implement diagonal matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
7922
diff
changeset
|
1145 r.xelem (i, j) = dm.elem (i, i) * m.elem (i, j); \ |
2829 | 1146 } \ |
1147 } \ | |
1148 } \ | |
1149 \ | |
1150 return r; \ | |
1151 } | |
1152 | |
5030 | 1153 #define DMM_BIN_OPS(R, DM, M, R_ZERO) \ |
3585 | 1154 DMM_BIN_OP (R, operator +, DM, M, +=, ) \ |
1155 DMM_BIN_OP (R, operator -, DM, M, +=, -) \ | |
5030 | 1156 DMM_MULTIPLY_OP (R, DM, M, R_ZERO) |
2829 | 1157 |
6708 | 1158 #define DMM_OP_DECLS(R, DM, M, API) \ |
1159 DMM_BIN_OP_DECLS(R, DM, M, API) | |
2870 | 1160 |
1161 // diagonal matrix by diagonal matrix operations. | |
2829 | 1162 |
6708 | 1163 #define DMDM_BIN_OP_DECLS(R, DM1, DM2, API) \ |
1164 BIN_OP_DECL (R, operator +, DM1, DM2, API); \ | |
1165 BIN_OP_DECL (R, operator -, DM1, DM2, API); \ | |
1166 BIN_OP_DECL (R, product, DM1, DM2, API); | |
2870 | 1167 |
1168 #define DMDM_BIN_OP(R, OP, DM1, DM2, F) \ | |
2829 | 1169 R \ |
1170 OP (const DM1& dm1, const DM2& dm2) \ | |
1171 { \ | |
1172 R r; \ | |
1173 \ | |
1174 int dm1_nr = dm1.rows (); \ | |
1175 int dm1_nc = dm1.cols (); \ | |
1176 \ | |
1177 int dm2_nr = dm2.rows (); \ | |
1178 int dm2_nc = dm2.cols (); \ | |
1179 \ | |
1180 if (dm1_nr != dm2_nr || dm1_nc != dm2_nc) \ | |
1181 gripe_nonconformant (#OP, dm1_nr, dm1_nc, dm2_nr, dm2_nc); \ | |
1182 else \ | |
1183 { \ | |
1184 r.resize (dm1_nr, dm1_nc); \ | |
1185 \ | |
1186 if (dm1_nr > 0 && dm1_nc > 0) \ | |
1187 F ## _vv (r.fortran_vec (), dm1.data (), dm2.data (), \ | |
1188 dm1_nr * dm2_nc); \ | |
1189 } \ | |
1190 \ | |
1191 return r; \ | |
1192 } | |
1193 | |
2870 | 1194 #define DMDM_BIN_OPS(R, DM1, DM2) \ |
3769 | 1195 DMDM_BIN_OP (R, operator +, DM1, DM2, mx_inline_add) \ |
1196 DMDM_BIN_OP (R, operator -, DM1, DM2, mx_inline_subtract) \ | |
1197 DMDM_BIN_OP (R, product, DM1, DM2, mx_inline_multiply) | |
2870 | 1198 |
6708 | 1199 #define DMDM_OP_DECLS(R, DM1, DM2, API) \ |
1200 DMDM_BIN_OP_DECLS (R, DM1, DM2, API) | |
2829 | 1201 |
3582 | 1202 #endif |
1203 | |
7189 | 1204 #define SND_MINMAX_FCN(FCN, OP, T) \ |
1205 T ## NDArray \ | |
1206 FCN (octave_ ## T d, const T ## NDArray& m) \ | |
1207 { \ | |
1208 dim_vector dv = m.dims (); \ | |
1209 octave_idx_type nel = dv.numel (); \ | |
1210 \ | |
1211 if (nel == 0) \ | |
1212 return T ## NDArray (dv); \ | |
1213 \ | |
1214 T ## NDArray result (dv); \ | |
1215 \ | |
1216 for (octave_idx_type i = 0; i < nel; i++) \ | |
1217 { \ | |
1218 OCTAVE_QUIT; \ | |
1219 result (i) = d OP m (i) ? d : m(i); \ | |
1220 } \ | |
1221 \ | |
1222 return result; \ | |
1223 } | |
1224 | |
1225 #define NDS_MINMAX_FCN(FCN, OP, T) \ | |
1226 T ## NDArray \ | |
1227 FCN (const T ## NDArray& m, octave_ ## T d) \ | |
1228 { \ | |
1229 dim_vector dv = m.dims (); \ | |
1230 octave_idx_type nel = dv.numel (); \ | |
1231 \ | |
1232 if (nel == 0) \ | |
1233 return T ## NDArray (dv); \ | |
1234 \ | |
1235 T ## NDArray result (dv); \ | |
1236 \ | |
1237 for (octave_idx_type i = 0; i < nel; i++) \ | |
1238 { \ | |
1239 OCTAVE_QUIT; \ | |
1240 result (i) = m (i) OP d ? m(i) : d; \ | |
1241 } \ | |
1242 \ | |
1243 return result; \ | |
1244 } | |
1245 | |
1246 #define NDND_MINMAX_FCN(FCN, OP, T) \ | |
1247 T ## NDArray \ | |
1248 FCN (const T ## NDArray& a, const T ## NDArray& b) \ | |
1249 { \ | |
1250 dim_vector dv = a.dims (); \ | |
1251 octave_idx_type nel = dv.numel (); \ | |
1252 \ | |
1253 if (dv != b.dims ()) \ | |
1254 { \ | |
1255 (*current_liboctave_error_handler) \ | |
1256 ("two-arg min expecting args of same size"); \ | |
1257 return T ## NDArray (); \ | |
1258 } \ | |
1259 \ | |
1260 if (nel == 0) \ | |
1261 return T ## NDArray (dv); \ | |
1262 \ | |
1263 T ## NDArray result (dv); \ | |
1264 \ | |
1265 for (octave_idx_type i = 0; i < nel; i++) \ | |
1266 { \ | |
1267 OCTAVE_QUIT; \ | |
1268 result (i) = a(i) OP b(i) ? a(i) : b(i); \ | |
1269 } \ | |
1270 \ | |
1271 return result; \ | |
1272 } | |
1273 | |
1274 #define MINMAX_FCNS(T) \ | |
1275 SND_MINMAX_FCN (min, <, T) \ | |
1276 NDS_MINMAX_FCN (min, <, T) \ | |
1277 NDND_MINMAX_FCN (min, <, T) \ | |
1278 SND_MINMAX_FCN (max, >, T) \ | |
1279 NDS_MINMAX_FCN (max, >, T) \ | |
1280 NDND_MINMAX_FCN (max, >, T) | |
1281 | |
1282 #define MINMAX_DECLS(T) \ | |
1283 extern OCTAVE_API T ## NDArray min (octave_ ## T d, const T ## NDArray& m); \ | |
1284 extern OCTAVE_API T ## NDArray min (const T ## NDArray& m, octave_ ## T d); \ | |
1285 extern OCTAVE_API T ## NDArray min (const T ## NDArray& a, \ | |
1286 const T ## NDArray& b); \ | |
1287 extern OCTAVE_API T ## NDArray max (octave_ ## T d, const T ## NDArray& m); \ | |
1288 extern OCTAVE_API T ## NDArray max (const T ## NDArray& m, octave_ ## T d); \ | |
1289 extern OCTAVE_API T ## NDArray max (const T ## NDArray& a, \ | |
1290 const T ## NDArray& b); | |
1291 | |
8367
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1292 #define PMM_MULTIPLY_OP(PM, M) \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1293 M operator * (const PM& p, const M& x) \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1294 { \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1295 octave_idx_type nr = x.rows (), nc = x.columns (); \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1296 M result; \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1297 if (p.columns () != nr) \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1298 gripe_nonconformant ("operator *", p.rows (), p.columns (), nr, nc); \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1299 else \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1300 { \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1301 if (p.is_col_perm ()) \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1302 { \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1303 result = M (nr, nc); \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1304 result.assign (idx_vector (p), idx_vector::colon, x); \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1305 } \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1306 else \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1307 result = x.index (idx_vector (p), idx_vector::colon); \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1308 } \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1309 \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1310 return result; \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1311 } |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1312 |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1313 #define MPM_MULTIPLY_OP(M, PM) \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1314 M operator * (const M& x, const PM& p) \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1315 { \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1316 octave_idx_type nr = x.rows (), nc = x.columns (); \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1317 M result; \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1318 if (p.rows () != nc) \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1319 gripe_nonconformant ("operator *", nr, nc, p.rows (), p.columns ()); \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1320 else \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1321 { \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1322 if (p.is_col_perm ()) \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1323 result = x.index (idx_vector::colon, idx_vector (p)); \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1324 else \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1325 { \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1326 result = M (nr, nc); \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1327 result.assign (idx_vector::colon, idx_vector (p), x); \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1328 } \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1329 } \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1330 \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1331 return result; \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1332 } |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1333 |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1334 #define PMM_BIN_OP_DECLS(R, PM, M, API) \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1335 BIN_OP_DECL (R, operator *, PM, M, API); |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1336 |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1337 #define PMM_BIN_OPS(R, PM, M) \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1338 PMM_MULTIPLY_OP(PM, M); |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1339 |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1340 #define MPM_BIN_OP_DECLS(R, M, PM, API) \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1341 BIN_OP_DECL (R, operator *, M, PM, API); |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1342 |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1343 #define MPM_BIN_OPS(R, M, PM) \ |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1344 MPM_MULTIPLY_OP(M, PM); |
445d27d79f4e
support permutation matrix objects
Jaroslav Hajek <highegg@gmail.com>
parents:
8366
diff
changeset
|
1345 |
7189 | 1346 |
2829 | 1347 /* |
1348 ;;; Local Variables: *** | |
1349 ;;; mode: C++ *** | |
1350 ;;; End: *** | |
1351 */ |