1 // SPDX-License-Identifier: Apache-2.0
2 //
3 // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
4 // Copyright 2008-2016 National ICT Australia (NICTA)
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 // ------------------------------------------------------------------------
17 
18 
19 //! \addtogroup BaseCube
20 //! @{
21 
22 
23 
24 template<typename elem_type, typename derived>
25 arma_inline
26 const derived&
get_ref() const27 BaseCube<elem_type,derived>::get_ref() const
28   {
29   return static_cast<const derived&>(*this);
30   }
31 
32 
33 
34 template<typename elem_type, typename derived>
35 arma_cold
36 inline
37 void
print(const std::string extra_text) const38 BaseCube<elem_type,derived>::print(const std::string extra_text) const
39   {
40   arma_extra_debug_sigprint();
41 
42   const unwrap_cube<derived> tmp( (*this).get_ref() );
43 
44   if(extra_text.length() != 0)
45     {
46     const std::streamsize orig_width = get_cout_stream().width();
47 
48     get_cout_stream() << extra_text << '\n';
49 
50     get_cout_stream().width(orig_width);
51     }
52 
53   arma_ostream::print(get_cout_stream(), tmp.M, true);
54   }
55 
56 
57 
58 template<typename elem_type, typename derived>
59 arma_cold
60 inline
61 void
print(std::ostream & user_stream,const std::string extra_text) const62 BaseCube<elem_type,derived>::print(std::ostream& user_stream, const std::string extra_text) const
63   {
64   arma_extra_debug_sigprint();
65 
66   const unwrap_cube<derived> tmp( (*this).get_ref() );
67 
68   if(extra_text.length() != 0)
69     {
70     const std::streamsize orig_width = user_stream.width();
71 
72     user_stream << extra_text << '\n';
73 
74     user_stream.width(orig_width);
75     }
76 
77   arma_ostream::print(user_stream, tmp.M, true);
78   }
79 
80 
81 
82 template<typename elem_type, typename derived>
83 arma_cold
84 inline
85 void
raw_print(const std::string extra_text) const86 BaseCube<elem_type,derived>::raw_print(const std::string extra_text) const
87   {
88   arma_extra_debug_sigprint();
89 
90   const unwrap_cube<derived> tmp( (*this).get_ref() );
91 
92   if(extra_text.length() != 0)
93     {
94     const std::streamsize orig_width = get_cout_stream().width();
95 
96     get_cout_stream() << extra_text << '\n';
97 
98     get_cout_stream().width(orig_width);
99     }
100 
101   arma_ostream::print(get_cout_stream(), tmp.M, false);
102   }
103 
104 
105 
106 template<typename elem_type, typename derived>
107 arma_cold
108 inline
109 void
raw_print(std::ostream & user_stream,const std::string extra_text) const110 BaseCube<elem_type,derived>::raw_print(std::ostream& user_stream, const std::string extra_text) const
111   {
112   arma_extra_debug_sigprint();
113 
114   const unwrap_cube<derived> tmp( (*this).get_ref() );
115 
116   if(extra_text.length() != 0)
117     {
118     const std::streamsize orig_width = user_stream.width();
119 
120     user_stream << extra_text << '\n';
121 
122     user_stream.width(orig_width);
123     }
124 
125   arma_ostream::print(user_stream, tmp.M, false);
126   }
127 
128 
129 
130 template<typename elem_type, typename derived>
131 arma_cold
132 inline
133 void
brief_print(const std::string extra_text) const134 BaseCube<elem_type,derived>::brief_print(const std::string extra_text) const
135   {
136   arma_extra_debug_sigprint();
137 
138   const unwrap_cube<derived> tmp( (*this).get_ref() );
139 
140   if(extra_text.length() != 0)
141     {
142     const std::streamsize orig_width = get_cout_stream().width();
143 
144     get_cout_stream() << extra_text << '\n';
145 
146     get_cout_stream().width(orig_width);
147     }
148 
149   arma_ostream::brief_print(get_cout_stream(), tmp.M);
150   }
151 
152 
153 
154 template<typename elem_type, typename derived>
155 arma_cold
156 inline
157 void
brief_print(std::ostream & user_stream,const std::string extra_text) const158 BaseCube<elem_type,derived>::brief_print(std::ostream& user_stream, const std::string extra_text) const
159   {
160   arma_extra_debug_sigprint();
161 
162   const unwrap_cube<derived> tmp( (*this).get_ref() );
163 
164   if(extra_text.length() != 0)
165     {
166     const std::streamsize orig_width = user_stream.width();
167 
168     user_stream << extra_text << '\n';
169 
170     user_stream.width(orig_width);
171     }
172 
173   arma_ostream::brief_print(user_stream, tmp.M);
174   }
175 
176 
177 
178 template<typename elem_type, typename derived>
179 inline
180 arma_warn_unused
181 elem_type
min() const182 BaseCube<elem_type,derived>::min() const
183   {
184   return op_min::min( (*this).get_ref() );
185   }
186 
187 
188 
189 template<typename elem_type, typename derived>
190 inline
191 arma_warn_unused
192 elem_type
max() const193 BaseCube<elem_type,derived>::max() const
194   {
195   return op_max::max( (*this).get_ref() );
196   }
197 
198 
199 
200 template<typename elem_type, typename derived>
201 inline
202 arma_warn_unused
203 uword
index_min() const204 BaseCube<elem_type,derived>::index_min() const
205   {
206   const ProxyCube<derived> P( (*this).get_ref() );
207 
208   uword index = 0;
209 
210   if(P.get_n_elem() == 0)
211     {
212     arma_debug_check(true, "index_min(): object has no elements");
213     }
214   else
215     {
216     op_min::min_with_index(P, index);
217     }
218 
219   return index;
220   }
221 
222 
223 
224 template<typename elem_type, typename derived>
225 inline
226 arma_warn_unused
227 uword
index_max() const228 BaseCube<elem_type,derived>::index_max() const
229   {
230   const ProxyCube<derived> P( (*this).get_ref() );
231 
232   uword index = 0;
233 
234   if(P.get_n_elem() == 0)
235     {
236     arma_debug_check(true, "index_max(): object has no elements");
237     }
238   else
239     {
240     op_max::max_with_index(P, index);
241     }
242 
243   return index;
244   }
245 
246 
247 
248 template<typename elem_type, typename derived>
249 inline
250 arma_warn_unused
251 bool
is_zero(const typename get_pod_type<elem_type>::result tol) const252 BaseCube<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::result tol) const
253   {
254   arma_extra_debug_sigprint();
255 
256   typedef typename get_pod_type<elem_type>::result T;
257 
258   arma_debug_check( (tol < T(0)), "is_zero(): parameter 'tol' must be >= 0" );
259 
260   if(ProxyCube<derived>::use_at || is_Cube<typename ProxyCube<derived>::stored_type>::value)
261     {
262     const unwrap_cube<derived> U( (*this).get_ref() );
263 
264     return arrayops::is_zero( U.M.memptr(), U.M.n_elem, tol );
265     }
266 
267   const ProxyCube<derived> P( (*this).get_ref() );
268 
269   const uword n_elem = P.get_n_elem();
270 
271   if(n_elem == 0)  { return false; }
272 
273   const typename ProxyCube<derived>::ea_type Pea = P.get_ea();
274 
275   if(is_cx<elem_type>::yes)
276     {
277     for(uword i=0; i<n_elem; ++i)
278       {
279       const elem_type val = Pea[i];
280 
281       const T val_real = access::tmp_real(val);
282       const T val_imag = access::tmp_imag(val);
283 
284       if(eop_aux::arma_abs(val_real) > tol)  { return false; }
285       if(eop_aux::arma_abs(val_imag) > tol)  { return false; }
286       }
287     }
288   else  // not complex
289     {
290     for(uword i=0; i < n_elem; ++i)
291       {
292       if(eop_aux::arma_abs(Pea[i]) > tol)  { return false; }
293       }
294     }
295 
296   return true;
297   }
298 
299 
300 
301 template<typename elem_type, typename derived>
302 inline
303 arma_warn_unused
304 bool
is_empty() const305 BaseCube<elem_type,derived>::is_empty() const
306   {
307   arma_extra_debug_sigprint();
308 
309   const ProxyCube<derived> P( (*this).get_ref() );
310 
311   return (P.get_n_elem() == uword(0));
312   }
313 
314 
315 
316 template<typename elem_type, typename derived>
317 inline
318 arma_warn_unused
319 bool
is_finite() const320 BaseCube<elem_type,derived>::is_finite() const
321   {
322   arma_extra_debug_sigprint();
323 
324   const ProxyCube<derived> P( (*this).get_ref() );
325 
326   if(is_Cube<typename ProxyCube<derived>::stored_type>::value)
327     {
328     const unwrap_cube<typename ProxyCube<derived>::stored_type> U(P.Q);
329 
330     return arrayops::is_finite( U.M.memptr(), U.M.n_elem );
331     }
332 
333   const uword n_r = P.get_n_rows();
334   const uword n_c = P.get_n_cols();
335   const uword n_s = P.get_n_slices();
336 
337   for(uword s=0; s<n_s; ++s)
338   for(uword c=0; c<n_c; ++c)
339   for(uword r=0; r<n_r; ++r)
340     {
341     if( arma_isfinite(P.at(r,c,s)) == false )  { return false; }
342     }
343 
344   return true;
345   }
346 
347 
348 
349 template<typename elem_type, typename derived>
350 inline
351 arma_warn_unused
352 bool
has_inf() const353 BaseCube<elem_type,derived>::has_inf() const
354   {
355   arma_extra_debug_sigprint();
356 
357   const ProxyCube<derived> P( (*this).get_ref() );
358 
359   if(is_Cube<typename ProxyCube<derived>::stored_type>::value)
360     {
361     const unwrap_cube<typename ProxyCube<derived>::stored_type> U(P.Q);
362 
363     return arrayops::has_inf( U.M.memptr(), U.M.n_elem );
364     }
365 
366   const uword n_r = P.get_n_rows();
367   const uword n_c = P.get_n_cols();
368   const uword n_s = P.get_n_slices();
369 
370   for(uword s=0; s<n_s; ++s)
371   for(uword c=0; c<n_c; ++c)
372   for(uword r=0; r<n_r; ++r)
373     {
374     if(arma_isinf(P.at(r,c,s)))  { return true; }
375     }
376 
377   return false;
378   }
379 
380 
381 
382 template<typename elem_type, typename derived>
383 inline
384 arma_warn_unused
385 bool
has_nan() const386 BaseCube<elem_type,derived>::has_nan() const
387   {
388   arma_extra_debug_sigprint();
389 
390   const ProxyCube<derived> P( (*this).get_ref() );
391 
392   if(is_Cube<typename ProxyCube<derived>::stored_type>::value)
393     {
394     const unwrap_cube<typename ProxyCube<derived>::stored_type> U(P.Q);
395 
396     return arrayops::has_nan( U.M.memptr(), U.M.n_elem );
397     }
398 
399   const uword n_r = P.get_n_rows();
400   const uword n_c = P.get_n_cols();
401   const uword n_s = P.get_n_slices();
402 
403   for(uword s=0; s<n_s; ++s)
404   for(uword c=0; c<n_c; ++c)
405   for(uword r=0; r<n_r; ++r)
406     {
407     if(arma_isnan(P.at(r,c,s)))  { return true; }
408     }
409 
410   return false;
411   }
412 
413 
414 
415 //
416 // extra functions defined in BaseCube_eval_Cube
417 
418 template<typename elem_type, typename derived>
419 arma_inline
420 arma_warn_unused
421 const derived&
eval() const422 BaseCube_eval_Cube<elem_type, derived>::eval() const
423   {
424   arma_extra_debug_sigprint();
425 
426   return static_cast<const derived&>(*this);
427   }
428 
429 
430 
431 //
432 // extra functions defined in BaseCube_eval_expr
433 
434 template<typename elem_type, typename derived>
435 inline
436 arma_warn_unused
437 Cube<elem_type>
eval() const438 BaseCube_eval_expr<elem_type, derived>::eval() const
439   {
440   arma_extra_debug_sigprint();
441 
442   return Cube<elem_type>( static_cast<const derived&>(*this) );
443   }
444 
445 
446 
447 //! @}
448