GNU Octave  4.0.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
mx-inlines.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1993-2015 John W. Eaton
4 Copyright (C) 2009 Jaroslav Hajek
5 Copyright (C) 2009 VZLU Prague
6 
7 This file is part of Octave.
8 
9 Octave is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13 
14 Octave is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Octave; see the file COPYING. If not, see
21 <http://www.gnu.org/licenses/>.
22 
23 */
24 
25 #if !defined (octave_mx_inlines_h)
26 #define octave_mx_inlines_h 1
27 
28 #include <cstddef>
29 #include <cmath>
30 #include <cstring>
31 #include <memory>
32 
33 #include "quit.h"
34 
35 #include "oct-cmplx.h"
36 #include "oct-locbuf.h"
37 #include "oct-inttypes.h"
38 #include "Array.h"
39 #include "Array-util.h"
40 
41 #include "bsxfun.h"
42 
43 // Provides some commonly repeated, basic loop templates.
44 
45 template <class R, class S>
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; }
48 
49 #define DEFMXUNOP(F, OP) \
50 template <class R, class X> \
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]; }
53 
55 
56 #define DEFMXUNOPEQ(F, OP) \
57 template <class R> \
58 inline void F (size_t n, R *r) throw () \
59 { for (size_t i = 0; i < n; i++) r[i] = OP r[i]; }
60 
62 
63 #define DEFMXUNBOOLOP(F, OP) \
64 template <class X> \
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; }
67 
70 
71 #define DEFMXBINOP(F, OP) \
72 template <class R, class X, class Y> \
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]; } \
75 template <class R, class X, class Y> \
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; } \
78 template <class R, class X, class Y> \
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]; }
81 
86 
87 #define DEFMXBINOPEQ(F, OP) \
88 template <class R, class X> \
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]; } \
91 template <class R, class X> \
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; }
94 
99 
100 #define DEFMXCMPOP(F, OP) \
101 template <class X, class Y> \
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]; } \
104 template <class X, class Y> \
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; } \
107 template <class X, class Y> \
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]; }
110 
117 
118 // Convert to logical value, for logical op purposes.
119 template <class T> inline bool logical_value (T x) { return x; }
120 template <class T> inline bool logical_value (const std::complex<T>& x)
121 { return x.real () != 0 || x.imag () != 0; }
122 template <class T> inline bool logical_value (const octave_int<T>& x)
123 { return x.value (); }
124 
125 template <class X>
126 void mx_inline_not (size_t n, bool *r, const X* x) throw ()
127 {
128  for (size_t i = 0; i < n; i++)
129  r[i] = ! logical_value (x[i]);
130 }
131 
132 inline void mx_inline_not2 (size_t n, bool *r) throw ()
133 {
134  for (size_t i = 0; i < n; i++) r[i] = ! r[i];
135 }
136 
137 #define DEFMXBOOLOP(F, NOT1, OP, NOT2) \
138 template <class X, class Y> \
139 inline void F (size_t n, bool *r, const X *x, const Y *y) throw () \
140 { \
141  for (size_t i = 0; i < n; i++) \
142  r[i] = (NOT1 logical_value (x[i])) OP (NOT2 logical_value (y[i])); \
143 } \
144 template <class X, class Y> \
145 inline void F (size_t n, bool *r, const X *x, Y y) throw () \
146 { \
147  const bool yy = (NOT2 logical_value (y)); \
148  for (size_t i = 0; i < n; i++) \
149  r[i] = (NOT1 logical_value (x[i])) OP yy; \
150 } \
151 template <class X, class Y> \
152 inline void F (size_t n, bool *r, X x, const Y *y) throw () \
153 { \
154  const bool xx = (NOT1 logical_value (x)); \
155  for (size_t i = 0; i < n; i++) \
156  r[i] = xx OP (NOT2 logical_value (y[i])); \
157 }
158 
165 
166 #define DEFMXBOOLOPEQ(F, OP) \
167 template <class X> \
168 inline void F (size_t n, bool *r, const X *x) throw () \
169 { \
170  for (size_t i = 0; i < n; i++) \
171  r[i] OP logical_value (x[i]); \
172 } \
173 template <class X> \
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; }
176 
179 
180 template <class T>
181 inline bool
182 mx_inline_any_nan (size_t n, const T* x) throw ()
183 {
184  for (size_t i = 0; i < n; i++)
185  {
186  if (xisnan (x[i]))
187  return true;
188  }
189 
190  return false;
191 }
192 
193 template <class T>
194 inline bool
195 mx_inline_all_finite (size_t n, const T* x) throw ()
196 {
197  for (size_t i = 0; i < n; i++)
198  {
199  if (! xfinite (x[i]))
200  return false;
201  }
202 
203  return true;
204 }
205 
206 template <class T>
207 inline bool
208 mx_inline_any_negative (size_t n, const T* x) throw ()
209 {
210  for (size_t i = 0; i < n; i++)
211  {
212  if (x[i] < 0)
213  return true;
214  }
215 
216  return false;
217 }
218 
219 template <class T>
220 inline bool
221 mx_inline_any_positive (size_t n, const T* x) throw ()
222 {
223  for (size_t i = 0; i < n; i++)
224  {
225  if (x[i] > 0)
226  return true;
227  }
228 
229  return false;
230 }
231 
232 template<class T>
233 inline bool
234 mx_inline_all_real (size_t n, const std::complex<T>* x) throw ()
235 {
236  for (size_t i = 0; i < n; i++)
237  {
238  if (x[i].imag () != 0)
239  return false;
240  }
241 
242  return true;
243 }
244 
245 #define DEFMXMAPPER(F, FUN) \
246 template <class T> \
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]); }
249 
250 template<class T>
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 (); }
253 template<class T>
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 (); }
256 
257 // Pairwise minimums/maximums
258 #define DEFMXMAPPER2(F, FUN) \
259 template <class T> \
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]); } \
262 template <class T> \
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); } \
265 template <class T> \
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]); }
268 
271 
272 // Specialize array-scalar max/min
273 #define DEFMINMAXSPEC(T, F, OP) \
274 template <> \
275 inline void F<T> (size_t n, T *r, const T *x, T y) throw () \
276 { \
277  if (xisnan (y)) \
278  std::memcpy (r, x, n * sizeof (T)); \
279  else \
280  for (size_t i = 0; i < n; i++) r[i] = (x[i] OP y) ? x[i] : y; \
281 } \
282 template <> \
283 inline void F<T> (size_t n, T *r, T x, const T *y) throw () \
284 { \
285  if (xisnan (x)) \
286  std::memcpy (r, y, n * sizeof (T)); \
287  else \
288  for (size_t i = 0; i < n; i++) r[i] = (y[i] OP x) ? y[i] : x; \
289 }
290 
292 DEFMINMAXSPEC (double, mx_inline_xmax, >=)
294 DEFMINMAXSPEC (float, mx_inline_xmax, >=)
295 
296 // Pairwise power
297 #define DEFMXMAPPER2X(F, FUN) \
298 template <class R, class X, class Y> \
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]); } \
301 template <class R, class X, class Y> \
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); } \
304 template <class R, class X, class Y> \
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]); }
307 
308 // Let the compiler decide which pow to use, whichever best matches the
309 // arguments provided.
310 using std::pow;
312 
313 // Arbitrary function appliers. The function is a template parameter to enable
314 // inlining.
315 template <class R, class X, R fun (X x)>
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]); }
318 
319 template <class R, class X, R fun (const X& x)>
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]); }
322 
323 // Appliers. Since these call the operation just once, we pass it as
324 // a pointer, to allow the compiler reduce number of instances.
325 
326 template <class R, class X>
327 inline Array<R>
329  void (*op) (size_t, R *, const X *) throw ())
330 {
331  Array<R> r (x.dims ());
332  op (r.numel (), r.fortran_vec (), x.data ());
333  return r;
334 }
335 
336 // Shortcuts for applying mx_inline_map.
337 
338 template <class R, class X, R fun (X)>
339 inline Array<R>
341 {
342  return do_mx_unary_op<R, X> (x, mx_inline_map<R, X, fun>);
343 }
344 
345 template <class R, class X, R fun (const X&)>
346 inline Array<R>
347 do_mx_unary_map (const Array<X>& x)
348 {
349  return do_mx_unary_op<R, X> (x, mx_inline_map<R, X, fun>);
350 }
351 
352 template <class R>
353 inline Array<R>&
355  void (*op) (size_t, R *) throw ())
356 {
357  op (r.numel (), r.fortran_vec ());
358  return r;
359 }
360 
361 template <class R, class X, class Y>
362 inline Array<R>
363 do_mm_binary_op (const Array<X>& x, const Array<Y>& y,
364  void (*op) (size_t, R *, const X *, const Y *) throw (),
365  void (*op1) (size_t, R *, X, const Y *) throw (),
366  void (*op2) (size_t, R *, const X *, Y) throw (),
367  const char *opname)
368 {
369  dim_vector dx = x.dims ();
370  dim_vector dy = y.dims ();
371  if (dx == dy)
372  {
373  Array<R> r (dx);
374  op (r.length (), r.fortran_vec (), x.data (), y.data ());
375  return r;
376  }
377  else if (is_valid_bsxfun (opname, dx, dy))
378  {
379  return do_bsxfun_op (x, y, op, op1, op2);
380  }
381  else
382  {
383  gripe_nonconformant (opname, dx, dy);
384  return Array<R> ();
385  }
386 }
387 
388 template <class R, class X, class Y>
389 inline Array<R>
390 do_ms_binary_op (const Array<X>& x, const Y& y,
391  void (*op) (size_t, R *, const X *, Y) throw ())
392 {
393  Array<R> r (x.dims ());
394  op (r.length (), r.fortran_vec (), x.data (), y);
395  return r;
396 }
397 
398 template <class R, class X, class Y>
399 inline Array<R>
400 do_sm_binary_op (const X& x, const Array<Y>& y,
401  void (*op) (size_t, R *, X, const Y *) throw ())
402 {
403  Array<R> r (y.dims ());
404  op (r.length (), r.fortran_vec (), x, y.data ());
405  return r;
406 }
407 
408 template <class R, class X>
409 inline Array<R>&
411  void (*op) (size_t, R *, const X *) throw (),
412  void (*op1) (size_t, R *, X) throw (),
413  const char *opname)
414 {
415  dim_vector dr = r.dims ();
416  dim_vector dx = x.dims ();
417  if (dr == dx)
418  {
419  op (r.length (), r.fortran_vec (), x.data ());
420  }
421  else if (is_valid_inplace_bsxfun (opname, dr, dx))
422  {
423  do_inplace_bsxfun_op (r, x, op, op1);
424  }
425  else
426  gripe_nonconformant (opname, dr, dx);
427  return r;
428 }
429 
430 template <class R, class X>
431 inline Array<R>&
432 do_ms_inplace_op (Array<R>& r, const X& x,
433  void (*op) (size_t, R *, X) throw ())
434 {
435  op (r.length (), r.fortran_vec (), x);
436  return r;
437 }
438 
439 template <class T1, class T2>
440 inline bool
441 mx_inline_equal (size_t n, const T1 *x, const T2 *y) throw ()
442 {
443  for (size_t i = 0; i < n; i++)
444  if (x[i] != y[i])
445  return false;
446  return true;
447 }
448 
449 template <class T>
450 inline bool
452  bool (*op) (size_t, const T *) throw ())
453 {
454  return op (a.numel (), a.data ());
455 }
456 
457 // NOTE: we don't use std::norm because it typically does some heavyweight
458 // magic to avoid underflows, which we don't need here.
459 template <class T>
460 inline T cabsq (const std::complex<T>& c)
461 { return c.real () * c.real () + c.imag () * c.imag (); }
462 
463 // default. works for integers and bool.
464 template <class T>
465 inline bool xis_true (T x) { return x; }
466 template <class T>
467 inline bool xis_false (T x) { return ! x; }
468 // for octave_ints
469 template <class T>
470 inline bool xis_true (const octave_int<T>& x) { return x.value (); }
471 template <class T>
472 inline bool xis_false (const octave_int<T>& x) { return ! x.value (); }
473 // for reals, we want to ignore NaNs.
474 inline bool xis_true (double x) { return ! xisnan (x) && x != 0.0; }
475 inline bool xis_false (double x) { return x == 0.0; }
476 inline bool xis_true (float x) { return ! xisnan (x) && x != 0.0f; }
477 inline bool xis_false (float x) { return x == 0.0f; }
478 // Ditto for complex.
479 inline bool xis_true (const Complex& x) { return ! xisnan (x) && x != 0.0; }
480 inline bool xis_false (const Complex& x) { return x == 0.0; }
481 inline bool xis_true (const FloatComplex& x) { return ! xisnan (x) && x != 0.0f; }
482 inline bool xis_false (const FloatComplex& x) { return x == 0.0f; }
483 
484 #define OP_RED_SUM(ac, el) ac += el
485 #define OP_RED_PROD(ac, el) ac *= el
486 #define OP_RED_SUMSQ(ac, el) ac += el*el
487 #define OP_RED_SUMSQC(ac, el) ac += cabsq (el)
488 
489 inline void op_dble_prod (double& ac, float el)
490 { ac *= el; }
491 inline void op_dble_prod (Complex& ac, const FloatComplex& el)
492 { ac *= el; } // FIXME: guaranteed?
493 template <class T>
494 inline void op_dble_prod (double& ac, const octave_int<T>& el)
495 { ac *= el.double_value (); }
496 
497 inline void op_dble_sum (double& ac, float el)
498 { ac += el; }
499 inline void op_dble_sum (Complex& ac, const FloatComplex& el)
500 { ac += el; } // FIXME: guaranteed?
501 template <class T>
502 inline void op_dble_sum (double& ac, const octave_int<T>& el)
503 { ac += el.double_value (); }
504 
505 // The following two implement a simple short-circuiting.
506 #define OP_RED_ANYC(ac, el) if (xis_true (el)) { ac = true; break; } else continue
507 #define OP_RED_ALLC(ac, el) if (xis_false (el)) { ac = false; break; } else continue
508 
509 #define OP_RED_FCN(F, TSRC, TRES, OP, ZERO) \
510 template <class T> \
511 inline TRES \
512 F (const TSRC* v, octave_idx_type n) \
513 { \
514  TRES ac = ZERO; \
515  for (octave_idx_type i = 0; i < n; i++) \
516  OP(ac, v[i]); \
517  return ac; \
518 }
519 
520 #define PROMOTE_DOUBLE(T) typename subst_template_param<std::complex, T, double>::type
521 
528 OP_RED_FCN (mx_inline_sumsq, std::complex<T>, T, OP_RED_SUMSQC, 0)
529 OP_RED_FCN (mx_inline_any, T, bool, OP_RED_ANYC, false)
530 OP_RED_FCN (mx_inline_all, T, bool, OP_RED_ALLC, true)
531 
532 
533 #define OP_RED_FCN2(F, TSRC, TRES, OP, ZERO) \
534 template <class T> \
535 inline void \
536 F (const TSRC* v, TRES *r, octave_idx_type m, octave_idx_type n) \
537 { \
538  for (octave_idx_type i = 0; i < m; i++) \
539  r[i] = ZERO; \
540  for (octave_idx_type j = 0; j < n; j++) \
541  { \
542  for (octave_idx_type i = 0; i < m; i++) \
543  OP(r[i], v[i]); \
544  v += m; \
545  } \
546 }
547 
548 OP_RED_FCN2 (mx_inline_sum, T, T, OP_RED_SUM, 0)
549 OP_RED_FCN2 (mx_inline_dsum, T, PROMOTE_DOUBLE(T), op_dble_sum, 0.0)
550 OP_RED_FCN2 (mx_inline_count, bool, T, OP_RED_SUM, 0)
551 OP_RED_FCN2 (mx_inline_prod, T, T, OP_RED_PROD, 1)
552 OP_RED_FCN2 (mx_inline_dprod, T, PROMOTE_DOUBLE(T), op_dble_prod, 0.0)
553 OP_RED_FCN2 (mx_inline_sumsq, T, T, OP_RED_SUMSQ, 0)
554 OP_RED_FCN2 (mx_inline_sumsq, std::complex<T>, T, OP_RED_SUMSQC, 0)
555 
556 #define OP_RED_ANYR(ac, el) ac |= xis_true (el)
557 #define OP_RED_ALLR(ac, el) ac &= xis_true (el)
558 
559 OP_RED_FCN2 (mx_inline_any_r, T, bool, OP_RED_ANYR, false)
560 OP_RED_FCN2 (mx_inline_all_r, T, bool, OP_RED_ALLR, true)
561 
562 // Using the general code for any/all would sacrifice short-circuiting.
563 // OTOH, going by rows would sacrifice cache-coherence. The following algorithm
564 // will achieve both, at the cost of a temporary octave_idx_type array.
565 
566 #define OP_ROW_SHORT_CIRCUIT(F, PRED, ZERO) \
567 template <class T> \
568 inline void \
569 F (const T* v, bool *r, octave_idx_type m, octave_idx_type n) \
570 { \
571  if (n <= 8) \
572  return F ## _r (v, r, m, n); \
573  \
574  /* FIXME: it may be sub-optimal to allocate the buffer here. */ \
575  OCTAVE_LOCAL_BUFFER (octave_idx_type, iact, m); \
576  for (octave_idx_type i = 0; i < m; i++) iact[i] = i; \
577  octave_idx_type nact = m; \
578  for (octave_idx_type j = 0; j < n; j++) \
579  { \
580  octave_idx_type k = 0; \
581  for (octave_idx_type i = 0; i < nact; i++) \
582  { \
583  octave_idx_type ia = iact[i]; \
584  if (! PRED (v[ia])) \
585  iact[k++] = ia; \
586  } \
587  nact = k; \
588  v += m; \
589  } \
590  for (octave_idx_type i = 0; i < m; i++) r[i] = ! ZERO; \
591  for (octave_idx_type i = 0; i < nact; i++) r[iact[i]] = ZERO; \
592 }
593 
594 OP_ROW_SHORT_CIRCUIT (mx_inline_any, xis_true, false)
595 OP_ROW_SHORT_CIRCUIT (mx_inline_all, xis_false, true)
596 
597 #define OP_RED_FCNN(F, TSRC, TRES) \
598 template <class T> \
599 inline void \
600 F (const TSRC *v, TRES *r, octave_idx_type l, \
601  octave_idx_type n, octave_idx_type u) \
602 { \
603  if (l == 1) \
604  { \
605  for (octave_idx_type i = 0; i < u; i++) \
606  { \
607  r[i] = F<T> (v, n); \
608  v += n; \
609  } \
610  } \
611  else \
612  { \
613  for (octave_idx_type i = 0; i < u; i++) \
614  { \
615  F (v, r, l, n); \
616  v += l*n; \
617  r += l; \
618  } \
619  } \
620 }
621 
623 OP_RED_FCNN (mx_inline_dsum, T, PROMOTE_DOUBLE(T))
624 OP_RED_FCNN (mx_inline_count, bool, T)
625 OP_RED_FCNN (mx_inline_prod, T, T)
626 OP_RED_FCNN (mx_inline_dprod, T, PROMOTE_DOUBLE(T))
627 OP_RED_FCNN (mx_inline_sumsq, T, T)
628 OP_RED_FCNN (mx_inline_sumsq, std::complex<T>, T)
629 OP_RED_FCNN (mx_inline_any, T, bool)
630 OP_RED_FCNN (mx_inline_all, T, bool)
632 #define OP_CUM_FCN(F, TSRC, TRES, OP) \
633 template <class T> \
634 inline void \
635 F (const TSRC *v, TRES *r, octave_idx_type n) \
636 { \
637  if (n) \
638  { \
639  TRES t = r[0] = v[0]; \
640  for (octave_idx_type i = 1; i < n; i++) \
641  r[i] = t = t OP v[i]; \
642  } \
643 }
644 
645 OP_CUM_FCN (mx_inline_cumsum, T, T, +)
646 OP_CUM_FCN (mx_inline_cumprod, T, T, *)
647 OP_CUM_FCN (mx_inline_cumcount, bool, T, +)
648 
649 #define OP_CUM_FCN2(F, TSRC, TRES, OP) \
650 template <class T> \
651 inline void \
652 F (const TSRC *v, TRES *r, octave_idx_type m, octave_idx_type n) \
653 { \
654  if (n) \
655  { \
656  for (octave_idx_type i = 0; i < m; i++) \
657  r[i] = v[i]; \
658  const T *r0 = r; \
659  for (octave_idx_type j = 1; j < n; j++) \
660  { \
661  r += m; v += m; \
662  for (octave_idx_type i = 0; i < m; i++) \
663  r[i] = r0[i] OP v[i]; \
664  r0 += m; \
665  } \
666  } \
667 }
668 
669 OP_CUM_FCN2 (mx_inline_cumsum, T, T, +)
670 OP_CUM_FCN2 (mx_inline_cumprod, T, T, *)
671 OP_CUM_FCN2 (mx_inline_cumcount, bool, T, +)
672 
673 #define OP_CUM_FCNN(F, TSRC, TRES) \
674 template <class T> \
675 inline void \
676 F (const TSRC *v, TRES *r, octave_idx_type l, \
677  octave_idx_type n, octave_idx_type u) \
678 { \
679  if (l == 1) \
680  { \
681  for (octave_idx_type i = 0; i < u; i++) \
682  { \
683  F (v, r, n); \
684  v += n; r += n; \
685  } \
686  } \
687  else \
688  { \
689  for (octave_idx_type i = 0; i < u; i++) \
690  { \
691  F (v, r, l, n); \
692  v += l*n; \
693  r += l*n; \
694  } \
695  } \
696 }
697 
699 OP_CUM_FCNN (mx_inline_cumprod, T, T)
700 OP_CUM_FCNN (mx_inline_cumcount, bool, T)
701 
702 #define OP_MINMAX_FCN(F, OP) \
703 template <class T> \
704 void F (const T *v, T *r, octave_idx_type n) \
705 { \
706  if (! n) return; \
707  T tmp = v[0]; \
708  octave_idx_type i = 1; \
709  if (xisnan (tmp)) \
710  { \
711  for (; i < n && xisnan (v[i]); i++) ; \
712  if (i < n) tmp = v[i]; \
713  } \
714  for (; i < n; i++) \
715  if (v[i] OP tmp) tmp = v[i]; \
716  *r = tmp; \
717 } \
718 template <class T> \
719 void F (const T *v, T *r, octave_idx_type *ri, octave_idx_type n) \
720 { \
721  if (! n) return; \
722  T tmp = v[0]; \
723  octave_idx_type tmpi = 0; \
724  octave_idx_type i = 1; \
725  if (xisnan (tmp)) \
726  { \
727  for (; i < n && xisnan (v[i]); i++) ; \
728  if (i < n) { tmp = v[i]; tmpi = i; } \
729  } \
730  for (; i < n; i++) \
731  if (v[i] OP tmp) { tmp = v[i]; tmpi = i; }\
732  *r = tmp; \
733  *ri = tmpi; \
734 }
735 
738 
739 // Row reductions will be slightly complicated. We will proceed with checks
740 // for NaNs until we detect that no row will yield a NaN, in which case we
741 // proceed to a faster code.
742 
743 #define OP_MINMAX_FCN2(F, OP) \
744 template <class T> \
745 inline void \
746 F (const T *v, T *r, octave_idx_type m, octave_idx_type n) \
747 { \
748  if (! n) return; \
749  bool nan = false; \
750  octave_idx_type j = 0; \
751  for (octave_idx_type i = 0; i < m; i++) \
752  { \
753  r[i] = v[i]; \
754  if (xisnan (v[i])) nan = true; \
755  } \
756  j++; v += m; \
757  while (nan && j < n) \
758  { \
759  nan = false; \
760  for (octave_idx_type i = 0; i < m; i++) \
761  { \
762  if (xisnan (v[i])) \
763  nan = true; \
764  else if (xisnan (r[i]) || v[i] OP r[i]) \
765  r[i] = v[i]; \
766  } \
767  j++; v += m; \
768  } \
769  while (j < n) \
770  { \
771  for (octave_idx_type i = 0; i < m; i++) \
772  if (v[i] OP r[i]) r[i] = v[i]; \
773  j++; v += m; \
774  } \
775 } \
776 template <class T> \
777 inline void \
778 F (const T *v, T *r, octave_idx_type *ri, \
779  octave_idx_type m, octave_idx_type n) \
780 { \
781  if (! n) return; \
782  bool nan = false; \
783  octave_idx_type j = 0; \
784  for (octave_idx_type i = 0; i < m; i++) \
785  { \
786  r[i] = v[i]; ri[i] = j; \
787  if (xisnan (v[i])) nan = true; \
788  } \
789  j++; v += m; \
790  while (nan && j < n) \
791  { \
792  nan = false; \
793  for (octave_idx_type i = 0; i < m; i++) \
794  { \
795  if (xisnan (v[i])) \
796  nan = true; \
797  else if (xisnan (r[i]) || v[i] OP r[i]) \
798  { r[i] = v[i]; ri[i] = j; } \
799  } \
800  j++; v += m; \
801  } \
802  while (j < n) \
803  { \
804  for (octave_idx_type i = 0; i < m; i++) \
805  if (v[i] OP r[i]) \
806  { r[i] = v[i]; ri[i] = j; } \
807  j++; v += m; \
808  } \
809 }
810 
812 OP_MINMAX_FCN2 (mx_inline_max, >)
813 
814 #define OP_MINMAX_FCNN(F) \
815 template <class T> \
816 inline void \
817 F (const T *v, T *r, octave_idx_type l, \
818  octave_idx_type n, octave_idx_type u) \
819 { \
820  if (! n) return; \
821  if (l == 1) \
822  { \
823  for (octave_idx_type i = 0; i < u; i++) \
824  { \
825  F (v, r, n); \
826  v += n; r++; \
827  } \
828  } \
829  else \
830  { \
831  for (octave_idx_type i = 0; i < u; i++) \
832  { \
833  F (v, r, l, n); \
834  v += l*n; \
835  r += l; \
836  } \
837  } \
838 } \
839 template <class T> \
840 inline void \
841 F (const T *v, T *r, octave_idx_type *ri, \
842  octave_idx_type l, octave_idx_type n, octave_idx_type u) \
843 { \
844  if (! n) return; \
845  if (l == 1) \
846  { \
847  for (octave_idx_type i = 0; i < u; i++) \
848  { \
849  F (v, r, ri, n); \
850  v += n; r++; ri++; \
851  } \
852  } \
853  else \
854  { \
855  for (octave_idx_type i = 0; i < u; i++) \
856  { \
857  F (v, r, ri, l, n); \
858  v += l*n; \
859  r += l; ri += l; \
860  } \
861  } \
862 }
863 
865 OP_MINMAX_FCNN (mx_inline_max)
866 
867 #define OP_CUMMINMAX_FCN(F, OP) \
868 template <class T> \
869 void F (const T *v, T *r, octave_idx_type n) \
870 { \
871  if (! n) return; \
872  T tmp = v[0]; \
873  octave_idx_type i = 1; \
874  octave_idx_type j = 0; \
875  if (xisnan (tmp)) \
876  { \
877  for (; i < n && xisnan (v[i]); i++) ; \
878  for (; j < i; j++) r[j] = tmp; \
879  if (i < n) tmp = v[i]; \
880  } \
881  for (; i < n; i++) \
882  if (v[i] OP tmp) \
883  { \
884  for (; j < i; j++) r[j] = tmp; \
885  tmp = v[i]; \
886  } \
887  for (; j < i; j++) r[j] = tmp; \
888 } \
889 template <class T> \
890 void F (const T *v, T *r, octave_idx_type *ri, octave_idx_type n) \
891 { \
892  if (! n) return; \
893  T tmp = v[0]; octave_idx_type tmpi = 0; \
894  octave_idx_type i = 1; \
895  octave_idx_type j = 0; \
896  if (xisnan (tmp)) \
897  { \
898  for (; i < n && xisnan (v[i]); i++) ; \
899  for (; j < i; j++) { r[j] = tmp; ri[j] = tmpi; } \
900  if (i < n) { tmp = v[i]; tmpi = i; } \
901  } \
902  for (; i < n; i++) \
903  if (v[i] OP tmp) \
904  { \
905  for (; j < i; j++) { r[j] = tmp; ri[j] = tmpi; } \
906  tmp = v[i]; tmpi = i; \
907  } \
908  for (; j < i; j++) { r[j] = tmp; ri[j] = tmpi; } \
909 }
910 
913 
914 // Row reductions will be slightly complicated. We will proceed with checks
915 // for NaNs until we detect that no row will yield a NaN, in which case we
916 // proceed to a faster code.
917 
918 #define OP_CUMMINMAX_FCN2(F, OP) \
919 template <class T> \
920 inline void \
921 F (const T *v, T *r, octave_idx_type m, octave_idx_type n) \
922 { \
923  if (! n) return; \
924  bool nan = false; \
925  const T *r0; \
926  octave_idx_type j = 0; \
927  for (octave_idx_type i = 0; i < m; i++) \
928  { \
929  r[i] = v[i]; \
930  if (xisnan (v[i])) nan = true; \
931  } \
932  j++; v += m; r0 = r; r += m; \
933  while (nan && j < n) \
934  { \
935  nan = false; \
936  for (octave_idx_type i = 0; i < m; i++) \
937  { \
938  if (xisnan (v[i])) \
939  { r[i] = r0[i]; nan = true; } \
940  else if (xisnan (r0[i]) || v[i] OP r0[i]) \
941  r[i] = v[i]; \
942  else \
943  r[i] = r0[i]; \
944  } \
945  j++; v += m; r0 = r; r += m; \
946  } \
947  while (j < n) \
948  { \
949  for (octave_idx_type i = 0; i < m; i++) \
950  if (v[i] OP r0[i]) \
951  r[i] = v[i]; \
952  else \
953  r[i] = r0[i]; \
954  j++; v += m; r0 = r; r += m; \
955  } \
956 } \
957 template <class T> \
958 inline void \
959 F (const T *v, T *r, octave_idx_type *ri, \
960  octave_idx_type m, octave_idx_type n) \
961 { \
962  if (! n) return; \
963  bool nan = false; \
964  const T *r0; const octave_idx_type *r0i; \
965  octave_idx_type j = 0; \
966  for (octave_idx_type i = 0; i < m; i++) \
967  { \
968  r[i] = v[i]; ri[i] = 0; \
969  if (xisnan (v[i])) nan = true; \
970  } \
971  j++; v += m; r0 = r; r += m; r0i = ri; ri += m; \
972  while (nan && j < n) \
973  { \
974  nan = false; \
975  for (octave_idx_type i = 0; i < m; i++) \
976  { \
977  if (xisnan (v[i])) \
978  { r[i] = r0[i]; ri[i] = r0i[i]; nan = true; } \
979  else if (xisnan (r0[i]) || v[i] OP r0[i]) \
980  { r[i] = v[i]; ri[i] = j; }\
981  else \
982  { r[i] = r0[i]; ri[i] = r0i[i]; }\
983  } \
984  j++; v += m; r0 = r; r += m; r0i = ri; ri += m; \
985  } \
986  while (j < n) \
987  { \
988  for (octave_idx_type i = 0; i < m; i++) \
989  if (v[i] OP r0[i]) \
990  { r[i] = v[i]; ri[i] = j; } \
991  else \
992  { r[i] = r0[i]; ri[i] = r0i[i]; } \
993  j++; v += m; r0 = r; r += m; r0i = ri; ri += m; \
994  } \
995 }
996 
998 OP_CUMMINMAX_FCN2 (mx_inline_cummax, >)
999 
1000 #define OP_CUMMINMAX_FCNN(F) \
1001 template <class T> \
1002 inline void \
1003 F (const T *v, T *r, octave_idx_type l, \
1004  octave_idx_type n, octave_idx_type u) \
1005 { \
1006  if (! n) return; \
1007  if (l == 1) \
1008  { \
1009  for (octave_idx_type i = 0; i < u; i++) \
1010  { \
1011  F (v, r, n); \
1012  v += n; r += n; \
1013  } \
1014  } \
1015  else \
1016  { \
1017  for (octave_idx_type i = 0; i < u; i++) \
1018  { \
1019  F (v, r, l, n); \
1020  v += l*n; \
1021  r += l*n; \
1022  } \
1023  } \
1024 } \
1025 template <class T> \
1026 inline void \
1027 F (const T *v, T *r, octave_idx_type *ri, \
1028  octave_idx_type l, octave_idx_type n, octave_idx_type u) \
1029 { \
1030  if (! n) return; \
1031  if (l == 1) \
1032  { \
1033  for (octave_idx_type i = 0; i < u; i++) \
1034  { \
1035  F (v, r, ri, n); \
1036  v += n; r += n; ri += n; \
1037  } \
1038  } \
1039  else \
1040  { \
1041  for (octave_idx_type i = 0; i < u; i++) \
1042  { \
1043  F (v, r, ri, l, n); \
1044  v += l*n; \
1045  r += l*n; ri += l*n; \
1046  } \
1047  } \
1048 }
1049 
1051 OP_CUMMINMAX_FCNN (mx_inline_cummax)
1052 
1053 template <class T>
1054 void mx_inline_diff (const T *v, T *r, octave_idx_type n,
1055  octave_idx_type order)
1056 {
1057  switch (order)
1058  {
1059  case 1:
1060  for (octave_idx_type i = 0; i < n-1; i++)
1061  r[i] = v[i+1] - v[i];
1062  break;
1063  case 2:
1064  if (n > 1)
1065  {
1066  T lst = v[1] - v[0];
1067  for (octave_idx_type i = 0; i < n-2; i++)
1068  {
1069  T dif = v[i+2] - v[i+1];
1070  r[i] = dif - lst;
1071  lst = dif;
1072  }
1073  }
1074  break;
1075  default:
1076  {
1077  OCTAVE_LOCAL_BUFFER (T, buf, n-1);
1078 
1079  for (octave_idx_type i = 0; i < n-1; i++)
1080  buf[i] = v[i+1] - v[i];
1081 
1082  for (octave_idx_type o = 2; o <= order; o++)
1083  {
1084  for (octave_idx_type i = 0; i < n-o; i++)
1085  buf[i] = buf[i+1] - buf[i];
1086  }
1087 
1088  for (octave_idx_type i = 0; i < n-order; i++)
1089  r[i] = buf[i];
1090  }
1091  }
1092 }
1093 
1094 template <class T>
1095 void mx_inline_diff (const T *v, T *r,
1097  octave_idx_type order)
1098 {
1099  switch (order)
1100  {
1101  case 1:
1102  for (octave_idx_type i = 0; i < m*(n-1); i++)
1103  r[i] = v[i+m] - v[i];
1104  break;
1105  case 2:
1106  for (octave_idx_type i = 0; i < n-2; i++)
1107  {
1108  for (octave_idx_type j = i*m; j < i*m+m; j++)
1109  r[j] = (v[j+m+m] - v[j+m]) - (v[j+m] - v[j]);
1110  }
1111  break;
1112  default:
1113  {
1114  OCTAVE_LOCAL_BUFFER (T, buf, n-1);
1115 
1116  for (octave_idx_type j = 0; j < m; j++)
1117  {
1118  for (octave_idx_type i = 0; i < n-1; i++)
1119  buf[i] = v[i*m+j+m] - v[i*m+j];
1120 
1121  for (octave_idx_type o = 2; o <= order; o++)
1122  {
1123  for (octave_idx_type i = 0; i < n-o; i++)
1124  buf[i] = buf[i+1] - buf[i];
1125  }
1126 
1127  for (octave_idx_type i = 0; i < n-order; i++)
1128  r[i*m+j] = buf[i];
1129  }
1130  }
1131  }
1132 }
1133 
1134 template <class T>
1135 inline void
1136 mx_inline_diff (const T *v, T *r,
1138  octave_idx_type order)
1139 {
1140  if (! n) return;
1141  if (l == 1)
1142  {
1143  for (octave_idx_type i = 0; i < u; i++)
1144  {
1145  mx_inline_diff (v, r, n, order);
1146  v += n; r += n-order;
1147  }
1148  }
1149  else
1150  {
1151  for (octave_idx_type i = 0; i < u; i++)
1152  {
1153  mx_inline_diff (v, r, l, n, order);
1154  v += l*n;
1155  r += l*(n-order);
1156  }
1157  }
1158 }
1159 
1160 // Assistant function
1161 
1162 inline void
1163 get_extent_triplet (const dim_vector& dims, int& dim,
1165  octave_idx_type& u)
1166 {
1167  octave_idx_type ndims = dims.length ();
1168  if (dim >= ndims)
1169  {
1170  l = dims.numel ();
1171  n = 1;
1172  u = 1;
1173  }
1174  else
1175  {
1176  if (dim < 0)
1177  dim = dims.first_non_singleton ();
1178 
1179  // calculate extent triplet.
1180  l = 1, n = dims(dim), u = 1;
1181  for (octave_idx_type i = 0; i < dim; i++)
1182  l *= dims (i);
1183  for (octave_idx_type i = dim + 1; i < ndims; i++)
1184  u *= dims (i);
1185  }
1186 }
1187 
1188 // Appliers.
1189 // FIXME: is this the best design? C++ gives a lot of options here...
1190 // maybe it can be done without an explicit parameter?
1191 
1192 template <class R, class T>
1193 inline Array<R>
1194 do_mx_red_op (const Array<T>& src, int dim,
1195  void (*mx_red_op) (const T *, R *, octave_idx_type,
1197 {
1198  octave_idx_type l, n, u;
1199  dim_vector dims = src.dims ();
1200  // M*b inconsistency: sum ([]) = 0 etc.
1201  if (dims.length () == 2 && dims(0) == 0 && dims(1) == 0)
1202  dims (1) = 1;
1203 
1204  get_extent_triplet (dims, dim, l, n, u);
1205 
1206  // Reduction operation reduces the array size.
1207  if (dim < dims.length ()) dims(dim) = 1;
1208  dims.chop_trailing_singletons ();
1209 
1210  Array<R> ret (dims);
1211  mx_red_op (src.data (), ret.fortran_vec (), l, n, u);
1212 
1213  return ret;
1214 }
1215 
1216 template <class R, class T>
1217 inline Array<R>
1218 do_mx_cum_op (const Array<T>& src, int dim,
1219  void (*mx_cum_op) (const T *, R *, octave_idx_type,
1221 {
1222  octave_idx_type l, n, u;
1223  dim_vector dims = src.dims ();
1224  get_extent_triplet (dims, dim, l, n, u);
1225 
1226  // Cumulative operation doesn't reduce the array size.
1227  Array<R> ret (dims);
1228  mx_cum_op (src.data (), ret.fortran_vec (), l, n, u);
1229 
1230  return ret;
1231 }
1232 
1233 template <class R>
1234 inline Array<R>
1235 do_mx_minmax_op (const Array<R>& src, int dim,
1236  void (*mx_minmax_op) (const R *, R *, octave_idx_type,
1238 {
1239  octave_idx_type l, n, u;
1240  dim_vector dims = src.dims ();
1241  get_extent_triplet (dims, dim, l, n, u);
1242 
1243  // If the dimension is zero, we don't do anything.
1244  if (dim < dims.length () && dims(dim) != 0) dims(dim) = 1;
1245  dims.chop_trailing_singletons ();
1246 
1247  Array<R> ret (dims);
1248  mx_minmax_op (src.data (), ret.fortran_vec (), l, n, u);
1249 
1250  return ret;
1251 }
1252 
1253 template <class R>
1254 inline Array<R>
1255 do_mx_minmax_op (const Array<R>& src, Array<octave_idx_type>& idx, int dim,
1256  void (*mx_minmax_op) (const R *, R *, octave_idx_type *,
1258 {
1259  octave_idx_type l, n, u;
1260  dim_vector dims = src.dims ();
1261  get_extent_triplet (dims, dim, l, n, u);
1262 
1263  // If the dimension is zero, we don't do anything.
1264  if (dim < dims.length () && dims(dim) != 0) dims(dim) = 1;
1265  dims.chop_trailing_singletons ();
1266 
1267  Array<R> ret (dims);
1268  if (idx.dims () != dims) idx = Array<octave_idx_type> (dims);
1269 
1270  mx_minmax_op (src.data (), ret.fortran_vec (), idx.fortran_vec (),
1271  l, n, u);
1272 
1273  return ret;
1274 }
1275 
1276 template <class R>
1277 inline Array<R>
1278 do_mx_cumminmax_op (const Array<R>& src, int dim,
1279  void (*mx_cumminmax_op) (const R *, R *, octave_idx_type,
1281 {
1282  octave_idx_type l, n, u;
1283  dim_vector dims = src.dims ();
1284  get_extent_triplet (dims, dim, l, n, u);
1285 
1286  Array<R> ret (dims);
1287  mx_cumminmax_op (src.data (), ret.fortran_vec (), l, n, u);
1288 
1289  return ret;
1290 }
1291 
1292 template <class R>
1293 inline Array<R>
1294 do_mx_cumminmax_op (const Array<R>& src, Array<octave_idx_type>& idx, int dim,
1295  void (*mx_cumminmax_op) (const R *, R *, octave_idx_type *,
1297 {
1298  octave_idx_type l, n, u;
1299  dim_vector dims = src.dims ();
1300  get_extent_triplet (dims, dim, l, n, u);
1301 
1302  Array<R> ret (dims);
1303  if (idx.dims () != dims) idx = Array<octave_idx_type> (dims);
1304 
1305  mx_cumminmax_op (src.data (), ret.fortran_vec (), idx.fortran_vec (),
1306  l, n, u);
1307 
1308  return ret;
1309 }
1310 
1311 template <class R>
1312 inline Array<R>
1313 do_mx_diff_op (const Array<R>& src, int dim, octave_idx_type order,
1314  void (*mx_diff_op) (const R *, R *,
1316  octave_idx_type))
1317 {
1318  octave_idx_type l, n, u;
1319  if (order <= 0)
1320  return src;
1321 
1322  dim_vector dims = src.dims ();
1323 
1324  get_extent_triplet (dims, dim, l, n, u);
1325  if (dim >= dims.length ())
1326  dims.resize (dim+1, 1);
1327 
1328  if (dims(dim) <= order)
1329  {
1330  dims (dim) = 0;
1331  return Array<R> (dims);
1332  }
1333  else
1334  {
1335  dims(dim) -= order;
1336  }
1337 
1338  Array<R> ret (dims);
1339  mx_diff_op (src.data (), ret.fortran_vec (), l, n, u, order);
1340 
1341  return ret;
1342 }
1343 
1344 // Fast extra-precise summation. According to
1345 // T. Ogita, S. M. Rump, S. Oishi:
1346 // Accurate Sum And Dot Product,
1347 // SIAM J. Sci. Computing, Vol. 26, 2005
1348 
1349 template <class T>
1350 inline void twosum_accum (T& s, T& e,
1351  const T& x)
1352 {
1353  T s1 = s + x;
1354  T t = s1 - s;
1355  T e1 = (s - (s1 - t)) + (x - t);
1356  s = s1;
1357  e += e1;
1358 }
1359 
1360 template <class T>
1361 inline T
1362 mx_inline_xsum (const T *v, octave_idx_type n)
1363 {
1364  T s, e;
1365  s = e = 0;
1366  for (octave_idx_type i = 0; i < n; i++)
1367  twosum_accum (s, e, v[i]);
1368 
1369  return s + e;
1370 }
1371 
1372 template <class T>
1373 inline void
1374 mx_inline_xsum (const T *v, T *r,
1376 {
1377  OCTAVE_LOCAL_BUFFER (T, e, m);
1378  for (octave_idx_type i = 0; i < m; i++)
1379  e[i] = r[i] = T ();
1380 
1381  for (octave_idx_type j = 0; j < n; j++)
1382  {
1383  for (octave_idx_type i = 0; i < m; i++)
1384  twosum_accum (r[i], e[i], v[i]);
1385 
1386  v += m;
1387  }
1388 
1389  for (octave_idx_type i = 0; i < m; i++)
1390  r[i] += e[i];
1391 }
1392 
1394 
1395 #endif
void mx_inline_or_not(size_t n, bool *r, const X *x, const Y *y)
Definition: mx-inlines.cc:164
T mx_inline_xsum(const T *v, octave_idx_type n)
Definition: mx-inlines.cc:1344
void mx_inline_mul2(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:97
void op_dble_prod(double &ac, float el)
Definition: mx-inlines.cc:489
bool xis_false(T x)
Definition: mx-inlines.cc:467
#define PROMOTE_DOUBLE(T)
Definition: mx-inlines.cc:520
void mx_inline_add2(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:95
#define DEFMINMAXSPEC(T, F, OP)
Definition: mx-inlines.cc:273
Array< R > & do_ms_inplace_op(Array< R > &r, const X &x, void(*op)(size_t, R *, X) throw())
Definition: mx-inlines.cc:432
void mx_inline_or2(size_t n, bool *r, const X *x)
Definition: mx-inlines.cc:178
void gripe_nonconformant(const char *op, octave_idx_type op1_len, octave_idx_type op2_len)
void mx_inline_sub2(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:96
void mx_inline_cummax(const T *v, T *r, octave_idx_type n)
Definition: mx-inlines.cc:894
#define OP_MINMAX_FCN(F, OP)
Definition: mx-inlines.cc:684
void mx_inline_notzero(size_t n, bool *r, const X *x)
Definition: mx-inlines.cc:69
#define DEFMXMAPPER2(F, FUN)
Definition: mx-inlines.cc:258
void mx_inline_le(size_t n, bool *r, const X *x, const Y *y)
Definition: mx-inlines.cc:112
bool xisnan(double x)
Definition: lo-mappers.cc:144
void mx_inline_fill(size_t n, R *r, S s)
Definition: mx-inlines.cc:46
void mx_inline_uminus2(size_t n, R *r)
Definition: mx-inlines.cc:61
bool logical_value(T x)
Definition: mx-inlines.cc:119
#define OP_CUM_FCN2(F, TSRC, TRES, OP)
Definition: mx-inlines.cc:631
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:275
Array< R > do_mx_diff_op(const Array< R > &src, int dim, octave_idx_type order, void(*mx_diff_op)(const R *, R *, octave_idx_type, octave_idx_type, octave_idx_type, octave_idx_type))
Definition: mx-inlines.cc:1295
T cabsq(const std::complex< T > &c)
Definition: mx-inlines.cc:460
#define DEFMXBOOLOP(F, NOT1, OP, NOT2)
Definition: mx-inlines.cc:137
void mx_inline_real(size_t n, T *r, const std::complex< T > *x)
Definition: mx-inlines.cc:251
bool do_mx_check(const Array< T > &a, bool(*op)(size_t, const T *) throw())
Definition: mx-inlines.cc:451
bool mx_inline_all_finite(size_t n, const T *x)
Definition: mx-inlines.cc:195
void resize(int n, int fill_value=0)
Definition: dim-vector.h:287
Complex xmax(const Complex &x, const Complex &y)
Definition: lo-mappers.cc:269
double double_value(void) const
Definition: oct-inttypes.h:881
void mx_inline_cumcount(const bool *v, T *r, octave_idx_type n)
Definition: mx-inlines.cc:629
STL namespace.
void mx_inline_map(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:316
bool xis_true(T x)
Definition: mx-inlines.cc:465
Complex xmin(const Complex &x, const Complex &y)
Definition: lo-mappers.cc:263
Array< R > do_mx_unary_op(const Array< X > &x, void(*op)(size_t, R *, const X *) throw())
Definition: mx-inlines.cc:328
void mx_inline_ne(size_t n, bool *r, const X *x, const Y *y)
Definition: mx-inlines.cc:116
T mx_inline_sumsq(const T *v, octave_idx_type n)
Definition: mx-inlines.cc:524
bool mx_inline_any_negative(size_t n, const T *x)
Definition: mx-inlines.cc:208
void mx_inline_max(const T *v, T *r, octave_idx_type n)
Definition: mx-inlines.cc:719
void mx_inline_eq(size_t n, bool *r, const X *x, const Y *y)
Definition: mx-inlines.cc:115
#define OP_RED_ALLC(ac, el)
Definition: mx-inlines.cc:507
bool mx_inline_any(const T *v, octave_idx_type n)
Definition: mx-inlines.cc:524
static void dif(octave_idx_type nt, double *root, double *dif1, double *dif2, double *dif3)
Definition: CollocWt.cc:56
int first_non_singleton(int def=0) const
Definition: dim-vector.h:435
octave_idx_type numel(int n=0) const
Number of elements that a matrix with this dimensions would have.
Definition: dim-vector.h:361
void mx_inline_mul(size_t n, R *r, const X *x, const Y *y)
Definition: mx-inlines.cc:84
Array< R > do_mm_binary_op(const Array< X > &x, const Array< Y > &y, void(*op)(size_t, R *, const X *, const Y *) throw(), void(*op1)(size_t, R *, X, const Y *) throw(), void(*op2)(size_t, R *, const X *, Y) throw(), const char *opname)
Definition: mx-inlines.cc:363
bool is_valid_inplace_bsxfun(const std::string &name, const dim_vector &dr, const dim_vector &dx)
Definition: bsxfun.h:60
void mx_inline_imag(size_t n, T *r, const std::complex< T > *x)
Definition: mx-inlines.cc:254
void mx_inline_xmin(size_t n, T *r, const T *x, const T *y)
Definition: mx-inlines.cc:269
#define OP_CUMMINMAX_FCN2(F, OP)
Definition: mx-inlines.cc:900
#define DEFMXCMPOP(F, OP)
Definition: mx-inlines.cc:100
bool mx_inline_all_real(size_t n, const std::complex< T > *x)
Definition: mx-inlines.cc:234
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
Definition: Array.h:337
#define DEFMXUNOPEQ(F, OP)
Definition: mx-inlines.cc:56
FloatComplexMatrix r
Definition: base-qr.h:74
Array< R > & do_mm_inplace_op(Array< R > &r, const Array< X > &x, void(*op)(size_t, R *, const X *) throw(), void(*op1)(size_t, R *, X) throw(), const char *opname)
Definition: mx-inlines.cc:410
void mx_inline_sub(size_t n, R *r, const X *x, const Y *y)
Definition: mx-inlines.cc:83
void mx_inline_uminus(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:54
#define DEFMXBOOLOPEQ(F, OP)
Definition: mx-inlines.cc:166
#define OP_RED_SUMSQC(ac, el)
Definition: mx-inlines.cc:487
Array< R > & do_mx_inplace_op(Array< R > &r, void(*op)(size_t, R *) throw())
Definition: mx-inlines.cc:354
void mx_inline_and2(size_t n, bool *r, const X *x)
Definition: mx-inlines.cc:177
subst_template_param< std::complex, T, double >::type mx_inline_dprod(const T *v, octave_idx_type n)
Definition: mx-inlines.cc:523
const T * data(void) const
Definition: Array.h:479
#define OP_CUMMINMAX_FCNN(F)
Definition: mx-inlines.cc:982
#define OP_ROW_SHORT_CIRCUIT(F, PRED, ZERO)
Definition: mx-inlines.cc:548
octave_int< T > pow(const octave_int< T > &a, const octave_int< T > &b)
#define OP_RED_ANYC(ac, el)
Definition: mx-inlines.cc:506
bool mx_inline_any_positive(size_t n, const T *x)
Definition: mx-inlines.cc:221
void mx_inline_ge(size_t n, bool *r, const X *x, const Y *y)
Definition: mx-inlines.cc:114
void mx_inline_cummin(const T *v, T *r, octave_idx_type n)
Definition: mx-inlines.cc:893
void mx_inline_pow(size_t n, R *r, const X *x, const Y *y)
Definition: mx-inlines.cc:311
void mx_inline_all_r(const T *v, bool *r, octave_idx_type m, octave_idx_type n)
Definition: mx-inlines.cc:544
Array< R > do_mx_red_op(const Array< T > &src, int dim, void(*mx_red_op)(const T *, R *, octave_idx_type, octave_idx_type, octave_idx_type))
Definition: mx-inlines.cc:1176
Array< R > do_sm_binary_op(const X &x, const Array< Y > &y, void(*op)(size_t, R *, X, const Y *) throw())
Definition: mx-inlines.cc:400
bool mx_inline_any_nan(size_t n, const T *x)
Definition: mx-inlines.cc:182
subst_template_param< std::complex, T, double >::type mx_inline_dsum(const T *v, octave_idx_type n)
Definition: mx-inlines.cc:522
#define OP_RED_ALLR(ac, el)
Definition: mx-inlines.cc:542
#define OP_MINMAX_FCNN(F)
Definition: mx-inlines.cc:796
T value(void) const
Definition: oct-inttypes.h:870
#define OP_CUMMINMAX_FCN(F, OP)
Definition: mx-inlines.cc:849
void do_inplace_bsxfun_op(Array< R > &r, const Array< X > &x, void(*op_vv)(size_t, R *, const X *), void(*op_vs)(size_t, R *, X))
Definition: bsxfun-defs.cc:142
#define OP_CUM_FCN(F, TSRC, TRES, OP)
Definition: mx-inlines.cc:614
T mx_inline_sum(const T *v, octave_idx_type n)
Definition: mx-inlines.cc:522
void mx_inline_gt(size_t n, bool *r, const X *x, const Y *y)
Definition: mx-inlines.cc:113
Array< R > do_mx_cum_op(const Array< T > &src, int dim, void(*mx_cum_op)(const T *, R *, octave_idx_type, octave_idx_type, octave_idx_type))
Definition: mx-inlines.cc:1200
Handles the reference counting for all the derived classes.
Definition: Array.h:45
void mx_inline_not_or(size_t n, bool *r, const X *x, const Y *y)
Definition: mx-inlines.cc:162
octave_idx_type length(void) const
Number of elements in the array.
Definition: Array.h:267
void mx_inline_cumprod(const T *v, T *r, octave_idx_type n)
Definition: mx-inlines.cc:628
void mx_inline_and(size_t n, bool *r, const X *x, const Y *y)
Definition: mx-inlines.cc:159
void mx_inline_not_and(size_t n, bool *r, const X *x, const Y *y)
Definition: mx-inlines.cc:161
bool xfinite(double x)
Definition: lo-mappers.cc:152
FloatComplexMatrix R(void) const
Definition: base-qr.h:65
void mx_inline_cumsum(const T *v, T *r, octave_idx_type n)
Definition: mx-inlines.cc:627
void mx_inline_iszero(size_t n, bool *r, const X *x)
Definition: mx-inlines.cc:68
#define DEFMXUNOP(F, OP)
Definition: mx-inlines.cc:49
#define DEFMXBINOPEQ(F, OP)
Definition: mx-inlines.cc:87
#define OP_RED_SUMSQ(ac, el)
Definition: mx-inlines.cc:486
void mx_inline_or(size_t n, bool *r, const X *x, const Y *y)
Definition: mx-inlines.cc:160
Array< R > do_mx_unary_map(const Array< X > &x)
Definition: mx-inlines.cc:340
void get_extent_triplet(const dim_vector &dims, int &dim, octave_idx_type &l, octave_idx_type &n, octave_idx_type &u)
Definition: mx-inlines.cc:1145
#define DEFMXMAPPER2X(F, FUN)
Definition: mx-inlines.cc:297
Array< R > do_mx_cumminmax_op(const Array< R > &src, int dim, void(*mx_cumminmax_op)(const R *, R *, octave_idx_type, octave_idx_type, octave_idx_type))
Definition: mx-inlines.cc:1260
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
Definition: oct-locbuf.h:197
Array< R > do_mx_minmax_op(const Array< R > &src, int dim, void(*mx_minmax_op)(const R *, R *, octave_idx_type, octave_idx_type, octave_idx_type))
Definition: mx-inlines.cc:1217
Array< R > do_ms_binary_op(const Array< X > &x, const Y &y, void(*op)(size_t, R *, const X *, Y) throw())
Definition: mx-inlines.cc:390
ColumnVector imag(const ComplexColumnVector &a)
Definition: dColVector.cc:162
void mx_inline_add(size_t n, R *r, const X *x, const Y *y)
Definition: mx-inlines.cc:82
void mx_inline_any_r(const T *v, bool *r, octave_idx_type m, octave_idx_type n)
Definition: mx-inlines.cc:544
std::complex< float > FloatComplex
Definition: oct-cmplx.h:30
void mx_inline_and_not(size_t n, bool *r, const X *x, const Y *y)
Definition: mx-inlines.cc:163
void mx_inline_div(size_t n, R *r, const X *x, const Y *y)
Definition: mx-inlines.cc:85
#define OP_RED_FCNN(F, TSRC, TRES)
Definition: mx-inlines.cc:579
#define OP_RED_FCN(F, TSRC, TRES, OP, ZERO)
Definition: mx-inlines.cc:509
bool mx_inline_all(const T *v, octave_idx_type n)
Definition: mx-inlines.cc:524
#define OP_RED_SUM(ac, el)
Definition: mx-inlines.cc:484
std::complex< double > Complex
Definition: oct-cmplx.h:29
bool is_valid_bsxfun(const std::string &name, const dim_vector &dx, const dim_vector &dy)
Definition: bsxfun.h:36
const T * fortran_vec(void) const
Definition: Array.h:481
void mx_inline_div2(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:98
#define DEFMXBINOP(F, OP)
Definition: mx-inlines.cc:71
void mx_inline_not(size_t n, bool *r, const X *x)
Definition: mx-inlines.cc:126
#define OP_CUM_FCNN(F, TSRC, TRES)
Definition: mx-inlines.cc:655
ColumnVector real(const ComplexColumnVector &a)
Definition: dColVector.cc:156
void mx_inline_lt(size_t n, bool *r, const X *x, const Y *y)
Definition: mx-inlines.cc:111
bool mx_inline_equal(size_t n, const T1 *x, const T2 *y)
Definition: mx-inlines.cc:441
#define OP_MINMAX_FCN2(F, OP)
Definition: mx-inlines.cc:725
void op_dble_sum(double &ac, float el)
Definition: mx-inlines.cc:497
#define OP_RED_PROD(ac, el)
Definition: mx-inlines.cc:485
void chop_trailing_singletons(void)
Definition: dim-vector.h:214
void mx_inline_not2(size_t n, bool *r)
Definition: mx-inlines.cc:132
#define DEFMXUNBOOLOP(F, OP)
Definition: mx-inlines.cc:63
int length(void) const
Definition: dim-vector.h:281
T mx_inline_prod(const T *v, octave_idx_type n)
Definition: mx-inlines.cc:523
void twosum_accum(T &s, T &e, const T &x)
Definition: mx-inlines.cc:1332
F77_RET_T const double * x
void mx_inline_diff(const T *v, T *r, octave_idx_type n, octave_idx_type order)
Definition: mx-inlines.cc:1036
void mx_inline_xmax(size_t n, T *r, const T *x, const T *y)
Definition: mx-inlines.cc:270
Array< R > do_bsxfun_op(const Array< X > &x, const Array< Y > &y, void(*op_vv)(size_t, R *, const X *, const Y *), void(*op_sv)(size_t, R *, X, const Y *), void(*op_vs)(size_t, R *, const X *, Y))
Definition: bsxfun-defs.cc:38
T mx_inline_count(const bool *v, octave_idx_type n)
Definition: mx-inlines.cc:523
void mx_inline_min(const T *v, T *r, octave_idx_type n)
Definition: mx-inlines.cc:718