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