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