00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #if !defined (octave_mx_op_defs_h)
00027 #define octave_mx_op_defs_h 1
00028
00029 #include "mx-op-decl.h"
00030 #include "mx-inlines.cc"
00031
00032
00033
00034 #define VS_BIN_OP(R, F, OP, V, S) \
00035 R \
00036 F (const V& v, const S& s) \
00037 { \
00038 return do_ms_binary_op<R, V, S> (v, s, OP); \
00039 }
00040
00041 #define VS_BIN_OPS(R, V, S) \
00042 VS_BIN_OP (R, operator +, mx_inline_add, V, S) \
00043 VS_BIN_OP (R, operator -, mx_inline_sub, V, S) \
00044 VS_BIN_OP (R, operator *, mx_inline_mul, V, S) \
00045 VS_BIN_OP (R, operator /, mx_inline_div, V, S)
00046
00047
00048
00049 #define SV_BIN_OP(R, F, OP, S, V) \
00050 R \
00051 F (const S& s, const V& v) \
00052 { \
00053 return do_sm_binary_op<R, S, V> (s, v, OP); \
00054 }
00055
00056 #define SV_BIN_OPS(R, S, V) \
00057 SV_BIN_OP (R, operator +, mx_inline_add, S, V) \
00058 SV_BIN_OP (R, operator -, mx_inline_sub, S, V) \
00059 SV_BIN_OP (R, operator *, mx_inline_mul, S, V) \
00060 SV_BIN_OP (R, operator /, mx_inline_div, S, V)
00061
00062
00063
00064 #define VV_BIN_OP(R, F, OP, V1, V2) \
00065 R \
00066 F (const V1& v1, const V2& v2) \
00067 { \
00068 return do_mm_binary_op<R, V1, V2> (v1, v2, OP, #F); \
00069 }
00070
00071 #define VV_BIN_OPS(R, V1, V2) \
00072 VV_BIN_OP (R, operator +, mx_inline_add, V1, V2) \
00073 VV_BIN_OP (R, operator -, mx_inline_sub, V1, V2) \
00074 VV_BIN_OP (R, product, mx_inline_mul, V1, V2) \
00075 VV_BIN_OP (R, quotient, mx_inline_div, V1, V2)
00076
00077
00078
00079 #define MS_BIN_OP(R, OP, M, S, F) \
00080 R \
00081 OP (const M& m, const S& s) \
00082 { \
00083 return do_ms_binary_op<R, M, S> (m, s, F); \
00084 }
00085
00086 #define MS_BIN_OPS(R, M, S) \
00087 MS_BIN_OP (R, operator +, M, S, mx_inline_add) \
00088 MS_BIN_OP (R, operator -, M, S, mx_inline_sub) \
00089 MS_BIN_OP (R, operator *, M, S, mx_inline_mul) \
00090 MS_BIN_OP (R, operator /, M, S, mx_inline_div)
00091
00092 #define MS_CMP_OP(F, OP, M, S) \
00093 boolMatrix \
00094 F (const M& m, const S& s) \
00095 { \
00096 return do_ms_binary_op<boolMatrix, M, S> (m, s, OP); \
00097 }
00098
00099 #define MS_CMP_OPS(M, S) \
00100 MS_CMP_OP (mx_el_lt, mx_inline_lt, M, S) \
00101 MS_CMP_OP (mx_el_le, mx_inline_le, M, S) \
00102 MS_CMP_OP (mx_el_ge, mx_inline_ge, M, S) \
00103 MS_CMP_OP (mx_el_gt, mx_inline_gt, M, S) \
00104 MS_CMP_OP (mx_el_eq, mx_inline_eq, M, S) \
00105 MS_CMP_OP (mx_el_ne, mx_inline_ne, M, S)
00106
00107 #define MS_BOOL_OP(F, OP, M, S) \
00108 boolMatrix \
00109 F (const M& m, const S& s) \
00110 { \
00111 return do_ms_binary_op<boolMatrix, M, S> (m, s, OP); \
00112 }
00113
00114 #define MS_BOOL_OPS(M, S) \
00115 MS_BOOL_OP (mx_el_and, mx_inline_and, M, S) \
00116 MS_BOOL_OP (mx_el_or, mx_inline_or, M, S)
00117
00118
00119
00120 #define SM_BIN_OP(R, OP, S, M, F) \
00121 R \
00122 OP (const S& s, const M& m) \
00123 { \
00124 return do_sm_binary_op<R, S, M> (s, m, F); \
00125 }
00126
00127 #define SM_BIN_OPS(R, S, M) \
00128 SM_BIN_OP (R, operator +, S, M, mx_inline_add) \
00129 SM_BIN_OP (R, operator -, S, M, mx_inline_sub) \
00130 SM_BIN_OP (R, operator *, S, M, mx_inline_mul) \
00131 SM_BIN_OP (R, operator /, S, M, mx_inline_div)
00132
00133 #define SM_CMP_OP(F, OP, S, M) \
00134 boolMatrix \
00135 F (const S& s, const M& m) \
00136 { \
00137 return do_sm_binary_op<boolMatrix, S, M> (s, m, OP); \
00138 }
00139
00140 #define SM_CMP_OPS(S, M) \
00141 SM_CMP_OP (mx_el_lt, mx_inline_lt, S, M) \
00142 SM_CMP_OP (mx_el_le, mx_inline_le, S, M) \
00143 SM_CMP_OP (mx_el_ge, mx_inline_ge, S, M) \
00144 SM_CMP_OP (mx_el_gt, mx_inline_gt, S, M) \
00145 SM_CMP_OP (mx_el_eq, mx_inline_eq, S, M) \
00146 SM_CMP_OP (mx_el_ne, mx_inline_ne, S, M)
00147
00148 #define SM_BOOL_OP(F, OP, S, M) \
00149 boolMatrix \
00150 F (const S& s, const M& m) \
00151 { \
00152 return do_sm_binary_op<boolMatrix, S, M> (s, m, OP); \
00153 }
00154
00155 #define SM_BOOL_OPS(S, M) \
00156 SM_BOOL_OP (mx_el_and, mx_inline_and, S, M) \
00157 SM_BOOL_OP (mx_el_or, mx_inline_or, S, M)
00158
00159
00160
00161 #define MM_BIN_OP(R, OP, M1, M2, F) \
00162 R \
00163 OP (const M1& m1, const M2& m2) \
00164 { \
00165 return do_mm_binary_op<R, M1, M2> (m1, m2, F, #OP); \
00166 }
00167
00168 #define MM_BIN_OPS(R, M1, M2) \
00169 MM_BIN_OP (R, operator +, M1, M2, mx_inline_add) \
00170 MM_BIN_OP (R, operator -, M1, M2, mx_inline_sub) \
00171 MM_BIN_OP (R, product, M1, M2, mx_inline_mul) \
00172 MM_BIN_OP (R, quotient, M1, M2, mx_inline_div)
00173
00174 #define MM_CMP_OP(F, OP, M1, M2) \
00175 boolMatrix \
00176 F (const M1& m1, const M2& m2) \
00177 { \
00178 return do_mm_binary_op<boolMatrix, M1, M2> (m1, m2, OP, #F); \
00179 }
00180
00181 #define MM_CMP_OPS(M1, M2) \
00182 MM_CMP_OP (mx_el_lt, mx_inline_lt, M1, M2) \
00183 MM_CMP_OP (mx_el_le, mx_inline_le, M1, M2) \
00184 MM_CMP_OP (mx_el_ge, mx_inline_ge, M1, M2) \
00185 MM_CMP_OP (mx_el_gt, mx_inline_gt, M1, M2) \
00186 MM_CMP_OP (mx_el_eq, mx_inline_eq, M1, M2) \
00187 MM_CMP_OP (mx_el_ne, mx_inline_ne, M1, M2)
00188
00189 #define MM_BOOL_OP(F, OP, M1, M2) \
00190 boolMatrix \
00191 F (const M1& m1, const M2& m2) \
00192 { \
00193 return do_mm_binary_op<boolMatrix, M1, M2> (m1, m2, OP, #F); \
00194 }
00195
00196 #define MM_BOOL_OPS(M1, M2) \
00197 MM_BOOL_OP (mx_el_and, mx_inline_and, M1, M2) \
00198 MM_BOOL_OP (mx_el_or, mx_inline_or, M1, M2)
00199
00200
00201
00202 #define NDS_BIN_OP(R, OP, ND, S, F) \
00203 R \
00204 OP (const ND& m, const S& s) \
00205 { \
00206 return do_ms_binary_op<R, ND, S> (m, s, F); \
00207 }
00208
00209 #define NDS_BIN_OPS(R, ND, S) \
00210 NDS_BIN_OP (R, operator +, ND, S, mx_inline_add) \
00211 NDS_BIN_OP (R, operator -, ND, S, mx_inline_sub) \
00212 NDS_BIN_OP (R, operator *, ND, S, mx_inline_mul) \
00213 NDS_BIN_OP (R, operator /, ND, S, mx_inline_div)
00214
00215 #define NDS_CMP_OP(F, OP, ND, S) \
00216 boolNDArray \
00217 F (const ND& m, const S& s) \
00218 { \
00219 return do_ms_binary_op<boolNDArray, ND, S> (m, s, OP); \
00220 }
00221
00222 #define NDS_CMP_OPS(ND, S) \
00223 NDS_CMP_OP (mx_el_lt, mx_inline_lt, ND, S) \
00224 NDS_CMP_OP (mx_el_le, mx_inline_le, ND, S) \
00225 NDS_CMP_OP (mx_el_ge, mx_inline_ge, ND, S) \
00226 NDS_CMP_OP (mx_el_gt, mx_inline_gt, ND, S) \
00227 NDS_CMP_OP (mx_el_eq, mx_inline_eq, ND, S) \
00228 NDS_CMP_OP (mx_el_ne, mx_inline_ne, ND, S)
00229
00230 #define NDS_BOOL_OP(F, OP, ND, S) \
00231 boolNDArray \
00232 F (const ND& m, const S& s) \
00233 { \
00234 return do_ms_binary_op<boolNDArray, ND, S> (m, s, OP); \
00235 }
00236
00237 #define NDS_BOOL_OPS(ND, S) \
00238 NDS_BOOL_OP (mx_el_and, mx_inline_and, ND, S) \
00239 NDS_BOOL_OP (mx_el_or, mx_inline_or, ND, S) \
00240 NDS_BOOL_OP (mx_el_not_and, mx_inline_not_and, ND, S) \
00241 NDS_BOOL_OP (mx_el_not_or, mx_inline_not_or, ND, S) \
00242 NDS_BOOL_OP (mx_el_and_not, mx_inline_and_not, ND, S) \
00243 NDS_BOOL_OP (mx_el_or_not, mx_inline_or_not, ND, S)
00244
00245
00246
00247 #define SND_BIN_OP(R, OP, S, ND, F) \
00248 R \
00249 OP (const S& s, const ND& m) \
00250 { \
00251 return do_sm_binary_op<R, S, ND> (s, m, F); \
00252 }
00253
00254 #define SND_BIN_OPS(R, S, ND) \
00255 SND_BIN_OP (R, operator +, S, ND, mx_inline_add) \
00256 SND_BIN_OP (R, operator -, S, ND, mx_inline_sub) \
00257 SND_BIN_OP (R, operator *, S, ND, mx_inline_mul) \
00258 SND_BIN_OP (R, operator /, S, ND, mx_inline_div)
00259
00260 #define SND_CMP_OP(F, OP, S, ND) \
00261 boolNDArray \
00262 F (const S& s, const ND& m) \
00263 { \
00264 return do_sm_binary_op<boolNDArray, S, ND> (s, m, OP); \
00265 }
00266
00267 #define SND_CMP_OPS(S, ND) \
00268 SND_CMP_OP (mx_el_lt, mx_inline_lt, S, ND) \
00269 SND_CMP_OP (mx_el_le, mx_inline_le, S, ND) \
00270 SND_CMP_OP (mx_el_ge, mx_inline_ge, S, ND) \
00271 SND_CMP_OP (mx_el_gt, mx_inline_gt, S, ND) \
00272 SND_CMP_OP (mx_el_eq, mx_inline_eq, S, ND) \
00273 SND_CMP_OP (mx_el_ne, mx_inline_ne, S, ND)
00274
00275 #define SND_BOOL_OP(F, OP, S, ND) \
00276 boolNDArray \
00277 F (const S& s, const ND& m) \
00278 { \
00279 return do_sm_binary_op<boolNDArray, S, ND> (s, m, OP); \
00280 }
00281
00282 #define SND_BOOL_OPS(S, ND) \
00283 SND_BOOL_OP (mx_el_and, mx_inline_and, S, ND) \
00284 SND_BOOL_OP (mx_el_or, mx_inline_or, S, ND) \
00285 SND_BOOL_OP (mx_el_not_and, mx_inline_not_and, S, ND) \
00286 SND_BOOL_OP (mx_el_not_or, mx_inline_not_or, S, ND) \
00287 SND_BOOL_OP (mx_el_and_not, mx_inline_and_not, S, ND) \
00288 SND_BOOL_OP (mx_el_or_not, mx_inline_or_not, S, ND)
00289
00290
00291
00292 #define NDND_BIN_OP(R, OP, ND1, ND2, F) \
00293 R \
00294 OP (const ND1& m1, const ND2& m2) \
00295 { \
00296 return do_mm_binary_op<R, ND1, ND2> (m1, m2, F, #OP); \
00297 }
00298
00299 #define NDND_BIN_OPS(R, ND1, ND2) \
00300 NDND_BIN_OP (R, operator +, ND1, ND2, mx_inline_add) \
00301 NDND_BIN_OP (R, operator -, ND1, ND2, mx_inline_sub) \
00302 NDND_BIN_OP (R, product, ND1, ND2, mx_inline_mul) \
00303 NDND_BIN_OP (R, quotient, ND1, ND2, mx_inline_div)
00304
00305 #define NDND_CMP_OP(F, OP, ND1, ND2) \
00306 boolNDArray \
00307 F (const ND1& m1, const ND2& m2) \
00308 { \
00309 return do_mm_binary_op<boolNDArray, ND1, ND2> (m1, m2, OP, #F); \
00310 }
00311
00312 #define NDND_CMP_OPS(ND1, ND2) \
00313 NDND_CMP_OP (mx_el_lt, mx_inline_lt, ND1, ND2) \
00314 NDND_CMP_OP (mx_el_le, mx_inline_le, ND1, ND2) \
00315 NDND_CMP_OP (mx_el_ge, mx_inline_ge, ND1, ND2) \
00316 NDND_CMP_OP (mx_el_gt, mx_inline_gt, ND1, ND2) \
00317 NDND_CMP_OP (mx_el_eq, mx_inline_eq, ND1, ND2) \
00318 NDND_CMP_OP (mx_el_ne, mx_inline_ne, ND1, ND2)
00319
00320 #define NDND_BOOL_OP(F, OP, ND1, ND2) \
00321 boolNDArray \
00322 F (const ND1& m1, const ND2& m2) \
00323 { \
00324 return do_mm_binary_op<boolNDArray, ND1, ND2> (m1, m2, OP, #F); \
00325 }
00326
00327 #define NDND_BOOL_OPS(ND1, ND2) \
00328 NDND_BOOL_OP (mx_el_and, mx_inline_and, ND1, ND2) \
00329 NDND_BOOL_OP (mx_el_or, mx_inline_or, ND1, ND2) \
00330 NDND_BOOL_OP (mx_el_not_and, mx_inline_not_and, ND1, ND2) \
00331 NDND_BOOL_OP (mx_el_not_or, mx_inline_not_or, ND1, ND2) \
00332 NDND_BOOL_OP (mx_el_and_not, mx_inline_and_not, ND1, ND2) \
00333 NDND_BOOL_OP (mx_el_or_not, mx_inline_or_not, ND1, ND2)
00334
00335
00336
00337 #define SDM_BIN_OP(R, OP, S, DM) \
00338 R \
00339 operator OP (const S& s, const DM& dm) \
00340 { \
00341 R r (dm.rows (), dm.cols ()); \
00342 \
00343 for (octave_idx_type i = 0; i < dm.length (); i++) \
00344 r.dgxelem (i) = s OP dm.dgelem (i); \
00345 \
00346 return r; \
00347 }
00348
00349 #define SDM_BIN_OPS(R, S, DM) \
00350 SDM_BIN_OP (R, *, S, DM)
00351
00352
00353
00354 #define DMS_BIN_OP(R, OP, DM, S) \
00355 R \
00356 operator OP (const DM& dm, const S& s) \
00357 { \
00358 R r (dm.rows (), dm.cols ()); \
00359 \
00360 for (octave_idx_type i = 0; i < dm.length (); i++) \
00361 r.dgxelem (i) = dm.dgelem (i) OP s; \
00362 \
00363 return r; \
00364 }
00365
00366 #define DMS_BIN_OPS(R, DM, S) \
00367 DMS_BIN_OP (R, *, DM, S) \
00368 DMS_BIN_OP (R, /, DM, S)
00369
00370
00371
00372 #define MDM_BIN_OP(R, OP, M, DM, OPEQ) \
00373 R \
00374 OP (const M& m, const DM& dm) \
00375 { \
00376 R r; \
00377 \
00378 octave_idx_type m_nr = m.rows (); \
00379 octave_idx_type m_nc = m.cols (); \
00380 \
00381 octave_idx_type dm_nr = dm.rows (); \
00382 octave_idx_type dm_nc = dm.cols (); \
00383 \
00384 if (m_nr != dm_nr || m_nc != dm_nc) \
00385 gripe_nonconformant (#OP, m_nr, m_nc, dm_nr, dm_nc); \
00386 else \
00387 { \
00388 r.resize (m_nr, m_nc); \
00389 \
00390 if (m_nr > 0 && m_nc > 0) \
00391 { \
00392 r = R (m); \
00393 \
00394 octave_idx_type len = dm.length (); \
00395 \
00396 for (octave_idx_type i = 0; i < len; i++) \
00397 r.elem(i, i) OPEQ dm.elem(i, i); \
00398 } \
00399 } \
00400 \
00401 return r; \
00402 }
00403
00404 #define MDM_MULTIPLY_OP(R, M, DM, R_ZERO) \
00405 R \
00406 operator * (const M& m, const DM& dm) \
00407 { \
00408 R r; \
00409 \
00410 octave_idx_type m_nr = m.rows (); \
00411 octave_idx_type m_nc = m.cols (); \
00412 \
00413 octave_idx_type dm_nr = dm.rows (); \
00414 octave_idx_type dm_nc = dm.cols (); \
00415 \
00416 if (m_nc != dm_nr) \
00417 gripe_nonconformant ("operator *", m_nr, m_nc, dm_nr, dm_nc); \
00418 else \
00419 { \
00420 r = R (m_nr, dm_nc); \
00421 R::element_type *rd = r.fortran_vec (); \
00422 const M::element_type *md = m.data (); \
00423 const DM::element_type *dd = dm.data (); \
00424 \
00425 octave_idx_type len = dm.length (); \
00426 for (octave_idx_type i = 0; i < len; i++) \
00427 { \
00428 mx_inline_mul (m_nr, rd, md, dd[i]); \
00429 rd += m_nr; md += m_nr; \
00430 } \
00431 mx_inline_fill (m_nr * (dm_nc - len), rd, R_ZERO); \
00432 } \
00433 \
00434 return r; \
00435 }
00436
00437 #define MDM_BIN_OPS(R, M, DM, R_ZERO) \
00438 MDM_BIN_OP (R, operator +, M, DM, +=) \
00439 MDM_BIN_OP (R, operator -, M, DM, -=) \
00440 MDM_MULTIPLY_OP (R, M, DM, R_ZERO)
00441
00442
00443
00444 #define DMM_BIN_OP(R, OP, DM, M, OPEQ, PREOP) \
00445 R \
00446 OP (const DM& dm, const M& m) \
00447 { \
00448 R r; \
00449 \
00450 octave_idx_type dm_nr = dm.rows (); \
00451 octave_idx_type dm_nc = dm.cols (); \
00452 \
00453 octave_idx_type m_nr = m.rows (); \
00454 octave_idx_type m_nc = m.cols (); \
00455 \
00456 if (dm_nr != m_nr || dm_nc != m_nc) \
00457 gripe_nonconformant (#OP, dm_nr, dm_nc, m_nr, m_nc); \
00458 else \
00459 { \
00460 if (m_nr > 0 && m_nc > 0) \
00461 { \
00462 r = R (PREOP m); \
00463 \
00464 octave_idx_type len = dm.length (); \
00465 \
00466 for (octave_idx_type i = 0; i < len; i++) \
00467 r.elem(i, i) OPEQ dm.elem(i, i); \
00468 } \
00469 else \
00470 r.resize (m_nr, m_nc); \
00471 } \
00472 \
00473 return r; \
00474 }
00475
00476 #define DMM_MULTIPLY_OP(R, DM, M, R_ZERO) \
00477 R \
00478 operator * (const DM& dm, const M& m) \
00479 { \
00480 R r; \
00481 \
00482 octave_idx_type dm_nr = dm.rows (); \
00483 octave_idx_type dm_nc = dm.cols (); \
00484 \
00485 octave_idx_type m_nr = m.rows (); \
00486 octave_idx_type m_nc = m.cols (); \
00487 \
00488 if (dm_nc != m_nr) \
00489 gripe_nonconformant ("operator *", dm_nr, dm_nc, m_nr, m_nc); \
00490 else \
00491 { \
00492 r = R (dm_nr, m_nc); \
00493 R::element_type *rd = r.fortran_vec (); \
00494 const M::element_type *md = m.data (); \
00495 const DM::element_type *dd = dm.data (); \
00496 \
00497 octave_idx_type len = dm.length (); \
00498 for (octave_idx_type i = 0; i < m_nc; i++) \
00499 { \
00500 mx_inline_mul (len, rd, md, dd); \
00501 rd += len; md += m_nr; \
00502 mx_inline_fill (dm_nr - len, rd, R_ZERO); \
00503 rd += dm_nr - len; \
00504 } \
00505 } \
00506 \
00507 return r; \
00508 }
00509
00510 #define DMM_BIN_OPS(R, DM, M, R_ZERO) \
00511 DMM_BIN_OP (R, operator +, DM, M, +=, ) \
00512 DMM_BIN_OP (R, operator -, DM, M, +=, -) \
00513 DMM_MULTIPLY_OP (R, DM, M, R_ZERO)
00514
00515
00516
00517 #define DMDM_BIN_OP(R, OP, DM1, DM2, F) \
00518 R \
00519 OP (const DM1& dm1, const DM2& dm2) \
00520 { \
00521 R r; \
00522 \
00523 octave_idx_type dm1_nr = dm1.rows (); \
00524 octave_idx_type dm1_nc = dm1.cols (); \
00525 \
00526 octave_idx_type dm2_nr = dm2.rows (); \
00527 octave_idx_type dm2_nc = dm2.cols (); \
00528 \
00529 if (dm1_nr != dm2_nr || dm1_nc != dm2_nc) \
00530 gripe_nonconformant (#OP, dm1_nr, dm1_nc, dm2_nr, dm2_nc); \
00531 else \
00532 { \
00533 r.resize (dm1_nr, dm1_nc); \
00534 \
00535 if (dm1_nr > 0 && dm1_nc > 0) \
00536 F (dm1.length (), r.fortran_vec (), dm1.data (), dm2.data ()); \
00537 } \
00538 \
00539 return r; \
00540 }
00541
00542 #define DMDM_BIN_OPS(R, DM1, DM2) \
00543 DMDM_BIN_OP (R, operator +, DM1, DM2, mx_inline_add) \
00544 DMDM_BIN_OP (R, operator -, DM1, DM2, mx_inline_sub) \
00545 DMDM_BIN_OP (R, product, DM1, DM2, mx_inline_mul)
00546
00547
00548
00549 #define SND_MINMAX_FCN(FCN, OP, T) \
00550 T ## NDArray \
00551 FCN (octave_ ## T d, const T ## NDArray& m) \
00552 { \
00553 dim_vector dv = m.dims (); \
00554 octave_idx_type nel = dv.numel (); \
00555 \
00556 if (nel == 0) \
00557 return T ## NDArray (dv); \
00558 \
00559 T ## NDArray result (dv); \
00560 \
00561 for (octave_idx_type i = 0; i < nel; i++) \
00562 { \
00563 OCTAVE_QUIT; \
00564 result (i) = d OP m (i) ? d : m(i); \
00565 } \
00566 \
00567 return result; \
00568 }
00569
00570 #define NDS_MINMAX_FCN(FCN, OP, T) \
00571 T ## NDArray \
00572 FCN (const T ## NDArray& m, octave_ ## T d) \
00573 { \
00574 dim_vector dv = m.dims (); \
00575 octave_idx_type nel = dv.numel (); \
00576 \
00577 if (nel == 0) \
00578 return T ## NDArray (dv); \
00579 \
00580 T ## NDArray result (dv); \
00581 \
00582 for (octave_idx_type i = 0; i < nel; i++) \
00583 { \
00584 OCTAVE_QUIT; \
00585 result (i) = m (i) OP d ? m(i) : d; \
00586 } \
00587 \
00588 return result; \
00589 }
00590
00591 #define NDND_MINMAX_FCN(FCN, OP, T) \
00592 T ## NDArray \
00593 FCN (const T ## NDArray& a, const T ## NDArray& b) \
00594 { \
00595 dim_vector dv = a.dims (); \
00596 octave_idx_type nel = dv.numel (); \
00597 \
00598 if (dv != b.dims ()) \
00599 { \
00600 (*current_liboctave_error_handler) \
00601 ("two-arg min expecting args of same size"); \
00602 return T ## NDArray (); \
00603 } \
00604 \
00605 if (nel == 0) \
00606 return T ## NDArray (dv); \
00607 \
00608 T ## NDArray result (dv); \
00609 \
00610 for (octave_idx_type i = 0; i < nel; i++) \
00611 { \
00612 OCTAVE_QUIT; \
00613 result (i) = a(i) OP b(i) ? a(i) : b(i); \
00614 } \
00615 \
00616 return result; \
00617 }
00618
00619 #define MINMAX_FCNS(T) \
00620 SND_MINMAX_FCN (min, <, T) \
00621 NDS_MINMAX_FCN (min, <, T) \
00622 NDND_MINMAX_FCN (min, <, T) \
00623 SND_MINMAX_FCN (max, >, T) \
00624 NDS_MINMAX_FCN (max, >, T) \
00625 NDND_MINMAX_FCN (max, >, T)
00626
00627
00628
00629 #define PMM_MULTIPLY_OP(PM, M) \
00630 M operator * (const PM& p, const M& x) \
00631 { \
00632 octave_idx_type nr = x.rows (), nc = x.columns (); \
00633 M result; \
00634 if (p.columns () != nr) \
00635 gripe_nonconformant ("operator *", p.rows (), p.columns (), nr, nc); \
00636 else \
00637 { \
00638 if (p.is_col_perm ()) \
00639 { \
00640 result = M (nr, nc); \
00641 result.assign (p.pvec (), idx_vector::colon, x); \
00642 } \
00643 else \
00644 result = x.index (p.pvec (), idx_vector::colon); \
00645 } \
00646 \
00647 return result; \
00648 }
00649
00650 #define MPM_MULTIPLY_OP(M, PM) \
00651 M operator * (const M& x, const PM& p) \
00652 { \
00653 octave_idx_type nr = x.rows (), nc = x.columns (); \
00654 M result; \
00655 if (p.rows () != nc) \
00656 gripe_nonconformant ("operator *", nr, nc, p.rows (), p.columns ()); \
00657 else \
00658 { \
00659 if (p.is_col_perm ()) \
00660 result = x.index (idx_vector::colon, p.pvec ()); \
00661 else \
00662 { \
00663 result = M (nr, nc); \
00664 result.assign (idx_vector::colon, p.pvec (), x); \
00665 } \
00666 } \
00667 \
00668 return result; \
00669 }
00670
00671 #define PMM_BIN_OPS(R, PM, M) \
00672 PMM_MULTIPLY_OP(PM, M);
00673
00674 #define MPM_BIN_OPS(R, M, PM) \
00675 MPM_MULTIPLY_OP(M, PM);
00676
00677 #define NDND_MAPPER_BODY(R, NAME) \
00678 R retval (dims ()); \
00679 octave_idx_type n = numel (); \
00680 for (octave_idx_type i = 0; i < n; i++) \
00681 retval.xelem (i) = NAME (elem (i)); \
00682 return retval;
00683
00684 #endif
00685
00686
00687
00688
00689
00690
00691