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