1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2004-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 "Array-util.h"
31 #include "mx-base.h"
32 #include "lo-ieee.h"
33 #include "mx-inlines.cc"
34
35 // unary operations
36
37 template <typename T>
38 boolNDArray
operator !(void) const39 intNDArray<T>::operator ! (void) const
40 {
41 boolNDArray b (this->dims ());
42
43 for (octave_idx_type i = 0; i < this->numel (); i++)
44 b.elem (i) = ! this->elem (i);
45
46 return b;
47 }
48
49 template <typename T>
50 bool
any_element_not_one_or_zero(void) const51 intNDArray<T>::any_element_not_one_or_zero (void) const
52 {
53 octave_idx_type nel = this->numel ();
54
55 for (octave_idx_type i = 0; i < nel; i++)
56 {
57 T val = this->elem (i);
58
59 if (val != 0.0 && val != 1.0)
60 return true;
61 }
62
63 return false;
64 }
65
66 template <typename T>
67 intNDArray<T>
diag(octave_idx_type k) const68 intNDArray<T>::diag (octave_idx_type k) const
69 {
70 return MArray<T>::diag (k);
71 }
72
73 template <typename T>
74 intNDArray<T>
diag(octave_idx_type m,octave_idx_type n) const75 intNDArray<T>::diag (octave_idx_type m, octave_idx_type n) const
76 {
77 return MArray<T>::diag (m, n);
78 }
79
80 // FIXME: this is not quite the right thing.
81
82 template <typename T>
83 boolNDArray
all(int dim) const84 intNDArray<T>::all (int dim) const
85 {
86 return do_mx_red_op<bool, T > (*this, dim, mx_inline_all);
87 }
88
89 template <typename T>
90 boolNDArray
any(int dim) const91 intNDArray<T>::any (int dim) const
92 {
93 return do_mx_red_op<bool, T > (*this, dim, mx_inline_any);
94 }
95
96 template <typename T>
97 void
increment_index(Array<octave_idx_type> & ra_idx,const dim_vector & dimensions,int start_dimension)98 intNDArray<T>::increment_index (Array<octave_idx_type>& ra_idx,
99 const dim_vector& dimensions,
100 int start_dimension)
101 {
102 ::increment_index (ra_idx, dimensions, start_dimension);
103 }
104
105 template <typename T>
106 octave_idx_type
compute_index(Array<octave_idx_type> & ra_idx,const dim_vector & dimensions)107 intNDArray<T>::compute_index (Array<octave_idx_type>& ra_idx,
108 const dim_vector& dimensions)
109 {
110 return ::compute_index (ra_idx, dimensions);
111 }
112
113 template <typename T>
114 intNDArray<T>
concat(const intNDArray<T> & rb,const Array<octave_idx_type> & ra_idx)115 intNDArray<T>::concat (const intNDArray<T>& rb,
116 const Array<octave_idx_type>& ra_idx)
117 {
118 if (rb.numel () > 0)
119 insert (rb, ra_idx);
120 return *this;
121 }
122
123 template <typename T>
124 intNDArray<T>&
insert(const intNDArray<T> & a,octave_idx_type r,octave_idx_type c)125 intNDArray<T>::insert (const intNDArray<T>& a, octave_idx_type r,
126 octave_idx_type c)
127 {
128 Array<T>::insert (a, r, c);
129 return *this;
130 }
131
132 template <typename T>
133 intNDArray<T>&
insert(const intNDArray<T> & a,const Array<octave_idx_type> & ra_idx)134 intNDArray<T>::insert (const intNDArray<T>& a,
135 const Array<octave_idx_type>& ra_idx)
136 {
137 Array<T>::insert (a, ra_idx);
138 return *this;
139 }
140
141 // This contains no information on the array structure !!!
142
143 template <typename T>
144 std::ostream&
operator <<(std::ostream & os,const intNDArray<T> & a)145 operator << (std::ostream& os, const intNDArray<T>& a)
146 {
147 octave_idx_type nel = a.numel ();
148
149 for (octave_idx_type i = 0; i < nel; i++)
150 os << ' ' << a.elem (i) << "\n";
151
152 return os;
153 }
154
155 template <typename T>
156 std::istream&
operator >>(std::istream & is,intNDArray<T> & a)157 operator >> (std::istream& is, intNDArray<T>& a)
158 {
159 octave_idx_type nel = a.numel ();
160
161 if (nel > 0)
162 {
163 T tmp;
164
165 for (octave_idx_type i = 0; i < nel; i++)
166 {
167 is >> tmp;
168
169 if (is)
170 a.elem (i) = tmp;
171 else
172 return is;
173 }
174 }
175
176 return is;
177 }
178
179 // FIXME: should abs and signum just be mapper functions?
180
181 template <typename T>
182 intNDArray<T>
abs(void) const183 intNDArray<T>::abs (void) const
184 {
185 octave_idx_type nel = this->numel ();
186 intNDArray<T> ret (this->dims ());
187
188 for (octave_idx_type i = 0; i < nel; i++)
189 {
190 T val = this->elem (i);
191 ret.xelem (i) = val.abs ();
192 }
193
194 return ret;
195 }
196
197 template <typename T>
198 intNDArray<T>
signum(void) const199 intNDArray<T>::signum (void) const
200 {
201 octave_idx_type nel = this->numel ();
202 intNDArray<T> ret (this->dims ());
203
204 for (octave_idx_type i = 0; i < nel; i++)
205 {
206 T val = this->elem (i);
207 ret.xelem (i) = val.signum ();
208 }
209
210 return ret;
211 }
212
213 template <typename T>
214 intNDArray<T>
prod(int dim) const215 intNDArray<T>::prod (int dim) const
216 {
217 return do_mx_red_op<T, T> (*this, dim, mx_inline_prod);
218 }
219
220 template <typename T>
221 intNDArray<T>
sum(int dim) const222 intNDArray<T>::sum (int dim) const
223 {
224 return do_mx_red_op<T, T> (*this, dim, mx_inline_sum);
225 }
226
227 template <typename T>
228 NDArray
dsum(int dim) const229 intNDArray<T>::dsum (int dim) const
230 {
231 return do_mx_red_op<double, T> (*this, dim, mx_inline_dsum);
232 }
233
234 template <typename T>
235 intNDArray<T>
cumsum(int dim) const236 intNDArray<T>::cumsum (int dim) const
237 {
238 return do_mx_cum_op<T, T> (*this, dim, mx_inline_cumsum);
239 }
240
241 template <typename T>
242 intNDArray<T>
max(int dim) const243 intNDArray<T>::max (int dim) const
244 {
245 return do_mx_minmax_op<T> (*this, dim, mx_inline_max);
246 }
247
248 template <typename T>
249 intNDArray<T>
max(Array<octave_idx_type> & idx_arg,int dim) const250 intNDArray<T>::max (Array<octave_idx_type>& idx_arg, int dim) const
251 {
252 return do_mx_minmax_op<T> (*this, idx_arg, dim, mx_inline_max);
253 }
254
255 template <typename T>
256 intNDArray<T>
min(int dim) const257 intNDArray<T>::min (int dim) const
258 {
259 return do_mx_minmax_op<T> (*this, dim, mx_inline_min);
260 }
261
262 template <typename T>
263 intNDArray<T>
min(Array<octave_idx_type> & idx_arg,int dim) const264 intNDArray<T>::min (Array<octave_idx_type>& idx_arg, int dim) const
265 {
266 return do_mx_minmax_op<T> (*this, idx_arg, dim, mx_inline_min);
267 }
268
269 template <typename T>
270 intNDArray<T>
cummax(int dim) const271 intNDArray<T>::cummax (int dim) const
272 {
273 return do_mx_cumminmax_op<T> (*this, dim, mx_inline_cummax);
274 }
275
276 template <typename T>
277 intNDArray<T>
cummax(Array<octave_idx_type> & idx_arg,int dim) const278 intNDArray<T>::cummax (Array<octave_idx_type>& idx_arg, int dim) const
279 {
280 return do_mx_cumminmax_op<T> (*this, idx_arg, dim, mx_inline_cummax);
281 }
282
283 template <typename T>
284 intNDArray<T>
cummin(int dim) const285 intNDArray<T>::cummin (int dim) const
286 {
287 return do_mx_cumminmax_op<T> (*this, dim, mx_inline_cummin);
288 }
289
290 template <typename T>
291 intNDArray<T>
cummin(Array<octave_idx_type> & idx_arg,int dim) const292 intNDArray<T>::cummin (Array<octave_idx_type>& idx_arg, int dim) const
293 {
294 return do_mx_cumminmax_op<T> (*this, idx_arg, dim, mx_inline_cummin);
295 }
296
297 template <typename T>
298 intNDArray<T>
diff(octave_idx_type order,int dim) const299 intNDArray<T>::diff (octave_idx_type order, int dim) const
300 {
301 return do_mx_diff_op<T> (*this, dim, order, mx_inline_diff);
302 }
303