00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #if !defined (octave_mx_op_defs_h)
00024 #define octave_mx_op_defs_h 1
00025
00026 #include "mx-inlines.cc"
00027
00028 #define BIN_OP_DECL(R, OP, X, Y) \
00029 extern R OP (const X&, const Y&)
00030
00031 class boolMatrix;
00032 class boolNDArray;
00033
00034 #define CMP_OP_DECL(OP, X, Y) \
00035 extern boolMatrix OP (const X&, const Y&)
00036
00037 #define NDCMP_OP_DECL(OP, X, Y) \
00038 extern boolNDArray OP (const X&, const Y&)
00039
00040 #define BOOL_OP_DECL(OP, X, Y) \
00041 extern boolMatrix OP (const X&, const Y&)
00042
00043 #define NDBOOL_OP_DECL(OP, X, Y) \
00044 extern boolNDArray OP (const X&, const Y&)
00045
00046
00047
00048 #define VS_BIN_OP_DECLS(R, V, S) \
00049 BIN_OP_DECL (R, operator +, V, S); \
00050 BIN_OP_DECL (R, operator -, V, S); \
00051 BIN_OP_DECL (R, operator *, V, S); \
00052 BIN_OP_DECL (R, operator /, V, S);
00053
00054 #define VS_BIN_OP(R, F, OP, V, S) \
00055 R \
00056 F (const V& v, const S& s) \
00057 { \
00058 int len = v.length (); \
00059 \
00060 R r (len); \
00061 \
00062 for (int i = 0; i < len; i++) \
00063 r.elem(i) = v.elem(i) OP s; \
00064 \
00065 return r; \
00066 }
00067
00068 #define VS_BIN_OPS(R, V, S) \
00069 VS_BIN_OP (R, operator +, +, V, S) \
00070 VS_BIN_OP (R, operator -, -, V, S) \
00071 VS_BIN_OP (R, operator *, *, V, S) \
00072 VS_BIN_OP (R, operator /, /, V, S)
00073
00074 #define VS_OP_DECLS(R, V, S) \
00075 VS_BIN_OP_DECLS(R, V, S)
00076
00077
00078
00079 #define SV_BIN_OP_DECLS(R, S, V) \
00080 BIN_OP_DECL (R, operator +, S, V); \
00081 BIN_OP_DECL (R, operator -, S, V); \
00082 BIN_OP_DECL (R, operator *, S, V); \
00083 BIN_OP_DECL (R, operator /, S, V);
00084
00085 #define SV_BIN_OP(R, F, OP, S, V) \
00086 R \
00087 F (const S& s, const V& v) \
00088 { \
00089 int len = v.length (); \
00090 \
00091 R r (len); \
00092 \
00093 for (int i = 0; i < len; i++) \
00094 r.elem(i) = s OP v.elem(i); \
00095 \
00096 return r; \
00097 }
00098
00099 #define SV_BIN_OPS(R, S, V) \
00100 SV_BIN_OP (R, operator +, +, S, V) \
00101 SV_BIN_OP (R, operator -, -, S, V) \
00102 SV_BIN_OP (R, operator *, *, S, V) \
00103 SV_BIN_OP (R, operator /, /, S, V)
00104
00105 #define SV_OP_DECLS(R, S, V) \
00106 SV_BIN_OP_DECLS(R, S, V)
00107
00108
00109
00110 #define VV_BIN_OP_DECLS(R, V1, V2) \
00111 BIN_OP_DECL (R, operator +, V1, V2); \
00112 BIN_OP_DECL (R, operator -, V1, V2); \
00113 BIN_OP_DECL (R, product, V1, V2); \
00114 BIN_OP_DECL (R, quotient, V1, V2);
00115
00116 #define VV_BIN_OP(R, F, OP, V1, V2) \
00117 R \
00118 F (const V1& v1, const V2& v2) \
00119 { \
00120 R r; \
00121 \
00122 int v1_len = v1.length (); \
00123 int v2_len = v2.length (); \
00124 \
00125 if (v1_len != v2_len) \
00126 gripe_nonconformant (#OP, v1_len, v2_len); \
00127 else \
00128 { \
00129 r.resize (v1_len); \
00130 \
00131 for (int i = 0; i < v1_len; i++) \
00132 r.elem(i) = v1.elem(i) OP v2.elem(i); \
00133 } \
00134 \
00135 return r; \
00136 }
00137
00138 #define VV_BIN_OPS(R, V1, V2) \
00139 VV_BIN_OP (R, operator +, +, V1, V2) \
00140 VV_BIN_OP (R, operator -, -, V1, V2) \
00141 VV_BIN_OP (R, product, *, V1, V2) \
00142 VV_BIN_OP (R, quotient, /, V1, V2)
00143
00144 #define VV_OP_DECLS(R, V1, V2) \
00145 VV_BIN_OP_DECLS(R, V1, V2)
00146
00147
00148
00149 #define MS_BIN_OP_DECLS(R, M, S) \
00150 BIN_OP_DECL (R, operator +, M, S); \
00151 BIN_OP_DECL (R, operator -, M, S); \
00152 BIN_OP_DECL (R, operator *, M, S); \
00153 BIN_OP_DECL (R, operator /, M, S);
00154
00155 #define MS_BIN_OP(R, OP, M, S, F) \
00156 R \
00157 OP (const M& m, const S& s) \
00158 { \
00159 int nr = m.rows (); \
00160 int nc = m.cols (); \
00161 \
00162 R r (nr, nc); \
00163 \
00164 if (nr > 0 && nc > 0) \
00165 F ## _vs (r.fortran_vec (), m.data (), nr * nc, s); \
00166 \
00167 return r; \
00168 }
00169
00170 #define MS_BIN_OPS(R, M, S) \
00171 MS_BIN_OP (R, operator +, M, S, mx_inline_add) \
00172 MS_BIN_OP (R, operator -, M, S, mx_inline_subtract) \
00173 MS_BIN_OP (R, operator *, M, S, mx_inline_multiply) \
00174 MS_BIN_OP (R, operator /, M, S, mx_inline_divide)
00175
00176 #define MS_CMP_OP_DECLS(M, S) \
00177 CMP_OP_DECL (mx_el_lt, M, S); \
00178 CMP_OP_DECL (mx_el_le, M, S); \
00179 CMP_OP_DECL (mx_el_ge, M, S); \
00180 CMP_OP_DECL (mx_el_gt, M, S); \
00181 CMP_OP_DECL (mx_el_eq, M, S); \
00182 CMP_OP_DECL (mx_el_ne, M, S);
00183
00184 #define MS_CMP_OP(F, OP, M, MC, S, SC) \
00185 boolMatrix \
00186 F (const M& m, const S& s) \
00187 { \
00188 boolMatrix r; \
00189 \
00190 int nr = m.rows (); \
00191 int nc = m.cols (); \
00192 \
00193 r.resize (nr, nc); \
00194 \
00195 if (nr > 0 && nc > 0) \
00196 { \
00197 for (int j = 0; j < nc; j++) \
00198 for (int i = 0; i < nr; i++) \
00199 r.elem(i, j) = MC (m.elem(i, j)) OP SC (s); \
00200 } \
00201 \
00202 return r; \
00203 }
00204
00205 #define MS_CMP_OPS(M, CM, S, CS) \
00206 MS_CMP_OP (mx_el_lt, <, M, CM, S, CS) \
00207 MS_CMP_OP (mx_el_le, <=, M, CM, S, CS) \
00208 MS_CMP_OP (mx_el_ge, >=, M, CM, S, CS) \
00209 MS_CMP_OP (mx_el_gt, >, M, CM, S, CS) \
00210 MS_CMP_OP (mx_el_eq, ==, M, , S, ) \
00211 MS_CMP_OP (mx_el_ne, !=, M, , S, )
00212
00213 #define MS_BOOL_OP_DECLS(M, S) \
00214 BOOL_OP_DECL (mx_el_and, M, S); \
00215 BOOL_OP_DECL (mx_el_or, M, S); \
00216
00217 #define MS_BOOL_OP(F, OP, M, S, LHS_ZERO, RHS_ZERO) \
00218 boolMatrix \
00219 F (const M& m, const S& s) \
00220 { \
00221 boolMatrix r; \
00222 \
00223 int nr = m.rows (); \
00224 int nc = m.cols (); \
00225 \
00226 if (nr != 0 && nc != 0) \
00227 { \
00228 r.resize (nr, nc); \
00229 \
00230 for (int j = 0; j < nc; j++) \
00231 for (int i = 0; i < nr; i++) \
00232 r.elem(i, j) = (m.elem(i, j) != LHS_ZERO) OP (s != RHS_ZERO); \
00233 } \
00234 \
00235 return r; \
00236 }
00237
00238 #define MS_BOOL_OPS2(M, S, LHS_ZERO, RHS_ZERO) \
00239 MS_BOOL_OP (mx_el_and, &&, M, S, LHS_ZERO, RHS_ZERO) \
00240 MS_BOOL_OP (mx_el_or, ||, M, S, LHS_ZERO, RHS_ZERO)
00241
00242 #define MS_BOOL_OPS(M, S, ZERO) \
00243 MS_BOOL_OPS2(M, S, ZERO, ZERO)
00244
00245 #define MS_OP_DECLS(R, M, S) \
00246 MS_BIN_OP_DECLS (R, M, S) \
00247 MS_CMP_OP_DECLS (M, S) \
00248 MS_BOOL_OP_DECLS (M, S) \
00249
00250
00251
00252 #define SM_BIN_OP_DECLS(R, S, M) \
00253 BIN_OP_DECL (R, operator +, S, M); \
00254 BIN_OP_DECL (R, operator -, S, M); \
00255 BIN_OP_DECL (R, operator *, S, M); \
00256 BIN_OP_DECL (R, operator /, S, M);
00257
00258 #define SM_BIN_OP(R, OP, S, M, F) \
00259 R \
00260 OP (const S& s, const M& m) \
00261 { \
00262 int nr = m.rows (); \
00263 int nc = m.cols (); \
00264 \
00265 R r (nr, nc); \
00266 \
00267 if (nr > 0 && nc > 0) \
00268 F ## _sv (r.fortran_vec (), s, m.data (), nr * nc); \
00269 \
00270 return r; \
00271 }
00272
00273 #define SM_BIN_OPS(R, S, M) \
00274 SM_BIN_OP (R, operator +, S, M, mx_inline_add) \
00275 SM_BIN_OP (R, operator -, S, M, mx_inline_subtract) \
00276 SM_BIN_OP (R, operator *, S, M, mx_inline_multiply) \
00277 SM_BIN_OP (R, operator /, S, M, mx_inline_divide)
00278
00279 #define SM_CMP_OP_DECLS(S, M) \
00280 CMP_OP_DECL (mx_el_lt, S, M); \
00281 CMP_OP_DECL (mx_el_le, S, M); \
00282 CMP_OP_DECL (mx_el_ge, S, M); \
00283 CMP_OP_DECL (mx_el_gt, S, M); \
00284 CMP_OP_DECL (mx_el_eq, S, M); \
00285 CMP_OP_DECL (mx_el_ne, S, M);
00286
00287 #define SM_CMP_OP(F, OP, S, SC, M, MC) \
00288 boolMatrix \
00289 F (const S& s, const M& m) \
00290 { \
00291 boolMatrix r; \
00292 \
00293 int nr = m.rows (); \
00294 int nc = m.cols (); \
00295 \
00296 r.resize (nr, nc); \
00297 \
00298 if (nr > 0 && nc > 0) \
00299 { \
00300 for (int j = 0; j < nc; j++) \
00301 for (int i = 0; i < nr; i++) \
00302 r.elem(i, j) = SC (s) OP MC (m.elem(i, j)); \
00303 } \
00304 \
00305 return r; \
00306 }
00307
00308 #define SM_CMP_OPS(S, CS, M, CM) \
00309 SM_CMP_OP (mx_el_lt, <, S, CS, M, CM) \
00310 SM_CMP_OP (mx_el_le, <=, S, CS, M, CM) \
00311 SM_CMP_OP (mx_el_ge, >=, S, CS, M, CM) \
00312 SM_CMP_OP (mx_el_gt, >, S, CS, M, CM) \
00313 SM_CMP_OP (mx_el_eq, ==, S, , M, ) \
00314 SM_CMP_OP (mx_el_ne, !=, S, , M, )
00315
00316 #define SM_BOOL_OP_DECLS(S, M) \
00317 BOOL_OP_DECL (mx_el_and, S, M); \
00318 BOOL_OP_DECL (mx_el_or, S, M); \
00319
00320 #define SM_BOOL_OP(F, OP, S, M, LHS_ZERO, RHS_ZERO) \
00321 boolMatrix \
00322 F (const S& s, const M& m) \
00323 { \
00324 boolMatrix r; \
00325 \
00326 int nr = m.rows (); \
00327 int nc = m.cols (); \
00328 \
00329 if (nr != 0 && nc != 0) \
00330 { \
00331 r.resize (nr, nc); \
00332 \
00333 for (int j = 0; j < nc; j++) \
00334 for (int i = 0; i < nr; i++) \
00335 r.elem(i, j) = (s != LHS_ZERO) OP (m.elem(i, j) != RHS_ZERO); \
00336 } \
00337 \
00338 return r; \
00339 }
00340
00341 #define SM_BOOL_OPS2(S, M, LHS_ZERO, RHS_ZERO) \
00342 SM_BOOL_OP (mx_el_and, &&, S, M, LHS_ZERO, RHS_ZERO) \
00343 SM_BOOL_OP (mx_el_or, ||, S, M, LHS_ZERO, RHS_ZERO)
00344
00345 #define SM_BOOL_OPS(S, M, ZERO) \
00346 SM_BOOL_OPS2(S, M, ZERO, ZERO)
00347
00348 #define SM_OP_DECLS(R, S, M) \
00349 SM_BIN_OP_DECLS (R, S, M) \
00350 SM_CMP_OP_DECLS (S, M) \
00351 SM_BOOL_OP_DECLS (S, M) \
00352
00353
00354
00355 #define MM_BIN_OP_DECLS(R, M1, M2) \
00356 BIN_OP_DECL (R, operator +, M1, M2); \
00357 BIN_OP_DECL (R, operator -, M1, M2); \
00358 BIN_OP_DECL (R, product, M1, M2); \
00359 BIN_OP_DECL (R, quotient, M1, M2);
00360
00361 #define MM_BIN_OP(R, OP, M1, M2, F) \
00362 R \
00363 OP (const M1& m1, const M2& m2) \
00364 { \
00365 R r; \
00366 \
00367 int m1_nr = m1.rows (); \
00368 int m1_nc = m1.cols (); \
00369 \
00370 int m2_nr = m2.rows (); \
00371 int m2_nc = m2.cols (); \
00372 \
00373 if (m1_nr != m2_nr || m1_nc != m2_nc) \
00374 gripe_nonconformant (#OP, m1_nr, m1_nc, m2_nr, m2_nc); \
00375 else \
00376 { \
00377 r.resize (m1_nr, m1_nc); \
00378 \
00379 if (m1_nr > 0 && m1_nc > 0) \
00380 F ## _vv (r.fortran_vec (), m1.data (), m2.data (), m1_nr * m1_nc); \
00381 } \
00382 \
00383 return r; \
00384 }
00385
00386 #define MM_BIN_OPS(R, M1, M2) \
00387 MM_BIN_OP (R, operator +, M1, M2, mx_inline_add) \
00388 MM_BIN_OP (R, operator -, M1, M2, mx_inline_subtract) \
00389 MM_BIN_OP (R, product, M1, M2, mx_inline_multiply) \
00390 MM_BIN_OP (R, quotient, M1, M2, mx_inline_divide)
00391
00392 #define MM_CMP_OP_DECLS(M1, M2) \
00393 CMP_OP_DECL (mx_el_lt, M1, M2); \
00394 CMP_OP_DECL (mx_el_le, M1, M2); \
00395 CMP_OP_DECL (mx_el_ge, M1, M2); \
00396 CMP_OP_DECL (mx_el_gt, M1, M2); \
00397 CMP_OP_DECL (mx_el_eq, M1, M2); \
00398 CMP_OP_DECL (mx_el_ne, M1, M2);
00399
00400 #define MM_CMP_OP(F, OP, M1, C1, M2, C2) \
00401 boolMatrix \
00402 F (const M1& m1, const M2& m2) \
00403 { \
00404 boolMatrix r; \
00405 \
00406 int m1_nr = m1.rows (); \
00407 int m1_nc = m1.cols (); \
00408 \
00409 int m2_nr = m2.rows (); \
00410 int m2_nc = m2.cols (); \
00411 \
00412 if (m1_nr == m2_nr && m1_nc == m2_nc) \
00413 { \
00414 r.resize (m1_nr, m1_nc); \
00415 \
00416 for (int j = 0; j < m1_nc; j++) \
00417 for (int i = 0; i < m1_nr; i++) \
00418 r.elem(i, j) = C1 (m1.elem(i, j)) OP C2 (m2.elem(i, j)); \
00419 } \
00420 else \
00421 gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
00422 \
00423 return r; \
00424 }
00425
00426 #define MM_CMP_OPS(M1, C1, M2, C2) \
00427 MM_CMP_OP (mx_el_lt, <, M1, C1, M2, C2) \
00428 MM_CMP_OP (mx_el_le, <=, M1, C1, M2, C2) \
00429 MM_CMP_OP (mx_el_ge, >=, M1, C1, M2, C2) \
00430 MM_CMP_OP (mx_el_gt, >, M1, C1, M2, C2) \
00431 MM_CMP_OP (mx_el_eq, ==, M1, , M2, ) \
00432 MM_CMP_OP (mx_el_ne, !=, M1, , M2, )
00433
00434 #define MM_BOOL_OP_DECLS(M1, M2) \
00435 BOOL_OP_DECL (mx_el_and, M1, M2); \
00436 BOOL_OP_DECL (mx_el_or, M1, M2);
00437
00438 #define MM_BOOL_OP(F, OP, M1, M2, LHS_ZERO, RHS_ZERO) \
00439 boolMatrix \
00440 F (const M1& m1, const M2& m2) \
00441 { \
00442 boolMatrix r; \
00443 \
00444 int m1_nr = m1.rows (); \
00445 int m1_nc = m1.cols (); \
00446 \
00447 int m2_nr = m2.rows (); \
00448 int m2_nc = m2.cols (); \
00449 \
00450 if (m1_nr == m2_nr && m1_nc == m2_nc) \
00451 { \
00452 if (m1_nr != 0 || m1_nc != 0) \
00453 { \
00454 r.resize (m1_nr, m1_nc); \
00455 \
00456 for (int j = 0; j < m1_nc; j++) \
00457 for (int i = 0; i < m1_nr; i++) \
00458 r.elem(i, j) = (m1.elem(i, j) != LHS_ZERO) \
00459 OP (m2.elem(i, j) != RHS_ZERO); \
00460 } \
00461 } \
00462 else \
00463 { \
00464 if ((m1_nr != 0 || m1_nc != 0) && (m2_nr != 0 || m2_nc != 0)) \
00465 gripe_nonconformant (#F, m1_nr, m1_nc, m2_nr, m2_nc); \
00466 } \
00467 \
00468 return r; \
00469 }
00470
00471 #define MM_BOOL_OPS2(M1, M2, LHS_ZERO, RHS_ZERO) \
00472 MM_BOOL_OP (mx_el_and, &&, M1, M2, LHS_ZERO, RHS_ZERO) \
00473 MM_BOOL_OP (mx_el_or, ||, M1, M2, LHS_ZERO, RHS_ZERO)
00474
00475 #define MM_BOOL_OPS(M1, M2, ZERO) \
00476 MM_BOOL_OPS2(M1, M2, ZERO, ZERO)
00477
00478 #define MM_OP_DECLS(R, M1, M2) \
00479 MM_BIN_OP_DECLS (R, M1, M2) \
00480 MM_CMP_OP_DECLS (M1, M2) \
00481 MM_BOOL_OP_DECLS (M1, M2)
00482
00483
00484
00485 #define NDS_BIN_OP_DECLS(R, ND, S) \
00486 BIN_OP_DECL (R, operator +, ND, S); \
00487 BIN_OP_DECL (R, operator -, ND, S); \
00488 BIN_OP_DECL (R, operator *, ND, S); \
00489 BIN_OP_DECL (R, operator /, ND, S);
00490
00491 #define NDS_BIN_OP(R, OP, ND, S, F) \
00492 R \
00493 OP (const ND& m, const S& s) \
00494 { \
00495 R r (m.dims ()); \
00496 \
00497 int len = m.length (); \
00498 \
00499 if (len > 0) \
00500 F ## _vs (r.fortran_vec (), m.data (), len, s); \
00501 \
00502 return r; \
00503 }
00504
00505 #define NDS_BIN_OPS(R, ND, S) \
00506 NDS_BIN_OP (R, operator +, ND, S, mx_inline_add) \
00507 NDS_BIN_OP (R, operator -, ND, S, mx_inline_subtract) \
00508 NDS_BIN_OP (R, operator *, ND, S, mx_inline_multiply) \
00509 NDS_BIN_OP (R, operator /, ND, S, mx_inline_divide)
00510
00511 #define NDS_CMP_OP_DECLS(ND, S) \
00512 NDCMP_OP_DECL (mx_el_lt, ND, S); \
00513 NDCMP_OP_DECL (mx_el_le, ND, S); \
00514 NDCMP_OP_DECL (mx_el_ge, ND, S); \
00515 NDCMP_OP_DECL (mx_el_gt, ND, S); \
00516 NDCMP_OP_DECL (mx_el_eq, ND, S); \
00517 NDCMP_OP_DECL (mx_el_ne, ND, S);
00518
00519 #define NDS_CMP_OP(F, OP, ND, NDC, S, SC) \
00520 boolNDArray \
00521 F (const ND& m, const S& s) \
00522 { \
00523 boolNDArray r; \
00524 \
00525 int len = m.length (); \
00526 \
00527 r.resize (m.dims ()); \
00528 \
00529 for (int i = 0; i < len; i++) \
00530 r.elem(i) = NDC (m.elem(i)) OP SC (s); \
00531 \
00532 return r; \
00533 }
00534
00535 #define NDS_CMP_OPS(ND, NDC, S, SC) \
00536 NDS_CMP_OP (mx_el_lt, <, ND, NDC, S, SC) \
00537 NDS_CMP_OP (mx_el_le, <=, ND, NDC, S, SC) \
00538 NDS_CMP_OP (mx_el_ge, >=, ND, NDC, S, SC) \
00539 NDS_CMP_OP (mx_el_gt, >, ND, NDC, S, SC) \
00540 NDS_CMP_OP (mx_el_eq, ==, ND, , S, ) \
00541 NDS_CMP_OP (mx_el_ne, !=, ND, , S, )
00542
00543 #define NDS_BOOL_OP_DECLS(ND, S) \
00544 NDBOOL_OP_DECL (mx_el_and, ND, S); \
00545 NDBOOL_OP_DECL (mx_el_or, ND, S);
00546
00547 #define NDS_BOOL_OP(F, OP, ND, S, LHS_ZERO, RHS_ZERO) \
00548 boolNDArray \
00549 F (const ND& m, const S& s) \
00550 { \
00551 boolNDArray r; \
00552 \
00553 int len = m.length (); \
00554 \
00555 if (len > 0) \
00556 { \
00557 r.resize (m.dims ()); \
00558 \
00559 for (int i = 0; i < len; i++) \
00560 r.elem(i) = (m.elem(i) != LHS_ZERO) OP (s != RHS_ZERO); \
00561 } \
00562 \
00563 return r; \
00564 }
00565
00566 #define NDS_BOOL_OPS2(ND, S, LHS_ZERO, RHS_ZERO) \
00567 NDS_BOOL_OP (mx_el_and, &&, ND, S, LHS_ZERO, RHS_ZERO) \
00568 NDS_BOOL_OP (mx_el_or, ||, ND, S, LHS_ZERO, RHS_ZERO)
00569
00570 #define NDS_BOOL_OPS(ND, S, ZERO) \
00571 NDS_BOOL_OPS2(ND, S, ZERO, ZERO)
00572
00573 #define NDS_OP_DECLS(R, ND, S) \
00574 NDS_BIN_OP_DECLS (R, ND, S) \
00575 NDS_CMP_OP_DECLS (ND, S) \
00576 NDS_BOOL_OP_DECLS (ND, S)
00577
00578
00579
00580 #define SND_BIN_OP_DECLS(R, S, ND) \
00581 BIN_OP_DECL (R, operator +, S, ND); \
00582 BIN_OP_DECL (R, operator -, S, ND); \
00583 BIN_OP_DECL (R, operator *, S, ND); \
00584 BIN_OP_DECL (R, operator /, S, ND);
00585
00586 #define SND_BIN_OP(R, OP, S, ND, F) \
00587 R \
00588 OP (const S& s, const ND& m) \
00589 { \
00590 R r (m.dims ()); \
00591 \
00592 int len = m.length (); \
00593 \
00594 if (len > 0) \
00595 F ## _sv (r.fortran_vec (), s, m.data (), len); \
00596 \
00597 return r; \
00598 }
00599
00600 #define SND_BIN_OPS(R, S, ND) \
00601 SND_BIN_OP (R, operator +, S, ND, mx_inline_add) \
00602 SND_BIN_OP (R, operator -, S, ND, mx_inline_subtract) \
00603 SND_BIN_OP (R, operator *, S, ND, mx_inline_multiply) \
00604 SND_BIN_OP (R, operator /, S, ND, mx_inline_divide)
00605
00606 #define SND_CMP_OP_DECLS(S, ND) \
00607 NDCMP_OP_DECL (mx_el_lt, S, ND); \
00608 NDCMP_OP_DECL (mx_el_le, S, ND); \
00609 NDCMP_OP_DECL (mx_el_ge, S, ND); \
00610 NDCMP_OP_DECL (mx_el_gt, S, ND); \
00611 NDCMP_OP_DECL (mx_el_eq, S, ND); \
00612 NDCMP_OP_DECL (mx_el_ne, S, ND);
00613
00614 #define SND_CMP_OP(F, OP, S, SC, ND, NDC) \
00615 boolNDArray \
00616 F (const S& s, const ND& m) \
00617 { \
00618 boolNDArray r; \
00619 \
00620 int len = m.length (); \
00621 \
00622 r.resize (m.dims ()); \
00623 \
00624 for (int i = 0; i < len; i++) \
00625 r.elem(i) = SC (s) OP NDC (m.elem(i)); \
00626 \
00627 return r; \
00628 }
00629
00630 #define SND_CMP_OPS(S, CS, ND, CND) \
00631 SND_CMP_OP (mx_el_lt, <, S, CS, ND, CND) \
00632 SND_CMP_OP (mx_el_le, <=, S, CS, ND, CND) \
00633 SND_CMP_OP (mx_el_ge, >=, S, CS, ND, CND) \
00634 SND_CMP_OP (mx_el_gt, >, S, CS, ND, CND) \
00635 SND_CMP_OP (mx_el_eq, ==, S, , ND, ) \
00636 SND_CMP_OP (mx_el_ne, !=, S, , ND, )
00637
00638 #define SND_BOOL_OP_DECLS(S, ND) \
00639 NDBOOL_OP_DECL (mx_el_and, S, ND); \
00640 NDBOOL_OP_DECL (mx_el_or, S, ND);
00641
00642 #define SND_BOOL_OP(F, OP, S, ND, LHS_ZERO, RHS_ZERO) \
00643 boolNDArray \
00644 F (const S& s, const ND& m) \
00645 { \
00646 boolNDArray r; \
00647 \
00648 int len = m.length (); \
00649 \
00650 if (len > 0) \
00651 { \
00652 r.resize (m.dims ()); \
00653 \
00654 for (int i = 0; i < len; i++) \
00655 r.elem(i) = (s != LHS_ZERO) OP (m.elem(i) != RHS_ZERO); \
00656 } \
00657 \
00658 return r; \
00659 }
00660
00661 #define SND_BOOL_OPS2(S, ND, LHS_ZERO, RHS_ZERO) \
00662 SND_BOOL_OP (mx_el_and, &&, S, ND, LHS_ZERO, RHS_ZERO) \
00663 SND_BOOL_OP (mx_el_or, ||, S, ND, LHS_ZERO, RHS_ZERO)
00664
00665 #define SND_BOOL_OPS(S, ND, ZERO) \
00666 SND_BOOL_OPS2(S, ND, ZERO, ZERO)
00667
00668 #define SND_OP_DECLS(R, S, ND) \
00669 SND_BIN_OP_DECLS (R, S, ND) \
00670 SND_CMP_OP_DECLS (S, ND) \
00671 SND_BOOL_OP_DECLS (S, ND)
00672
00673
00674
00675 #define NDND_BIN_OP_DECLS(R, ND1, ND2) \
00676 BIN_OP_DECL (R, operator +, ND1, ND2); \
00677 BIN_OP_DECL (R, operator -, ND1, ND2); \
00678 BIN_OP_DECL (R, product, ND1, ND2); \
00679 BIN_OP_DECL (R, quotient, ND1, ND2);
00680
00681 #define NDND_BIN_OP(R, OP, ND1, ND2, F) \
00682 R \
00683 OP (const ND1& m1, const ND2& m2) \
00684 { \
00685 R r; \
00686 \
00687 dim_vector m1_dims = m1.dims (); \
00688 dim_vector m2_dims = m2.dims (); \
00689 \
00690 if (m1_dims != m2_dims) \
00691 gripe_nonconformant (#OP, m1_dims, m2_dims); \
00692 else \
00693 { \
00694 r.resize (m1_dims); \
00695 \
00696 int len = m1.length (); \
00697 \
00698 if (len > 0) \
00699 F ## _vv (r.fortran_vec (), m1.data (), m2.data (), len); \
00700 } \
00701 \
00702 return r; \
00703 }
00704
00705 #define NDND_BIN_OPS(R, ND1, ND2) \
00706 NDND_BIN_OP (R, operator +, ND1, ND2, mx_inline_add) \
00707 NDND_BIN_OP (R, operator -, ND1, ND2, mx_inline_subtract) \
00708 NDND_BIN_OP (R, product, ND1, ND2, mx_inline_multiply) \
00709 NDND_BIN_OP (R, quotient, ND1, ND2, mx_inline_divide)
00710
00711 #define NDND_CMP_OP_DECLS(ND1, ND2) \
00712 NDCMP_OP_DECL (mx_el_lt, ND1, ND2); \
00713 NDCMP_OP_DECL (mx_el_le, ND1, ND2); \
00714 NDCMP_OP_DECL (mx_el_ge, ND1, ND2); \
00715 NDCMP_OP_DECL (mx_el_gt, ND1, ND2); \
00716 NDCMP_OP_DECL (mx_el_eq, ND1, ND2); \
00717 NDCMP_OP_DECL (mx_el_ne, ND1, ND2);
00718
00719 #define NDND_CMP_OP(F, OP, ND1, C1, ND2, C2) \
00720 boolNDArray \
00721 F (const ND1& m1, const ND2& m2) \
00722 { \
00723 boolNDArray r; \
00724 \
00725 dim_vector m1_dims = m1.dims (); \
00726 dim_vector m2_dims = m2.dims (); \
00727 \
00728 if (m1_dims == m2_dims) \
00729 { \
00730 r.resize (m1_dims); \
00731 \
00732 for (int i = 0; i < m1.length (); i++) \
00733 r.elem(i) = C1 (m1.elem(i)) OP C2 (m2.elem(i)); \
00734 } \
00735 else \
00736 gripe_nonconformant (#F, m1_dims, m2_dims); \
00737 \
00738 return r; \
00739 }
00740
00741 #define NDND_CMP_OPS(ND1, C1, ND2, C2) \
00742 NDND_CMP_OP (mx_el_lt, <, ND1, C1, ND2, C2) \
00743 NDND_CMP_OP (mx_el_le, <=, ND1, C1, ND2, C2) \
00744 NDND_CMP_OP (mx_el_ge, >=, ND1, C1, ND2, C2) \
00745 NDND_CMP_OP (mx_el_gt, >, ND1, C1, ND2, C2) \
00746 NDND_CMP_OP (mx_el_eq, ==, ND1, , ND2, ) \
00747 NDND_CMP_OP (mx_el_ne, !=, ND1, , ND2, )
00748
00749 #define NDND_BOOL_OP_DECLS(ND1, ND2) \
00750 NDBOOL_OP_DECL (mx_el_and, ND1, ND2); \
00751 NDBOOL_OP_DECL (mx_el_or, ND1, ND2);
00752
00753 #define NDND_BOOL_OP(F, OP, ND1, ND2, LHS_ZERO, RHS_ZERO) \
00754 boolNDArray \
00755 F (const ND1& m1, const ND2& m2) \
00756 { \
00757 boolNDArray r; \
00758 \
00759 dim_vector m1_dims = m1.dims (); \
00760 dim_vector m2_dims = m2.dims (); \
00761 \
00762 if (m1_dims == m2_dims) \
00763 { \
00764 if (! m1_dims.all_zero ()) \
00765 { \
00766 r.resize (m1_dims); \
00767 \
00768 for (int i = 0; i < m1.length (); i++) \
00769 r.elem(i) = (m1.elem(i) != LHS_ZERO) OP (m2.elem(i) != RHS_ZERO); \
00770 } \
00771 } \
00772 else \
00773 gripe_nonconformant (#F, m1_dims, m2_dims); \
00774 \
00775 return r; \
00776 }
00777
00778 #define NDND_BOOL_OPS2(ND1, ND2, LHS_ZERO, RHS_ZERO) \
00779 NDND_BOOL_OP (mx_el_and, &&, ND1, ND2, LHS_ZERO, RHS_ZERO) \
00780 NDND_BOOL_OP (mx_el_or, ||, ND1, ND2, LHS_ZERO, RHS_ZERO)
00781
00782 #define NDND_BOOL_OPS(ND1, ND2, ZERO) \
00783 NDND_BOOL_OPS2(ND1, ND2, ZERO, ZERO)
00784
00785 #define NDND_OP_DECLS(R, ND1, ND2) \
00786 NDND_BIN_OP_DECLS (R, ND1, ND2) \
00787 NDND_CMP_OP_DECLS (ND1, ND2) \
00788 NDND_BOOL_OP_DECLS (ND1, ND2)
00789
00790
00791
00792 #define SDM_BIN_OP_DECLS(R, S, DM) \
00793 BIN_OP_DECL (R, operator +, S, DM); \
00794 BIN_OP_DECL (R, operator -, S, DM);
00795
00796 #define SDM_BIN_OP(R, OP, S, DM, OPEQ) \
00797 R \
00798 OP (const S& s, const DM& dm) \
00799 { \
00800 int nr = dm.rows (); \
00801 int nc = dm.cols (); \
00802 \
00803 R r (nr, nc, s); \
00804 \
00805 for (int i = 0; i < dm.length (); i++) \
00806 r.elem(i, i) OPEQ dm.elem(i, i); \
00807 \
00808 return r; \
00809 }
00810
00811 #define SDM_BIN_OPS(R, S, DM) \
00812 SDM_BIN_OP (R, operator +, S, DM, +=) \
00813 SDM_BIN_OP (R, operator -, S, DM, -=)
00814
00815 #define SDM_OP_DECLS(R, S, DM) \
00816 SDM_BIN_OP_DECLS(R, S, DM)
00817
00818
00819
00820 #define DMS_BIN_OP_DECLS(R, DM, S) \
00821 BIN_OP_DECL (R, operator +, DM, S); \
00822 BIN_OP_DECL (R, operator -, DM, S);
00823
00824 #define DMS_BIN_OP(R, OP, DM, S, SGN) \
00825 R \
00826 OP (const DM& dm, const S& s) \
00827 { \
00828 int nr = dm.rows (); \
00829 int nc = dm.cols (); \
00830 \
00831 R r (nr, nc, SGN s); \
00832 \
00833 for (int i = 0; i < dm.length (); i++) \
00834 r.elem(i, i) += dm.elem(i, i); \
00835 \
00836 return r; \
00837 }
00838
00839 #define DMS_BIN_OPS(R, DM, S) \
00840 DMS_BIN_OP (R, operator +, DM, S, ) \
00841 DMS_BIN_OP (R, operator -, DM, S, -)
00842
00843 #define DMS_OP_DECLS(R, DM, S) \
00844 DMS_BIN_OP_DECLS(R, DM, S)
00845
00846
00847
00848 #define MDM_BIN_OP_DECLS(R, M, DM) \
00849 BIN_OP_DECL (R, operator +, M, DM); \
00850 BIN_OP_DECL (R, operator -, M, DM); \
00851 BIN_OP_DECL (R, operator *, M, DM);
00852
00853 #define MDM_BIN_OP(R, OP, M, DM, OPEQ) \
00854 R \
00855 OP (const M& m, const DM& dm) \
00856 { \
00857 R r; \
00858 \
00859 int m_nr = m.rows (); \
00860 int m_nc = m.cols (); \
00861 \
00862 int dm_nr = dm.rows (); \
00863 int dm_nc = dm.cols (); \
00864 \
00865 if (m_nr != dm_nr || m_nc != dm_nc) \
00866 gripe_nonconformant (#OP, m_nr, m_nc, dm_nr, dm_nc); \
00867 else \
00868 { \
00869 r.resize (m_nr, m_nc); \
00870 \
00871 if (m_nr > 0 && m_nc > 0) \
00872 { \
00873 r = R (m); \
00874 \
00875 int len = dm.length (); \
00876 \
00877 for (int i = 0; i < len; i++) \
00878 r.elem(i, i) OPEQ dm.elem(i, i); \
00879 } \
00880 } \
00881 \
00882 return r; \
00883 }
00884
00885 #define MDM_MULTIPLY_OP(R, M, DM, R_ZERO) \
00886 R \
00887 operator * (const M& m, const DM& dm) \
00888 { \
00889 R r; \
00890 \
00891 int m_nr = m.rows (); \
00892 int m_nc = m.cols (); \
00893 \
00894 int dm_nr = dm.rows (); \
00895 int dm_nc = dm.cols (); \
00896 \
00897 if (m_nc != dm_nr) \
00898 gripe_nonconformant ("operator *", m_nr, m_nc, dm_nr, dm_nc); \
00899 else \
00900 { \
00901 r.resize (m_nr, dm_nc, R_ZERO); \
00902 \
00903 if (m_nr > 0 && m_nc > 0 && dm_nc > 0) \
00904 { \
00905 int len = dm.length (); \
00906 \
00907 for (int j = 0; j < len; j++) \
00908 { \
00909 if (dm.elem(j, j) == 1.0) \
00910 { \
00911 for (int i = 0; i < m_nr; i++) \
00912 r.elem(i, j) = m.elem(i, j); \
00913 } \
00914 else \
00915 { \
00916 for (int i = 0; i < m_nr; i++) \
00917 r.elem(i, j) = dm.elem(j, j) * m.elem(i, j); \
00918 } \
00919 } \
00920 } \
00921 } \
00922 \
00923 return r; \
00924 }
00925
00926 #define MDM_BIN_OPS(R, M, DM, R_ZERO) \
00927 MDM_BIN_OP (R, operator +, M, DM, +=) \
00928 MDM_BIN_OP (R, operator -, M, DM, -=) \
00929 MDM_MULTIPLY_OP (R, M, DM, R_ZERO)
00930
00931 #define MDM_OP_DECLS(R, M, DM) \
00932 MDM_BIN_OP_DECLS(R, M, DM)
00933
00934
00935
00936 #define DMM_BIN_OP_DECLS(R, DM, M) \
00937 BIN_OP_DECL (R, operator +, DM, M); \
00938 BIN_OP_DECL (R, operator -, DM, M); \
00939 BIN_OP_DECL (R, operator *, DM, M);
00940
00941 #define DMM_BIN_OP(R, OP, DM, M, OPEQ, PREOP) \
00942 R \
00943 OP (const DM& dm, const M& m) \
00944 { \
00945 R r; \
00946 \
00947 int dm_nr = dm.rows (); \
00948 int dm_nc = dm.cols (); \
00949 \
00950 int m_nr = m.rows (); \
00951 int m_nc = m.cols (); \
00952 \
00953 if (dm_nr != m_nr || dm_nc != m_nc) \
00954 gripe_nonconformant (#OP, dm_nr, dm_nc, m_nr, m_nc); \
00955 else \
00956 { \
00957 if (m_nr > 0 && m_nc > 0) \
00958 { \
00959 r = R (PREOP m); \
00960 \
00961 int len = dm.length (); \
00962 \
00963 for (int i = 0; i < len; i++) \
00964 r.elem(i, i) OPEQ dm.elem(i, i); \
00965 } \
00966 else \
00967 r.resize (m_nr, m_nc); \
00968 } \
00969 \
00970 return r; \
00971 }
00972
00973 #define DMM_MULTIPLY_OP(R, DM, M, R_ZERO) \
00974 R \
00975 operator * (const DM& dm, const M& m) \
00976 { \
00977 R r; \
00978 \
00979 int dm_nr = dm.rows (); \
00980 int dm_nc = dm.cols (); \
00981 \
00982 int m_nr = m.rows (); \
00983 int m_nc = m.cols (); \
00984 \
00985 if (dm_nc != m_nr) \
00986 gripe_nonconformant ("operator *", dm_nr, dm_nc, m_nr, m_nc); \
00987 else \
00988 { \
00989 r.resize (dm_nr, m_nc, R_ZERO); \
00990 \
00991 if (dm_nr > 0 && dm_nc > 0 && m_nc > 0) \
00992 { \
00993 int len = dm.length (); \
00994 \
00995 for (int i = 0; i < len; i++) \
00996 { \
00997 if (dm.elem(i, i) == 1.0) \
00998 { \
00999 for (int j = 0; j < m_nc; j++) \
01000 r.elem(i, j) = m.elem(i, j); \
01001 } \
01002 else \
01003 { \
01004 for (int j = 0; j < m_nc; j++) \
01005 r.elem(i, j) = dm.elem(i, i) * m.elem(i, j); \
01006 } \
01007 } \
01008 } \
01009 } \
01010 \
01011 return r; \
01012 }
01013
01014 #define DMM_BIN_OPS(R, DM, M, R_ZERO) \
01015 DMM_BIN_OP (R, operator +, DM, M, +=, ) \
01016 DMM_BIN_OP (R, operator -, DM, M, +=, -) \
01017 DMM_MULTIPLY_OP (R, DM, M, R_ZERO)
01018
01019 #define DMM_OP_DECLS(R, DM, M) \
01020 DMM_BIN_OP_DECLS(R, DM, M)
01021
01022
01023
01024 #define DMDM_BIN_OP_DECLS(R, DM1, DM2) \
01025 BIN_OP_DECL (R, operator +, DM1, DM2); \
01026 BIN_OP_DECL (R, operator -, DM1, DM2); \
01027 BIN_OP_DECL (R, product, DM1, DM2);
01028
01029 #define DMDM_BIN_OP(R, OP, DM1, DM2, F) \
01030 R \
01031 OP (const DM1& dm1, const DM2& dm2) \
01032 { \
01033 R r; \
01034 \
01035 int dm1_nr = dm1.rows (); \
01036 int dm1_nc = dm1.cols (); \
01037 \
01038 int dm2_nr = dm2.rows (); \
01039 int dm2_nc = dm2.cols (); \
01040 \
01041 if (dm1_nr != dm2_nr || dm1_nc != dm2_nc) \
01042 gripe_nonconformant (#OP, dm1_nr, dm1_nc, dm2_nr, dm2_nc); \
01043 else \
01044 { \
01045 r.resize (dm1_nr, dm1_nc); \
01046 \
01047 if (dm1_nr > 0 && dm1_nc > 0) \
01048 F ## _vv (r.fortran_vec (), dm1.data (), dm2.data (), \
01049 dm1_nr * dm2_nc); \
01050 } \
01051 \
01052 return r; \
01053 }
01054
01055 #define DMDM_BIN_OPS(R, DM1, DM2) \
01056 DMDM_BIN_OP (R, operator +, DM1, DM2, mx_inline_add) \
01057 DMDM_BIN_OP (R, operator -, DM1, DM2, mx_inline_subtract) \
01058 DMDM_BIN_OP (R, product, DM1, DM2, mx_inline_multiply)
01059
01060 #define DMDM_OP_DECLS(R, DM1, DM2) \
01061 DMDM_BIN_OP_DECLS (R, DM1, DM2)
01062
01063 #endif
01064
01065
01066
01067
01068
01069