GNU Octave  4.2.1
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
MArray.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1993-2017 John W. Eaton
4 Copyright (C) 2009 VZLU Prague
5 
6 This file is part of Octave.
7 
8 Octave is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Octave; see the file COPYING. If not, see
20 <http://www.gnu.org/licenses/>.
21 
22 */
23 
24 // This file should not include config.h. It is only included in other
25 // C++ source files that should have included config.h before including
26 // this file.
27 
28 #include "MArray.h"
29 #include "Array-util.h"
30 #include "lo-error.h"
31 
32 template <typename T>
34 {
35  T *array;
36  T val;
37  _idxadds_helper (T *a, T v) : array (a), val (v) { }
39  { array[i] += val; }
40 };
41 
42 template <typename T>
44 {
45  T *array;
46  const T *vals;
47  _idxadda_helper (T *a, const T *v) : array (a), vals (v) { }
49  { array[i] += *vals++; }
50 };
51 
52 template <typename T>
53 void
55 {
56  octave_idx_type n = this->numel ();
57  octave_idx_type ext = idx.extent (n);
58  if (ext > n)
59  {
60  this->resize1 (ext);
61  n = ext;
62  }
63 
64  octave_quit ();
65 
66  octave_idx_type len = idx.length (n);
67  idx.loop (len, _idxadds_helper<T> (this->fortran_vec (), val));
68 }
69 
70 template <typename T>
71 void
72 MArray<T>::idx_add (const idx_vector& idx, const MArray<T>& vals)
73 {
74  octave_idx_type n = this->numel ();
75  octave_idx_type ext = idx.extent (n);
76  if (ext > n)
77  {
78  this->resize1 (ext);
79  n = ext;
80  }
81 
82  octave_quit ();
83 
84  octave_idx_type len = std::min (idx.length (n), vals.numel ());
85  idx.loop (len, _idxadda_helper<T> (this->fortran_vec (), vals.data ()));
86 }
87 
89  typename ref_param<T>::type)>
91 {
92  T *array;
93  const T *vals;
94  _idxbinop_helper (T *a, const T *v) : array (a), vals (v) { }
95  void operator () (octave_idx_type i)
96  { array[i] = op (array[i], *vals++); }
97 };
98 
99 template <typename T>
100 void
101 MArray<T>::idx_min (const idx_vector& idx, const MArray<T>& vals)
102 {
103  octave_idx_type n = this->numel ();
104  octave_idx_type ext = idx.extent (n);
105  if (ext > n)
106  {
107  this->resize1 (ext);
108  n = ext;
109  }
110 
111  octave_quit ();
112 
113  octave_idx_type len = std::min (idx.length (n), vals.numel ());
114  idx.loop (len, _idxbinop_helper<T, octave::math::min> (this->fortran_vec (),
115  vals.data ()));
116 }
117 
118 template <typename T>
119 void
120 MArray<T>::idx_max (const idx_vector& idx, const MArray<T>& vals)
121 {
122  octave_idx_type n = this->numel ();
123  octave_idx_type ext = idx.extent (n);
124  if (ext > n)
125  {
126  this->resize1 (ext);
127  n = ext;
128  }
129 
130  octave_quit ();
131 
132  octave_idx_type len = std::min (idx.length (n), vals.numel ());
133  idx.loop (len, _idxbinop_helper<T, octave::math::max> (this->fortran_vec (),
134  vals.data ()));
135 }
136 
137 #include <iostream>
138 
139 template <typename T>
140 void MArray<T>::idx_add_nd (const idx_vector& idx, const MArray<T>& vals,
141  int dim)
142 {
143  int nd = std::max (this->ndims (), vals.ndims ());
144  if (dim < 0)
145  dim = vals.dims ().first_non_singleton ();
146  else if (dim > nd)
147  nd = dim;
148 
149  // Check dimensions.
150  dim_vector ddv = Array<T>::dims ().redim (nd);
151  dim_vector sdv = vals.dims ().redim (nd);
152 
153  octave_idx_type ext = idx.extent (ddv(dim));
154 
155  if (ext > ddv(dim))
156  {
157  ddv(dim) = ext;
158  Array<T>::resize (ddv);
159  ext = ddv(dim);
160  }
161 
162  octave_idx_type l,n,u,ns;
163  get_extent_triplet (ddv, dim, l, n, u);
164  ns = sdv(dim);
165 
166  sdv(dim) = ddv(dim) = 0;
167  if (ddv != sdv)
168  (*current_liboctave_error_handler) ("accumdim: dimension mismatch");
169 
170  T *dst = Array<T>::fortran_vec ();
171  const T *src = vals.data ();
172  octave_idx_type len = idx.length (ns);
173 
174  if (l == 1)
175  {
176  for (octave_idx_type j = 0; j < u; j++)
177  {
178  octave_quit ();
179 
180  idx.loop (len, _idxadda_helper<T> (dst + j*n, src + j*ns));
181  }
182  }
183  else
184  {
185  for (octave_idx_type j = 0; j < u; j++)
186  {
187  octave_quit ();
188  for (octave_idx_type i = 0; i < len; i++)
189  {
190  octave_idx_type k = idx(i);
191 
192  mx_inline_add2 (l, dst + l*k, src + l*i);
193  }
194 
195  dst += l*n;
196  src += l*ns;
197  }
198  }
199 }
200 
201 // N-dimensional array with math ops.
202 template <typename T>
203 void
205 {
206  if (Array<T>::is_shared ())
207  *this = - *this;
208  else
209  do_mx_inplace_op<T> (*this, mx_inline_uminus2);
210 }
211 
212 // Element by element MArray by scalar ops.
213 
214 template <typename T>
215 MArray<T>&
217 {
218  if (a.is_shared ())
219  a = a + s;
220  else
221  do_ms_inplace_op<T, T> (a, s, mx_inline_add2);
222  return a;
223 }
224 
225 template <typename T>
226 MArray<T>&
228 {
229  if (a.is_shared ())
230  a = a - s;
231  else
232  do_ms_inplace_op<T, T> (a, s, mx_inline_sub2);
233  return a;
234 }
235 
236 template <typename T>
237 MArray<T>&
239 {
240  if (a.is_shared ())
241  a = a * s;
242  else
243  do_ms_inplace_op<T, T> (a, s, mx_inline_mul2);
244  return a;
245 }
246 
247 template <typename T>
248 MArray<T>&
250 {
251  if (a.is_shared ())
252  a = a / s;
253  else
254  do_ms_inplace_op<T, T> (a, s, mx_inline_div2);
255  return a;
256 }
257 
258 // Element by element MArray by MArray ops.
259 
260 template <typename T>
261 MArray<T>&
263 {
264  if (a.is_shared ())
265  a = a + b;
266  else
267  do_mm_inplace_op<T, T> (a, b, mx_inline_add2, mx_inline_add2, "+=");
268  return a;
269 }
270 
271 template <typename T>
272 MArray<T>&
274 {
275  if (a.is_shared ())
276  a = a - b;
277  else
278  do_mm_inplace_op<T, T> (a, b, mx_inline_sub2, mx_inline_sub2, "-=");
279  return a;
280 }
281 
282 template <typename T>
283 MArray<T>&
285 {
286  if (a.is_shared ())
287  return a = product (a, b);
288  else
289  do_mm_inplace_op<T, T> (a, b, mx_inline_mul2, mx_inline_mul2, ".*=");
290  return a;
291 }
292 
293 template <typename T>
294 MArray<T>&
296 {
297  if (a.is_shared ())
298  return a = quotient (a, b);
299  else
300  do_mm_inplace_op<T, T> (a, b, mx_inline_div2, mx_inline_div2, "./=");
301  return a;
302 }
303 
304 // Element by element MArray by scalar ops.
305 
306 #define MARRAY_NDS_OP(OP, FN) \
307  template <typename T> \
308  MArray<T> \
309  operator OP (const MArray<T>& a, const T& s) \
310  { \
311  return do_ms_binary_op<T, T, T> (a, s, FN); \
312  }
313 
318 
319 // Element by element scalar by MArray ops.
320 
321 #define MARRAY_SND_OP(OP, FN) \
322  template <typename T> \
323  MArray<T> \
324  operator OP (const T& s, const MArray<T>& a) \
325  { \
326  return do_sm_binary_op<T, T, T> (s, a, FN); \
327  }
328 
333 
334 // Element by element MArray by MArray ops.
335 
336 #define MARRAY_NDND_OP(FCN, OP, FN) \
337  template <typename T> \
338  MArray<T> \
339  FCN (const MArray<T>& a, const MArray<T>& b) \
340  { \
341  return do_mm_binary_op<T, T, T> (a, b, FN, FN, FN, #FCN); \
342  }
343 
348 
349 template <typename T>
350 MArray<T>
351 operator + (const MArray<T>& a)
352 {
353  return a;
354 }
355 
356 template <typename T>
357 MArray<T>
359 {
360  return do_mx_unary_op<T, T> (a, mx_inline_uminus);
361 }
void mx_inline_mul2(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:129
void mx_inline_add2(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:127
_idxadds_helper(T *a, T v)
Definition: MArray.cc:37
void operator()(octave_idx_type i)
Definition: MArray.cc:38
octave_idx_type length(octave_idx_type n=0) const
Definition: idx-vector.h:541
void mx_inline_sub2(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:128
_idxadda_helper(T *a, const T *v)
Definition: MArray.cc:47
int ndims(void) const
Definition: Array.h:590
void mx_inline_uminus2(size_t n, R *r)
Definition: mx-inlines.cc:74
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:363
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:5068
for large enough k
Definition: lu.cc:606
MArray< T > & operator-=(MArray< T > &a, const T &s)
Definition: MArray.cc:227
MArray< T > operator-(const MArray< T > &a, const T &s)
Definition: MArray.cc:315
MArray< T > & operator*=(MArray< T > &a, const T &s)
Definition: MArray.cc:238
u
Definition: lu.cc:138
_idxbinop_helper(T *a, const T *v)
Definition: MArray.cc:94
Template for N-dimensional array classes with like-type math operators.
Definition: MArray.h:32
s
Definition: file-io.cc:2682
void idx_max(const idx_vector &idx, const MArray< T > &vals)
Definition: MArray.cc:120
void changesign(void)
Definition: MArray.cc:204
int first_non_singleton(int def=0) const
Definition: dim-vector.h:463
void mx_inline_mul(size_t n, R *r, const X *x, const Y *y)
Definition: mx-inlines.cc:110
MArray< T > & product_eq(MArray< T > &a, const MArray< T > &b)
Definition: MArray.cc:284
calling an anonymous function involves an overhead quite comparable to the overhead of an m file function Passing a handle to a built in function is because the interpreter is not involved in the internal loop For a
Definition: cellfun.cc:398
void idx_add_nd(const idx_vector &idx, const MArray< T > &vals, int dim=-1)
Definition: MArray.cc:140
void loop(octave_idx_type n, Functor body) const
Definition: idx-vector.h:827
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
Definition: Array.h:439
MArray< T > product(const MArray< T > &a, const MArray< T > &b)
Definition: MArray.cc:346
void mx_inline_sub(size_t n, R *r, const X *x, const Y *y)
Definition: mx-inlines.cc:109
void mx_inline_uminus(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:64
MArray< T > & operator+=(MArray< T > &a, const T &s)
Definition: MArray.cc:216
const T * vals
Definition: MArray.cc:46
MArray< T > & operator/=(MArray< T > &a, const T &s)
Definition: MArray.cc:249
void idx_add(const idx_vector &idx, T val)
Performs indexed accumulative addition.
Definition: MArray.cc:54
void operator()(octave_idx_type i)
Definition: MArray.cc:48
const T * data(void) const
Definition: Array.h:582
void resize(const dim_vector &dv, const T &rfv)
Definition: Array.cc:1028
dim_vector redim(int n) const
Definition: dim-vector.cc:275
idx type
Definition: ov.cc:3129
if_then_else< is_class_type< T >::no, T, T const & >::result type
Definition: lo-traits.h:118
MArray< T > & quotient_eq(MArray< T > &a, const MArray< T > &b)
Definition: MArray.cc:295
#define MARRAY_NDND_OP(FCN, OP, FN)
Definition: MArray.cc:336
void idx_min(const idx_vector &idx, const MArray< T > &vals)
Definition: MArray.cc:101
N Dimensional Array with copy-on-write semantics.
Definition: Array.h:126
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:228
octave_idx_type extent(octave_idx_type n) const
Definition: idx-vector.h:544
T::size_type numel(const T &str)
Definition: oct-string.cc:61
bool is_shared(void)
Definition: Array.h:588
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
MArray< T > quotient(const MArray< T > &a, const MArray< T > &b)
Definition: MArray.cc:347
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:1452
b
Definition: cellfun.cc:398
void mx_inline_add(size_t n, R *r, const X *x, const Y *y)
Definition: mx-inlines.cc:108
#define MARRAY_SND_OP(OP, FN)
Definition: MArray.cc:321
void mx_inline_div(size_t n, R *r, const X *x, const Y *y)
Definition: mx-inlines.cc:111
const T * fortran_vec(void) const
Definition: Array.h:584
void mx_inline_div2(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:130
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
const T * vals
Definition: MArray.cc:93
#define MARRAY_NDS_OP(OP, FN)
Definition: MArray.cc:306
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:205