GNU Octave  6.2.0
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-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 // This file should not include config.h. It is only included in other
27 // C++ source files that should have included config.h before including
28 // this file.
29 
30 #include "MArray.h"
31 #include "Array-util.h"
32 #include "lo-error.h"
33 
34 template <typename T>
36 {
37  T *array;
38  T val;
39  _idxadds_helper (T *a, T v) : array (a), val (v) { }
41  { array[i] += val; }
42 };
43 
44 template <typename T>
46 {
47  T *array;
48  const T *vals;
49  _idxadda_helper (T *a, const T *v) : array (a), vals (v) { }
51  { array[i] += *vals++; }
52 };
53 
54 template <typename T>
55 void
56 MArray<T>::idx_add (const idx_vector& idx, T val)
57 {
58  octave_idx_type n = this->numel ();
59  octave_idx_type ext = idx.extent (n);
60  if (ext > n)
61  {
62  this->resize1 (ext);
63  n = ext;
64  }
65 
66  octave_quit ();
67 
68  octave_idx_type len = idx.length (n);
69  idx.loop (len, _idxadds_helper<T> (this->fortran_vec (), val));
70 }
71 
72 template <typename T>
73 void
74 MArray<T>::idx_add (const idx_vector& idx, const MArray<T>& vals)
75 {
76  octave_idx_type n = this->numel ();
77  octave_idx_type ext = idx.extent (n);
78  if (ext > n)
79  {
80  this->resize1 (ext);
81  n = ext;
82  }
83 
84  octave_quit ();
85 
86  octave_idx_type len = std::min (idx.length (n), vals.numel ());
87  idx.loop (len, _idxadda_helper<T> (this->fortran_vec (), vals.data ()));
88 }
89 
90 template <typename T, T op (typename ref_param<T>::type,
91  typename ref_param<T>::type)>
93 {
94  T *array;
95  const T *vals;
96  _idxbinop_helper (T *a, const T *v) : array (a), vals (v) { }
98  { array[i] = op (array[i], *vals++); }
99 };
100 
101 template <typename T>
102 void
103 MArray<T>::idx_min (const idx_vector& idx, const MArray<T>& vals)
104 {
105  octave_idx_type n = this->numel ();
106  octave_idx_type ext = idx.extent (n);
107  if (ext > n)
108  {
109  this->resize1 (ext);
110  n = ext;
111  }
112 
113  octave_quit ();
114 
115  octave_idx_type len = std::min (idx.length (n), vals.numel ());
116  idx.loop (len, _idxbinop_helper<T, octave::math::min> (this->fortran_vec (),
117  vals.data ()));
118 }
119 
120 template <typename T>
121 void
122 MArray<T>::idx_max (const idx_vector& idx, const MArray<T>& vals)
123 {
124  octave_idx_type n = this->numel ();
125  octave_idx_type ext = idx.extent (n);
126  if (ext > n)
127  {
128  this->resize1 (ext);
129  n = ext;
130  }
131 
132  octave_quit ();
133 
134  octave_idx_type len = std::min (idx.length (n), vals.numel ());
135  idx.loop (len, _idxbinop_helper<T, octave::math::max> (this->fortran_vec (),
136  vals.data ()));
137 }
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>&
216 operator += (MArray<T>& a, const T& s)
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>&
227 operator -= (MArray<T>& a, const T& s)
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>&
238 operator *= (MArray<T>& a, const T& s)
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>&
249 operator /= (MArray<T>& a, const T& s)
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 }
MArray< T > & quotient_eq(MArray< T > &a, const MArray< T > &b)
Definition: MArray.cc:295
#define MARRAY_NDS_OP(OP, FN)
Definition: MArray.cc:306
MArray< T > operator-(const MArray< T > &a, const T &s)
Definition: MArray.cc:315
MArray< T > & product_eq(MArray< T > &a, const MArray< T > &b)
Definition: MArray.cc:284
MArray< T > quotient(const MArray< T > &a, const MArray< T > &b)
Definition: MArray.cc:347
MArray< T > & operator*=(MArray< T > &a, const T &s)
Definition: MArray.cc:238
MArray< T > & operator+=(MArray< T > &a, const T &s)
Definition: MArray.cc:216
#define MARRAY_SND_OP(OP, FN)
Definition: MArray.cc:321
MArray< T > & operator/=(MArray< T > &a, const T &s)
Definition: MArray.cc:249
MArray< T > & operator-=(MArray< T > &a, const T &s)
Definition: MArray.cc:227
MArray< T > product(const MArray< T > &a, const MArray< T > &b)
Definition: MArray.cc:346
#define MARRAY_NDND_OP(FCN, OP, FN)
Definition: MArray.cc:336
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:230
charNDArray min(char d, const charNDArray &m)
Definition: chNDArray.cc:207
N Dimensional Array with copy-on-write semantics.
Definition: Array.h:128
void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
Definition: Array.cc:1011
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:377
const T * data(void) const
Size of the specified dimension.
Definition: Array.h:581
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
Definition: Array.h:453
int ndims(void) const
Size of the specified dimension.
Definition: Array.h:589
const T * fortran_vec(void) const
Size of the specified dimension.
Definition: Array.h:583
bool is_shared(void)
Size of the specified dimension.
Definition: Array.h:587
Template for N-dimensional array classes with like-type math operators.
Definition: MArray.h:63
void idx_min(const idx_vector &idx, const MArray< T > &vals)
Definition: MArray.cc:103
void idx_add_nd(const idx_vector &idx, const MArray< T > &vals, int dim=-1)
Definition: MArray.cc:140
void idx_max(const idx_vector &idx, const MArray< T > &vals)
Definition: MArray.cc:122
void changesign(void)
Definition: MArray.cc:204
void idx_add(const idx_vector &idx, T val)
Performs indexed accumulative addition.
Definition: MArray.cc:56
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:95
int first_non_singleton(int def=0) const
Definition: dim-vector.h:510
dim_vector redim(int n) const
Force certain dimensionality, preserving numel ().
Definition: dim-vector.cc:245
void loop(octave_idx_type n, Functor body) const
Definition: idx-vector.h:838
octave_idx_type length(octave_idx_type n=0) const
Definition: idx-vector.h:558
octave_idx_type extent(octave_idx_type n) const
Definition: idx-vector.h:561
void mx_inline_div(size_t n, R *r, const X *x, const Y *y)
Definition: mx-inlines.cc:110
void mx_inline_div2(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:129
void mx_inline_uminus(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:55
void mx_inline_mul(size_t n, R *r, const X *x, const Y *y)
Definition: mx-inlines.cc:109
void mx_inline_add2(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:126
void mx_inline_sub2(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:127
void mx_inline_uminus2(size_t n, R *r)
Definition: mx-inlines.cc:63
void mx_inline_add(size_t n, R *r, const X *x, const Y *y)
Definition: mx-inlines.cc:107
octave_idx_type n
Definition: mx-inlines.cc:753
void mx_inline_mul2(size_t n, R *r, const X *x)
Definition: mx-inlines.cc:128
void mx_inline_sub(size_t n, R *r, const X *x, const Y *y)
Definition: mx-inlines.cc:108
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:1499
T::size_type numel(const T &str)
Definition: oct-string.cc:71
const T * vals
Definition: MArray.cc:48
void operator()(octave_idx_type i)
Definition: MArray.cc:50
_idxadda_helper(T *a, const T *v)
Definition: MArray.cc:49
void operator()(octave_idx_type i)
Definition: MArray.cc:40
_idxadds_helper(T *a, T v)
Definition: MArray.cc:39
_idxbinop_helper(T *a, const T *v)
Definition: MArray.cc:96
const T * vals
Definition: MArray.cc:95
void operator()(octave_idx_type i)
Definition: MArray.cc:97
F77_RET_T len
Definition: xerbla.cc:61