STK++ 0.9.13
STK_lapack_Svd.h
Go to the documentation of this file.
1/*--------------------------------------------------------------------*/
2/* Copyright (C) 2004-2016 Serge Iovleff, Université Lille 1, Inria
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR a PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this program; if not, write to the
16 Free Software Foundation, Inc.,
17 59 Temple Place,
18 Suite 330,
19 Boston, MA 02111-1307
20 USA
21
22 Contact : S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
23*/
24
25/*
26 * Project: stkpp::Algebra
27 * created on: 20 nov. 2013
28 * Author: iovleff, S..._Dot_I..._At_stkpp_Dot_org (see copyright for ...)
29 **/
30
36#ifndef STK_LAPACK_SVD_H
37#define STK_LAPACK_SVD_H
38
41
42#include "STK_ISvd.h"
43#include "STK_lapack_Util.h"
44#include "STK_transpose.h"
45
46namespace STK
47{
48
49namespace lapack
50{
51class Svd;
52}
53
54namespace hidden
55{
59template<>
60struct AlgebraTraits< lapack::Svd >
61{
65};
66
67} // namespace hidden
68
69
70namespace lapack
71{
107class Svd: public ISvd<Svd>
108{
109 public:
113
114 using Base::norm_;
115 using Base::rank_;
116 using Base::U_;
117 using Base::D_;
118 using Base::V_;
119 using Base::withU_;
120 using Base::withV_;
121 using Base::nrowU;
122 using Base::ncolU;
123 using Base::ncolV;
124
131 inline Svd( CArrayXX const& A, bool ref = false, bool withU= true, bool withV= true)
132 : Base(A, ref, withU, withV), jobz_( (withU|withV) ? 'O':'N') {}
138 template<class OtherArray>
139 inline Svd( ArrayBase<OtherArray> const& A, bool withU= true, bool withV= true)
140 : Base(A, withU, withV), jobz_( (withU|withV) ? 'O':'N') {}
144 inline Svd( Svd const& decomp): Base(decomp), jobz_(decomp.jobz_) {}
146 inline virtual ~Svd() {}
148 inline virtual Svd* clone() const { return new Svd(*this);}
150 inline Svd& operator=(Svd const& decomp)
151 {
152 Base::operator=(decomp);
153 jobz_ = decomp.jobz_;
154 return *this;
155 }
156 // getters
158 char jobz() const { return jobz_;}
159 // setters
161 void setJobz(char jobz) { jobz_ = jobz;}
162
164 bool runImpl();
165
166 private:
168 char jobz_;
172};
173
174/* @brief Run svd decomposition */
175inline bool Svd::runImpl()
176{
177 if (jobz_ == 'A' || jobz_ == 'S')
178 {
179 msg_error_ = _T("In lapack::Svd::runImpl, the options 'A' and 'S' are not available");
180 return false;
181 }
182 int beginRow = U_.beginRows(), beginCol = U_.beginCols();
183 bool result = true;
184 // compute results
185 if ( (jobz_ == 'O' && U_.sizeRows() >= U_.sizeCols()) || jobz_ == 'N')
186 {
187 if (!computeSvd(U_, U_, D_, V_)) { result = false;}
188 }
189 else
190 { // jobz_ == 'O' and m<n, V_ will contain u and U_ will contain vt
191 if (!computeSvd(U_, V_, D_, V_)) { result = false;};
192 U_.exchange(V_); // !now U_ is (m,m) and V_ is (m,n)
193 }
194 U_.shift(beginRow, beginCol);
195 D_.shift(beginCol);
196 transpose(V_.shift(beginCol));
197 return result;
198}
199
200
201/* Computing the Svd decomposition of the matrix U_. */
203{
204 int m = a.sizeRows(), n = a.sizeCols(), nbSv = std::min(m,n);
205 a.shift(0,0);
206 // Workspace and status variables:
207 double workSize;
208 double *p_work = &workSize;
209 int* p_iwork = new int[8*nbSv];
210 int lwork = -1;
211 int info;
212 //
213 // Call dgesdd_ with lwork = -1 to query optimal workspace size:
214 info = gesdd( jobz_, m, n
215 , a.p_data(), m, s.p_data(), u.p_data(), m, vt.p_data(), n
216 , p_work, lwork, p_iwork);
217 // check any error
218 if (info!=0)
219 {
220 if (info>0)
222 return false;
223 }
225 return false;
226 }
227 // optimal storage dimension is returned in work[0]
228 lwork = workSize;
229 p_work = new Real[lwork];
230 // resize u
231 if ( !((jobz_ == 'O' && m >= n) || (jobz_ == 'N')) )
232 {
233 int ucol = (jobz_ == 'A' || jobz_ == 'O') ? m : nbSv;
234 u.resize(m, ucol);
235 }
236 if ( !((jobz_ == 'O' && m < n) || (jobz_ == 'N')) )
237 {
238 int ldvt = (jobz_ == 'A' || jobz_ == 'O') ? n : nbSv;
239 vt.resize(ldvt,n);
240 }
241 s.resize(nbSv).shift(0);
242 u.shift(0,0);
243 vt.shift(0,0);
244
245 // Call dgesdd_ to do the actual computation:
246 info = gesdd( jobz_, m, n
247 , a.p_data(), a.sizeRows(), s.p_data()
248 , u.p_data(), u.sizeRows()
249 , vt.p_data(), vt.sizeRows()
250 , p_work, lwork, p_iwork);
251 // clean
252 delete[] p_work;
253 delete[] p_iwork;
254 // check any error
255 if (info!=0)
256 {
257 if (info>0)
259 return false;
260 }
262 return false;
263 }
264 return true;
265}
266
267} // namespace lapack
268
269} // namespace STK
270
271#endif /* STK_LAPACK_SVD_H */
In this file we implement the final class CArrayVector.
In this file we implement the final class CArray.
In this file we define the interface class ISvd.
#define STKERROR_NO_ARG(Where, Error)
Definition STK_Macros.h:49
#define STKERROR_1ARG(Where, Arg, Error)
Definition STK_Macros.h:61
#define _T(x)
Let x unmodified.
In this file we define and implement utilities classes and methods for the interface with lapack.
In this file we define the transpose method.
Derived & resize(Range const &I, Range const &J)
resize the Array.
Derived & shift(int beginRows, int beginCols)
shift the Array.
Type *const & p_data() const
String msg_error_
String with the last error message.
Definition STK_IRunner.h:96
String const & error() const
get the last error message.
Definition STK_IRunner.h:82
Compute the Singular Value Decomposition of an array.
Definition STK_ISvd.h:61
bool withU_
Compute U_ ?
Definition STK_ISvd.h:195
Type norm_
trace norm
Definition STK_ISvd.h:199
int nrowU() const
Definition STK_ISvd.h:208
ArrayD D_
Diagonal array of the singular values.
Definition STK_ISvd.h:193
ISvd & operator=(const ISvd &S)
Operator = : overwrite the ISvd with S.
Definition STK_ISvd.h:101
ArrayV V_
V_ matrix.
Definition STK_ISvd.h:191
ArrayU U_
U_ matrix.
Definition STK_ISvd.h:189
int ncolV() const
Definition STK_ISvd.h:218
bool withV_
Compute V_ ?
Definition STK_ISvd.h:197
int ncolU() const
Definition STK_ISvd.h:210
The MultidimRegression class allows to regress a multidimensional output variable among a multivariat...
The class Svd compute the Singular Value Decomposition of a Array with the Golub-Reinsch Algorithm.
Definition STK_Svd.h:117
bool computeSvd()
Svd main steps.
Definition STK_Svd.h:235
Svd(Svd const &decomp)
Copy constructor.
Svd(CArrayXX const &A, bool ref=false, bool withU=true, bool withV=true)
Default constructor.
Svd & operator=(Svd const &decomp)
Operator = : overwrite the Svd with decomp.
bool computeSvd(CArrayXX &a, CArrayXX &u, CVectorX &s, CArrayXX &v)
compute the svd decomposition.
char jobz() const
bool runImpl()
Run svd decomposition.
hidden::Traits< CArrayXX >::Col ColVector
virtual Svd * clone() const
clone pattern
virtual ~Svd()
virtual destructor
hidden::Traits< CArrayXX >::Row RowVector
Svd(ArrayBase< OtherArray > const &A, bool withU=true, bool withV=true)
constructor with other kind of array/expression
void setJobz(char jobz)
set the option chosen for the svd
TContainer2D & transpose(ArrayBase< TContainer2D > &A)
The transpose method allow to transpose an array in place.
int gesdd(char jobz, int m, int n, Real *a, int lda, Real *s, Real *u, int ldu, Real *vt, int ldvt, Real *work, int lWork, int *iWork)
wrapper of the LAPACK DGESDD routine.
double Real
STK fundamental type of Real values.
The namespace STK is the main domain space of the Statistical ToolKit project.
traits class for the algebra methods.