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 debug
20 //! @{
21 
22 
23 
24 template<typename T>
25 inline
26 std::ostream&
arma_cout_stream(std::ostream * user_stream)27 arma_cout_stream(std::ostream* user_stream)
28   {
29   static std::ostream* cout_stream = &(ARMA_COUT_STREAM);
30 
31   if(user_stream != nullptr)  { cout_stream = user_stream; }
32 
33   return (*cout_stream);
34   }
35 
36 
37 
38 template<typename T>
39 inline
40 std::ostream&
arma_cerr_stream(std::ostream * user_stream)41 arma_cerr_stream(std::ostream* user_stream)
42   {
43   static std::ostream* cerr_stream = &(ARMA_CERR_STREAM);
44 
45   if(user_stream != nullptr)  { cerr_stream = user_stream; }
46 
47   return (*cerr_stream);
48   }
49 
50 
51 
52 inline
53 void
set_cout_stream(std::ostream & user_stream)54 set_cout_stream(std::ostream& user_stream)
55   {
56   arma_cout_stream<char>(&user_stream);
57   }
58 
59 
60 
61 inline
62 void
set_cerr_stream(std::ostream & user_stream)63 set_cerr_stream(std::ostream& user_stream)
64   {
65   arma_cerr_stream<char>(&user_stream);
66   }
67 
68 
69 
70 inline
71 std::ostream&
get_cout_stream()72 get_cout_stream()
73   {
74   return arma_cout_stream<char>(nullptr);
75   }
76 
77 
78 
79 inline
80 std::ostream&
get_cerr_stream()81 get_cerr_stream()
82   {
83   return arma_cerr_stream<char>(nullptr);
84   }
85 
86 
87 
88 //! do not use this function - it's deprecated and will be removed
89 inline
90 arma_deprecated
91 void
set_stream_err1(std::ostream & user_stream)92 set_stream_err1(std::ostream& user_stream)
93   {
94   set_cerr_stream(user_stream);
95   }
96 
97 
98 
99 //! do not use this function - it's deprecated and will be removed
100 inline
101 arma_deprecated
102 void
set_stream_err2(std::ostream & user_stream)103 set_stream_err2(std::ostream& user_stream)
104   {
105   set_cerr_stream(user_stream);
106   }
107 
108 
109 
110 //! do not use this function - it's deprecated and will be removed
111 inline
112 arma_deprecated
113 std::ostream&
get_stream_err1()114 get_stream_err1()
115   {
116   return get_cerr_stream();
117   }
118 
119 
120 
121 //! do not use this function - it's deprecated and will be removed
122 inline
123 arma_deprecated
124 std::ostream&
get_stream_err2()125 get_stream_err2()
126   {
127   return get_cerr_stream();
128   }
129 
130 
131 
132 //! print a message to get_cerr_stream() and throw logic_error exception
133 template<typename T1>
134 arma_cold
135 arma_noinline
136 static
137 void
arma_stop_logic_error(const T1 & x)138 arma_stop_logic_error(const T1& x)
139   {
140   #if (defined(ARMA_PRINT_EXCEPTIONS) && defined(ARMA_PRINT_ERRORS))
141     {
142     get_cerr_stream() << "\nerror: " << x << std::endl;
143     }
144   #endif
145 
146   throw std::logic_error( std::string(x) );
147   }
148 
149 
150 
151 arma_cold
152 arma_noinline
153 static
154 void
arma_stop_logic_error(const char * x,const char * y)155 arma_stop_logic_error(const char* x, const char* y)
156   {
157   arma_stop_logic_error( std::string(x) + std::string(y) );
158   }
159 
160 
161 
162 //! print a message to get_cerr_stream() and throw logic_error exception
163 template<typename T1>
164 arma_cold
165 arma_noinline
166 static
167 void
arma_stop_bounds_error(const T1 & x)168 arma_stop_bounds_error(const T1& x)
169   {
170   #if (defined(ARMA_PRINT_EXCEPTIONS) && defined(ARMA_PRINT_ERRORS))
171     {
172     get_cerr_stream() << "\nerror: " << x << std::endl;
173     }
174   #endif
175 
176   throw std::out_of_range( std::string(x) );
177   }
178 
179 
180 
181 //! print a message to get_cerr_stream() and throw bad_alloc exception
182 template<typename T1>
183 arma_cold
184 arma_noinline
185 static
186 void
arma_stop_bad_alloc(const T1 & x)187 arma_stop_bad_alloc(const T1& x)
188   {
189   #if (defined(ARMA_PRINT_EXCEPTIONS) && defined(ARMA_PRINT_ERRORS))
190     {
191     get_cerr_stream() << "\nerror: " << x << std::endl;
192     }
193   #else
194     {
195     arma_ignore(x);
196     }
197   #endif
198 
199   throw std::bad_alloc();
200   }
201 
202 
203 
204 //! print a message to get_cerr_stream() and throw runtime_error exception
205 template<typename T1>
206 arma_cold
207 arma_noinline
208 static
209 void
arma_stop_runtime_error(const T1 & x)210 arma_stop_runtime_error(const T1& x)
211   {
212   #if (defined(ARMA_PRINT_EXCEPTIONS) && defined(ARMA_PRINT_ERRORS))
213     {
214     get_cerr_stream() << "\nerror: " << x << std::endl;
215     }
216   #endif
217 
218   throw std::runtime_error( std::string(x) );
219   }
220 
221 
222 
223 //
224 // arma_print
225 
226 
227 arma_cold
228 inline
229 void
arma_print()230 arma_print()
231   {
232   get_cerr_stream() << std::endl;
233   }
234 
235 
236 template<typename T1>
237 arma_cold
238 arma_noinline
239 static
240 void
arma_print(const T1 & x)241 arma_print(const T1& x)
242   {
243   get_cerr_stream() << x << std::endl;
244   }
245 
246 
247 
248 template<typename T1, typename T2>
249 arma_cold
250 arma_noinline
251 static
252 void
arma_print(const T1 & x,const T2 & y)253 arma_print(const T1& x, const T2& y)
254   {
255   get_cerr_stream() << x << y << std::endl;
256   }
257 
258 
259 
260 template<typename T1, typename T2, typename T3>
261 arma_cold
262 arma_noinline
263 static
264 void
arma_print(const T1 & x,const T2 & y,const T3 & z)265 arma_print(const T1& x, const T2& y, const T3& z)
266   {
267   get_cerr_stream() << x << y << z << std::endl;
268   }
269 
270 
271 
272 
273 
274 
275 //
276 // arma_sigprint
277 
278 //! print a message the the log stream with a preceding @ character.
279 //! by default the log stream is cout.
280 //! used for printing the signature of a function
281 //! (see the arma_extra_debug_sigprint macro)
282 inline
283 void
arma_sigprint(const char * x)284 arma_sigprint(const char* x)
285   {
286   get_cerr_stream() << "@ " << x;
287   }
288 
289 
290 
291 //
292 // arma_bktprint
293 
294 
295 inline
296 void
arma_bktprint()297 arma_bktprint()
298   {
299   get_cerr_stream() << std::endl;
300   }
301 
302 
303 template<typename T1>
304 inline
305 void
arma_bktprint(const T1 & x)306 arma_bktprint(const T1& x)
307   {
308   get_cerr_stream() << " [" << x << ']' << std::endl;
309   }
310 
311 
312 
313 template<typename T1, typename T2>
314 inline
315 void
arma_bktprint(const T1 & x,const T2 & y)316 arma_bktprint(const T1& x, const T2& y)
317   {
318   get_cerr_stream() << " [" << x << y << ']' << std::endl;
319   }
320 
321 
322 
323 
324 
325 
326 //
327 // arma_thisprint
328 
329 inline
330 void
arma_thisprint(const void * this_ptr)331 arma_thisprint(const void* this_ptr)
332   {
333   get_cerr_stream() << " [this = " << this_ptr << ']' << std::endl;
334   }
335 
336 
337 
338 //
339 // arma_warn
340 
341 
342 //! print a message to the warn stream
343 template<typename T1>
344 arma_cold
345 arma_noinline
346 static
347 void
arma_warn(const T1 & arg1)348 arma_warn(const T1& arg1)
349   {
350   #if defined(ARMA_PRINT_ERRORS)
351     {
352     get_cerr_stream() << "\nwarning: " << arg1 << '\n';
353     }
354   #else
355     {
356     arma_ignore(arg1);
357     }
358   #endif
359   }
360 
361 
362 template<typename T1, typename T2>
363 arma_cold
364 arma_noinline
365 static
366 void
arma_warn(const T1 & arg1,const T2 & arg2)367 arma_warn(const T1& arg1, const T2& arg2)
368   {
369   #if defined(ARMA_PRINT_ERRORS)
370     {
371     get_cerr_stream() << "\nwarning: " << arg1 << arg2 << '\n';
372     }
373   #else
374     {
375     arma_ignore(arg1);
376     arma_ignore(arg2);
377     }
378   #endif
379   }
380 
381 
382 template<typename T1, typename T2, typename T3>
383 arma_cold
384 arma_noinline
385 static
386 void
arma_warn(const T1 & arg1,const T2 & arg2,const T3 & arg3)387 arma_warn(const T1& arg1, const T2& arg2, const T3& arg3)
388   {
389   #if defined(ARMA_PRINT_ERRORS)
390     {
391     get_cerr_stream() << "\nwarning: " << arg1 << arg2 << arg3 << '\n';
392     }
393   #else
394     {
395     arma_ignore(arg1);
396     arma_ignore(arg2);
397     arma_ignore(arg3);
398     }
399   #endif
400   }
401 
402 
403 template<typename T1, typename T2, typename T3, typename T4>
404 arma_cold
405 arma_noinline
406 static
407 void
arma_warn(const T1 & arg1,const T2 & arg2,const T3 & arg3,const T4 & arg4)408 arma_warn(const T1& arg1, const T2& arg2, const T3& arg3, const T4& arg4)
409   {
410   #if defined(ARMA_PRINT_ERRORS)
411     {
412     get_cerr_stream() << "\nwarning: " << arg1 << arg2 << arg3 << arg4 << '\n';
413     }
414   #else
415     {
416     arma_ignore(arg1);
417     arma_ignore(arg2);
418     arma_ignore(arg3);
419     arma_ignore(arg4);
420     }
421   #endif
422   }
423 
424 
425 
426 //
427 // arma_warn_level
428 
429 
430 template<typename T1>
431 inline
432 void
arma_warn_level(const uword level,const T1 & arg1)433 arma_warn_level(const uword level, const T1& arg1)
434   {
435   constexpr uword config_level = (sword(ARMA_WARN_LEVEL) > 0) ? uword(ARMA_WARN_LEVEL) : uword(0);
436 
437   if((config_level > 0) && (level <= config_level))  { arma_warn(arg1); }
438   }
439 
440 
441 template<typename T1, typename T2>
442 inline
443 void
arma_warn_level(const uword level,const T1 & arg1,const T2 & arg2)444 arma_warn_level(const uword level, const T1& arg1, const T2& arg2)
445   {
446   constexpr uword config_level = (sword(ARMA_WARN_LEVEL) > 0) ? uword(ARMA_WARN_LEVEL) : uword(0);
447 
448   if((config_level > 0) && (level <= config_level))  { arma_warn(arg1,arg2); }
449   }
450 
451 
452 template<typename T1, typename T2, typename T3>
453 inline
454 void
arma_warn_level(const uword level,const T1 & arg1,const T2 & arg2,const T3 & arg3)455 arma_warn_level(const uword level, const T1& arg1, const T2& arg2, const T3& arg3)
456   {
457   constexpr uword config_level = (sword(ARMA_WARN_LEVEL) > 0) ? uword(ARMA_WARN_LEVEL) : uword(0);
458 
459   if((config_level > 0) && (level <= config_level))  { arma_warn(arg1,arg2,arg3); }
460   }
461 
462 
463 template<typename T1, typename T2, typename T3, typename T4>
464 inline
465 void
arma_warn_level(const uword level,const T1 & arg1,const T2 & arg2,const T3 & arg3,const T4 & arg4)466 arma_warn_level(const uword level, const T1& arg1, const T2& arg2, const T3& arg3, const T4& arg4)
467   {
468   constexpr uword config_level = (sword(ARMA_WARN_LEVEL) > 0) ? uword(ARMA_WARN_LEVEL) : uword(0);
469 
470   if((config_level > 0) && (level <= config_level))  { arma_warn(arg1,arg2,arg3,arg4); }
471   }
472 
473 
474 
475 //
476 // arma_check
477 
478 //! if state is true, abort program
479 template<typename T1>
480 arma_hot
481 inline
482 void
arma_check(const bool state,const T1 & x)483 arma_check(const bool state, const T1& x)
484   {
485   if(state)  { arma_stop_logic_error(arma_str::str_wrapper(x)); }
486   }
487 
488 
489 arma_hot
490 inline
491 void
arma_check(const bool state,const char * x,const char * y)492 arma_check(const bool state, const char* x, const char* y)
493   {
494   if(state)  { arma_stop_logic_error(x,y); }
495   }
496 
497 
498 template<typename T1>
499 arma_hot
500 inline
501 void
arma_check_bounds(const bool state,const T1 & x)502 arma_check_bounds(const bool state, const T1& x)
503   {
504   if(state)  { arma_stop_bounds_error(arma_str::str_wrapper(x)); }
505   }
506 
507 
508 template<typename T1>
509 arma_hot
510 inline
511 void
arma_check_bad_alloc(const bool state,const T1 & x)512 arma_check_bad_alloc(const bool state, const T1& x)
513   {
514   if(state)  { arma_stop_bad_alloc(x); }
515   }
516 
517 
518 
519 //
520 // arma_set_error
521 
522 
523 arma_hot
524 arma_inline
525 void
arma_set_error(bool & err_state,char * & err_msg,const bool expression,const char * message)526 arma_set_error(bool& err_state, char*& err_msg, const bool expression, const char* message)
527   {
528   if(expression)
529     {
530     err_state = true;
531     err_msg   = const_cast<char*>(message);
532     }
533   }
534 
535 
536 
537 
538 //
539 // functions for generating strings indicating size errors
540 
541 arma_cold
542 arma_noinline
543 static
544 std::string
arma_incompat_size_string(const uword A_n_rows,const uword A_n_cols,const uword B_n_rows,const uword B_n_cols,const char * x)545 arma_incompat_size_string(const uword A_n_rows, const uword A_n_cols, const uword B_n_rows, const uword B_n_cols, const char* x)
546   {
547   std::ostringstream tmp;
548 
549   tmp << x << ": incompatible matrix dimensions: " << A_n_rows << 'x' << A_n_cols << " and " << B_n_rows << 'x' << B_n_cols;
550 
551   return tmp.str();
552   }
553 
554 
555 
556 arma_cold
557 arma_noinline
558 static
559 std::string
arma_incompat_size_string(const uword A_n_rows,const uword A_n_cols,const uword A_n_slices,const uword B_n_rows,const uword B_n_cols,const uword B_n_slices,const char * x)560 arma_incompat_size_string(const uword A_n_rows, const uword A_n_cols, const uword A_n_slices, const uword B_n_rows, const uword B_n_cols, const uword B_n_slices, const char* x)
561   {
562   std::ostringstream tmp;
563 
564   tmp << x << ": incompatible cube dimensions: " << A_n_rows << 'x' << A_n_cols << 'x' << A_n_slices << " and " << B_n_rows << 'x' << B_n_cols << 'x' << B_n_slices;
565 
566   return tmp.str();
567   }
568 
569 
570 
571 template<typename eT>
572 arma_cold
573 arma_noinline
574 static
575 std::string
arma_incompat_size_string(const subview_cube<eT> & Q,const Mat<eT> & A,const char * x)576 arma_incompat_size_string(const subview_cube<eT>& Q, const Mat<eT>& A, const char* x)
577   {
578   std::ostringstream tmp;
579 
580   tmp << x
581       << ": interpreting matrix as cube with dimensions: "
582       << A.n_rows << 'x' << A.n_cols << 'x' << 1
583       << " or "
584       << A.n_rows << 'x' << 1        << 'x' << A.n_cols
585       << " or "
586       << 1        << 'x' << A.n_rows << 'x' << A.n_cols
587       << " is incompatible with cube dimensions: "
588       << Q.n_rows << 'x' << Q.n_cols << 'x' << Q.n_slices;
589 
590   return tmp.str();
591   }
592 
593 
594 
595 //
596 // functions for checking whether two dense matrices have the same dimensions
597 
598 
599 
600 arma_inline
601 arma_hot
602 void
arma_assert_same_size(const uword A_n_rows,const uword A_n_cols,const uword B_n_rows,const uword B_n_cols,const char * x)603 arma_assert_same_size(const uword A_n_rows, const uword A_n_cols, const uword B_n_rows, const uword B_n_cols, const char* x)
604   {
605   if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
606     {
607     arma_stop_logic_error( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
608     }
609   }
610 
611 
612 
613 //! stop if given matrices have different sizes
614 template<typename eT1, typename eT2>
615 arma_hot
616 inline
617 void
arma_assert_same_size(const Mat<eT1> & A,const Mat<eT2> & B,const char * x)618 arma_assert_same_size(const Mat<eT1>& A, const Mat<eT2>& B, const char* x)
619   {
620   const uword A_n_rows = A.n_rows;
621   const uword A_n_cols = A.n_cols;
622 
623   const uword B_n_rows = B.n_rows;
624   const uword B_n_cols = B.n_cols;
625 
626   if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
627     {
628     arma_stop_logic_error( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
629     }
630   }
631 
632 
633 
634 //! stop if given proxies have different sizes
635 template<typename eT1, typename eT2>
636 arma_hot
637 inline
638 void
arma_assert_same_size(const Proxy<eT1> & A,const Proxy<eT2> & B,const char * x)639 arma_assert_same_size(const Proxy<eT1>& A, const Proxy<eT2>& B, const char* x)
640   {
641   const uword A_n_rows = A.get_n_rows();
642   const uword A_n_cols = A.get_n_cols();
643 
644   const uword B_n_rows = B.get_n_rows();
645   const uword B_n_cols = B.get_n_cols();
646 
647   if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
648     {
649     arma_stop_logic_error( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
650     }
651   }
652 
653 
654 
655 template<typename eT1, typename eT2>
656 arma_hot
657 inline
658 void
arma_assert_same_size(const subview<eT1> & A,const subview<eT2> & B,const char * x)659 arma_assert_same_size(const subview<eT1>& A, const subview<eT2>& B, const char* x)
660   {
661   const uword A_n_rows = A.n_rows;
662   const uword A_n_cols = A.n_cols;
663 
664   const uword B_n_rows = B.n_rows;
665   const uword B_n_cols = B.n_cols;
666 
667   if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
668     {
669     arma_stop_logic_error( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
670     }
671   }
672 
673 
674 
675 template<typename eT1, typename eT2>
676 arma_hot
677 inline
678 void
arma_assert_same_size(const Mat<eT1> & A,const subview<eT2> & B,const char * x)679 arma_assert_same_size(const Mat<eT1>& A, const subview<eT2>& B, const char* x)
680   {
681   const uword A_n_rows = A.n_rows;
682   const uword A_n_cols = A.n_cols;
683 
684   const uword B_n_rows = B.n_rows;
685   const uword B_n_cols = B.n_cols;
686 
687   if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
688     {
689     arma_stop_logic_error( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
690     }
691   }
692 
693 
694 
695 template<typename eT1, typename eT2>
696 arma_hot
697 inline
698 void
arma_assert_same_size(const subview<eT1> & A,const Mat<eT2> & B,const char * x)699 arma_assert_same_size(const subview<eT1>& A, const Mat<eT2>& B, const char* x)
700   {
701   const uword A_n_rows = A.n_rows;
702   const uword A_n_cols = A.n_cols;
703 
704   const uword B_n_rows = B.n_rows;
705   const uword B_n_cols = B.n_cols;
706 
707   if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
708     {
709     arma_stop_logic_error( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
710     }
711   }
712 
713 
714 
715 template<typename eT1, typename eT2>
716 arma_hot
717 inline
718 void
arma_assert_same_size(const Mat<eT1> & A,const Proxy<eT2> & B,const char * x)719 arma_assert_same_size(const Mat<eT1>& A, const Proxy<eT2>& B, const char* x)
720   {
721   const uword A_n_rows = A.n_rows;
722   const uword A_n_cols = A.n_cols;
723 
724   const uword B_n_rows = B.get_n_rows();
725   const uword B_n_cols = B.get_n_cols();
726 
727   if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
728     {
729     arma_stop_logic_error( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
730     }
731   }
732 
733 
734 
735 template<typename eT1, typename eT2>
736 arma_hot
737 inline
738 void
arma_assert_same_size(const Proxy<eT1> & A,const Mat<eT2> & B,const char * x)739 arma_assert_same_size(const Proxy<eT1>& A, const Mat<eT2>& B, const char* x)
740   {
741   const uword A_n_rows = A.get_n_rows();
742   const uword A_n_cols = A.get_n_cols();
743 
744   const uword B_n_rows = B.n_rows;
745   const uword B_n_cols = B.n_cols;
746 
747   if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
748     {
749     arma_stop_logic_error( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
750     }
751   }
752 
753 
754 
755 template<typename eT1, typename eT2>
756 arma_hot
757 inline
758 void
arma_assert_same_size(const Proxy<eT1> & A,const subview<eT2> & B,const char * x)759 arma_assert_same_size(const Proxy<eT1>& A, const subview<eT2>& B, const char* x)
760   {
761   const uword A_n_rows = A.get_n_rows();
762   const uword A_n_cols = A.get_n_cols();
763 
764   const uword B_n_rows = B.n_rows;
765   const uword B_n_cols = B.n_cols;
766 
767   if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
768     {
769     arma_stop_logic_error( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
770     }
771   }
772 
773 
774 
775 template<typename eT1, typename eT2>
776 arma_hot
777 inline
778 void
arma_assert_same_size(const subview<eT1> & A,const Proxy<eT2> & B,const char * x)779 arma_assert_same_size(const subview<eT1>& A, const Proxy<eT2>& B, const char* x)
780   {
781   const uword A_n_rows = A.n_rows;
782   const uword A_n_cols = A.n_cols;
783 
784   const uword B_n_rows = B.get_n_rows();
785   const uword B_n_cols = B.get_n_cols();
786 
787   if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
788     {
789     arma_stop_logic_error( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
790     }
791   }
792 
793 
794 
795 //
796 // functions for checking whether two sparse matrices have the same dimensions
797 
798 
799 
800 template<typename eT1, typename eT2>
801 arma_hot
802 inline
803 void
arma_assert_same_size(const SpMat<eT1> & A,const SpMat<eT2> & B,const char * x)804 arma_assert_same_size(const SpMat<eT1>& A, const SpMat<eT2>& B, const char* x)
805   {
806   const uword A_n_rows = A.n_rows;
807   const uword A_n_cols = A.n_cols;
808 
809   const uword B_n_rows = B.n_rows;
810   const uword B_n_cols = B.n_cols;
811 
812   if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) )
813     {
814     arma_stop_logic_error( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
815     }
816   }
817 
818 
819 
820 //
821 // functions for checking whether two cubes have the same dimensions
822 
823 
824 
825 arma_hot
826 inline
827 void
arma_assert_same_size(const uword A_n_rows,const uword A_n_cols,const uword A_n_slices,const uword B_n_rows,const uword B_n_cols,const uword B_n_slices,const char * x)828 arma_assert_same_size(const uword A_n_rows, const uword A_n_cols, const uword A_n_slices, const uword B_n_rows, const uword B_n_cols, const uword B_n_slices, const char* x)
829   {
830   if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) || (A_n_slices != B_n_slices) )
831     {
832     arma_stop_logic_error( arma_incompat_size_string(A_n_rows, A_n_cols, A_n_slices, B_n_rows, B_n_cols, B_n_slices, x) );
833     }
834   }
835 
836 
837 
838 //! stop if given cubes have different sizes
839 template<typename eT1, typename eT2>
840 arma_hot
841 inline
842 void
arma_assert_same_size(const Cube<eT1> & A,const Cube<eT2> & B,const char * x)843 arma_assert_same_size(const Cube<eT1>& A, const Cube<eT2>& B, const char* x)
844   {
845   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != B.n_slices) )
846     {
847     arma_stop_logic_error( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, B.n_slices, x) );
848     }
849   }
850 
851 
852 
853 template<typename eT1, typename eT2>
854 arma_hot
855 inline
856 void
arma_assert_same_size(const Cube<eT1> & A,const subview_cube<eT2> & B,const char * x)857 arma_assert_same_size(const Cube<eT1>& A, const subview_cube<eT2>& B, const char* x)
858   {
859   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != B.n_slices) )
860     {
861     arma_stop_logic_error( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, B.n_slices, x) );
862     }
863   }
864 
865 
866 
867 template<typename eT1, typename eT2>
868 arma_hot
869 inline
870 void
arma_assert_same_size(const subview_cube<eT1> & A,const Cube<eT2> & B,const char * x)871 arma_assert_same_size(const subview_cube<eT1>& A, const Cube<eT2>& B, const char* x)
872   {
873   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != B.n_slices) )
874     {
875     arma_stop_logic_error( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, B.n_slices, x) );
876     }
877   }
878 
879 
880 
881 template<typename eT1, typename eT2>
882 arma_hot
883 inline
884 void
arma_assert_same_size(const subview_cube<eT1> & A,const subview_cube<eT2> & B,const char * x)885 arma_assert_same_size(const subview_cube<eT1>& A, const subview_cube<eT2>& B, const char* x)
886   {
887   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != B.n_slices))
888     {
889     arma_stop_logic_error( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, B.n_slices, x) );
890     }
891   }
892 
893 
894 
895 template<typename eT, typename T1>
896 arma_hot
897 inline
898 void
arma_assert_same_size(const subview_cube<eT> & A,const ProxyCube<T1> & B,const char * x)899 arma_assert_same_size(const subview_cube<eT>& A, const ProxyCube<T1>& B, const char* x)
900   {
901   const uword A_n_rows   = A.n_rows;
902   const uword A_n_cols   = A.n_cols;
903   const uword A_n_slices = A.n_slices;
904 
905   const uword B_n_rows   = B.get_n_rows();
906   const uword B_n_cols   = B.get_n_cols();
907   const uword B_n_slices = B.get_n_slices();
908 
909   if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) || (A_n_slices != B_n_slices) )
910     {
911     arma_stop_logic_error( arma_incompat_size_string(A_n_rows, A_n_cols, A_n_slices, B_n_rows, B_n_cols, B_n_slices, x) );
912     }
913   }
914 
915 
916 
917 //! stop if given cube proxies have different sizes
918 template<typename eT1, typename eT2>
919 arma_hot
920 inline
921 void
arma_assert_same_size(const ProxyCube<eT1> & A,const ProxyCube<eT2> & B,const char * x)922 arma_assert_same_size(const ProxyCube<eT1>& A, const ProxyCube<eT2>& B, const char* x)
923   {
924   const uword A_n_rows   = A.get_n_rows();
925   const uword A_n_cols   = A.get_n_cols();
926   const uword A_n_slices = A.get_n_slices();
927 
928   const uword B_n_rows   = B.get_n_rows();
929   const uword B_n_cols   = B.get_n_cols();
930   const uword B_n_slices = B.get_n_slices();
931 
932   if( (A_n_rows != B_n_rows) || (A_n_cols != B_n_cols) || (A_n_slices != B_n_slices))
933     {
934     arma_stop_logic_error( arma_incompat_size_string(A_n_rows, A_n_cols, A_n_slices, B_n_rows, B_n_cols, B_n_slices, x) );
935     }
936   }
937 
938 
939 
940 //
941 // functions for checking whether a cube or subcube can be interpreted as a matrix (ie. single slice)
942 
943 
944 
945 template<typename eT1, typename eT2>
946 arma_hot
947 inline
948 void
arma_assert_same_size(const Cube<eT1> & A,const Mat<eT2> & B,const char * x)949 arma_assert_same_size(const Cube<eT1>& A, const Mat<eT2>& B, const char* x)
950   {
951   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != 1) )
952     {
953     arma_stop_logic_error( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, 1, x) );
954     }
955   }
956 
957 
958 
959 template<typename eT1, typename eT2>
960 arma_hot
961 inline
962 void
arma_assert_same_size(const Mat<eT1> & A,const Cube<eT2> & B,const char * x)963 arma_assert_same_size(const Mat<eT1>& A, const Cube<eT2>& B, const char* x)
964   {
965   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (1 != B.n_slices) )
966     {
967     arma_stop_logic_error( arma_incompat_size_string(A.n_rows, A.n_cols, 1, B.n_rows, B.n_cols, B.n_slices, x) );
968     }
969   }
970 
971 
972 
973 template<typename eT1, typename eT2>
974 arma_hot
975 inline
976 void
arma_assert_same_size(const subview_cube<eT1> & A,const Mat<eT2> & B,const char * x)977 arma_assert_same_size(const subview_cube<eT1>& A, const Mat<eT2>& B, const char* x)
978   {
979   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (A.n_slices != 1) )
980     {
981     arma_stop_logic_error( arma_incompat_size_string(A.n_rows, A.n_cols, A.n_slices, B.n_rows, B.n_cols, 1, x) );
982     }
983   }
984 
985 
986 
987 template<typename eT1, typename eT2>
988 arma_hot
989 inline
990 void
arma_assert_same_size(const Mat<eT1> & A,const subview_cube<eT2> & B,const char * x)991 arma_assert_same_size(const Mat<eT1>& A, const subview_cube<eT2>& B, const char* x)
992   {
993   if( (A.n_rows != B.n_rows) || (A.n_cols != B.n_cols) || (1 != B.n_slices) )
994     {
995     arma_stop_logic_error( arma_incompat_size_string(A.n_rows, A.n_cols, 1, B.n_rows, B.n_cols, B.n_slices, x) );
996     }
997   }
998 
999 
1000 
1001 template<typename eT, typename T1>
1002 inline
1003 void
arma_assert_cube_as_mat(const Mat<eT> & M,const T1 & Q,const char * x,const bool check_compat_size)1004 arma_assert_cube_as_mat(const Mat<eT>& M, const T1& Q, const char* x, const bool check_compat_size)
1005   {
1006   const uword Q_n_rows   = Q.n_rows;
1007   const uword Q_n_cols   = Q.n_cols;
1008   const uword Q_n_slices = Q.n_slices;
1009 
1010   const uword M_vec_state = M.vec_state;
1011 
1012   if(M_vec_state == 0)
1013     {
1014     if( ( (Q_n_rows == 1) || (Q_n_cols == 1) || (Q_n_slices == 1) ) == false )
1015       {
1016       std::ostringstream tmp;
1017 
1018       tmp << x
1019           << ": can't interpret cube with dimensions "
1020           << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
1021           << " as a matrix; one of the dimensions must be 1";
1022 
1023       arma_stop_logic_error( tmp.str() );
1024       }
1025     }
1026   else
1027     {
1028     if(Q_n_slices == 1)
1029       {
1030       if( (M_vec_state == 1) && (Q_n_cols != 1) )
1031         {
1032         std::ostringstream tmp;
1033 
1034         tmp << x
1035             << ": can't interpret cube with dimensions "
1036             << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
1037             << " as a column vector";
1038 
1039         arma_stop_logic_error( tmp.str() );
1040         }
1041 
1042       if( (M_vec_state == 2) && (Q_n_rows != 1) )
1043         {
1044         std::ostringstream tmp;
1045 
1046         tmp << x
1047             << ": can't interpret cube with dimensions "
1048             << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
1049             << " as a row vector";
1050 
1051         arma_stop_logic_error( tmp.str() );
1052         }
1053       }
1054     else
1055       {
1056       if( (Q_n_cols != 1) && (Q_n_rows != 1) )
1057         {
1058         std::ostringstream tmp;
1059 
1060         tmp << x
1061             << ": can't interpret cube with dimensions "
1062             << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
1063             << " as a vector";
1064 
1065         arma_stop_logic_error( tmp.str() );
1066         }
1067       }
1068     }
1069 
1070 
1071   if(check_compat_size)
1072     {
1073     const uword M_n_rows = M.n_rows;
1074     const uword M_n_cols = M.n_cols;
1075 
1076     if(M_vec_state == 0)
1077       {
1078       if(
1079           (
1080           ( (Q_n_rows == M_n_rows) && (Q_n_cols   == M_n_cols) )
1081           ||
1082           ( (Q_n_rows == M_n_rows) && (Q_n_slices == M_n_cols) )
1083           ||
1084           ( (Q_n_cols == M_n_rows) && (Q_n_slices == M_n_cols) )
1085           )
1086           == false
1087         )
1088         {
1089         std::ostringstream tmp;
1090 
1091         tmp << x
1092             << ": can't interpret cube with dimensions "
1093             << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
1094             << " as a matrix with dimensions "
1095             << M_n_rows << 'x' << M_n_cols;
1096 
1097         arma_stop_logic_error( tmp.str() );
1098         }
1099       }
1100     else
1101       {
1102       if(Q_n_slices == 1)
1103         {
1104         if( (M_vec_state == 1) && (Q_n_rows != M_n_rows) )
1105           {
1106           std::ostringstream tmp;
1107 
1108           tmp << x
1109               << ": can't interpret cube with dimensions "
1110               << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
1111               << " as a column vector with dimensions "
1112               << M_n_rows << 'x' << M_n_cols;
1113 
1114           arma_stop_logic_error( tmp.str() );
1115           }
1116 
1117         if( (M_vec_state == 2) && (Q_n_cols != M_n_cols) )
1118           {
1119           std::ostringstream tmp;
1120 
1121           tmp << x
1122               << ": can't interpret cube with dimensions "
1123               << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
1124               << " as a row vector with dimensions "
1125               << M_n_rows << 'x' << M_n_cols;
1126 
1127           arma_stop_logic_error( tmp.str() );
1128           }
1129         }
1130       else
1131         {
1132         if( ( (M_n_cols == Q_n_slices) || (M_n_rows == Q_n_slices) ) == false )
1133           {
1134           std::ostringstream tmp;
1135 
1136           tmp << x
1137               << ": can't interpret cube with dimensions "
1138               << Q_n_rows << 'x' << Q_n_cols << 'x' << Q_n_slices
1139               << " as a vector with dimensions "
1140               << M_n_rows << 'x' << M_n_cols;
1141 
1142           arma_stop_logic_error( tmp.str() );
1143           }
1144         }
1145       }
1146     }
1147   }
1148 
1149 
1150 
1151 //
1152 // functions for checking whether two matrices have dimensions that are compatible with the matrix multiply operation
1153 
1154 
1155 
1156 arma_hot
1157 inline
1158 void
arma_assert_mul_size(const uword A_n_rows,const uword A_n_cols,const uword B_n_rows,const uword B_n_cols,const char * x)1159 arma_assert_mul_size(const uword A_n_rows, const uword A_n_cols, const uword B_n_rows, const uword B_n_cols, const char* x)
1160   {
1161   if(A_n_cols != B_n_rows)
1162     {
1163     arma_stop_logic_error( arma_incompat_size_string(A_n_rows, A_n_cols, B_n_rows, B_n_cols, x) );
1164     }
1165   }
1166 
1167 
1168 
1169 //! stop if given matrices are incompatible for multiplication
1170 template<typename eT1, typename eT2>
1171 arma_hot
1172 inline
1173 void
arma_assert_mul_size(const Mat<eT1> & A,const Mat<eT2> & B,const char * x)1174 arma_assert_mul_size(const Mat<eT1>& A, const Mat<eT2>& B, const char* x)
1175   {
1176   const uword A_n_cols = A.n_cols;
1177   const uword B_n_rows = B.n_rows;
1178 
1179   if(A_n_cols != B_n_rows)
1180     {
1181     arma_stop_logic_error( arma_incompat_size_string(A.n_rows, A_n_cols, B_n_rows, B.n_cols, x) );
1182     }
1183   }
1184 
1185 
1186 
1187 //! stop if given matrices are incompatible for multiplication
1188 template<typename eT1, typename eT2>
1189 arma_hot
1190 inline
1191 void
arma_assert_mul_size(const Mat<eT1> & A,const Mat<eT2> & B,const bool do_trans_A,const bool do_trans_B,const char * x)1192 arma_assert_mul_size(const Mat<eT1>& A, const Mat<eT2>& B, const bool do_trans_A, const bool do_trans_B, const char* x)
1193   {
1194   const uword final_A_n_cols = (do_trans_A == false) ? A.n_cols : A.n_rows;
1195   const uword final_B_n_rows = (do_trans_B == false) ? B.n_rows : B.n_cols;
1196 
1197   if(final_A_n_cols != final_B_n_rows)
1198     {
1199     const uword final_A_n_rows = (do_trans_A == false) ? A.n_rows : A.n_cols;
1200     const uword final_B_n_cols = (do_trans_B == false) ? B.n_cols : B.n_rows;
1201 
1202     arma_stop_logic_error( arma_incompat_size_string(final_A_n_rows, final_A_n_cols, final_B_n_rows, final_B_n_cols, x) );
1203     }
1204   }
1205 
1206 
1207 
1208 template<const bool do_trans_A, const bool do_trans_B>
1209 arma_hot
1210 inline
1211 void
arma_assert_trans_mul_size(const uword A_n_rows,const uword A_n_cols,const uword B_n_rows,const uword B_n_cols,const char * x)1212 arma_assert_trans_mul_size(const uword A_n_rows, const uword A_n_cols, const uword B_n_rows, const uword B_n_cols, const char* x)
1213   {
1214   const uword final_A_n_cols = (do_trans_A == false) ? A_n_cols : A_n_rows;
1215   const uword final_B_n_rows = (do_trans_B == false) ? B_n_rows : B_n_cols;
1216 
1217   if(final_A_n_cols != final_B_n_rows)
1218     {
1219     const uword final_A_n_rows = (do_trans_A == false) ? A_n_rows : A_n_cols;
1220     const uword final_B_n_cols = (do_trans_B == false) ? B_n_cols : B_n_rows;
1221 
1222     arma_stop_logic_error( arma_incompat_size_string(final_A_n_rows, final_A_n_cols, final_B_n_rows, final_B_n_cols, x) );
1223     }
1224   }
1225 
1226 
1227 
1228 template<typename eT1, typename eT2>
1229 arma_hot
1230 inline
1231 void
arma_assert_mul_size(const Mat<eT1> & A,const subview<eT2> & B,const char * x)1232 arma_assert_mul_size(const Mat<eT1>& A, const subview<eT2>& B, const char* x)
1233   {
1234   if(A.n_cols != B.n_rows)
1235     {
1236     arma_stop_logic_error( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
1237     }
1238   }
1239 
1240 
1241 
1242 template<typename eT1, typename eT2>
1243 arma_hot
1244 inline
1245 void
arma_assert_mul_size(const subview<eT1> & A,const Mat<eT2> & B,const char * x)1246 arma_assert_mul_size(const subview<eT1>& A, const Mat<eT2>& B, const char* x)
1247   {
1248   if(A.n_cols != B.n_rows)
1249     {
1250     arma_stop_logic_error( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
1251     }
1252   }
1253 
1254 
1255 
1256 template<typename eT1, typename eT2>
1257 arma_hot
1258 inline
1259 void
arma_assert_mul_size(const subview<eT1> & A,const subview<eT2> & B,const char * x)1260 arma_assert_mul_size(const subview<eT1>& A, const subview<eT2>& B, const char* x)
1261   {
1262   if(A.n_cols != B.n_rows)
1263     {
1264     arma_stop_logic_error( arma_incompat_size_string(A.n_rows, A.n_cols, B.n_rows, B.n_cols, x) );
1265     }
1266   }
1267 
1268 
1269 
1270 template<typename T1>
1271 arma_hot
1272 inline
1273 void
arma_assert_blas_size(const T1 & A)1274 arma_assert_blas_size(const T1& A)
1275   {
1276   if(sizeof(uword) >= sizeof(blas_int))
1277     {
1278     bool overflow;
1279 
1280     overflow = (A.n_rows > ARMA_MAX_BLAS_INT);
1281     overflow = (A.n_cols > ARMA_MAX_BLAS_INT) || overflow;
1282 
1283     if(overflow)
1284       {
1285       arma_stop_runtime_error("integer overflow: matrix dimensions are too large for integer type used by BLAS and LAPACK");
1286       }
1287     }
1288   }
1289 
1290 
1291 
1292 template<typename T1, typename T2>
1293 arma_hot
1294 inline
1295 void
arma_assert_blas_size(const T1 & A,const T2 & B)1296 arma_assert_blas_size(const T1& A, const T2& B)
1297   {
1298   if(sizeof(uword) >= sizeof(blas_int))
1299     {
1300     bool overflow;
1301 
1302     overflow = (A.n_rows > ARMA_MAX_BLAS_INT);
1303     overflow = (A.n_cols > ARMA_MAX_BLAS_INT) || overflow;
1304     overflow = (B.n_rows > ARMA_MAX_BLAS_INT) || overflow;
1305     overflow = (B.n_cols > ARMA_MAX_BLAS_INT) || overflow;
1306 
1307     if(overflow)
1308       {
1309       arma_stop_runtime_error("integer overflow: matrix dimensions are too large for integer type used by BLAS and LAPACK");
1310       }
1311     }
1312   }
1313 
1314 
1315 
1316 template<typename T1>
1317 arma_hot
1318 inline
1319 void
arma_assert_atlas_size(const T1 & A)1320 arma_assert_atlas_size(const T1& A)
1321   {
1322   if(sizeof(uword) >= sizeof(int))
1323     {
1324     bool overflow;
1325 
1326     overflow = (A.n_rows > INT_MAX);
1327     overflow = (A.n_cols > INT_MAX) || overflow;
1328 
1329     if(overflow)
1330       {
1331       arma_stop_runtime_error("integer overflow: matrix dimensions are too large for integer type used by ATLAS");
1332       }
1333     }
1334   }
1335 
1336 
1337 
1338 template<typename T1, typename T2>
1339 arma_hot
1340 inline
1341 void
arma_assert_atlas_size(const T1 & A,const T2 & B)1342 arma_assert_atlas_size(const T1& A, const T2& B)
1343   {
1344   if(sizeof(uword) >= sizeof(int))
1345     {
1346     bool overflow;
1347 
1348     overflow = (A.n_rows > INT_MAX);
1349     overflow = (A.n_cols > INT_MAX) || overflow;
1350     overflow = (B.n_rows > INT_MAX) || overflow;
1351     overflow = (B.n_cols > INT_MAX) || overflow;
1352 
1353     if(overflow)
1354       {
1355       arma_stop_runtime_error("integer overflow: matrix dimensions are too large for integer type used by ATLAS");
1356       }
1357     }
1358   }
1359 
1360 
1361 
1362 //
1363 // macros
1364 
1365 
1366 // #define ARMA_STRING1(x) #x
1367 // #define ARMA_STRING2(x) ARMA_STRING1(x)
1368 // #define ARMA_FILELINE  __FILE__ ": " ARMA_STRING2(__LINE__)
1369 
1370 
1371 #if defined(ARMA_NO_DEBUG)
1372 
1373   #define arma_debug_print                   true ? (void)0 : arma_print
1374   #define arma_debug_warn                    true ? (void)0 : arma_warn
1375   #define arma_debug_warn_level              true ? (void)0 : arma_warn_level
1376   #define arma_debug_check                   true ? (void)0 : arma_check
1377   #define arma_debug_check_bounds            true ? (void)0 : arma_check_bounds
1378   #define arma_debug_set_error               true ? (void)0 : arma_set_error
1379   #define arma_debug_assert_same_size        true ? (void)0 : arma_assert_same_size
1380   #define arma_debug_assert_mul_size         true ? (void)0 : arma_assert_mul_size
1381   #define arma_debug_assert_trans_mul_size   true ? (void)0 : arma_assert_trans_mul_size
1382   #define arma_debug_assert_cube_as_mat      true ? (void)0 : arma_assert_cube_as_mat
1383   #define arma_debug_assert_blas_size        true ? (void)0 : arma_assert_blas_size
1384   #define arma_debug_assert_atlas_size       true ? (void)0 : arma_assert_atlas_size
1385 
1386 #else
1387 
1388   #define arma_debug_print                 arma_print
1389   #define arma_debug_warn                  arma_warn
1390   #define arma_debug_warn_level            arma_warn_level
1391   #define arma_debug_check                 arma_check
1392   #define arma_debug_check_bounds          arma_check_bounds
1393   #define arma_debug_set_error             arma_set_error
1394   #define arma_debug_assert_same_size      arma_assert_same_size
1395   #define arma_debug_assert_mul_size       arma_assert_mul_size
1396   #define arma_debug_assert_trans_mul_size arma_assert_trans_mul_size
1397   #define arma_debug_assert_cube_as_mat    arma_assert_cube_as_mat
1398   #define arma_debug_assert_blas_size      arma_assert_blas_size
1399   #define arma_debug_assert_atlas_size     arma_assert_atlas_size
1400 
1401 #endif
1402 
1403 
1404 
1405 #if defined(ARMA_EXTRA_DEBUG)
1406 
1407   #undef  ARMA_WARN_LEVEL
1408   #define ARMA_WARN_LEVEL 3
1409 
1410   #define arma_extra_debug_sigprint       arma_sigprint(ARMA_FNSIG); arma_bktprint
1411   #define arma_extra_debug_sigprint_this  arma_sigprint(ARMA_FNSIG); arma_thisprint
1412   #define arma_extra_debug_print          arma_print
1413 
1414 #else
1415 
1416   #define arma_extra_debug_sigprint        true ? (void)0 : arma_bktprint
1417   #define arma_extra_debug_sigprint_this   true ? (void)0 : arma_thisprint
1418   #define arma_extra_debug_print           true ? (void)0 : arma_print
1419 
1420 #endif
1421 
1422 
1423 
1424 
1425 #if defined(ARMA_EXTRA_DEBUG)
1426 
1427   namespace junk
1428     {
1429     class arma_first_extra_debug_message
1430       {
1431       public:
1432 
1433       inline
arma_first_extra_debug_message()1434       arma_first_extra_debug_message()
1435         {
1436         union
1437           {
1438           unsigned short a;
1439           unsigned char  b[sizeof(unsigned short)];
1440           } endian_test;
1441 
1442         endian_test.a = 1;
1443 
1444         const bool  little_endian = (endian_test.b[0] == 1);
1445         const char* nickname      = ARMA_VERSION_NAME;
1446 
1447         std::ostream& out = get_cerr_stream();
1448 
1449         out << "@ ---" << '\n';
1450         out << "@ Armadillo "
1451             << arma_version::major << '.' << arma_version::minor << '.' << arma_version::patch
1452             << " (" << nickname << ")\n";
1453 
1454         out << "@ arma_config::wrapper      = " << arma_config::wrapper      << '\n';
1455         out << "@ arma_config::cxx14        = " << arma_config::cxx14        << '\n';
1456         out << "@ arma_config::cxx17        = " << arma_config::cxx17        << '\n';
1457         out << "@ arma_config::std_mutex    = " << arma_config::std_mutex    << '\n';
1458         out << "@ arma_config::posix        = " << arma_config::posix        << '\n';
1459         out << "@ arma_config::openmp       = " << arma_config::openmp       << '\n';
1460         out << "@ arma_config::lapack       = " << arma_config::lapack       << '\n';
1461         out << "@ arma_config::blas         = " << arma_config::blas         << '\n';
1462         out << "@ arma_config::newarp       = " << arma_config::newarp       << '\n';
1463         out << "@ arma_config::arpack       = " << arma_config::arpack       << '\n';
1464         out << "@ arma_config::superlu      = " << arma_config::superlu      << '\n';
1465         out << "@ arma_config::atlas        = " << arma_config::atlas        << '\n';
1466         out << "@ arma_config::hdf5         = " << arma_config::hdf5         << '\n';
1467         out << "@ arma_config::good_comp    = " << arma_config::good_comp    << '\n';
1468         out << "@ arma_config::extra_code   = " << arma_config::extra_code   << '\n';
1469         out << "@ arma_config::hidden_args  = " << arma_config::hidden_args  << '\n';
1470         out << "@ arma_config::mat_prealloc = " << arma_config::mat_prealloc << '\n';
1471         out << "@ arma_config::mp_threshold = " << arma_config::mp_threshold << '\n';
1472         out << "@ arma_config::mp_threads   = " << arma_config::mp_threads   << '\n';
1473         out << "@ sizeof(void*)    = " << sizeof(void*)    << '\n';
1474         out << "@ sizeof(int)      = " << sizeof(int)      << '\n';
1475         out << "@ sizeof(long)     = " << sizeof(long)     << '\n';
1476         out << "@ sizeof(uword)    = " << sizeof(uword)    << '\n';
1477         out << "@ sizeof(blas_int) = " << sizeof(blas_int) << '\n';
1478         out << "@ little_endian    = " << little_endian    << '\n';
1479         out << "@ ---" << std::endl;
1480         }
1481 
1482       };
1483 
1484     static arma_first_extra_debug_message arma_first_extra_debug_message_run;
1485     }
1486 
1487 #endif
1488 
1489 
1490 
1491 //! @}
1492