cisst-saw
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
nmrPInverseEconomy.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  Author(s): Ankur Kapoor
6  Created on: 2005-10-18
7 
8  (C) Copyright 2005-2014 Johns Hopkins University (JHU), All Rights Reserved.
9 
10 --- begin cisst license - do not edit ---
11 
12 This software is provided "as is" under an open source license, with
13 no warranty. The complete license can be found in license.txt and
14 http://www.cisst.org/cisst/license.txt.
15 
16 --- end cisst license ---
17 */
18 
19 
26 #ifndef _nmrPInverseEconomy_h
27 #define _nmrPInverseEconomy_h
28 
29 #include <cisstCommon/cmnThrow.h>
34 
35 // Always include last
37 
120 /*
121  ****************************************************************************
122  DYNAMIC SIZE
123  ****************************************************************************
124  */
125 
129 
130 public:
136  typedef unsigned int size_type;
137 
138 protected:
161 
162  /* Just store M, N, and StorageOrder which are needed
163  to check if A matrix passed to solve method matches
164  the allocated size. */
168 
169 
174  inline void SetDimension(size_type m, size_type n, bool storageOrder)
175  {
176  StorageOrderMember = storageOrder;
177  MMember = m;
178  NMember = n;
179  }
180 
194  inline void AllocateOutputWorkspace(bool allocateOutput, bool allocateWorkspace)
195  {
196  // allocate output
197  if (allocateOutput) {
200  (StorageOrderMember) ? MMember : 1,
201  (StorageOrderMember) ? 1 : NMember,
203  } else {
205  }
206  // allocate workspace
207  if (allocateWorkspace) {
209  this->SetRefSVD(this->WorkspaceMemory);
210  } else {
211  this->WorkspaceMemory.SetSize(0);
212  }
213  }
214 
215 
222  template <class _vectorOwnerTypeWorkspace>
224  {
225  const size_type minmn = (MMember < NMember) ? MMember : NMember;
226  size_type current = 0;
227  UReference.SetRef(MMember, minmn,
228  (StorageOrderMember) ? minmn : 1,
229  (StorageOrderMember) ? 1 : MMember,
230  workspace.Pointer(current));
231  current += (MMember * minmn);
233  (StorageOrderMember) ? NMember : 1,
234  (StorageOrderMember) ? 1 : NMember,
235  workspace.Pointer(current));
236  current += (NMember * NMember);
237  SReference.SetRef(minmn,
238  workspace.Pointer(current),
239  1);
240  current += minmn;
242  workspace.Pointer(current),
243  1);
244  }
245 
246 
247 
254  template <typename _matrixOwnerTypePInverse>
256  throw(std::runtime_error)
257  {
258  // check sizes and storage order
259  if ((MMember != pInverse.cols()) || (NMember != pInverse.rows())) {
260  cmnThrow(std::runtime_error("nmrPInverseEconomyDynamicData: Size of matrix pInverse is incorrect."));
261  }
262  if (pInverse.StorageOrder() != StorageOrderMember) {
263  cmnThrow(std::runtime_error("nmrPInverseEconomyDynamicData: Storage order of pInverse is incorrect."));
264  }
265  }
266 
274  template <typename _vectorOwnerTypeWorkspace>
275  inline void
277  throw(std::runtime_error)
278  {
280  if (lwork > workspace.size()) {
281  cmnThrow(std::runtime_error("nmrPInverseEconomyDynamicData: Workspace is too small."));
282  }
283  if (!workspace.IsCompact()) {
284  cmnThrow(std::runtime_error("nmrPInverseEconomyDynamicData: Workspace must be compact."));
285  }
286  }
287 
288 
289 public:
296  {
297  const size_type minmn = (m < n) ? m : n;
298  const size_type maxmn = (m > n) ? m : n;
299  const size_type lwork_1 = 3 * minmn + maxmn;
300  const size_type lwork_2 = 5 * minmn;
301  const size_type lwork = (lwork_1 > lwork_2) ? lwork_1 : lwork_2;
302  // u vt s workspace
303  return m * minmn + n * n + minmn + lwork;
304  }
305 
311  template <class _matrixOwnerTypeA>
313  {
315  }
316 
317 #ifndef SWIG
318 #ifndef DOXYGEN
319 
325  class Friend {
326  private:
328  public:
330  }
332  return Data.SReference;
333  }
335  return Data.PInverseReference;
336  }
338  return Data.UReference;
339  }
341  return Data.VtReference;
342  }
344  return Data.WorkspaceReference;
345  }
346  inline size_type M(void) {
347  return Data.MMember;
348  }
349  inline size_type N(void) {
350  return Data.NMember;
351  }
352  inline bool StorageOrder(void) {
353  return Data.StorageOrderMember;
354  }
355  };
356  friend class Friend;
357 #endif // DOXYGEN
358 #endif // SWIG
359 
367  MMember(static_cast<size_type>(0)),
368  NMember(static_cast<size_type>(0)),
370  {
371  AllocateOutputWorkspace(false, false);
372  };
373 
374 
383  template <class _matrixOwnerTypeA>
385  {
386  this->Allocate(A.rows(), A.cols(), A.StorageOrder());
387  }
388 
400  template <class _matrixOwnerTypeA, class _vectorOwnerTypeWorkspace>
403  {
404  this->SetRefWorkspace(A, workspace);
405  }
406 
418  template <class _matrixOwnerTypeA,
419  class _matrixOwnerTypePInverse,
420  class _vectorOwnerTypeWorkspace>
424  {
425  this->SetRef(pInverse, workspace);
426  }
441  template <class _matrixOwnerTypeA, class _matrixOwnerTypePInverse>
444  {
445  this->SetRefOutput(pInverse);
446  }
447 
448 
460  template <class _matrixOwnerTypeA>
462  {
463  this->SetDimension(A.rows(), A.cols(), A.StorageOrder());
464  this->AllocateOutputWorkspace(true, true);
465  }
466 
467 
486  template <class _matrixOwnerTypeA, class _vectorOwnerTypeWorkspace>
489  {
490  this->SetDimension(A.rows(), A.cols(), A.StorageOrder());
491  this->AllocateOutputWorkspace(true, false);
492  // call helper method to set references for SVD components
493  this->ThrowUnlessWorkspaceSizeIsCorrect(workspace);
494  this->SetRefSVD(workspace);
495  }
496 
508  template <class _matrixOwnerTypePInverse,
509  class _vectorOwnerTypeWorkspace>
512  {
513  this->SetDimension(pInverse.cols(), pInverse.rows(), pInverse.StorageOrder());
514  this->AllocateOutputWorkspace(false, false);
515  // set reference on output
516  this->ThrowUnlessOutputSizeIsCorrect(pInverse);
517  this->PInverseReference.SetRef(pInverse);
518  // set reference on workspace
519  this->ThrowUnlessWorkspaceSizeIsCorrect(workspace);
520  this->SetRefSVD(workspace);
521  }
522 
537  template <class _matrixOwnerTypePInverse>
539  {
540  this->SetDimension(pInverse.cols(), pInverse.rows(), pInverse.StorageOrder());
541  this->AllocateOutputWorkspace(false, true);
542  this->ThrowUnlessOutputSizeIsCorrect(pInverse);
543  this->PInverseReference.SetRef(pInverse);
544  }
545 
546 
547 
548 public:
557  inline const vctDynamicVectorRef<CISSTNETLIB_DOUBLE> &S(void) const {
558  return SReference;
559  }
560  inline const vctDynamicMatrixRef<CISSTNETLIB_DOUBLE> &U(void) const {
561  return UReference;
562  }
563  inline const vctDynamicMatrixRef<CISSTNETLIB_DOUBLE> &Vt(void) const {
564  return VtReference;
565  }
567  return PInverseReference;
568  }
570 };
571 
589 template <class _matrixOwnerType>
591  nmrPInverseEconomyDynamicData &data) throw (std::runtime_error)
592 {
593  typedef unsigned int size_type;
594 
595  typename nmrPInverseEconomyDynamicData::Friend dataFriend(data);
596  CISSTNETLIB_INTEGER ret_value;
597  /* check that the size and storage order matches with Allocate() */
598  if (A.StorageOrder() != dataFriend.StorageOrder()) {
599  cmnThrow(std::runtime_error("nmrPInverseEconomy Solve: Storage order used for Allocate was different"));
600  }
601  if ((A.rows() != dataFriend.M()) || (A.cols() != dataFriend.N())) {
602  cmnThrow(std::runtime_error("nmrPInverseEconomy Solve: Size used for Allocate was different"));
603  }
604  const size_type rows = A.rows();
605  const size_type cols = A.cols();
606  const size_type minmn = (rows < cols) ? rows : cols;
607 
608  ret_value = nmrSVDEconomy(A, dataFriend.U(), dataFriend.S(),
609  dataFriend.Vt(), dataFriend.Workspace());
610  const CISSTNETLIB_DOUBLE eps = cmnTypeTraits<CISSTNETLIB_DOUBLE>::Tolerance() * dataFriend.S().at(0);
611 
612  dataFriend.PInverse().SetAll(0);
613  CISSTNETLIB_DOUBLE singularValue;
614  size_type irank, i, j;
615  for (irank = 0; irank < minmn; irank++) {
616  if ((singularValue = dataFriend.S().at(irank)) > eps) {
617  for (j = 0; j < rows; j++) {
618  for (i = 0; i < cols; i++) {
619  dataFriend.PInverse().at(i, j) = dataFriend.PInverse().at(i, j)
620  + dataFriend.Vt().at(irank, i) * dataFriend.U().at(j, irank) / singularValue;
621  }
622  }
623  }
624  }
625  return ret_value;
626 }
627 
645 template <class _matrixOwnerTypeA, class _matrixOwnerTypePInverse, class _vectorOwnerTypeWorkspace>
649 {
650  nmrPInverseEconomyDynamicData svdData(A, pInverse, workspace);
651  CISSTNETLIB_INTEGER ret_value = nmrPInverseEconomy(A, svdData);
652  return ret_value;
653 }
654 
668 template <class _matrixOwnerTypeA, class _matrixOwnerTypePInverse>
671 {
672  nmrPInverseEconomyDynamicData svdData(A, pInverse);
673  CISSTNETLIB_INTEGER ret_value = nmrPInverseEconomy(A, svdData);
674  return ret_value;
675 }
676 
677 
678 #endif
679 
void SetDimension(size_type m, size_type n, bool storageOrder)
Definition: nmrPInverseEconomy.h:174
const vctDynamicVectorRef< CISSTNETLIB_DOUBLE > & S(void) const
Definition: nmrPInverseEconomy.h:557
Declaration of vctDynamicMatrix.
Definition: vctDynamicMatrixBase.h:42
Definition: nmrPInverseEconomy.h:325
nmrPInverseEconomyDynamicData()
Definition: nmrPInverseEconomy.h:366
vctDynamicMatrixRef< CISSTNETLIB_DOUBLE > UReference
Definition: nmrPInverseEconomy.h:156
#define CMN_UNUSED(argument)
Definition: cmnPortability.h:479
size_type MMember
Definition: nmrPInverseEconomy.h:165
static Type Tolerance(void)
Definition: cmnTypeTraits.h:170
Declaration of vctFixedSizeMatrix.
void ThrowUnlessWorkspaceSizeIsCorrect(vctDynamicVectorBase< _vectorOwnerTypeWorkspace, CISSTNETLIB_DOUBLE > &workspace) const
Definition: nmrPInverseEconomy.h:276
const vctDynamicMatrixRef< CISSTNETLIB_DOUBLE > & U(void) const
Definition: nmrPInverseEconomy.h:560
size_t size_type
Definition: vctContainerTraits.h:35
nmrPInverseEconomyDynamicData(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &CMN_UNUSED(A), vctDynamicMatrixBase< _matrixOwnerTypePInverse, CISSTNETLIB_DOUBLE > &pInverse)
Definition: nmrPInverseEconomy.h:442
void ThrowUnlessOutputSizeIsCorrect(vctDynamicMatrixBase< _matrixOwnerTypePInverse, CISSTNETLIB_DOUBLE > &pInverse) const
Definition: nmrPInverseEconomy.h:255
bool StorageOrder(void) const
Definition: vctDynamicConstMatrixBase.h:656
unsigned int size_type
Definition: nmrPInverseEconomy.h:136
static size_type WorkspaceSize(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A)
Definition: nmrPInverseEconomy.h:312
void SetRef(size_type size, pointer data, stride_type stride=1)
Definition: vctDynamicVectorRef.h:156
bool StorageOrder(void)
Definition: nmrPInverseEconomy.h:352
nmrPInverseEconomyDynamicData(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &CMN_UNUSED(A), vctDynamicMatrixBase< _matrixOwnerTypePInverse, CISSTNETLIB_DOUBLE > &pInverse, vctDynamicVectorBase< _vectorOwnerTypeWorkspace, CISSTNETLIB_DOUBLE > &workspace)
Definition: nmrPInverseEconomy.h:421
void SetRefSVD(vctDynamicVectorBase< _vectorOwnerTypeWorkspace, CISSTNETLIB_DOUBLE > &workspace)
Definition: nmrPInverseEconomy.h:223
vctDynamicVector< CISSTNETLIB_DOUBLE > OutputMemory
Definition: nmrPInverseEconomy.h:150
static size_type WorkspaceSize(size_type m, size_type n)
Definition: nmrSVDEconomy.h:282
void SetSize(size_type size)
Definition: vctDynamicVector.h:315
vctDynamicMatrixRef< CISSTNETLIB_DOUBLE > PInverseReference
Definition: nmrPInverseEconomy.h:155
CISSTNETLIB_INTEGER nmrPInverseEconomy(vctDynamicMatrixBase< _matrixOwnerType, CISSTNETLIB_DOUBLE > &A, nmrPInverseEconomyDynamicData &data)
Definition: nmrPInverseEconomy.h:590
nmrPInverseEconomyDynamicData(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A)
Definition: nmrPInverseEconomy.h:384
vctDynamicVectorRef< CISSTNETLIB_DOUBLE > SReference
Definition: nmrPInverseEconomy.h:158
static size_type WorkspaceSize(size_type m, size_type n)
Definition: nmrPInverseEconomy.h:295
size_type NMember
Definition: nmrPInverseEconomy.h:166
void SetRef(size_type rows, size_type cols, stride_type rowStride, stride_type colStride, pointer dataPointer)
Definition: vctDynamicMatrixRef.h:217
bool StorageOrderMember
Definition: nmrPInverseEconomy.h:167
vctDynamicVectorRef< CISSTNETLIB_DOUBLE > & S(void)
Definition: nmrPInverseEconomy.h:331
reference at(index_type index)
Definition: vctDynamicVectorBase.h:170
const vctDynamicMatrixRef< CISSTNETLIB_DOUBLE > & Vt(void) const
Definition: nmrPInverseEconomy.h:563
vctDynamicMatrixRef< CISSTNETLIB_DOUBLE > & PInverse(void)
Definition: nmrPInverseEconomy.h:334
size_type N(void)
Definition: nmrPInverseEconomy.h:349
value_type SetAll(const value_type value)
Definition: vctDynamicMatrixBase.h:452
size_type rows() const
Definition: vctDynamicConstMatrixBase.h:238
size_type cols() const
Definition: vctDynamicConstMatrixBase.h:243
void Allocate(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A)
Definition: nmrPInverseEconomy.h:461
reference at(size_type index)
Definition: vctDynamicMatrixBase.h:171
vctDynamicVector< CISSTNETLIB_DOUBLE > WorkspaceMemory
Definition: nmrPInverseEconomy.h:146
size_type M(void)
Definition: nmrPInverseEconomy.h:346
#define cmnThrow(a)
Definition: MinimalCmn.h:4
void SetRefOutput(vctDynamicMatrixBase< _matrixOwnerTypePInverse, CISSTNETLIB_DOUBLE > &pInverse)
Definition: nmrPInverseEconomy.h:538
pointer Pointer(index_type index=0)
Definition: vctDynamicVectorBase.h:155
void SetRefWorkspace(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A, vctDynamicVectorBase< _vectorOwnerTypeWorkspace, CISSTNETLIB_DOUBLE > &workspace)
Definition: nmrPInverseEconomy.h:487
CISSTNETLIB_INTEGER nmrSVDEconomy(vctDynamicMatrixBase< _matrixOwnerType, CISSTNETLIB_DOUBLE > &A, nmrSVDEconomyDynamicData &data)
Definition: nmrSVDEconomy.h:801
vctDynamicVectorRef< CISSTNETLIB_DOUBLE > & Workspace(void)
Definition: nmrPInverseEconomy.h:343
Declaration of nmrSVDEconomy.
vctDynamicVectorRef< CISSTNETLIB_DOUBLE > WorkspaceReference
Definition: nmrPInverseEconomy.h:159
Declaration of the template function cmnThrow.
vctDynamicMatrixRef< CISSTNETLIB_DOUBLE > VtReference
Definition: nmrPInverseEconomy.h:157
Definition: nmrPInverseEconomy.h:128
void AllocateOutputWorkspace(bool allocateOutput, bool allocateWorkspace)
Definition: nmrPInverseEconomy.h:194
const bool VCT_COL_MAJOR
Definition: vctForwardDeclarations.h:46
vctDynamicMatrixRef< CISSTNETLIB_DOUBLE > & Vt(void)
Definition: nmrPInverseEconomy.h:340
const vctDynamicMatrixRef< CISSTNETLIB_DOUBLE > & PInverse(void) const
Definition: nmrPInverseEconomy.h:566
vctDynamicMatrixRef< CISSTNETLIB_DOUBLE > & U(void)
Definition: nmrPInverseEconomy.h:337
Rules of exporting.
Definition: vctDynamicVectorBase.h:61
Friend(nmrPInverseEconomyDynamicData &data)
Definition: nmrPInverseEconomy.h:329
nmrPInverseEconomyDynamicData(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A, vctDynamicVectorBase< _vectorOwnerTypeWorkspace, CISSTNETLIB_DOUBLE > &workspace)
Definition: nmrPInverseEconomy.h:401
void SetRef(vctDynamicMatrixBase< _matrixOwnerTypePInverse, CISSTNETLIB_DOUBLE > &pInverse, vctDynamicVectorBase< _vectorOwnerTypeWorkspace, CISSTNETLIB_DOUBLE > &workspace)
Definition: nmrPInverseEconomy.h:510