GNU Octave 7.1.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-2022 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
34template <typename T>
36{
37public:
38 _idxadds_helper (T *a, T v) : m_array (a), m_val (v) { }
39
41 { m_array[i] += m_val; }
42
43private:
46};
47
48template <typename T>
50{
51public:
52 _idxadda_helper (T *a, const T *v) : m_array (a), m_vals (v) { }
53
55 { m_array[i] += *m_vals++; }
56
57private:
59 const T *m_vals;
60};
61
62template <typename T>
63void
65{
66 octave_idx_type n = this->numel ();
67 octave_idx_type ext = idx.extent (n);
68 if (ext > n)
69 {
70 this->resize1 (ext);
71 n = ext;
72 }
73
74 octave_quit ();
75
76 octave_idx_type len = idx.length (n);
77 idx.loop (len, _idxadds_helper<T> (this->fortran_vec (), val));
78}
79
80template <typename T>
81void
83{
84 octave_idx_type n = this->numel ();
85 octave_idx_type ext = idx.extent (n);
86 if (ext > n)
87 {
88 this->resize1 (ext);
89 n = ext;
90 }
91
92 octave_quit ();
93
94 octave_idx_type len = std::min (idx.length (n), vals.numel ());
95 idx.loop (len, _idxadda_helper<T> (this->fortran_vec (), vals.data ()));
96}
97
98template <typename T, T op (typename ref_param<T>::type,
99 typename ref_param<T>::type)>
101{
102public:
103 _idxbinop_helper (T *a, const T *v) : m_array (a), m_vals (v) { }
104
106 { m_array[i] = op (m_array[i], *m_vals++); }
108private:
110 const T *m_vals;
111};
112
113template <typename T>
114void
117 octave_idx_type n = this->numel ();
118 octave_idx_type ext = idx.extent (n);
119 if (ext > n)
120 {
121 this->resize1 (ext);
122 n = ext;
123 }
124
125 octave_quit ();
126
127 octave_idx_type len = std::min (idx.length (n), vals.numel ());
128 idx.loop (len, _idxbinop_helper<T, octave::math::min> (this->fortran_vec (),
129 vals.data ()));
130}
131
132template <typename T>
133void
135{
136 octave_idx_type n = this->numel ();
137 octave_idx_type ext = idx.extent (n);
138 if (ext > n)
139 {
140 this->resize1 (ext);
141 n = ext;
142 }
143
144 octave_quit ();
145
146 octave_idx_type len = std::min (idx.length (n), vals.numel ());
147 idx.loop (len, _idxbinop_helper<T, octave::math::max> (this->fortran_vec (),
148 vals.data ()));
149}
150
151template <typename T>
153 const MArray<T>& vals, int dim)
154{
155 int nd = std::max (this->ndims (), vals.ndims ());
156 if (dim < 0)
157 dim = vals.dims ().first_non_singleton ();
158 else if (dim > nd)
159 nd = dim;
160
161 // Check dimensions.
162 dim_vector ddv = Array<T>::dims ().redim (nd);
163 dim_vector sdv = vals.dims ().redim (nd);
164
165 octave_idx_type ext = idx.extent (ddv(dim));
166
167 if (ext > ddv(dim))
168 {
169 ddv(dim) = ext;
170 Array<T>::resize (ddv);
171 ext = ddv(dim);
172 }
173
174 octave_idx_type l, n, u, ns;
175 get_extent_triplet (ddv, dim, l, n, u);
176 ns = sdv(dim);
177
178 sdv(dim) = ddv(dim) = 0;
179 if (ddv != sdv)
180 (*current_liboctave_error_handler) ("accumdim: dimension mismatch");
181
182 T *dst = Array<T>::fortran_vec ();
183 const T *src = vals.data ();
184 octave_idx_type len = idx.length (ns);
185
186 if (l == 1)
187 {
188 for (octave_idx_type j = 0; j < u; j++)
189 {
190 octave_quit ();
191
192 idx.loop (len, _idxadda_helper<T> (dst + j*n, src + j*ns));
193 }
194 }
195 else
196 {
197 for (octave_idx_type j = 0; j < u; j++)
198 {
199 octave_quit ();
200 for (octave_idx_type i = 0; i < len; i++)
201 {
202 octave_idx_type k = idx(i);
203
204 mx_inline_add2 (l, dst + l*k, src + l*i);
205 }
206
207 dst += l*n;
208 src += l*ns;
209 }
210 }
211}
212
213// N-dimensional array with math ops.
214template <typename T>
215void
217{
218 if (Array<T>::is_shared ())
219 *this = - *this;
220 else
221 do_mx_inplace_op<T> (*this, mx_inline_uminus2);
222}
223
224// Element by element MArray by scalar ops.
225
226template <typename T>
228operator += (MArray<T>& a, const T& s)
229{
230 if (a.is_shared ())
231 a = a + s;
232 else
233 do_ms_inplace_op<T, T> (a, s, mx_inline_add2);
234 return a;
235}
236
237template <typename T>
239operator -= (MArray<T>& a, const T& s)
240{
241 if (a.is_shared ())
242 a = a - s;
243 else
244 do_ms_inplace_op<T, T> (a, s, mx_inline_sub2);
245 return a;
246}
247
248template <typename T>
250operator *= (MArray<T>& a, const T& s)
251{
252 if (a.is_shared ())
253 a = a * s;
254 else
255 do_ms_inplace_op<T, T> (a, s, mx_inline_mul2);
256 return a;
257}
258
259template <typename T>
261operator /= (MArray<T>& a, const T& s)
262{
263 if (a.is_shared ())
264 a = a / s;
265 else
266 do_ms_inplace_op<T, T> (a, s, mx_inline_div2);
267 return a;
268}
269
270// Element by element MArray by MArray ops.
271
272template <typename T>
275{
276 if (a.is_shared ())
277 a = a + b;
278 else
279 do_mm_inplace_op<T, T> (a, b, mx_inline_add2, mx_inline_add2, "+=");
280 return a;
281}
282
283template <typename T>
286{
287 if (a.is_shared ())
288 a = a - b;
289 else
290 do_mm_inplace_op<T, T> (a, b, mx_inline_sub2, mx_inline_sub2, "-=");
291 return a;
292}
293
294template <typename T>
297{
298 if (a.is_shared ())
299 return a = product (a, b);
300 else
301 do_mm_inplace_op<T, T> (a, b, mx_inline_mul2, mx_inline_mul2, ".*=");
302 return a;
303}
304
305template <typename T>
308{
309 if (a.is_shared ())
310 return a = quotient (a, b);
311 else
312 do_mm_inplace_op<T, T> (a, b, mx_inline_div2, mx_inline_div2, "./=");
313 return a;
314}
315
316// Element by element MArray by scalar ops.
317
318#define MARRAY_NDS_OP(OP, FN) \
319 template <typename T> \
320 MArray<T> \
321 operator OP (const MArray<T>& a, const T& s) \
322 { \
323 return do_ms_binary_op<T, T, T> (a, s, FN); \
324 }
325
330
331// Element by element scalar by MArray ops.
332
333#define MARRAY_SND_OP(OP, FN) \
334 template <typename T> \
335 MArray<T> \
336 operator OP (const T& s, const MArray<T>& a) \
337 { \
338 return do_sm_binary_op<T, T, T> (s, a, FN); \
339 }
340
345
346// Element by element MArray by MArray ops.
347
348#define MARRAY_NDND_OP(FCN, OP, FN) \
349 template <typename T> \
350 MArray<T> \
351 FCN (const MArray<T>& a, const MArray<T>& b) \
352 { \
353 return do_mm_binary_op<T, T, T> (a, b, FN, FN, FN, #FCN); \
354 }
355
360
361template <typename T>
362MArray<T>
363operator + (const MArray<T>& a)
364{
365 return a;
366}
367
368template <typename T>
371{
372 return do_mx_unary_op<T, T> (a, mx_inline_uminus);
373}
374
375template <typename T>
377{
378 // This guards against accidental implicit instantiations.
379 // Array<T, Alloc> instances should always be explicit and use INSTANTIATE_ARRAY.
380 T::__xXxXx__ ();
381}
382
383#if defined (__clang__)
384# define INSTANTIATE_MARRAY(T, API) \
385 template <> API void \
386 MArray<T>::instantiation_guard () { } \
387 \
388 template class API MArray<T>
389#else
390# define INSTANTIATE_MARRAY(T, API) \
391 template <> API void \
392 MArray<T>::instantiation_guard () { } \
393 \
394 template class MArray<T>
395#endif
#define MARRAY_NDS_OP(OP, FN)
Definition: MArray.cc:318
MArray< T > & operator+=(MArray< T > &a, const T &s)
Definition: MArray.cc:228
MArray< T > & quotient_eq(MArray< T > &a, const MArray< T > &b)
Definition: MArray.cc:307
MArray< T > & operator/=(MArray< T > &a, const T &s)
Definition: MArray.cc:261
MArray< T > & operator-=(MArray< T > &a, const T &s)
Definition: MArray.cc:239
MArray< T > operator-(const MArray< T > &a, const T &s)
Definition: MArray.cc:327
MArray< T > product(const MArray< T > &a, const MArray< T > &b)
Definition: MArray.cc:358
MArray< T > & operator*=(MArray< T > &a, const T &s)
Definition: MArray.cc:250
#define MARRAY_SND_OP(OP, FN)
Definition: MArray.cc:333
MArray< T > & product_eq(MArray< T > &a, const MArray< T > &b)
Definition: MArray.cc:296
#define MARRAY_NDND_OP(FCN, OP, FN)
Definition: MArray.cc:348
MArray< T > quotient(const MArray< T > &a, const MArray< T > &b)
Definition: MArray.cc:359
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:129
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:411
const dim_vector & dims(void) const
Return a const-reference so that dims ()(i) works efficiently.
Definition: Array.h:487
OCTARRAY_API void resize(const dim_vector &dv, const T &rfv)
Size of the specified dimension.
Definition: Array.cc:1010
const T * data(void) const
Size of the specified dimension.
Definition: Array.h:616
OCTARRAY_API T * fortran_vec(void)
Size of the specified dimension.
Definition: Array.cc:1744
int ndims(void) const
Size of the specified dimension.
Definition: Array.h:627
bool is_shared(void)
Size of the specified dimension.
Definition: Array.h:625
Template for N-dimensional array classes with like-type math operators.
Definition: MArray.h:63
OCTARRAY_API void idx_min(const octave::idx_vector &idx, const MArray< T > &vals)
Definition: MArray.cc:115
OCTARRAY_API void idx_add_nd(const octave::idx_vector &idx, const MArray< T > &vals, int dim=-1)
Definition: MArray.cc:152
OCTARRAY_API void changesign(void)
Definition: MArray.cc:216
OCTARRAY_API void idx_add(const octave::idx_vector &idx, T val)
Performs indexed accumulative addition.
Definition: MArray.cc:64
OCTARRAY_API void idx_max(const octave::idx_vector &idx, const MArray< T > &vals)
Definition: MArray.cc:134
static OCTARRAY_API void instantiation_guard()
Definition: MArray.cc:376
const T * m_vals
Definition: MArray.cc:59
void operator()(octave_idx_type i)
Definition: MArray.cc:54
_idxadda_helper(T *a, const T *v)
Definition: MArray.cc:52
void operator()(octave_idx_type i)
Definition: MArray.cc:40
_idxadds_helper(T *a, T v)
Definition: MArray.cc:38
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:94
int first_non_singleton(int def=0) const
Definition: dim-vector.h:444
OCTAVE_API dim_vector redim(int n) const
Force certain dimensionality, preserving numel ().
Definition: dim-vector.cc:226
void loop(octave_idx_type n, Functor body) const
Definition: idx-vector.h:818
octave_idx_type extent(octave_idx_type n) const
Definition: idx-vector.h:540
octave_idx_type length(octave_idx_type n=0) const
Definition: idx-vector.h:537
void mx_inline_div2(std::size_t n, R *r, const X *x)
Definition: mx-inlines.cc:129
void mx_inline_sub2(std::size_t n, R *r, const X *x)
Definition: mx-inlines.cc:127
void mx_inline_add2(std::size_t n, R *r, const X *x)
Definition: mx-inlines.cc:126
void mx_inline_sub(std::size_t n, R *r, const X *x, const Y *y)
Definition: mx-inlines.cc:108
void mx_inline_uminus(std::size_t n, R *r, const X *x)
Definition: mx-inlines.cc:55
void mx_inline_uminus2(std::size_t n, R *r)
Definition: mx-inlines.cc:63
void mx_inline_div(std::size_t n, R *r, const X *x, const Y *y)
Definition: mx-inlines.cc:110
void mx_inline_add(std::size_t n, R *r, const X *x, const Y *y)
Definition: mx-inlines.cc:107
void mx_inline_mul2(std::size_t n, R *r, const X *x)
Definition: mx-inlines.cc:128
void mx_inline_mul(std::size_t n, R *r, const X *x, const Y *y)
Definition: mx-inlines.cc:109
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:1490
T::size_type numel(const T &str)
Definition: oct-string.cc:71
_idxbinop_helper(T *a, const T *v)
Definition: MArray.cc:103
void operator()(octave_idx_type i)
Definition: MArray.cc:105
const T * m_vals
Definition: MArray.cc:110
F77_RET_T len
Definition: xerbla.cc:61