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 fn_svd
20 //! @{
21 
22 
23 
24 template<typename T1>
25 inline
26 bool
svd(Col<typename T1::pod_type> & S,const Base<typename T1::elem_type,T1> & X,const typename arma_blas_type_only<typename T1::elem_type>::result * junk=nullptr)27 svd
28   (
29          Col<typename T1::pod_type>&     S,
30   const Base<typename T1::elem_type,T1>& X,
31   const typename arma_blas_type_only<typename T1::elem_type>::result* junk = nullptr
32   )
33   {
34   arma_extra_debug_sigprint();
35   arma_ignore(junk);
36 
37   typedef typename T1::elem_type eT;
38 
39   Mat<eT> A(X.get_ref());
40 
41   const bool status = auxlib::svd_dc(S, A);
42 
43   if(status == false)
44     {
45     S.soft_reset();
46     arma_debug_warn_level(3, "svd(): decomposition failed");
47     }
48 
49   return status;
50   }
51 
52 
53 
54 template<typename T1>
55 arma_warn_unused
56 inline
57 Col<typename T1::pod_type>
svd(const Base<typename T1::elem_type,T1> & X,const typename arma_blas_type_only<typename T1::elem_type>::result * junk=nullptr)58 svd
59   (
60   const Base<typename T1::elem_type,T1>& X,
61   const typename arma_blas_type_only<typename T1::elem_type>::result* junk = nullptr
62   )
63   {
64   arma_extra_debug_sigprint();
65   arma_ignore(junk);
66 
67   typedef typename T1::elem_type eT;
68   typedef typename T1::pod_type   T;
69 
70   Col<T> out;
71 
72   Mat<eT> A(X.get_ref());
73 
74   const bool status = auxlib::svd_dc(out, A);
75 
76   if(status == false)
77     {
78     out.soft_reset();
79     arma_stop_runtime_error("svd(): decomposition failed");
80     }
81 
82   return out;
83   }
84 
85 
86 
87 template<typename T1>
88 inline
89 bool
svd(Mat<typename T1::elem_type> & U,Col<typename T1::pod_type> & S,Mat<typename T1::elem_type> & V,const Base<typename T1::elem_type,T1> & X,const char * method="dc",const typename arma_blas_type_only<typename T1::elem_type>::result * junk=nullptr)90 svd
91   (
92          Mat<typename T1::elem_type>&    U,
93          Col<typename T1::pod_type >&    S,
94          Mat<typename T1::elem_type>&    V,
95   const Base<typename T1::elem_type,T1>& X,
96   const char*                            method = "dc",
97   const typename arma_blas_type_only<typename T1::elem_type>::result* junk = nullptr
98   )
99   {
100   arma_extra_debug_sigprint();
101   arma_ignore(junk);
102 
103   typedef typename T1::elem_type eT;
104 
105   arma_debug_check
106     (
107     ( ((void*)(&U) == (void*)(&S)) || (&U == &V) || ((void*)(&S) == (void*)(&V)) ),
108     "svd(): two or more output objects are the same object"
109     );
110 
111   const char sig = (method != nullptr) ? method[0] : char(0);
112 
113   arma_debug_check( ((sig != 's') && (sig != 'd')), "svd(): unknown method specified" );
114 
115   Mat<eT> A(X.get_ref());
116 
117   const bool status = (sig == 'd') ? auxlib::svd_dc(U, S, V, A) : auxlib::svd(U, S, V, A);
118 
119   if(status == false)
120     {
121     U.soft_reset();
122     S.soft_reset();
123     V.soft_reset();
124     arma_debug_warn_level(3, "svd(): decomposition failed");
125     }
126 
127   return status;
128   }
129 
130 
131 
132 template<typename T1>
133 inline
134 bool
svd_econ(Mat<typename T1::elem_type> & U,Col<typename T1::pod_type> & S,Mat<typename T1::elem_type> & V,const Base<typename T1::elem_type,T1> & X,const char mode,const char * method="dc",const typename arma_blas_type_only<typename T1::elem_type>::result * junk=nullptr)135 svd_econ
136   (
137          Mat<typename T1::elem_type>&    U,
138          Col<typename T1::pod_type >&    S,
139          Mat<typename T1::elem_type>&    V,
140   const Base<typename T1::elem_type,T1>& X,
141   const char                             mode,
142   const char*                            method = "dc",
143   const typename arma_blas_type_only<typename T1::elem_type>::result* junk = nullptr
144   )
145   {
146   arma_extra_debug_sigprint();
147   arma_ignore(junk);
148 
149   typedef typename T1::elem_type eT;
150 
151   arma_debug_check
152     (
153     ( ((void*)(&U) == (void*)(&S)) || (&U == &V) || ((void*)(&S) == (void*)(&V)) ),
154     "svd_econ(): two or more output objects are the same object"
155     );
156 
157   arma_debug_check
158     (
159     ( (mode != 'l') && (mode != 'r') && (mode != 'b') ),
160     "svd_econ(): parameter 'mode' is incorrect"
161     );
162 
163   const char sig = (method != nullptr) ? method[0] : char(0);
164 
165   arma_debug_check( ((sig != 's') && (sig != 'd')), "svd_econ(): unknown method specified" );
166 
167   Mat<eT> A(X.get_ref());
168 
169   const bool status = ((mode == 'b') && (sig == 'd')) ? auxlib::svd_dc_econ(U, S, V, A) : auxlib::svd_econ(U, S, V, A, mode);
170 
171   if(status == false)
172     {
173     U.soft_reset();
174     S.soft_reset();
175     V.soft_reset();
176     arma_debug_warn_level(3, "svd_econ(): decomposition failed");
177     }
178 
179   return status;
180   }
181 
182 
183 
184 template<typename T1>
185 inline
186 bool
svd_econ(Mat<typename T1::elem_type> & U,Col<typename T1::pod_type> & S,Mat<typename T1::elem_type> & V,const Base<typename T1::elem_type,T1> & X,const char * mode="both",const char * method="dc",const typename arma_blas_type_only<typename T1::elem_type>::result * junk=nullptr)187 svd_econ
188   (
189          Mat<typename T1::elem_type>&    U,
190          Col<typename T1::pod_type >&    S,
191          Mat<typename T1::elem_type>&    V,
192   const Base<typename T1::elem_type,T1>& X,
193   const char*                            mode   = "both",
194   const char*                            method = "dc",
195   const typename arma_blas_type_only<typename T1::elem_type>::result* junk = nullptr
196   )
197   {
198   arma_extra_debug_sigprint();
199   arma_ignore(junk);
200 
201   return svd_econ(U, S, V, X, ((mode != nullptr) ? mode[0] : char(0)), method);
202   }
203 
204 
205 
206 //! @}
207