GNU Octave  4.4.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
MArray.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1993-2018 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
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12 
13 Octave is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License 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 <https://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:127
void mx_inline_add2(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:125
_idxadds_helper(T *a, T v)
Definition: MArray.cc:37
void operator()(octave_idx_type i)
Definition: MArray.cc:38
void idx_min(const idx_vector &idx, const MArray< T > &vals)
Definition: MArray.cc:101
Template for N-dimensional array classes with like-type math operators.
Definition: MArray.h:32
void mx_inline_sub2(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:126
_idxadda_helper(T *a, const T *v)
Definition: MArray.cc:47
void loop(octave_idx_type n, Functor body) const
Definition: idx-vector.h:837
const T * data(void) const
Definition: Array.h:582
void idx_add_nd(const idx_vector &idx, const MArray< T > &vals, int dim=-1)
Definition: MArray.cc:140
octave_idx_type extent(octave_idx_type n) const
Definition: idx-vector.h:560
void mx_inline_uminus2(size_t n, R *r)
Definition: mx-inlines.cc:62
identity matrix If supplied two scalar respectively For allows like xample val
Definition: data.cc:4986
void changesign(void)
Definition: MArray.cc:204
for large enough k
Definition: lu.cc:617
const T * fortran_vec(void) const
Definition: Array.h:584
void idx_max(const idx_vector &idx, const MArray< T > &vals)
Definition: MArray.cc:120
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
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
Definition: Array.h:442
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
s
Definition: file-io.cc:2729
void mx_inline_mul(size_t n, R *r, const X *x, const Y *y)
Definition: mx-inlines.cc:108
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:400
then the function must return scalars which will be concatenated into the return array(s). If code
Definition: cellfun.cc:400
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:107
void mx_inline_uminus(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:54
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 operator()(octave_idx_type i)
Definition: MArray.cc:48
int first_non_singleton(int def=0) const
Definition: dim-vector.h:475
void resize(const dim_vector &dv, const T &rfv)
Resizing (with fill).
Definition: Array.cc:1010
octave_idx_type length(octave_idx_type n=0) const
Definition: idx-vector.h:557
idx type
Definition: ov.cc:3114
dim_vector redim(int n) const
Force certain dimensionality, preserving numel ().
Definition: dim-vector.cc:233
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
N Dimensional Array with copy-on-write semantics.
Definition: Array.h:125
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:227
T::size_type numel(const T &str)
Definition: oct-string.cc:61
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:1489
b
Definition: cellfun.cc:400
for i
Definition: data.cc:5264
void mx_inline_add(size_t n, R *r, const X *x, const Y *y)
Definition: mx-inlines.cc:106
#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:109
void mx_inline_div2(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:128
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:366
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
void idx_add(const idx_vector &idx, T val)
Performs indexed accumulative addition.
Definition: MArray.cc:54
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:204
int ndims(void) const
Definition: Array.h:590