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 Base
20 //! @{
21 
22 
23 
24 template<typename elem_type, typename derived>
25 struct Base_extra_yes
26   {
27   inline arma_warn_unused const Op<derived,op_inv> i() const;   //!< matrix inverse
28 
29   inline arma_warn_unused bool is_sympd() const;
30   inline arma_warn_unused bool is_sympd(typename get_pod_type<elem_type>::result tol) const;
31   };
32 
33 
34 template<typename elem_type, typename derived>
35 struct Base_extra_no
36   {
37   };
38 
39 
40 template<typename elem_type, typename derived, bool condition>
41 struct Base_extra {};
42 
43 template<typename elem_type, typename derived>
44 struct Base_extra<elem_type, derived, true>  { typedef Base_extra_yes<elem_type, derived> result; };
45 
46 template<typename elem_type, typename derived>
47 struct Base_extra<elem_type, derived, false> { typedef Base_extra_no<elem_type, derived>  result; };
48 
49 
50 
51 template<typename elem_type, typename derived>
52 struct Base_eval_Mat
53   {
54   arma_inline arma_warn_unused const derived& eval() const;
55   };
56 
57 
58 template<typename elem_type, typename derived>
59 struct Base_eval_expr
60   {
61   inline arma_warn_unused Mat<elem_type> eval() const;   //!< force the immediate evaluation of a delayed expression
62   };
63 
64 
65 template<typename elem_type, typename derived, bool condition>
66 struct Base_eval {};
67 
68 template<typename elem_type, typename derived>
69 struct Base_eval<elem_type, derived, true>  { typedef Base_eval_Mat<elem_type, derived>  result; };
70 
71 template<typename elem_type, typename derived>
72 struct Base_eval<elem_type, derived, false> { typedef Base_eval_expr<elem_type, derived> result; };
73 
74 
75 
76 template<typename derived>
77 struct Base_trans_cx
78   {
79   arma_inline arma_warn_unused const Op<derived,op_htrans>  t() const;
80   arma_inline arma_warn_unused const Op<derived,op_htrans> ht() const;
81   arma_inline arma_warn_unused const Op<derived,op_strans> st() const;  // simple transpose: no complex conjugates
82   };
83 
84 
85 template<typename derived>
86 struct Base_trans_default
87   {
88   arma_inline arma_warn_unused const Op<derived,op_htrans>  t() const;
89   arma_inline arma_warn_unused const Op<derived,op_htrans> ht() const;
90   arma_inline arma_warn_unused const Op<derived,op_htrans> st() const;  // return op_htrans instead of op_strans, as it's handled better by matrix multiplication code
91   };
92 
93 
94 template<typename derived, bool condition>
95 struct Base_trans {};
96 
97 template<typename derived>
98 struct Base_trans<derived, true>  { typedef Base_trans_cx<derived>      result; };
99 
100 template<typename derived>
101 struct Base_trans<derived, false> { typedef Base_trans_default<derived> result; };
102 
103 
104 
105 //! Class for static polymorphism, modelled after the "Curiously Recurring Template Pattern" (CRTP).
106 //! Used for type-safe downcasting in functions that restrict their input(s) to be classes that are
107 //! derived from Base (eg. Mat, Op, Glue, diagview, subview).
108 //! A Base object can be converted to a Mat object by the unwrap class.
109 
110 template<typename elem_type, typename derived>
111 struct Base
112   : public Base_extra<elem_type, derived, is_supported_blas_type<elem_type>::value>::result
113   , public Base_eval<elem_type, derived, is_Mat<derived>::value>::result
114   , public Base_trans<derived, is_cx<elem_type>::value>::result
115   {
116   arma_inline const derived& get_ref() const;
117 
118   arma_cold inline void print(                           const std::string extra_text = "") const;
119   arma_cold inline void print(std::ostream& user_stream, const std::string extra_text = "") const;
120 
121   arma_cold inline void raw_print(                           const std::string extra_text = "") const;
122   arma_cold inline void raw_print(std::ostream& user_stream, const std::string extra_text = "") const;
123 
124   arma_cold inline void brief_print(                           const std::string extra_text = "") const;
125   arma_cold inline void brief_print(std::ostream& user_stream, const std::string extra_text = "") const;
126 
127   inline arma_warn_unused elem_type min() const;
128   inline arma_warn_unused elem_type max() const;
129 
130   inline elem_type min(uword& index_of_min_val) const;
131   inline elem_type max(uword& index_of_max_val) const;
132 
133   inline elem_type min(uword& row_of_min_val, uword& col_of_min_val) const;
134   inline elem_type max(uword& row_of_max_val, uword& col_of_max_val) const;
135 
136   inline arma_warn_unused uword index_min() const;
137   inline arma_warn_unused uword index_max() const;
138 
139   inline arma_warn_unused bool is_symmetric() const;
140   inline arma_warn_unused bool is_symmetric(const typename get_pod_type<elem_type>::result tol) const;
141 
142   inline arma_warn_unused bool is_hermitian() const;
143   inline arma_warn_unused bool is_hermitian(const typename get_pod_type<elem_type>::result tol) const;
144 
145   inline arma_warn_unused bool is_zero(const typename get_pod_type<elem_type>::result tol = 0) const;
146 
147   inline arma_warn_unused bool is_trimatu() const;
148   inline arma_warn_unused bool is_trimatl() const;
149   inline arma_warn_unused bool is_diagmat() const;
150   inline arma_warn_unused bool is_empty()   const;
151   inline arma_warn_unused bool is_square()  const;
152   inline arma_warn_unused bool is_vec()     const;
153   inline arma_warn_unused bool is_colvec()  const;
154   inline arma_warn_unused bool is_rowvec()  const;
155   inline arma_warn_unused bool is_finite()  const;
156   inline arma_warn_unused bool has_inf()    const;
157   inline arma_warn_unused bool has_nan()    const;
158 
159   inline arma_warn_unused const Op<derived,op_vectorise_col> as_col() const;
160   inline arma_warn_unused const Op<derived,op_vectorise_row> as_row() const;
161   };
162 
163 
164 
165 //! @}
166