cisst-saw
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
nmrSVDSolver.h
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */
3 
4 /*
5 
6  Author(s): Ankur Kapoor
7  Created on: 2004-10-26
8 
9  (C) Copyright 2004-2007 Johns Hopkins University (JHU), All Rights
10  Reserved.
11 
12 --- begin cisst license - do not edit ---
13 
14 This software is provided "as is" under an open source license, with
15 no warranty. The complete license can be found in license.txt and
16 http://www.cisst.org/cisst/license.txt.
17 
18 --- end cisst license ---
19 */
20 
21 
28 #ifndef _nmrSVDSolver_h
29 #define _nmrSVDSolver_h
30 
31 
34 
87 class nmrSVDSolver {
88  // we have this class so that we reserve memory only one
89  // would help if svd of a same size matrix (or a matrix)
90  // that doesnt change much is desired.
91 
92 protected:
93  CISSTNETLIB_INTEGER M;
94  CISSTNETLIB_INTEGER N;
95  CISSTNETLIB_INTEGER Lda;
96  CISSTNETLIB_INTEGER Ldu;
97  CISSTNETLIB_INTEGER Ldvt;
98  CISSTNETLIB_INTEGER Lwork;
99  char Jobu;
100  char Jobvt;
105  CISSTNETLIB_INTEGER Info;
107 
108 public:
114  { Allocate(M, N, StorageOrder); }
115 
116 
127  nmrSVDSolver( CISSTNETLIB_INTEGER m,
128  CISSTNETLIB_INTEGER n,
129  bool storageOrder)
130  { Allocate(m, n, storageOrder); }
131 
132 
144  template <class _matrixOwnerType>
145  nmrSVDSolver(const vctDynamicMatrixBase<_matrixOwnerType,
146  CISSTNETLIB_DOUBLE> &A)
147  { Allocate(A); }
148 
149  template <vct::size_type _rows,
150  vct::size_type _cols,
151  bool _storageOrder>
152  nmrSVDSolver(const vctFixedSizeMatrix<CISSTNETLIB_DOUBLE,
153  _rows,
154  _cols,
155  _storageOrder>& A)
156  { Allocate(A); }
158 
159 
168  inline void Allocate( CISSTNETLIB_INTEGER m,
169  CISSTNETLIB_INTEGER n,
170  bool storageOrder) {
171  const CISSTNETLIB_INTEGER one = 1;
172  StorageOrder = storageOrder;
173  if (storageOrder == VCT_COL_MAJOR) {
174  M = m;
175  N = n;
176  } else {
177  M = n;
178  N = m;
179  }
180  Lda = std::max(one, M);
181  Ldu = M;
182  Ldvt = N;
183  Lwork = std::max(3 * std::min(M, N) + std::max(M, N),
184  5 * std::min(M, N));
185  Jobu = 'A';
186  Jobvt = 'A';
187  S.SetSize(std::min(M, N), 1, StorageOrder);
191  }
192 
193 
201  template <class _matrixOwnerType>
202  inline void
203  Allocate(const vctDynamicMatrixBase<_matrixOwnerType,
204  CISSTNETLIB_DOUBLE>& A)
205  { Allocate(A.rows(), A.cols(), A.IsRowMajor()); }
206 
207  template <vct::size_type _rows,
208  vct::size_type _cols,
209  bool _storageOrder>
210  inline void
211  Allocate(const vctFixedSizeMatrix<CISSTNETLIB_DOUBLE,
212  _rows,
213  _cols,
214  _storageOrder> & A)
215  { Allocate(_rows, _cols, _storageOrder); }
217 
218 
230  template <class _matrixOwnerType>
231  inline void
232  Solve(vctDynamicMatrixBase<_matrixOwnerType,
233  CISSTNETLIB_DOUBLE> &A)
234  throw (std::runtime_error){
235  /*
236  check that the size and storage order matches with
237  Allocate()
238  */
239  if (A.IsRowMajor() != StorageOrder) {
240  cmnThrow(std::runtime_error("nmrSVDSolver Solve: Storage order used for Allocate was different"));
241  }
242 
243  /*
244  check sizes based on storage order, there is a more compact
245  expression for this test but I find this easier to read and
246  debug (Anton)
247  */
248  if (A.IsColMajor()) {
249  if ((M != static_cast<CISSTNETLIB_INTEGER>(A.rows())) ||
250  (N != static_cast<CISSTNETLIB_INTEGER>(A.cols()))) {
251  cmnThrow(std::runtime_error("nmrSVDSolver Solve: Size used for Allocate was different"));
252  }
253  }
254  else if (A.IsRowMajor()) {
255  if ((M != static_cast<CISSTNETLIB_INTEGER>(A.cols())) ||
256  (N != static_cast<CISSTNETLIB_INTEGER>(A.rows()))) {
257  cmnThrow(std::runtime_error("nmrSVDSolver Solve: Size used for Allocate was different"));
258  }
259  }
260 
261  /* check that the matrices are Fortran like */
262  if (! A.IsCompact()) {
263  cmnThrow(std::runtime_error("nmrSVDSolver Solve: Requires a compact matrix"));
264  }
265 
266  dgesvd_(&Jobu, &Jobvt, &M, &N,
267  A.Pointer(), &Lda, S.Pointer(),
268  U.Pointer(), &Ldu,
269  Vt.Pointer(), &Ldvt,
270  Work.Pointer(), &Lwork, &Info );
271  }
272 
273 
274  template <vct::size_type _rows,
275  vct::size_type _cols,
276  bool _storageOrder>
277  inline void
278  Solve(vctFixedSizeMatrix<CISSTNETLIB_DOUBLE,
279  _rows,
280  _cols,
281  _storageOrder>& A) {
283  Solve(Aref);
284  }
286 
287 
288  inline const vctDynamicMatrix<CISSTNETLIB_DOUBLE> &GetS(void) const
289  { return S; }
290 
291  inline const vctDynamicMatrix<CISSTNETLIB_DOUBLE> &GetU(void) const
292  { return (StorageOrder == VCT_COL_MAJOR) ? U : Vt; }
293 
295  { return (StorageOrder == VCT_COL_MAJOR) ? Vt : U; }
296 };
297 
298 
299 #ifdef CISST_COMPILER_IS_MSVC
301 #endif // CISST_COMPILER_IS_MSVC
302 
303 
304 #endif // _nmrSVDSolver_h
305 
CISSTNETLIB_INTEGER M
Definition: nmrSVDSolver.h:93
const vctDynamicMatrix< CISSTNETLIB_DOUBLE > & GetVt(void) const
Definition: nmrSVDSolver.h:294
char Jobvt
Definition: nmrSVDSolver.h:100
Declaration of vctDynamicMatrix.
Definition: vctDynamicMatrixBase.h:42
#define CISST_DEPRECATED
Definition: cmnPortability.h:310
CISSTNETLIB_INTEGER Ldvt
Definition: nmrSVDSolver.h:97
vctDynamicMatrix< CISSTNETLIB_DOUBLE > S
Definition: nmrSVDSolver.h:101
const vctDynamicMatrix< CISSTNETLIB_DOUBLE > & GetS(void) const
Definition: nmrSVDSolver.h:288
size_t size_type
Definition: vctContainerTraits.h:35
bool StorageOrder
Definition: nmrSVDSolver.h:106
void Solve(vctFixedSizeMatrix< CISSTNETLIB_DOUBLE, _rows, _cols, _storageOrder > &A)
Definition: nmrSVDSolver.h:278
CISSTNETLIB_INTEGER Lda
Definition: nmrSVDSolver.h:95
void Allocate(const vctDynamicMatrixBase< _matrixOwnerType, CISSTNETLIB_DOUBLE > &A)
Definition: nmrSVDSolver.h:203
void Allocate(CISSTNETLIB_INTEGER m, CISSTNETLIB_INTEGER n, bool storageOrder)
Definition: nmrSVDSolver.h:168
nmrSVDSolver(void)
Definition: nmrSVDSolver.h:113
CISSTNETLIB_INTEGER Lwork
Definition: nmrSVDSolver.h:98
CISSTNETLIB_INTEGER Info
Definition: nmrSVDSolver.h:105
pointer Pointer(size_type rowIndex, size_type colIndex)
Definition: vctDynamicMatrixBase.h:143
CISSTNETLIB_INTEGER Ldu
Definition: nmrSVDSolver.h:96
vctDynamicMatrix< CISSTNETLIB_DOUBLE > U
Definition: nmrSVDSolver.h:102
vctDynamicMatrix< CISSTNETLIB_DOUBLE > Work
Definition: nmrSVDSolver.h:104
void SetSize(size_type rows, size_type cols, bool storageOrder)
Definition: vctDynamicMatrix.h:364
#define cmnThrow(a)
Definition: MinimalCmn.h:4
Implementation of a fixed-size matrix using template metaprogramming.
Definition: vctFixedSizeMatrix.h:52
void Allocate(const vctFixedSizeMatrix< CISSTNETLIB_DOUBLE, _rows, _cols, _storageOrder > &A)
Definition: nmrSVDSolver.h:211
void Solve(vctDynamicMatrixBase< _matrixOwnerType, CISSTNETLIB_DOUBLE > &A)
Definition: nmrSVDSolver.h:232
vctDynamicMatrix< CISSTNETLIB_DOUBLE > Vt
Definition: nmrSVDSolver.h:103
const vctDynamicMatrix< CISSTNETLIB_DOUBLE > & GetU(void) const
Definition: nmrSVDSolver.h:291
nmrSVDSolver(const vctFixedSizeMatrix< CISSTNETLIB_DOUBLE, _rows, _cols, _storageOrder > &A)
Definition: nmrSVDSolver.h:152
nmrSVDSolver(const vctDynamicMatrixBase< _matrixOwnerType, CISSTNETLIB_DOUBLE > &A)
Definition: nmrSVDSolver.h:145
const bool VCT_COL_MAJOR
Definition: vctForwardDeclarations.h:46
Definition: nmrSVDSolver.h:87
CISSTNETLIB_INTEGER N
Definition: nmrSVDSolver.h:94
nmrSVDSolver(CISSTNETLIB_INTEGER m, CISSTNETLIB_INTEGER n, bool storageOrder)
Definition: nmrSVDSolver.h:127
char Jobu
Definition: nmrSVDSolver.h:99