Mercurial > jwe > octave
comparison liboctave/operators/mx-inlines.cc @ 21139:538b57866b90
consistently use "typename" intead of "class" in template declarations
* Object.h, QtHandlesUtils.cc, QtHandlesUtils.h, ToolBarButton.cc,
ToolBarButton.h, Cell.h, __lin_interpn__.cc, bitfcns.cc, bsxfun.cc,
cellfun.cc, data.cc, filter.cc, gcd.cc, graphics.cc, help.cc, kron.cc,
lookup.cc, ls-mat5.cc, ls-oct-text.h, lu.cc, max.cc, mgorth.cc,
oct-map.cc, oct-map.h, oct-stream.cc, oct-stream.h, octave-link.h,
pr-output.cc, profiler.h, schur.cc, sparse-xdiv.cc, sparse-xpow.cc,
sqrtm.cc, symtab.h, tril.cc, typecast.cc, variables.cc, xdiv.cc,
zfstream.h, __init_fltk__.cc, __magick_read__.cc, chol.cc, qr.cc,
ov-base-diag.cc, ov-base-diag.h, ov-base-int.cc, ov-base-int.h,
ov-base-mat.cc, ov-base-mat.h, ov-base-scalar.cc, ov-base-scalar.h,
ov-base-sparse.cc, ov-base-sparse.h, ov-base.h, ov-classdef.cc,
ov-int-traits.h, ov-java.h, ov-usr-fcn.h, ov.cc, ov.h,
op-dms-template.cc, oct-parse.in.yy, parse.h, pt-mat.cc, Array-b.cc,
Array.cc, Array.h, CDiagMatrix.h, CMatrix.h, CNDArray.h,
DiagArray2.cc, DiagArray2.h, MArray.cc, MArray.h, MDiagArray2.cc,
MDiagArray2.h, MSparse.cc, MSparse.h, MatrixType.cc, Sparse.cc,
Sparse.h, dDiagMatrix.h, dMatrix.h, dNDArray.h, fCDiagMatrix.h,
fCMatrix.h, fCNDArray.h, fDiagMatrix.h, fMatrix.h, fNDArray.h,
idx-vector.cc, idx-vector.h, intNDArray.cc, intNDArray.h, DET.h,
base-aepbal.h, base-lu.cc, base-lu.h, base-qr.cc, base-qr.h,
bsxfun-defs.cc, eigs-base.cc, lo-mappers.h, lo-specfun.cc,
lo-specfun.h, oct-convn.cc, oct-fftw.cc, oct-norm.cc,
sparse-base-chol.cc, sparse-base-chol.h, sparse-base-lu.cc,
sparse-base-lu.h, sparse-dmsolve.cc, mx-inlines.cc,
action-container.h, base-list.h, lo-traits.h, lo-utils.h,
oct-base64.h, oct-binmap.h, oct-cmplx.h, oct-inttypes.cc,
oct-inttypes.h, oct-locbuf.h, oct-refcount.h, oct-sort.cc, oct-sort.h:
Use "typename" instead of "class" in template declarations.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Sun, 24 Jan 2016 13:50:04 -0500 |
parents | 228b65504557 |
children | 53728df3e4c9 |
comparison
equal
deleted
inserted
replaced
21138:e2fca7d79169 | 21139:538b57866b90 |
---|---|
40 | 40 |
41 #include "bsxfun.h" | 41 #include "bsxfun.h" |
42 | 42 |
43 // Provides some commonly repeated, basic loop templates. | 43 // Provides some commonly repeated, basic loop templates. |
44 | 44 |
45 template <class R, class S> | 45 template <typename R, typename S> |
46 inline void mx_inline_fill (size_t n, R *r, S s) throw () | 46 inline void mx_inline_fill (size_t n, R *r, S s) throw () |
47 { for (size_t i = 0; i < n; i++) r[i] = s; } | 47 { for (size_t i = 0; i < n; i++) r[i] = s; } |
48 | 48 |
49 #define DEFMXUNOP(F, OP) \ | 49 #define DEFMXUNOP(F, OP) \ |
50 template <class R, class X> \ | 50 template <typename R, typename X> \ |
51 inline void F (size_t n, R *r, const X *x) throw () \ | 51 inline void F (size_t n, R *r, const X *x) throw () \ |
52 { for (size_t i = 0; i < n; i++) r[i] = OP x[i]; } | 52 { for (size_t i = 0; i < n; i++) r[i] = OP x[i]; } |
53 | 53 |
54 DEFMXUNOP (mx_inline_uminus, -) | 54 DEFMXUNOP (mx_inline_uminus, -) |
55 | 55 |
56 #define DEFMXUNOPEQ(F, OP) \ | 56 #define DEFMXUNOPEQ(F, OP) \ |
57 template <class R> \ | 57 template <typename R> \ |
58 inline void F (size_t n, R *r) throw () \ | 58 inline void F (size_t n, R *r) throw () \ |
59 { for (size_t i = 0; i < n; i++) r[i] = OP r[i]; } | 59 { for (size_t i = 0; i < n; i++) r[i] = OP r[i]; } |
60 | 60 |
61 DEFMXUNOPEQ (mx_inline_uminus2, -) | 61 DEFMXUNOPEQ (mx_inline_uminus2, -) |
62 | 62 |
63 #define DEFMXUNBOOLOP(F, OP) \ | 63 #define DEFMXUNBOOLOP(F, OP) \ |
64 template <class X> \ | 64 template <typename X> \ |
65 inline void F (size_t n, bool *r, const X *x) throw () \ | 65 inline void F (size_t n, bool *r, const X *x) throw () \ |
66 { const X zero = X (); for (size_t i = 0; i < n; i++) r[i] = x[i] OP zero; } | 66 { const X zero = X (); for (size_t i = 0; i < n; i++) r[i] = x[i] OP zero; } |
67 | 67 |
68 DEFMXUNBOOLOP (mx_inline_iszero, ==) | 68 DEFMXUNBOOLOP (mx_inline_iszero, ==) |
69 DEFMXUNBOOLOP (mx_inline_notzero, !=) | 69 DEFMXUNBOOLOP (mx_inline_notzero, !=) |
70 | 70 |
71 #define DEFMXBINOP(F, OP) \ | 71 #define DEFMXBINOP(F, OP) \ |
72 template <class R, class X, class Y> \ | 72 template <typename R, typename X, typename Y> \ |
73 inline void F (size_t n, R *r, const X *x, const Y *y) throw () \ | 73 inline void F (size_t n, R *r, const X *x, const Y *y) throw () \ |
74 { for (size_t i = 0; i < n; i++) r[i] = x[i] OP y[i]; } \ | 74 { for (size_t i = 0; i < n; i++) r[i] = x[i] OP y[i]; } \ |
75 template <class R, class X, class Y> \ | 75 template <typename R, typename X, typename Y> \ |
76 inline void F (size_t n, R *r, const X *x, Y y) throw () \ | 76 inline void F (size_t n, R *r, const X *x, Y y) throw () \ |
77 { for (size_t i = 0; i < n; i++) r[i] = x[i] OP y; } \ | 77 { for (size_t i = 0; i < n; i++) r[i] = x[i] OP y; } \ |
78 template <class R, class X, class Y> \ | 78 template <typename R, typename X, typename Y> \ |
79 inline void F (size_t n, R *r, X x, const Y *y) throw () \ | 79 inline void F (size_t n, R *r, X x, const Y *y) throw () \ |
80 { for (size_t i = 0; i < n; i++) r[i] = x OP y[i]; } | 80 { for (size_t i = 0; i < n; i++) r[i] = x OP y[i]; } |
81 | 81 |
82 DEFMXBINOP (mx_inline_add, +) | 82 DEFMXBINOP (mx_inline_add, +) |
83 DEFMXBINOP (mx_inline_sub, -) | 83 DEFMXBINOP (mx_inline_sub, -) |
84 DEFMXBINOP (mx_inline_mul, *) | 84 DEFMXBINOP (mx_inline_mul, *) |
85 DEFMXBINOP (mx_inline_div, /) | 85 DEFMXBINOP (mx_inline_div, /) |
86 | 86 |
87 #define DEFMXBINOPEQ(F, OP) \ | 87 #define DEFMXBINOPEQ(F, OP) \ |
88 template <class R, class X> \ | 88 template <typename R, typename X> \ |
89 inline void F (size_t n, R *r, const X *x) throw () \ | 89 inline void F (size_t n, R *r, const X *x) throw () \ |
90 { for (size_t i = 0; i < n; i++) r[i] OP x[i]; } \ | 90 { for (size_t i = 0; i < n; i++) r[i] OP x[i]; } \ |
91 template <class R, class X> \ | 91 template <typename R, typename X> \ |
92 inline void F (size_t n, R *r, X x) throw () \ | 92 inline void F (size_t n, R *r, X x) throw () \ |
93 { for (size_t i = 0; i < n; i++) r[i] OP x; } | 93 { for (size_t i = 0; i < n; i++) r[i] OP x; } |
94 | 94 |
95 DEFMXBINOPEQ (mx_inline_add2, +=) | 95 DEFMXBINOPEQ (mx_inline_add2, +=) |
96 DEFMXBINOPEQ (mx_inline_sub2, -=) | 96 DEFMXBINOPEQ (mx_inline_sub2, -=) |
97 DEFMXBINOPEQ (mx_inline_mul2, *=) | 97 DEFMXBINOPEQ (mx_inline_mul2, *=) |
98 DEFMXBINOPEQ (mx_inline_div2, /=) | 98 DEFMXBINOPEQ (mx_inline_div2, /=) |
99 | 99 |
100 #define DEFMXCMPOP(F, OP) \ | 100 #define DEFMXCMPOP(F, OP) \ |
101 template <class X, class Y> \ | 101 template <typename X, typename Y> \ |
102 inline void F (size_t n, bool *r, const X *x, const Y *y) throw () \ | 102 inline void F (size_t n, bool *r, const X *x, const Y *y) throw () \ |
103 { for (size_t i = 0; i < n; i++) r[i] = x[i] OP y[i]; } \ | 103 { for (size_t i = 0; i < n; i++) r[i] = x[i] OP y[i]; } \ |
104 template <class X, class Y> \ | 104 template <typename X, typename Y> \ |
105 inline void F (size_t n, bool *r, const X *x, Y y) throw () \ | 105 inline void F (size_t n, bool *r, const X *x, Y y) throw () \ |
106 { for (size_t i = 0; i < n; i++) r[i] = x[i] OP y; } \ | 106 { for (size_t i = 0; i < n; i++) r[i] = x[i] OP y; } \ |
107 template <class X, class Y> \ | 107 template <typename X, typename Y> \ |
108 inline void F (size_t n, bool *r, X x, const Y *y) throw () \ | 108 inline void F (size_t n, bool *r, X x, const Y *y) throw () \ |
109 { for (size_t i = 0; i < n; i++) r[i] = x OP y[i]; } | 109 { for (size_t i = 0; i < n; i++) r[i] = x OP y[i]; } |
110 | 110 |
111 DEFMXCMPOP (mx_inline_lt, <) | 111 DEFMXCMPOP (mx_inline_lt, <) |
112 DEFMXCMPOP (mx_inline_le, <=) | 112 DEFMXCMPOP (mx_inline_le, <=) |
114 DEFMXCMPOP (mx_inline_ge, >=) | 114 DEFMXCMPOP (mx_inline_ge, >=) |
115 DEFMXCMPOP (mx_inline_eq, ==) | 115 DEFMXCMPOP (mx_inline_eq, ==) |
116 DEFMXCMPOP (mx_inline_ne, !=) | 116 DEFMXCMPOP (mx_inline_ne, !=) |
117 | 117 |
118 // Convert to logical value, for logical op purposes. | 118 // Convert to logical value, for logical op purposes. |
119 template <class T> inline bool logical_value (T x) { return x; } | 119 template <typename T> inline bool logical_value (T x) { return x; } |
120 template <class T> inline bool logical_value (const std::complex<T>& x) | 120 template <typename T> inline bool logical_value (const std::complex<T>& x) |
121 { return x.real () != 0 || x.imag () != 0; } | 121 { return x.real () != 0 || x.imag () != 0; } |
122 template <class T> inline bool logical_value (const octave_int<T>& x) | 122 template <typename T> inline bool logical_value (const octave_int<T>& x) |
123 { return x.value (); } | 123 { return x.value (); } |
124 | 124 |
125 template <class X> | 125 template <typename X> |
126 void mx_inline_not (size_t n, bool *r, const X* x) throw () | 126 void mx_inline_not (size_t n, bool *r, const X* x) throw () |
127 { | 127 { |
128 for (size_t i = 0; i < n; i++) | 128 for (size_t i = 0; i < n; i++) |
129 r[i] = ! logical_value (x[i]); | 129 r[i] = ! logical_value (x[i]); |
130 } | 130 } |
133 { | 133 { |
134 for (size_t i = 0; i < n; i++) r[i] = ! r[i]; | 134 for (size_t i = 0; i < n; i++) r[i] = ! r[i]; |
135 } | 135 } |
136 | 136 |
137 #define DEFMXBOOLOP(F, NOT1, OP, NOT2) \ | 137 #define DEFMXBOOLOP(F, NOT1, OP, NOT2) \ |
138 template <class X, class Y> \ | 138 template <typename X, typename Y> \ |
139 inline void F (size_t n, bool *r, const X *x, const Y *y) throw () \ | 139 inline void F (size_t n, bool *r, const X *x, const Y *y) throw () \ |
140 { \ | 140 { \ |
141 for (size_t i = 0; i < n; i++) \ | 141 for (size_t i = 0; i < n; i++) \ |
142 r[i] = (NOT1 logical_value (x[i])) OP (NOT2 logical_value (y[i])); \ | 142 r[i] = (NOT1 logical_value (x[i])) OP (NOT2 logical_value (y[i])); \ |
143 } \ | 143 } \ |
144 template <class X, class Y> \ | 144 template <typename X, typename Y> \ |
145 inline void F (size_t n, bool *r, const X *x, Y y) throw () \ | 145 inline void F (size_t n, bool *r, const X *x, Y y) throw () \ |
146 { \ | 146 { \ |
147 const bool yy = (NOT2 logical_value (y)); \ | 147 const bool yy = (NOT2 logical_value (y)); \ |
148 for (size_t i = 0; i < n; i++) \ | 148 for (size_t i = 0; i < n; i++) \ |
149 r[i] = (NOT1 logical_value (x[i])) OP yy; \ | 149 r[i] = (NOT1 logical_value (x[i])) OP yy; \ |
150 } \ | 150 } \ |
151 template <class X, class Y> \ | 151 template <typename X, typename Y> \ |
152 inline void F (size_t n, bool *r, X x, const Y *y) throw () \ | 152 inline void F (size_t n, bool *r, X x, const Y *y) throw () \ |
153 { \ | 153 { \ |
154 const bool xx = (NOT1 logical_value (x)); \ | 154 const bool xx = (NOT1 logical_value (x)); \ |
155 for (size_t i = 0; i < n; i++) \ | 155 for (size_t i = 0; i < n; i++) \ |
156 r[i] = xx OP (NOT2 logical_value (y[i])); \ | 156 r[i] = xx OP (NOT2 logical_value (y[i])); \ |
162 DEFMXBOOLOP (mx_inline_not_or, !, |, ) | 162 DEFMXBOOLOP (mx_inline_not_or, !, |, ) |
163 DEFMXBOOLOP (mx_inline_and_not, , &, !) | 163 DEFMXBOOLOP (mx_inline_and_not, , &, !) |
164 DEFMXBOOLOP (mx_inline_or_not, , |, !) | 164 DEFMXBOOLOP (mx_inline_or_not, , |, !) |
165 | 165 |
166 #define DEFMXBOOLOPEQ(F, OP) \ | 166 #define DEFMXBOOLOPEQ(F, OP) \ |
167 template <class X> \ | 167 template <typename X> \ |
168 inline void F (size_t n, bool *r, const X *x) throw () \ | 168 inline void F (size_t n, bool *r, const X *x) throw () \ |
169 { \ | 169 { \ |
170 for (size_t i = 0; i < n; i++) \ | 170 for (size_t i = 0; i < n; i++) \ |
171 r[i] OP logical_value (x[i]); \ | 171 r[i] OP logical_value (x[i]); \ |
172 } \ | 172 } \ |
173 template <class X> \ | 173 template <typename X> \ |
174 inline void F (size_t n, bool *r, X x) throw () \ | 174 inline void F (size_t n, bool *r, X x) throw () \ |
175 { for (size_t i = 0; i < n; i++) r[i] OP x; } | 175 { for (size_t i = 0; i < n; i++) r[i] OP x; } |
176 | 176 |
177 DEFMXBOOLOPEQ (mx_inline_and2, &=) | 177 DEFMXBOOLOPEQ (mx_inline_and2, &=) |
178 DEFMXBOOLOPEQ (mx_inline_or2, |=) | 178 DEFMXBOOLOPEQ (mx_inline_or2, |=) |
179 | 179 |
180 template <class T> | 180 template <typename T> |
181 inline bool | 181 inline bool |
182 mx_inline_any_nan (size_t n, const T* x) throw () | 182 mx_inline_any_nan (size_t n, const T* x) throw () |
183 { | 183 { |
184 for (size_t i = 0; i < n; i++) | 184 for (size_t i = 0; i < n; i++) |
185 { | 185 { |
188 } | 188 } |
189 | 189 |
190 return false; | 190 return false; |
191 } | 191 } |
192 | 192 |
193 template <class T> | 193 template <typename T> |
194 inline bool | 194 inline bool |
195 mx_inline_all_finite (size_t n, const T* x) throw () | 195 mx_inline_all_finite (size_t n, const T* x) throw () |
196 { | 196 { |
197 for (size_t i = 0; i < n; i++) | 197 for (size_t i = 0; i < n; i++) |
198 { | 198 { |
201 } | 201 } |
202 | 202 |
203 return true; | 203 return true; |
204 } | 204 } |
205 | 205 |
206 template <class T> | 206 template <typename T> |
207 inline bool | 207 inline bool |
208 mx_inline_any_negative (size_t n, const T* x) throw () | 208 mx_inline_any_negative (size_t n, const T* x) throw () |
209 { | 209 { |
210 for (size_t i = 0; i < n; i++) | 210 for (size_t i = 0; i < n; i++) |
211 { | 211 { |
214 } | 214 } |
215 | 215 |
216 return false; | 216 return false; |
217 } | 217 } |
218 | 218 |
219 template <class T> | 219 template <typename T> |
220 inline bool | 220 inline bool |
221 mx_inline_any_positive (size_t n, const T* x) throw () | 221 mx_inline_any_positive (size_t n, const T* x) throw () |
222 { | 222 { |
223 for (size_t i = 0; i < n; i++) | 223 for (size_t i = 0; i < n; i++) |
224 { | 224 { |
227 } | 227 } |
228 | 228 |
229 return false; | 229 return false; |
230 } | 230 } |
231 | 231 |
232 template<class T> | 232 template <typename T> |
233 inline bool | 233 inline bool |
234 mx_inline_all_real (size_t n, const std::complex<T>* x) throw () | 234 mx_inline_all_real (size_t n, const std::complex<T>* x) throw () |
235 { | 235 { |
236 for (size_t i = 0; i < n; i++) | 236 for (size_t i = 0; i < n; i++) |
237 { | 237 { |
241 | 241 |
242 return true; | 242 return true; |
243 } | 243 } |
244 | 244 |
245 #define DEFMXMAPPER(F, FUN) \ | 245 #define DEFMXMAPPER(F, FUN) \ |
246 template <class T> \ | 246 template <typename T> \ |
247 inline void F (size_t n, T *r, const T *x) throw () \ | 247 inline void F (size_t n, T *r, const T *x) throw () \ |
248 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i]); } | 248 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i]); } |
249 | 249 |
250 template<class T> | 250 template <typename T> |
251 inline void mx_inline_real (size_t n, T *r, const std::complex<T>* x) throw () | 251 inline void mx_inline_real (size_t n, T *r, const std::complex<T>* x) throw () |
252 { for (size_t i = 0; i < n; i++) r[i] = x[i].real (); } | 252 { for (size_t i = 0; i < n; i++) r[i] = x[i].real (); } |
253 template<class T> | 253 template <typename T> |
254 inline void mx_inline_imag (size_t n, T *r, const std::complex<T>* x) throw () | 254 inline void mx_inline_imag (size_t n, T *r, const std::complex<T>* x) throw () |
255 { for (size_t i = 0; i < n; i++) r[i] = x[i].imag (); } | 255 { for (size_t i = 0; i < n; i++) r[i] = x[i].imag (); } |
256 | 256 |
257 // Pairwise minimums/maximums | 257 // Pairwise minimums/maximums |
258 #define DEFMXMAPPER2(F, FUN) \ | 258 #define DEFMXMAPPER2(F, FUN) \ |
259 template <class T> \ | 259 template <typename T> \ |
260 inline void F (size_t n, T *r, const T *x, const T *y) throw () \ | 260 inline void F (size_t n, T *r, const T *x, const T *y) throw () \ |
261 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y[i]); } \ | 261 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y[i]); } \ |
262 template <class T> \ | 262 template <typename T> \ |
263 inline void F (size_t n, T *r, const T *x, T y) throw () \ | 263 inline void F (size_t n, T *r, const T *x, T y) throw () \ |
264 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y); } \ | 264 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y); } \ |
265 template <class T> \ | 265 template <typename T> \ |
266 inline void F (size_t n, T *r, T x, const T *y) throw () \ | 266 inline void F (size_t n, T *r, T x, const T *y) throw () \ |
267 { for (size_t i = 0; i < n; i++) r[i] = FUN (x, y[i]); } | 267 { for (size_t i = 0; i < n; i++) r[i] = FUN (x, y[i]); } |
268 | 268 |
269 DEFMXMAPPER2 (mx_inline_xmin, xmin) | 269 DEFMXMAPPER2 (mx_inline_xmin, xmin) |
270 DEFMXMAPPER2 (mx_inline_xmax, xmax) | 270 DEFMXMAPPER2 (mx_inline_xmax, xmax) |
293 DEFMINMAXSPEC (float, mx_inline_xmin, <=) | 293 DEFMINMAXSPEC (float, mx_inline_xmin, <=) |
294 DEFMINMAXSPEC (float, mx_inline_xmax, >=) | 294 DEFMINMAXSPEC (float, mx_inline_xmax, >=) |
295 | 295 |
296 // Pairwise power | 296 // Pairwise power |
297 #define DEFMXMAPPER2X(F, FUN) \ | 297 #define DEFMXMAPPER2X(F, FUN) \ |
298 template <class R, class X, class Y> \ | 298 template <typename R, typename X, typename Y> \ |
299 inline void F (size_t n, R *r, const X *x, const Y *y) throw () \ | 299 inline void F (size_t n, R *r, const X *x, const Y *y) throw () \ |
300 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y[i]); } \ | 300 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y[i]); } \ |
301 template <class R, class X, class Y> \ | 301 template <typename R, typename X, typename Y> \ |
302 inline void F (size_t n, R *r, const X *x, Y y) throw () \ | 302 inline void F (size_t n, R *r, const X *x, Y y) throw () \ |
303 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y); } \ | 303 { for (size_t i = 0; i < n; i++) r[i] = FUN (x[i], y); } \ |
304 template <class R, class X, class Y> \ | 304 template <typename R, typename X, typename Y> \ |
305 inline void F (size_t n, R *r, X x, const Y *y) throw () \ | 305 inline void F (size_t n, R *r, X x, const Y *y) throw () \ |
306 { for (size_t i = 0; i < n; i++) r[i] = FUN (x, y[i]); } | 306 { for (size_t i = 0; i < n; i++) r[i] = FUN (x, y[i]); } |
307 | 307 |
308 // Let the compiler decide which pow to use, whichever best matches the | 308 // Let the compiler decide which pow to use, whichever best matches the |
309 // arguments provided. | 309 // arguments provided. |
310 using std::pow; | 310 using std::pow; |
311 DEFMXMAPPER2X (mx_inline_pow, pow) | 311 DEFMXMAPPER2X (mx_inline_pow, pow) |
312 | 312 |
313 // Arbitrary function appliers. The function is a template parameter to enable | 313 // Arbitrary function appliers. The function is a template parameter to enable |
314 // inlining. | 314 // inlining. |
315 template <class R, class X, R fun (X x)> | 315 template <typename R, typename X, R fun (X x)> |
316 inline void mx_inline_map (size_t n, R *r, const X *x) throw () | 316 inline void mx_inline_map (size_t n, R *r, const X *x) throw () |
317 { for (size_t i = 0; i < n; i++) r[i] = fun (x[i]); } | 317 { for (size_t i = 0; i < n; i++) r[i] = fun (x[i]); } |
318 | 318 |
319 template <class R, class X, R fun (const X& x)> | 319 template <typename R, typename X, R fun (const X& x)> |
320 inline void mx_inline_map (size_t n, R *r, const X *x) throw () | 320 inline void mx_inline_map (size_t n, R *r, const X *x) throw () |
321 { for (size_t i = 0; i < n; i++) r[i] = fun (x[i]); } | 321 { for (size_t i = 0; i < n; i++) r[i] = fun (x[i]); } |
322 | 322 |
323 // Appliers. Since these call the operation just once, we pass it as | 323 // Appliers. Since these call the operation just once, we pass it as |
324 // a pointer, to allow the compiler reduce number of instances. | 324 // a pointer, to allow the compiler reduce number of instances. |
325 | 325 |
326 template <class R, class X> | 326 template <typename R, typename X> |
327 inline Array<R> | 327 inline Array<R> |
328 do_mx_unary_op (const Array<X>& x, | 328 do_mx_unary_op (const Array<X>& x, |
329 void (*op) (size_t, R *, const X *) throw ()) | 329 void (*op) (size_t, R *, const X *) throw ()) |
330 { | 330 { |
331 Array<R> r (x.dims ()); | 331 Array<R> r (x.dims ()); |
333 return r; | 333 return r; |
334 } | 334 } |
335 | 335 |
336 // Shortcuts for applying mx_inline_map. | 336 // Shortcuts for applying mx_inline_map. |
337 | 337 |
338 template <class R, class X, R fun (X)> | 338 template <typename R, typename X, R fun (X)> |
339 inline Array<R> | 339 inline Array<R> |
340 do_mx_unary_map (const Array<X>& x) | 340 do_mx_unary_map (const Array<X>& x) |
341 { | 341 { |
342 return do_mx_unary_op<R, X> (x, mx_inline_map<R, X, fun>); | 342 return do_mx_unary_op<R, X> (x, mx_inline_map<R, X, fun>); |
343 } | 343 } |
344 | 344 |
345 template <class R, class X, R fun (const X&)> | 345 template <typename R, typename X, R fun (const X&)> |
346 inline Array<R> | 346 inline Array<R> |
347 do_mx_unary_map (const Array<X>& x) | 347 do_mx_unary_map (const Array<X>& x) |
348 { | 348 { |
349 return do_mx_unary_op<R, X> (x, mx_inline_map<R, X, fun>); | 349 return do_mx_unary_op<R, X> (x, mx_inline_map<R, X, fun>); |
350 } | 350 } |
351 | 351 |
352 template <class R> | 352 template <typename R> |
353 inline Array<R>& | 353 inline Array<R>& |
354 do_mx_inplace_op (Array<R>& r, | 354 do_mx_inplace_op (Array<R>& r, |
355 void (*op) (size_t, R *) throw ()) | 355 void (*op) (size_t, R *) throw ()) |
356 { | 356 { |
357 op (r.numel (), r.fortran_vec ()); | 357 op (r.numel (), r.fortran_vec ()); |
358 return r; | 358 return r; |
359 } | 359 } |
360 | 360 |
361 template <class R, class X, class Y> | 361 template <typename R, typename X, typename Y> |
362 inline Array<R> | 362 inline Array<R> |
363 do_mm_binary_op (const Array<X>& x, const Array<Y>& y, | 363 do_mm_binary_op (const Array<X>& x, const Array<Y>& y, |
364 void (*op) (size_t, R *, const X *, const Y *) throw (), | 364 void (*op) (size_t, R *, const X *, const Y *) throw (), |
365 void (*op1) (size_t, R *, X, const Y *) throw (), | 365 void (*op1) (size_t, R *, X, const Y *) throw (), |
366 void (*op2) (size_t, R *, const X *, Y) throw (), | 366 void (*op2) (size_t, R *, const X *, Y) throw (), |
380 } | 380 } |
381 else | 381 else |
382 err_nonconformant (opname, dx, dy); | 382 err_nonconformant (opname, dx, dy); |
383 } | 383 } |
384 | 384 |
385 template <class R, class X, class Y> | 385 template <typename R, typename X, typename Y> |
386 inline Array<R> | 386 inline Array<R> |
387 do_ms_binary_op (const Array<X>& x, const Y& y, | 387 do_ms_binary_op (const Array<X>& x, const Y& y, |
388 void (*op) (size_t, R *, const X *, Y) throw ()) | 388 void (*op) (size_t, R *, const X *, Y) throw ()) |
389 { | 389 { |
390 Array<R> r (x.dims ()); | 390 Array<R> r (x.dims ()); |
391 op (r.numel (), r.fortran_vec (), x.data (), y); | 391 op (r.numel (), r.fortran_vec (), x.data (), y); |
392 return r; | 392 return r; |
393 } | 393 } |
394 | 394 |
395 template <class R, class X, class Y> | 395 template <typename R, typename X, typename Y> |
396 inline Array<R> | 396 inline Array<R> |
397 do_sm_binary_op (const X& x, const Array<Y>& y, | 397 do_sm_binary_op (const X& x, const Array<Y>& y, |
398 void (*op) (size_t, R *, X, const Y *) throw ()) | 398 void (*op) (size_t, R *, X, const Y *) throw ()) |
399 { | 399 { |
400 Array<R> r (y.dims ()); | 400 Array<R> r (y.dims ()); |
401 op (r.numel (), r.fortran_vec (), x, y.data ()); | 401 op (r.numel (), r.fortran_vec (), x, y.data ()); |
402 return r; | 402 return r; |
403 } | 403 } |
404 | 404 |
405 template <class R, class X> | 405 template <typename R, typename X> |
406 inline Array<R>& | 406 inline Array<R>& |
407 do_mm_inplace_op (Array<R>& r, const Array<X>& x, | 407 do_mm_inplace_op (Array<R>& r, const Array<X>& x, |
408 void (*op) (size_t, R *, const X *) throw (), | 408 void (*op) (size_t, R *, const X *) throw (), |
409 void (*op1) (size_t, R *, X) throw (), | 409 void (*op1) (size_t, R *, X) throw (), |
410 const char *opname) | 410 const char *opname) |
419 err_nonconformant (opname, dr, dx); | 419 err_nonconformant (opname, dr, dx); |
420 | 420 |
421 return r; | 421 return r; |
422 } | 422 } |
423 | 423 |
424 template <class R, class X> | 424 template <typename R, typename X> |
425 inline Array<R>& | 425 inline Array<R>& |
426 do_ms_inplace_op (Array<R>& r, const X& x, | 426 do_ms_inplace_op (Array<R>& r, const X& x, |
427 void (*op) (size_t, R *, X) throw ()) | 427 void (*op) (size_t, R *, X) throw ()) |
428 { | 428 { |
429 op (r.numel (), r.fortran_vec (), x); | 429 op (r.numel (), r.fortran_vec (), x); |
430 return r; | 430 return r; |
431 } | 431 } |
432 | 432 |
433 template <class T1, class T2> | 433 template <typename T1, typename T2> |
434 inline bool | 434 inline bool |
435 mx_inline_equal (size_t n, const T1 *x, const T2 *y) throw () | 435 mx_inline_equal (size_t n, const T1 *x, const T2 *y) throw () |
436 { | 436 { |
437 for (size_t i = 0; i < n; i++) | 437 for (size_t i = 0; i < n; i++) |
438 if (x[i] != y[i]) | 438 if (x[i] != y[i]) |
439 return false; | 439 return false; |
440 return true; | 440 return true; |
441 } | 441 } |
442 | 442 |
443 template <class T> | 443 template <typename T> |
444 inline bool | 444 inline bool |
445 do_mx_check (const Array<T>& a, | 445 do_mx_check (const Array<T>& a, |
446 bool (*op) (size_t, const T *) throw ()) | 446 bool (*op) (size_t, const T *) throw ()) |
447 { | 447 { |
448 return op (a.numel (), a.data ()); | 448 return op (a.numel (), a.data ()); |
449 } | 449 } |
450 | 450 |
451 // NOTE: we don't use std::norm because it typically does some heavyweight | 451 // NOTE: we don't use std::norm because it typically does some heavyweight |
452 // magic to avoid underflows, which we don't need here. | 452 // magic to avoid underflows, which we don't need here. |
453 template <class T> | 453 template <typename T> |
454 inline T cabsq (const std::complex<T>& c) | 454 inline T cabsq (const std::complex<T>& c) |
455 { return c.real () * c.real () + c.imag () * c.imag (); } | 455 { return c.real () * c.real () + c.imag () * c.imag (); } |
456 | 456 |
457 // default. works for integers and bool. | 457 // default. works for integers and bool. |
458 template <class T> | 458 template <typename T> |
459 inline bool xis_true (T x) { return x; } | 459 inline bool xis_true (T x) { return x; } |
460 template <class T> | 460 template <typename T> |
461 inline bool xis_false (T x) { return ! x; } | 461 inline bool xis_false (T x) { return ! x; } |
462 // for octave_ints | 462 // for octave_ints |
463 template <class T> | 463 template <typename T> |
464 inline bool xis_true (const octave_int<T>& x) { return x.value (); } | 464 inline bool xis_true (const octave_int<T>& x) { return x.value (); } |
465 template <class T> | 465 template <typename T> |
466 inline bool xis_false (const octave_int<T>& x) { return ! x.value (); } | 466 inline bool xis_false (const octave_int<T>& x) { return ! x.value (); } |
467 // for reals, we want to ignore NaNs. | 467 // for reals, we want to ignore NaNs. |
468 inline bool xis_true (double x) { return ! xisnan (x) && x != 0.0; } | 468 inline bool xis_true (double x) { return ! xisnan (x) && x != 0.0; } |
469 inline bool xis_false (double x) { return x == 0.0; } | 469 inline bool xis_false (double x) { return x == 0.0; } |
470 inline bool xis_true (float x) { return ! xisnan (x) && x != 0.0f; } | 470 inline bool xis_true (float x) { return ! xisnan (x) && x != 0.0f; } |
482 | 482 |
483 inline void op_dble_prod (double& ac, float el) | 483 inline void op_dble_prod (double& ac, float el) |
484 { ac *= el; } | 484 { ac *= el; } |
485 inline void op_dble_prod (Complex& ac, const FloatComplex& el) | 485 inline void op_dble_prod (Complex& ac, const FloatComplex& el) |
486 { ac *= el; } // FIXME: guaranteed? | 486 { ac *= el; } // FIXME: guaranteed? |
487 template <class T> | 487 template <typename T> |
488 inline void op_dble_prod (double& ac, const octave_int<T>& el) | 488 inline void op_dble_prod (double& ac, const octave_int<T>& el) |
489 { ac *= el.double_value (); } | 489 { ac *= el.double_value (); } |
490 | 490 |
491 inline void op_dble_sum (double& ac, float el) | 491 inline void op_dble_sum (double& ac, float el) |
492 { ac += el; } | 492 { ac += el; } |
493 inline void op_dble_sum (Complex& ac, const FloatComplex& el) | 493 inline void op_dble_sum (Complex& ac, const FloatComplex& el) |
494 { ac += el; } // FIXME: guaranteed? | 494 { ac += el; } // FIXME: guaranteed? |
495 template <class T> | 495 template <typename T> |
496 inline void op_dble_sum (double& ac, const octave_int<T>& el) | 496 inline void op_dble_sum (double& ac, const octave_int<T>& el) |
497 { ac += el.double_value (); } | 497 { ac += el.double_value (); } |
498 | 498 |
499 // The following two implement a simple short-circuiting. | 499 // The following two implement a simple short-circuiting. |
500 #define OP_RED_ANYC(ac, el) if (xis_true (el)) { ac = true; break; } else continue | 500 #define OP_RED_ANYC(ac, el) if (xis_true (el)) { ac = true; break; } else continue |
501 #define OP_RED_ALLC(ac, el) if (xis_false (el)) { ac = false; break; } else continue | 501 #define OP_RED_ALLC(ac, el) if (xis_false (el)) { ac = false; break; } else continue |
502 | 502 |
503 #define OP_RED_FCN(F, TSRC, TRES, OP, ZERO) \ | 503 #define OP_RED_FCN(F, TSRC, TRES, OP, ZERO) \ |
504 template <class T> \ | 504 template <typename T> \ |
505 inline TRES \ | 505 inline TRES \ |
506 F (const TSRC* v, octave_idx_type n) \ | 506 F (const TSRC* v, octave_idx_type n) \ |
507 { \ | 507 { \ |
508 TRES ac = ZERO; \ | 508 TRES ac = ZERO; \ |
509 for (octave_idx_type i = 0; i < n; i++) \ | 509 for (octave_idx_type i = 0; i < n; i++) \ |
523 OP_RED_FCN (mx_inline_any, T, bool, OP_RED_ANYC, false) | 523 OP_RED_FCN (mx_inline_any, T, bool, OP_RED_ANYC, false) |
524 OP_RED_FCN (mx_inline_all, T, bool, OP_RED_ALLC, true) | 524 OP_RED_FCN (mx_inline_all, T, bool, OP_RED_ALLC, true) |
525 | 525 |
526 | 526 |
527 #define OP_RED_FCN2(F, TSRC, TRES, OP, ZERO) \ | 527 #define OP_RED_FCN2(F, TSRC, TRES, OP, ZERO) \ |
528 template <class T> \ | 528 template <typename T> \ |
529 inline void \ | 529 inline void \ |
530 F (const TSRC* v, TRES *r, octave_idx_type m, octave_idx_type n) \ | 530 F (const TSRC* v, TRES *r, octave_idx_type m, octave_idx_type n) \ |
531 { \ | 531 { \ |
532 for (octave_idx_type i = 0; i < m; i++) \ | 532 for (octave_idx_type i = 0; i < m; i++) \ |
533 r[i] = ZERO; \ | 533 r[i] = ZERO; \ |
556 // Using the general code for any/all would sacrifice short-circuiting. | 556 // Using the general code for any/all would sacrifice short-circuiting. |
557 // OTOH, going by rows would sacrifice cache-coherence. The following algorithm | 557 // OTOH, going by rows would sacrifice cache-coherence. The following algorithm |
558 // will achieve both, at the cost of a temporary octave_idx_type array. | 558 // will achieve both, at the cost of a temporary octave_idx_type array. |
559 | 559 |
560 #define OP_ROW_SHORT_CIRCUIT(F, PRED, ZERO) \ | 560 #define OP_ROW_SHORT_CIRCUIT(F, PRED, ZERO) \ |
561 template <class T> \ | 561 template <typename T> \ |
562 inline void \ | 562 inline void \ |
563 F (const T* v, bool *r, octave_idx_type m, octave_idx_type n) \ | 563 F (const T* v, bool *r, octave_idx_type m, octave_idx_type n) \ |
564 { \ | 564 { \ |
565 if (n <= 8) \ | 565 if (n <= 8) \ |
566 return F ## _r (v, r, m, n); \ | 566 return F ## _r (v, r, m, n); \ |
587 | 587 |
588 OP_ROW_SHORT_CIRCUIT (mx_inline_any, xis_true, false) | 588 OP_ROW_SHORT_CIRCUIT (mx_inline_any, xis_true, false) |
589 OP_ROW_SHORT_CIRCUIT (mx_inline_all, xis_false, true) | 589 OP_ROW_SHORT_CIRCUIT (mx_inline_all, xis_false, true) |
590 | 590 |
591 #define OP_RED_FCNN(F, TSRC, TRES) \ | 591 #define OP_RED_FCNN(F, TSRC, TRES) \ |
592 template <class T> \ | 592 template <typename T> \ |
593 inline void \ | 593 inline void \ |
594 F (const TSRC *v, TRES *r, octave_idx_type l, \ | 594 F (const TSRC *v, TRES *r, octave_idx_type l, \ |
595 octave_idx_type n, octave_idx_type u) \ | 595 octave_idx_type n, octave_idx_type u) \ |
596 { \ | 596 { \ |
597 if (l == 1) \ | 597 if (l == 1) \ |
622 OP_RED_FCNN (mx_inline_sumsq, std::complex<T>, T) | 622 OP_RED_FCNN (mx_inline_sumsq, std::complex<T>, T) |
623 OP_RED_FCNN (mx_inline_any, T, bool) | 623 OP_RED_FCNN (mx_inline_any, T, bool) |
624 OP_RED_FCNN (mx_inline_all, T, bool) | 624 OP_RED_FCNN (mx_inline_all, T, bool) |
625 | 625 |
626 #define OP_CUM_FCN(F, TSRC, TRES, OP) \ | 626 #define OP_CUM_FCN(F, TSRC, TRES, OP) \ |
627 template <class T> \ | 627 template <typename T> \ |
628 inline void \ | 628 inline void \ |
629 F (const TSRC *v, TRES *r, octave_idx_type n) \ | 629 F (const TSRC *v, TRES *r, octave_idx_type n) \ |
630 { \ | 630 { \ |
631 if (n) \ | 631 if (n) \ |
632 { \ | 632 { \ |
639 OP_CUM_FCN (mx_inline_cumsum, T, T, +) | 639 OP_CUM_FCN (mx_inline_cumsum, T, T, +) |
640 OP_CUM_FCN (mx_inline_cumprod, T, T, *) | 640 OP_CUM_FCN (mx_inline_cumprod, T, T, *) |
641 OP_CUM_FCN (mx_inline_cumcount, bool, T, +) | 641 OP_CUM_FCN (mx_inline_cumcount, bool, T, +) |
642 | 642 |
643 #define OP_CUM_FCN2(F, TSRC, TRES, OP) \ | 643 #define OP_CUM_FCN2(F, TSRC, TRES, OP) \ |
644 template <class T> \ | 644 template <typename T> \ |
645 inline void \ | 645 inline void \ |
646 F (const TSRC *v, TRES *r, octave_idx_type m, octave_idx_type n) \ | 646 F (const TSRC *v, TRES *r, octave_idx_type m, octave_idx_type n) \ |
647 { \ | 647 { \ |
648 if (n) \ | 648 if (n) \ |
649 { \ | 649 { \ |
663 OP_CUM_FCN2 (mx_inline_cumsum, T, T, +) | 663 OP_CUM_FCN2 (mx_inline_cumsum, T, T, +) |
664 OP_CUM_FCN2 (mx_inline_cumprod, T, T, *) | 664 OP_CUM_FCN2 (mx_inline_cumprod, T, T, *) |
665 OP_CUM_FCN2 (mx_inline_cumcount, bool, T, +) | 665 OP_CUM_FCN2 (mx_inline_cumcount, bool, T, +) |
666 | 666 |
667 #define OP_CUM_FCNN(F, TSRC, TRES) \ | 667 #define OP_CUM_FCNN(F, TSRC, TRES) \ |
668 template <class T> \ | 668 template <typename T> \ |
669 inline void \ | 669 inline void \ |
670 F (const TSRC *v, TRES *r, octave_idx_type l, \ | 670 F (const TSRC *v, TRES *r, octave_idx_type l, \ |
671 octave_idx_type n, octave_idx_type u) \ | 671 octave_idx_type n, octave_idx_type u) \ |
672 { \ | 672 { \ |
673 if (l == 1) \ | 673 if (l == 1) \ |
692 OP_CUM_FCNN (mx_inline_cumsum, T, T) | 692 OP_CUM_FCNN (mx_inline_cumsum, T, T) |
693 OP_CUM_FCNN (mx_inline_cumprod, T, T) | 693 OP_CUM_FCNN (mx_inline_cumprod, T, T) |
694 OP_CUM_FCNN (mx_inline_cumcount, bool, T) | 694 OP_CUM_FCNN (mx_inline_cumcount, bool, T) |
695 | 695 |
696 #define OP_MINMAX_FCN(F, OP) \ | 696 #define OP_MINMAX_FCN(F, OP) \ |
697 template <class T> \ | 697 template <typename T> \ |
698 void F (const T *v, T *r, octave_idx_type n) \ | 698 void F (const T *v, T *r, octave_idx_type n) \ |
699 { \ | 699 { \ |
700 if (! n) return; \ | 700 if (! n) return; \ |
701 T tmp = v[0]; \ | 701 T tmp = v[0]; \ |
702 octave_idx_type i = 1; \ | 702 octave_idx_type i = 1; \ |
707 } \ | 707 } \ |
708 for (; i < n; i++) \ | 708 for (; i < n; i++) \ |
709 if (v[i] OP tmp) tmp = v[i]; \ | 709 if (v[i] OP tmp) tmp = v[i]; \ |
710 *r = tmp; \ | 710 *r = tmp; \ |
711 } \ | 711 } \ |
712 template <class T> \ | 712 template <typename T> \ |
713 void F (const T *v, T *r, octave_idx_type *ri, octave_idx_type n) \ | 713 void F (const T *v, T *r, octave_idx_type *ri, octave_idx_type n) \ |
714 { \ | 714 { \ |
715 if (! n) return; \ | 715 if (! n) return; \ |
716 T tmp = v[0]; \ | 716 T tmp = v[0]; \ |
717 octave_idx_type tmpi = 0; \ | 717 octave_idx_type tmpi = 0; \ |
733 // Row reductions will be slightly complicated. We will proceed with checks | 733 // Row reductions will be slightly complicated. We will proceed with checks |
734 // for NaNs until we detect that no row will yield a NaN, in which case we | 734 // for NaNs until we detect that no row will yield a NaN, in which case we |
735 // proceed to a faster code. | 735 // proceed to a faster code. |
736 | 736 |
737 #define OP_MINMAX_FCN2(F, OP) \ | 737 #define OP_MINMAX_FCN2(F, OP) \ |
738 template <class T> \ | 738 template <typename T> \ |
739 inline void \ | 739 inline void \ |
740 F (const T *v, T *r, octave_idx_type m, octave_idx_type n) \ | 740 F (const T *v, T *r, octave_idx_type m, octave_idx_type n) \ |
741 { \ | 741 { \ |
742 if (! n) return; \ | 742 if (! n) return; \ |
743 bool nan = false; \ | 743 bool nan = false; \ |
765 for (octave_idx_type i = 0; i < m; i++) \ | 765 for (octave_idx_type i = 0; i < m; i++) \ |
766 if (v[i] OP r[i]) r[i] = v[i]; \ | 766 if (v[i] OP r[i]) r[i] = v[i]; \ |
767 j++; v += m; \ | 767 j++; v += m; \ |
768 } \ | 768 } \ |
769 } \ | 769 } \ |
770 template <class T> \ | 770 template <typename T> \ |
771 inline void \ | 771 inline void \ |
772 F (const T *v, T *r, octave_idx_type *ri, \ | 772 F (const T *v, T *r, octave_idx_type *ri, \ |
773 octave_idx_type m, octave_idx_type n) \ | 773 octave_idx_type m, octave_idx_type n) \ |
774 { \ | 774 { \ |
775 if (! n) return; \ | 775 if (! n) return; \ |
804 | 804 |
805 OP_MINMAX_FCN2 (mx_inline_min, <) | 805 OP_MINMAX_FCN2 (mx_inline_min, <) |
806 OP_MINMAX_FCN2 (mx_inline_max, >) | 806 OP_MINMAX_FCN2 (mx_inline_max, >) |
807 | 807 |
808 #define OP_MINMAX_FCNN(F) \ | 808 #define OP_MINMAX_FCNN(F) \ |
809 template <class T> \ | 809 template <typename T> \ |
810 inline void \ | 810 inline void \ |
811 F (const T *v, T *r, octave_idx_type l, \ | 811 F (const T *v, T *r, octave_idx_type l, \ |
812 octave_idx_type n, octave_idx_type u) \ | 812 octave_idx_type n, octave_idx_type u) \ |
813 { \ | 813 { \ |
814 if (! n) return; \ | 814 if (! n) return; \ |
828 v += l*n; \ | 828 v += l*n; \ |
829 r += l; \ | 829 r += l; \ |
830 } \ | 830 } \ |
831 } \ | 831 } \ |
832 } \ | 832 } \ |
833 template <class T> \ | 833 template <typename T> \ |
834 inline void \ | 834 inline void \ |
835 F (const T *v, T *r, octave_idx_type *ri, \ | 835 F (const T *v, T *r, octave_idx_type *ri, \ |
836 octave_idx_type l, octave_idx_type n, octave_idx_type u) \ | 836 octave_idx_type l, octave_idx_type n, octave_idx_type u) \ |
837 { \ | 837 { \ |
838 if (! n) return; \ | 838 if (! n) return; \ |
857 | 857 |
858 OP_MINMAX_FCNN (mx_inline_min) | 858 OP_MINMAX_FCNN (mx_inline_min) |
859 OP_MINMAX_FCNN (mx_inline_max) | 859 OP_MINMAX_FCNN (mx_inline_max) |
860 | 860 |
861 #define OP_CUMMINMAX_FCN(F, OP) \ | 861 #define OP_CUMMINMAX_FCN(F, OP) \ |
862 template <class T> \ | 862 template <typename T> \ |
863 void F (const T *v, T *r, octave_idx_type n) \ | 863 void F (const T *v, T *r, octave_idx_type n) \ |
864 { \ | 864 { \ |
865 if (! n) return; \ | 865 if (! n) return; \ |
866 T tmp = v[0]; \ | 866 T tmp = v[0]; \ |
867 octave_idx_type i = 1; \ | 867 octave_idx_type i = 1; \ |
878 for (; j < i; j++) r[j] = tmp; \ | 878 for (; j < i; j++) r[j] = tmp; \ |
879 tmp = v[i]; \ | 879 tmp = v[i]; \ |
880 } \ | 880 } \ |
881 for (; j < i; j++) r[j] = tmp; \ | 881 for (; j < i; j++) r[j] = tmp; \ |
882 } \ | 882 } \ |
883 template <class T> \ | 883 template <typename T> \ |
884 void F (const T *v, T *r, octave_idx_type *ri, octave_idx_type n) \ | 884 void F (const T *v, T *r, octave_idx_type *ri, octave_idx_type n) \ |
885 { \ | 885 { \ |
886 if (! n) return; \ | 886 if (! n) return; \ |
887 T tmp = v[0]; octave_idx_type tmpi = 0; \ | 887 T tmp = v[0]; octave_idx_type tmpi = 0; \ |
888 octave_idx_type i = 1; \ | 888 octave_idx_type i = 1; \ |
908 // Row reductions will be slightly complicated. We will proceed with checks | 908 // Row reductions will be slightly complicated. We will proceed with checks |
909 // for NaNs until we detect that no row will yield a NaN, in which case we | 909 // for NaNs until we detect that no row will yield a NaN, in which case we |
910 // proceed to a faster code. | 910 // proceed to a faster code. |
911 | 911 |
912 #define OP_CUMMINMAX_FCN2(F, OP) \ | 912 #define OP_CUMMINMAX_FCN2(F, OP) \ |
913 template <class T> \ | 913 template <typename T> \ |
914 inline void \ | 914 inline void \ |
915 F (const T *v, T *r, octave_idx_type m, octave_idx_type n) \ | 915 F (const T *v, T *r, octave_idx_type m, octave_idx_type n) \ |
916 { \ | 916 { \ |
917 if (! n) return; \ | 917 if (! n) return; \ |
918 bool nan = false; \ | 918 bool nan = false; \ |
946 else \ | 946 else \ |
947 r[i] = r0[i]; \ | 947 r[i] = r0[i]; \ |
948 j++; v += m; r0 = r; r += m; \ | 948 j++; v += m; r0 = r; r += m; \ |
949 } \ | 949 } \ |
950 } \ | 950 } \ |
951 template <class T> \ | 951 template <typename T> \ |
952 inline void \ | 952 inline void \ |
953 F (const T *v, T *r, octave_idx_type *ri, \ | 953 F (const T *v, T *r, octave_idx_type *ri, \ |
954 octave_idx_type m, octave_idx_type n) \ | 954 octave_idx_type m, octave_idx_type n) \ |
955 { \ | 955 { \ |
956 if (! n) return; \ | 956 if (! n) return; \ |
990 | 990 |
991 OP_CUMMINMAX_FCN2 (mx_inline_cummin, <) | 991 OP_CUMMINMAX_FCN2 (mx_inline_cummin, <) |
992 OP_CUMMINMAX_FCN2 (mx_inline_cummax, >) | 992 OP_CUMMINMAX_FCN2 (mx_inline_cummax, >) |
993 | 993 |
994 #define OP_CUMMINMAX_FCNN(F) \ | 994 #define OP_CUMMINMAX_FCNN(F) \ |
995 template <class T> \ | 995 template <typename T> \ |
996 inline void \ | 996 inline void \ |
997 F (const T *v, T *r, octave_idx_type l, \ | 997 F (const T *v, T *r, octave_idx_type l, \ |
998 octave_idx_type n, octave_idx_type u) \ | 998 octave_idx_type n, octave_idx_type u) \ |
999 { \ | 999 { \ |
1000 if (! n) return; \ | 1000 if (! n) return; \ |
1014 v += l*n; \ | 1014 v += l*n; \ |
1015 r += l*n; \ | 1015 r += l*n; \ |
1016 } \ | 1016 } \ |
1017 } \ | 1017 } \ |
1018 } \ | 1018 } \ |
1019 template <class T> \ | 1019 template <typename T> \ |
1020 inline void \ | 1020 inline void \ |
1021 F (const T *v, T *r, octave_idx_type *ri, \ | 1021 F (const T *v, T *r, octave_idx_type *ri, \ |
1022 octave_idx_type l, octave_idx_type n, octave_idx_type u) \ | 1022 octave_idx_type l, octave_idx_type n, octave_idx_type u) \ |
1023 { \ | 1023 { \ |
1024 if (! n) return; \ | 1024 if (! n) return; \ |
1042 } | 1042 } |
1043 | 1043 |
1044 OP_CUMMINMAX_FCNN (mx_inline_cummin) | 1044 OP_CUMMINMAX_FCNN (mx_inline_cummin) |
1045 OP_CUMMINMAX_FCNN (mx_inline_cummax) | 1045 OP_CUMMINMAX_FCNN (mx_inline_cummax) |
1046 | 1046 |
1047 template <class T> | 1047 template <typename T> |
1048 void mx_inline_diff (const T *v, T *r, octave_idx_type n, | 1048 void mx_inline_diff (const T *v, T *r, octave_idx_type n, |
1049 octave_idx_type order) | 1049 octave_idx_type order) |
1050 { | 1050 { |
1051 switch (order) | 1051 switch (order) |
1052 { | 1052 { |
1083 r[i] = buf[i]; | 1083 r[i] = buf[i]; |
1084 } | 1084 } |
1085 } | 1085 } |
1086 } | 1086 } |
1087 | 1087 |
1088 template <class T> | 1088 template <typename T> |
1089 void mx_inline_diff (const T *v, T *r, | 1089 void mx_inline_diff (const T *v, T *r, |
1090 octave_idx_type m, octave_idx_type n, | 1090 octave_idx_type m, octave_idx_type n, |
1091 octave_idx_type order) | 1091 octave_idx_type order) |
1092 { | 1092 { |
1093 switch (order) | 1093 switch (order) |
1123 } | 1123 } |
1124 } | 1124 } |
1125 } | 1125 } |
1126 } | 1126 } |
1127 | 1127 |
1128 template <class T> | 1128 template <typename T> |
1129 inline void | 1129 inline void |
1130 mx_inline_diff (const T *v, T *r, | 1130 mx_inline_diff (const T *v, T *r, |
1131 octave_idx_type l, octave_idx_type n, octave_idx_type u, | 1131 octave_idx_type l, octave_idx_type n, octave_idx_type u, |
1132 octave_idx_type order) | 1132 octave_idx_type order) |
1133 { | 1133 { |
1181 | 1181 |
1182 // Appliers. | 1182 // Appliers. |
1183 // FIXME: is this the best design? C++ gives a lot of options here... | 1183 // FIXME: is this the best design? C++ gives a lot of options here... |
1184 // maybe it can be done without an explicit parameter? | 1184 // maybe it can be done without an explicit parameter? |
1185 | 1185 |
1186 template <class R, class T> | 1186 template <typename R, typename T> |
1187 inline Array<R> | 1187 inline Array<R> |
1188 do_mx_red_op (const Array<T>& src, int dim, | 1188 do_mx_red_op (const Array<T>& src, int dim, |
1189 void (*mx_red_op) (const T *, R *, octave_idx_type, | 1189 void (*mx_red_op) (const T *, R *, octave_idx_type, |
1190 octave_idx_type, octave_idx_type)) | 1190 octave_idx_type, octave_idx_type)) |
1191 { | 1191 { |
1205 mx_red_op (src.data (), ret.fortran_vec (), l, n, u); | 1205 mx_red_op (src.data (), ret.fortran_vec (), l, n, u); |
1206 | 1206 |
1207 return ret; | 1207 return ret; |
1208 } | 1208 } |
1209 | 1209 |
1210 template <class R, class T> | 1210 template <typename R, typename T> |
1211 inline Array<R> | 1211 inline Array<R> |
1212 do_mx_cum_op (const Array<T>& src, int dim, | 1212 do_mx_cum_op (const Array<T>& src, int dim, |
1213 void (*mx_cum_op) (const T *, R *, octave_idx_type, | 1213 void (*mx_cum_op) (const T *, R *, octave_idx_type, |
1214 octave_idx_type, octave_idx_type)) | 1214 octave_idx_type, octave_idx_type)) |
1215 { | 1215 { |
1222 mx_cum_op (src.data (), ret.fortran_vec (), l, n, u); | 1222 mx_cum_op (src.data (), ret.fortran_vec (), l, n, u); |
1223 | 1223 |
1224 return ret; | 1224 return ret; |
1225 } | 1225 } |
1226 | 1226 |
1227 template <class R> | 1227 template <typename R> |
1228 inline Array<R> | 1228 inline Array<R> |
1229 do_mx_minmax_op (const Array<R>& src, int dim, | 1229 do_mx_minmax_op (const Array<R>& src, int dim, |
1230 void (*mx_minmax_op) (const R *, R *, octave_idx_type, | 1230 void (*mx_minmax_op) (const R *, R *, octave_idx_type, |
1231 octave_idx_type, octave_idx_type)) | 1231 octave_idx_type, octave_idx_type)) |
1232 { | 1232 { |
1242 mx_minmax_op (src.data (), ret.fortran_vec (), l, n, u); | 1242 mx_minmax_op (src.data (), ret.fortran_vec (), l, n, u); |
1243 | 1243 |
1244 return ret; | 1244 return ret; |
1245 } | 1245 } |
1246 | 1246 |
1247 template <class R> | 1247 template <typename R> |
1248 inline Array<R> | 1248 inline Array<R> |
1249 do_mx_minmax_op (const Array<R>& src, Array<octave_idx_type>& idx, int dim, | 1249 do_mx_minmax_op (const Array<R>& src, Array<octave_idx_type>& idx, int dim, |
1250 void (*mx_minmax_op) (const R *, R *, octave_idx_type *, | 1250 void (*mx_minmax_op) (const R *, R *, octave_idx_type *, |
1251 octave_idx_type, octave_idx_type, octave_idx_type)) | 1251 octave_idx_type, octave_idx_type, octave_idx_type)) |
1252 { | 1252 { |
1265 l, n, u); | 1265 l, n, u); |
1266 | 1266 |
1267 return ret; | 1267 return ret; |
1268 } | 1268 } |
1269 | 1269 |
1270 template <class R> | 1270 template <typename R> |
1271 inline Array<R> | 1271 inline Array<R> |
1272 do_mx_cumminmax_op (const Array<R>& src, int dim, | 1272 do_mx_cumminmax_op (const Array<R>& src, int dim, |
1273 void (*mx_cumminmax_op) (const R *, R *, octave_idx_type, | 1273 void (*mx_cumminmax_op) (const R *, R *, octave_idx_type, |
1274 octave_idx_type, octave_idx_type)) | 1274 octave_idx_type, octave_idx_type)) |
1275 { | 1275 { |
1281 mx_cumminmax_op (src.data (), ret.fortran_vec (), l, n, u); | 1281 mx_cumminmax_op (src.data (), ret.fortran_vec (), l, n, u); |
1282 | 1282 |
1283 return ret; | 1283 return ret; |
1284 } | 1284 } |
1285 | 1285 |
1286 template <class R> | 1286 template <typename R> |
1287 inline Array<R> | 1287 inline Array<R> |
1288 do_mx_cumminmax_op (const Array<R>& src, Array<octave_idx_type>& idx, int dim, | 1288 do_mx_cumminmax_op (const Array<R>& src, Array<octave_idx_type>& idx, int dim, |
1289 void (*mx_cumminmax_op) (const R *, R *, octave_idx_type *, | 1289 void (*mx_cumminmax_op) (const R *, R *, octave_idx_type *, |
1290 octave_idx_type, octave_idx_type, octave_idx_type)) | 1290 octave_idx_type, octave_idx_type, octave_idx_type)) |
1291 { | 1291 { |
1300 l, n, u); | 1300 l, n, u); |
1301 | 1301 |
1302 return ret; | 1302 return ret; |
1303 } | 1303 } |
1304 | 1304 |
1305 template <class R> | 1305 template <typename R> |
1306 inline Array<R> | 1306 inline Array<R> |
1307 do_mx_diff_op (const Array<R>& src, int dim, octave_idx_type order, | 1307 do_mx_diff_op (const Array<R>& src, int dim, octave_idx_type order, |
1308 void (*mx_diff_op) (const R *, R *, | 1308 void (*mx_diff_op) (const R *, R *, |
1309 octave_idx_type, octave_idx_type, octave_idx_type, | 1309 octave_idx_type, octave_idx_type, octave_idx_type, |
1310 octave_idx_type)) | 1310 octave_idx_type)) |
1338 // Fast extra-precise summation. According to | 1338 // Fast extra-precise summation. According to |
1339 // T. Ogita, S. M. Rump, S. Oishi: | 1339 // T. Ogita, S. M. Rump, S. Oishi: |
1340 // Accurate Sum And Dot Product, | 1340 // Accurate Sum And Dot Product, |
1341 // SIAM J. Sci. Computing, Vol. 26, 2005 | 1341 // SIAM J. Sci. Computing, Vol. 26, 2005 |
1342 | 1342 |
1343 template <class T> | 1343 template <typename T> |
1344 inline void twosum_accum (T& s, T& e, | 1344 inline void twosum_accum (T& s, T& e, |
1345 const T& x) | 1345 const T& x) |
1346 { | 1346 { |
1347 T s1 = s + x; | 1347 T s1 = s + x; |
1348 T t = s1 - s; | 1348 T t = s1 - s; |
1349 T e1 = (s - (s1 - t)) + (x - t); | 1349 T e1 = (s - (s1 - t)) + (x - t); |
1350 s = s1; | 1350 s = s1; |
1351 e += e1; | 1351 e += e1; |
1352 } | 1352 } |
1353 | 1353 |
1354 template <class T> | 1354 template <typename T> |
1355 inline T | 1355 inline T |
1356 mx_inline_xsum (const T *v, octave_idx_type n) | 1356 mx_inline_xsum (const T *v, octave_idx_type n) |
1357 { | 1357 { |
1358 T s, e; | 1358 T s, e; |
1359 s = e = 0; | 1359 s = e = 0; |
1361 twosum_accum (s, e, v[i]); | 1361 twosum_accum (s, e, v[i]); |
1362 | 1362 |
1363 return s + e; | 1363 return s + e; |
1364 } | 1364 } |
1365 | 1365 |
1366 template <class T> | 1366 template <typename T> |
1367 inline void | 1367 inline void |
1368 mx_inline_xsum (const T *v, T *r, | 1368 mx_inline_xsum (const T *v, T *r, |
1369 octave_idx_type m, octave_idx_type n) | 1369 octave_idx_type m, octave_idx_type n) |
1370 { | 1370 { |
1371 OCTAVE_LOCAL_BUFFER (T, e, m); | 1371 OCTAVE_LOCAL_BUFFER (T, e, m); |