25 #if !defined (octave_mx_inlines_h)
26 #define octave_mx_inlines_h 1
44 template <
class R,
class S>
46 {
for (
size_t i = 0; i < n; i++)
r[i] = s; }
48 #define DEFMXUNOP(F, OP) \
49 template <class R, class X> \
50 inline void F (size_t n, R *r, const X *x) throw () \
51 { for (size_t i = 0; i < n; i++) r[i] = OP x[i]; }
55 #define DEFMXUNOPEQ(F, OP) \
57 inline void F (size_t n, R *r) throw () \
58 { for (size_t i = 0; i < n; i++) r[i] = OP r[i]; }
62 #define DEFMXUNBOOLOP(F, OP) \
64 inline void F (size_t n, bool *r, const X *x) throw () \
65 { const X zero = X (); for (size_t i = 0; i < n; i++) r[i] = x[i] OP zero; }
70 #define DEFMXBINOP(F, OP) \
71 template <class R, class X, class Y> \
72 inline void F (size_t n, R *r, const X *x, const Y *y) throw () \
73 { for (size_t i = 0; i < n; i++) r[i] = x[i] OP y[i]; } \
74 template <class R, class X, class Y> \
75 inline void F (size_t n, R *r, const X *x, Y y) throw () \
76 { for (size_t i = 0; i < n; i++) r[i] = x[i] OP y; } \
77 template <class R, class X, class Y> \
78 inline void F (size_t n, R *r, X x, const Y *y) throw () \
79 { for (size_t i = 0; i < n; i++) r[i] = x OP y[i]; }
86 #define DEFMXBINOPEQ(F, OP) \
87 template <class R, class X> \
88 inline void F (size_t n, R *r, const X *x) throw () \
89 { for (size_t i = 0; i < n; i++) r[i] OP x[i]; } \
90 template <class R, class X> \
91 inline void F (size_t n, R *r, X x) throw () \
92 { for (size_t i = 0; i < n; i++) r[i] OP x; }
99 #define DEFMXCMPOP(F, OP) \
100 template <class X, class Y> \
101 inline void F (size_t n, bool *r, const X *x, const Y *y) throw () \
102 { for (size_t i = 0; i < n; i++) r[i] = x[i] OP y[i]; } \
103 template <class X, class Y> \
104 inline void F (size_t n, bool *r, const X *x, Y y) throw () \
105 { for (size_t i = 0; i < n; i++) r[i] = x[i] OP y; } \
106 template <class X, class Y> \
107 inline void F (size_t n, bool *r, X x, const Y *y) throw () \
108 { for (size_t i = 0; i < n; i++) r[i] = x OP y[i]; }
120 {
return x.real () != 0 || x.imag () != 0; }
122 {
return x.
value (); }
127 for (
size_t i = 0; i < n; i++)
133 for (
size_t i = 0; i < n; i++)
r[i] = !
r[i];
136 #define DEFMXBOOLOP(F, NOT1, OP, NOT2) \
137 template <class X, class Y> \
138 inline void F (size_t n, bool *r, const X *x, const Y *y) throw () \
140 for (size_t i = 0; i < n; i++) \
141 r[i] = (NOT1 logical_value (x[i])) OP (NOT2 logical_value (y[i])); \
143 template <class X, class Y> \
144 inline void F (size_t n, bool *r, const X *x, Y y) throw () \
146 const bool yy = (NOT2 logical_value (y)); \
147 for (size_t i = 0; i < n; i++) \
148 r[i] = (NOT1 logical_value (x[i])) OP yy; \
150 template <class X, class Y> \
151 inline void F (size_t n, bool *r, X x, const Y *y) throw () \
153 const bool xx = (NOT1 logical_value (x)); \
154 for (size_t i = 0; i < n; i++) \
155 r[i] = xx OP (NOT2 logical_value (y[i])); \
165 #define DEFMXBOOLOPEQ(F, OP) \
167 inline void F (size_t n, bool *r, const X *x) throw () \
169 for (size_t i = 0; i < n; i++) \
170 r[i] OP logical_value (x[i]); \
173 inline void F (size_t n, bool *r, X x) throw () \
174 { for (size_t i = 0; i < n; i++) r[i] OP x; }
183 for (
size_t i = 0; i < n; i++)
196 for (
size_t i = 0; i < n; i++)
209 for (
size_t i = 0; i < n; i++)
222 for (
size_t i = 0; i < n; i++)
235 for (
size_t i = 0; i < n; i++)
237 if (
x[i].
imag () != 0)
244 #define DEFMXMAPPER(F, FUN) \
246 inline void F (size_t n, T *r, const T *x) throw () \
247 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i]); }
251 {
for (
size_t i = 0; i < n; i++)
r[i] =
x[i].
real (); }
254 {
for (
size_t i = 0; i < n; i++)
r[i] =
x[i].
imag (); }
257 #define DEFMXMAPPER2(F, FUN) \
259 inline void F (size_t n, T *r, const T *x, const T *y) throw () \
260 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y[i]); } \
262 inline void F (size_t n, T *r, const T *x, T y) throw () \
263 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y); } \
265 inline void F (size_t n, T *r, T x, const T *y) throw () \
266 { for (size_t i = 0; i < n; i++) r[i] = FUN (x, y[i]); }
272 #define DEFMINMAXSPEC(T, F, OP) \
274 inline void F<T> (size_t n, T *r, const T *x, T y) throw () \
277 std::memcpy (r, x, n * sizeof (T)); \
279 for (size_t i = 0; i < n; i++) r[i] = (x[i] OP y) ? x[i] : y; \
282 inline void F<T> (size_t n, T *r, T x, const T *y) throw () \
285 std::memcpy (r, y, n * sizeof (T)); \
287 for (size_t i = 0; i < n; i++) r[i] = (y[i] OP x) ? y[i] : x; \
296 #define DEFMXMAPPER2X(F, FUN) \
297 template <class R, class X, class Y> \
298 inline void F (size_t n, R *r, const X *x, const Y *y) throw () \
299 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y[i]); } \
300 template <class R, class X, class Y> \
301 inline void F (size_t n, R *r, const X *x, Y y) throw () \
302 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y); } \
303 template <class R, class X, class Y> \
304 inline void F (size_t n, R *r, X x, const Y *y) throw () \
305 { for (size_t i = 0; i < n; i++) r[i] = FUN (x, y[i]); }
314 template <class
R, class X, R fun (X
x)>
316 {
for (
size_t i = 0; i < n; i++) r[i] = fun (
x[i]); }
318 template <
class R,
class X, R fun (const X& x)>
320 {
for (
size_t i = 0; i < n; i++)
r[i] = fun (
x[i]); }
325 template <
class R,
class X>
328 void (*op) (
size_t,
R *,
const X *)
throw ())
337 template <
class R,
class X, R fun (X)>
341 return do_mx_unary_op<R, X> (
x, mx_inline_map<R, X, fun>);
344 template <
class R,
class X, R fun (const X&)>
348 return do_mx_unary_op<R, X> (
x, mx_inline_map<R, X, fun>);
354 void (*op) (
size_t,
R *)
throw ())
360 template <
class R,
class X,
class Y>
363 void (*op) (
size_t,
R *,
const X *,
const Y *)
throw (),
364 void (*op1) (
size_t,
R *, X,
const Y *)
throw (),
365 void (*op2) (
size_t,
R *,
const X *, Y)
throw (),
386 template <
class R,
class X,
class Y>
389 void (*op) (
size_t,
R *,
const X *, Y)
throw ())
396 template <
class R,
class X,
class Y>
399 void (*op) (
size_t,
R *, X,
const Y *)
throw ())
406 template <
class R,
class X>
409 void (*op) (
size_t,
R *,
const X *)
throw (),
410 void (*op1) (
size_t,
R *, X)
throw (),
427 template <
class R,
class X>
430 void (*op) (
size_t,
R *, X)
throw ())
436 template <
class T1,
class T2>
440 for (
size_t i = 0; i < n; i++)
449 bool (*op) (
size_t,
const T *)
throw ())
457 inline T
cabsq (
const std::complex<T>& c)
458 {
return c.real () * c.real () + c.imag () * c.imag (); }
481 #define OP_RED_SUM(ac, el) ac += el
482 #define OP_RED_PROD(ac, el) ac *= el
483 #define OP_RED_SUMSQ(ac, el) ac += el*el
484 #define OP_RED_SUMSQC(ac, el) ac += cabsq (el)
495 #define OP_RED_ANYC(ac, el) if (xis_true (el)) { ac = true; break; } else continue
496 #define OP_RED_ALLC(ac, el) if (xis_false (el)) { ac = false; break; } else continue
498 #define OP_RED_FCN(F, TSRC, TRES, OP, ZERO) \
501 F (const TSRC* v, octave_idx_type n) \
504 for (octave_idx_type i = 0; i < n; i++) \
509 #define PROMOTE_DOUBLE(T) typename subst_template_param<std::complex, T, double>::type
521 #define OP_RED_FCN2(F, TSRC, TRES, OP, ZERO) \
524 F (const TSRC* v, TRES *r, octave_idx_type m, octave_idx_type n) \
526 for (octave_idx_type i = 0; i < m; i++) \
528 for (octave_idx_type j = 0; j < n; j++) \
530 for (octave_idx_type i = 0; i < m; i++) \
537 OP_RED_FCN2 (mx_inline_dsum, T,
PROMOTE_DOUBLE(T), op_dble_sum, 0.0)
538 OP_RED_FCN2 (mx_inline_count,
bool, T, OP_RED_SUM, 0)
539 OP_RED_FCN2 (mx_inline_prod, T, T, OP_RED_PROD, 1)
540 OP_RED_FCN2 (mx_inline_sumsq, T, T, OP_RED_SUMSQ, 0)
541 OP_RED_FCN2 (mx_inline_sumsq, std::complex<T>, T, OP_RED_SUMSQC, 0)
543 #define OP_RED_ANYR(ac, el) ac |= xis_true (el)
544 #define OP_RED_ALLR(ac, el) ac &= xis_true (el)
546 OP_RED_FCN2 (mx_inline_any_r, T,
bool,
OP_RED_ANYR,
false)
547 OP_RED_FCN2 (mx_inline_all_r, T,
bool,
OP_RED_ALLR, true)
553 #define OP_ROW_SHORT_CIRCUIT(F, PRED, ZERO) \
556 F (const T* v, bool *r, octave_idx_type m, octave_idx_type n) \
559 return F ## _r (v, r, m, n); \
562 OCTAVE_LOCAL_BUFFER (octave_idx_type, iact, m); \
563 for (octave_idx_type i = 0; i < m; i++) iact[i] = i; \
564 octave_idx_type nact = m; \
565 for (octave_idx_type j = 0; j < n; j++) \
567 octave_idx_type k = 0; \
568 for (octave_idx_type i = 0; i < nact; i++) \
570 octave_idx_type ia = iact[i]; \
571 if (! PRED (v[ia])) \
577 for (octave_idx_type i = 0; i < m; i++) r[i] = ! ZERO; \
578 for (octave_idx_type i = 0; i < nact; i++) r[iact[i]] = ZERO; \
584 #define OP_RED_FCNN(F, TSRC, TRES) \
587 F (const TSRC *v, TRES *r, octave_idx_type l, \
588 octave_idx_type n, octave_idx_type u) \
592 for (octave_idx_type i = 0; i < u; i++) \
594 r[i] = F<T> (v, n); \
600 for (octave_idx_type i = 0; i < u; i++) \
618 #define OP_CUM_FCN(F, TSRC, TRES, OP) \
621 F (const TSRC *v, TRES *r, octave_idx_type n) \
625 TRES t = r[0] = v[0]; \
626 for (octave_idx_type i = 1; i < n; i++) \
627 r[i] = t = t OP v[i]; \
635 #define OP_CUM_FCN2(F, TSRC, TRES, OP) \
638 F (const TSRC *v, TRES *r, octave_idx_type m, octave_idx_type n) \
642 for (octave_idx_type i = 0; i < m; i++) \
645 for (octave_idx_type j = 1; j < n; j++) \
648 for (octave_idx_type i = 0; i < m; i++) \
649 r[i] = r0[i] OP v[i]; \
659 #define OP_CUM_FCNN(F, TSRC, TRES) \
662 F (const TSRC *v, TRES *r, octave_idx_type l, \
663 octave_idx_type n, octave_idx_type u) \
667 for (octave_idx_type i = 0; i < u; i++) \
675 for (octave_idx_type i = 0; i < u; i++) \
688 #define OP_MINMAX_FCN(F, OP) \
690 void F (const T *v, T *r, octave_idx_type n) \
694 octave_idx_type i = 1; \
697 for (; i < n && xisnan (v[i]); i++) ; \
698 if (i < n) tmp = v[i]; \
701 if (v[i] OP tmp) tmp = v[i]; \
705 void F (const T *v, T *r, octave_idx_type *ri, octave_idx_type n) \
709 octave_idx_type tmpi = 0; \
710 octave_idx_type i = 1; \
713 for (; i < n && xisnan (v[i]); i++) ; \
714 if (i < n) { tmp = v[i]; tmpi = i; } \
717 if (v[i] OP tmp) { tmp = v[i]; tmpi = i; }\
729 #define OP_MINMAX_FCN2(F, OP) \
732 F (const T *v, T *r, octave_idx_type m, octave_idx_type n) \
736 octave_idx_type j = 0; \
737 for (octave_idx_type i = 0; i < m; i++) \
740 if (xisnan (v[i])) nan = true; \
743 while (nan && j < n) \
746 for (octave_idx_type i = 0; i < m; i++) \
750 else if (xisnan (r[i]) || v[i] OP r[i]) \
757 for (octave_idx_type i = 0; i < m; i++) \
758 if (v[i] OP r[i]) r[i] = v[i]; \
764 F (const T *v, T *r, octave_idx_type *ri, \
765 octave_idx_type m, octave_idx_type n) \
769 octave_idx_type j = 0; \
770 for (octave_idx_type i = 0; i < m; i++) \
772 r[i] = v[i]; ri[i] = j; \
773 if (xisnan (v[i])) nan = true; \
776 while (nan && j < n) \
779 for (octave_idx_type i = 0; i < m; i++) \
783 else if (xisnan (r[i]) || v[i] OP r[i]) \
784 { r[i] = v[i]; ri[i] = j; } \
790 for (octave_idx_type i = 0; i < m; i++) \
792 { r[i] = v[i]; ri[i] = j; } \
800 #define OP_MINMAX_FCNN(F) \
803 F (const T *v, T *r, octave_idx_type l, \
804 octave_idx_type n, octave_idx_type u) \
809 for (octave_idx_type i = 0; i < u; i++) \
817 for (octave_idx_type i = 0; i < u; i++) \
827 F (const T *v, T *r, octave_idx_type *ri, \
828 octave_idx_type l, octave_idx_type n, octave_idx_type u) \
833 for (octave_idx_type i = 0; i < u; i++) \
841 for (octave_idx_type i = 0; i < u; i++) \
843 F (v, r, ri, l, n); \
853 #define OP_CUMMINMAX_FCN(F, OP) \
855 void F (const T *v, T *r, octave_idx_type n) \
859 octave_idx_type i = 1, j = 0; \
862 for (; i < n && xisnan (v[i]); i++) ; \
863 for (; j < i; j++) r[j] = tmp; \
864 if (i < n) tmp = v[i]; \
869 for (; j < i; j++) r[j] = tmp; \
872 for (; j < i; j++) r[j] = tmp; \
875 void F (const T *v, T *r, octave_idx_type *ri, octave_idx_type n) \
878 T tmp = v[0]; octave_idx_type tmpi = 0; \
879 octave_idx_type i = 1, j = 0; \
882 for (; i < n && xisnan (v[i]); i++) ; \
883 for (; j < i; j++) { r[j] = tmp; ri[j] = tmpi; } \
884 if (i < n) { tmp = v[i]; tmpi = i; } \
889 for (; j < i; j++) { r[j] = tmp; ri[j] = tmpi; } \
890 tmp = v[i]; tmpi = i; \
892 for (; j < i; j++) { r[j] = tmp; ri[j] = tmpi; } \
902 #define OP_CUMMINMAX_FCN2(F, OP) \
905 F (const T *v, T *r, octave_idx_type m, octave_idx_type n) \
910 octave_idx_type j = 0; \
911 for (octave_idx_type i = 0; i < m; i++) \
914 if (xisnan (v[i])) nan = true; \
916 j++; v += m; r0 = r; r += m; \
917 while (nan && j < n) \
920 for (octave_idx_type i = 0; i < m; i++) \
923 { r[i] = r0[i]; nan = true; } \
924 else if (xisnan (r0[i]) || v[i] OP r0[i]) \
927 j++; v += m; r0 = r; r += m; \
931 for (octave_idx_type i = 0; i < m; i++) \
936 j++; v += m; r0 = r; r += m; \
941 F (const T *v, T *r, octave_idx_type *ri, \
942 octave_idx_type m, octave_idx_type n) \
946 const T *r0; const octave_idx_type *r0i; \
947 octave_idx_type j = 0; \
948 for (octave_idx_type i = 0; i < m; i++) \
950 r[i] = v[i]; ri[i] = 0; \
951 if (xisnan (v[i])) nan = true; \
953 j++; v += m; r0 = r; r += m; r0i = ri; ri += m; \
954 while (nan && j < n) \
957 for (octave_idx_type i = 0; i < m; i++) \
960 { r[i] = r0[i]; ri[i] = r0i[i]; nan = true; } \
961 else if (xisnan (r0[i]) || v[i] OP r0[i]) \
962 { r[i] = v[i]; ri[i] = j; }\
964 j++; v += m; r0 = r; r += m; r0i = ri; ri += m; \
968 for (octave_idx_type i = 0; i < m; i++) \
970 { r[i] = v[i]; ri[i] = j; } \
972 { r[i] = r0[i]; ri[i] = r0i[i]; } \
973 j++; v += m; r0 = r; r += m; r0i = ri; ri += m; \
980 #define OP_CUMMINMAX_FCNN(F) \
983 F (const T *v, T *r, octave_idx_type l, \
984 octave_idx_type n, octave_idx_type u) \
989 for (octave_idx_type i = 0; i < u; i++) \
997 for (octave_idx_type i = 0; i < u; i++) \
1005 template <class T> \
1007 F (const T *v, T *r, octave_idx_type *ri, \
1008 octave_idx_type l, octave_idx_type n, octave_idx_type u) \
1013 for (octave_idx_type i = 0; i < u; i++) \
1016 v += n; r += n; ri += n; \
1021 for (octave_idx_type i = 0; i < u; i++) \
1023 F (v, r, ri, l, n); \
1025 r += l*n; ri += l*n; \
1041 r[i] = v[i+1] - v[i];
1046 T lst = v[1] - v[0];
1049 T
dif = v[i+2] - v[i+1];
1060 buf[i] = v[i+1] - v[i];
1065 buf[i] = buf[i+1] - buf[i];
1083 r[i] = v[i+m] - v[i];
1089 r[j] = (v[j+m+m] - v[j+m]) - (v[j+m] - v[j]);
1099 buf[i] = v[i*m+j+m] - v[i*m+j];
1104 buf[i] = buf[i+1] - buf[i];
1126 v += n; r += n-order;
1160 l = 1, n = dims(dim), u = 1;
1172 template <
class R,
class T>
1181 if (dims.
length () == 2 && dims(0) == 0 && dims(1) == 0)
1187 if (dim < dims.
length ()) dims(dim) = 1;
1191 mx_red_op (src.
data (), ret.fortran_vec (), l, n, u);
1196 template <
class R,
class T>
1208 mx_cum_op (src.
data (), ret.fortran_vec (), l, n, u);
1224 if (dim < dims.
length () && dims(dim) != 0) dims(dim) = 1;
1228 mx_minmax_op (src.
data (), ret.fortran_vec (), l, n, u);
1244 if (dim < dims.
length () && dims(dim) != 0) dims(dim) = 1;
1267 mx_cumminmax_op (src.
data (), ret.fortran_vec (), l, n, u);
1294 void (*mx_diff_op) (
const R *,
R *,
1305 if (dim >= dims.
length ())
1308 if (dims(dim) <= order)
1319 mx_diff_op (src.
data (), ret.fortran_vec (), l, n, u, order);
1333 T s1 = s +
x, t = s1 - s, e1 = (s - (s1 - t)) + (x - t);