cisst-saw
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
nmrInverse.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): Anton Deguet
7  Created on: 2006-01-27
8 
9  (C) Copyright 2006-2013 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 _nmrInverse_h
29 #define _nmrInverse_h
30 
31 #include <cisstCommon/cmnThrow.h>
35 
36 // Always include last
38 
39 
83 
84 public:
91 
92  enum {NB = 64};
93 
94 protected:
97 
100 
108 
115 
120  inline void SetDimension(size_type size, bool storageOrder)
121  {
122  SizeMember = size;
123  StorageOrderMember = storageOrder;
124  }
125 
139  inline void AllocatePivotIndicesWorkspace(bool allocatePivotIndices, bool allocateWorkspace)
140  {
141  const size_type maxSize1 = (SizeMember > 1) ? SizeMember : 1;
142 
143  // allocate PivotIndices
144  if (allocatePivotIndices) {
145  this->PivotIndicesMemory.SetSize(maxSize1);
147  } else {
148  this->PivotIndicesMemory.SetSize(0);
149  }
150 
151  // allocate Workspace
152  if (allocateWorkspace) {
153  this->WorkspaceMemory.SetSize(maxSize1 * NB);
155  } else {
156  this->WorkspaceMemory.SetSize(0);
157  }
158  }
159 
160 
168  template <class _vectorOwnerTypePivotIndices>
170  throw(std::runtime_error)
171  {
172  // check sizes and compacity
173  const size_type maxSize1 = (SizeMember > 1) ? SizeMember : 1;
174  if (maxSize1 > pivotIndices.size()) {
175  cmnThrow(std::runtime_error("nmrInverseDynamicData: Size of vector pivotIndices is incorrect."));
176  }
177  if (!pivotIndices.IsCompact()) {
178  cmnThrow(std::runtime_error("nmrInverseDynamicData: Vector pivotIndices must be compact."));
179  }
180  }
181 
182 
189  template <class _vectorOwnerTypeWorkspace>
191  throw(std::runtime_error)
192  {
193  // check sizes and compacity
194  const size_type maxSize1 = (SizeMember > 1) ? SizeMember : 1;
195  if (maxSize1 * NB > workspace.size()) {
196  cmnThrow(std::runtime_error("nmrInverseDynamicData: Size of vector workspace is incorrect."));
197  }
198  if (!workspace.IsCompact()) {
199  cmnThrow(std::runtime_error("nmrInverseDynamicData: Vector workspace must be compact."));
200  }
201  }
202 
203 
204 public:
205 
211  template <class _matrixOwnerTypeA>
212  static inline
214  {
215  return ((A.rows() > 1) ? A.rows() : 1);
216  }
217 
218 
224  template <class _matrixOwnerTypeA>
225  static inline
227  {
228  return ((A.rows() > 1) ? A.rows() : 1) * NB;
229  }
230 
231 
232 #ifndef SWIG
233 #ifndef DOXYGEN
234 
240  class Friend {
241  private:
242  nmrInverseDynamicData & Data;
243  public:
244  Friend(nmrInverseDynamicData &data): Data(data) {
245  }
247  return Data.PivotIndicesReference;
248  }
250  return Data.WorkspaceReference;
251  }
252  inline size_type Size(void) {
253  return Data.SizeMember;
254  }
255  inline size_type StorageOrder(void) {
256  return Data.StorageOrderMember;
257  }
258  };
259  friend class Friend;
260 #endif // DOXYGEN
261 #endif // SWIG
262 
271  SizeMember(static_cast<size_type>(0)),
273  {
274  AllocatePivotIndicesWorkspace(false, false);
275  }
276 
287  nmrInverseDynamicData(size_type size, bool storageOrder)
288  {
289  this->Allocate(size, storageOrder);
290  }
291 
301  template <class _matrixOwnerTypeA>
303  {
304  this->Allocate(A);
305  }
306 
319  template <class _matrixOwnerTypeA,
320  class _vectorOwnerTypePivotIndices,
321  class _vectorOwnerTypeWorkspace>
325  {
326  this->SetRef(A, pivotIndices, workspace);
327  }
328 
339  template <class _matrixOwnerTypeA>
341  {
342  this->Allocate(A.rows(), A.StorageOrder());
343  }
344 
352  void Allocate(size_type size, bool storageOrder)
353  {
354  this->SetDimension(size, storageOrder);
355  this->AllocatePivotIndicesWorkspace(true, true);
356  }
357 
370  template <class _matrixOwnerTypeA,
371  class _vectorOwnerTypePivotIndices,
372  class _vectorOwnerTypeWorkspace>
376  throw(std::runtime_error)
377  {
378  this->SetDimension(A.rows(), A.StorageOrder());
379  this->AllocatePivotIndicesWorkspace(false, false);
380  this->ThrowUnlessPivotIndicesSizeIsCorrect(pivotIndices);
381  this->PivotIndicesReference.SetRef(pivotIndices);
382  this->ThrowUnlessWorkspaceSizeIsCorrect(workspace);
383  this->WorkspaceReference.SetRef(workspace);
384 
385  }
386 };
387 
388 
389 
414 #ifndef SWIG
415 template <vct::size_type _size, bool _storageOrder>
417 {
418 public:
419 #ifndef DOXYGEN
421  enum {MAX_SIZE_1 = (_size > 1) ? _size : 1};
422  enum {NB = 64};
423  enum {LWORK = _size * NB};
424 
425 #endif // DOXYGEN
426 
435 
436 protected:
437  VectorTypePivotIndices PivotIndicesMember;
438  VectorTypeWorkspace WorkspaceMember;
440 public:
441 #ifndef DOXYGEN
442 
448  class Friend {
449  private:
451  public:
453  }
454  inline VectorTypePivotIndices & PivotIndices(void) {
455  return Data.PivotIndicesMember;
456  }
457  inline VectorTypeWorkspace & Workspace(void) {
458  return Data.WorkspaceMember;
459  }
460  };
461  friend class Friend;
462 #endif // DOXYGEN
463 
467 };
468 #endif // SWIG
469 
470 
555 
556 
573 template <class _matrixOwnerType>
575  nmrInverseDynamicData & data)
576  throw (std::runtime_error)
577 {
578  typename nmrInverseDynamicData::Friend dataFriend(data);
579  CISSTNETLIB_INTEGER info;
580 
581  /* check that the matrix is square */
582  if (!A.IsSquare()) {
583  cmnThrow(std::runtime_error("nmrInverse: Input must be a square matrix."));
584  }
585  /* check sizes */
586  if (dataFriend.Size() != A.rows()) {
587  cmnThrow(std::runtime_error("nmrInverse: Size used for Allocate was different."));
588  }
589  /* check that the matrices are compact */
590  if (! A.IsCompact()) {
591  cmnThrow(std::runtime_error("nmrInverse: Requires a compact matrix."));
592  }
593 
594  CISSTNETLIB_INTEGER size = dataFriend.Size();
595  CISSTNETLIB_INTEGER lda = (size > 1) ? size : 1;
596  CISSTNETLIB_INTEGER lwork = dataFriend.Workspace().size();
597  /* call the LAPACK C function */
598 #if defined(CISSTNETLIB_VERSION_MAJOR)
599 #if (CISSTNETLIB_VERSION_MAJOR >= 3)
600  cisstNetlib_dgetrf_(&size, &size,
601  A.Pointer(), &lda,
602  dataFriend.PivotIndices().Pointer(),
603  &info);
604  cisstNetlib_dgetri_(&size,
605  A.Pointer(), &lda,
606  dataFriend.PivotIndices().Pointer(),
607  dataFriend.Workspace().Pointer(),
608  &lwork,
609  &info);
610 #endif
611 #else // no major version
612  dgetrf_(&size, &size,
613  A.Pointer(), &lda,
614  dataFriend.PivotIndices().Pointer(),
615  &info);
616  dgetri_(&size,
617  A.Pointer(), &lda,
618  dataFriend.PivotIndices().Pointer(),
619  dataFriend.Workspace().Pointer(),
620  &lwork,
621  &info);
622 #endif // CISSTNETLIB_VERSION
623  return info;
624 }
625 
626 
627 
643 template <class _matrixOwnerTypeA,
644  class _vectorOwnerTypePivotIndices,
645  class _vectorOwnerTypeWorkspace>
649 {
650  nmrInverseDynamicData data(A, pivotIndices, workspace);
651  return nmrInverse(A, data);
652 }
653 
654 
663 template <class _matrixOwnerTypeA>
665 {
666  nmrInverseDynamicData data(A);
667  return nmrInverse(A, data);
668 }
669 
670 
671 #ifndef SWIG // don't have fixed size containers in Python
672 
695 template <vct::size_type _size, vct::size_type _maxSize1, vct::size_type _lWork, bool _storageOrder>
699 {
700  const CISSTNETLIB_INTEGER maxSize1 = static_cast<CISSTNETLIB_INTEGER>(nmrInverseFixedSizeData<_size, _storageOrder>::MAX_SIZE_1);
701  const CISSTNETLIB_INTEGER lWork = static_cast<CISSTNETLIB_INTEGER>(nmrInverseFixedSizeData<_size, _storageOrder>::LWORK);
702  //Assert if requirement is equal to size provided!
703  CMN_ASSERT(maxSize1 == static_cast<CISSTNETLIB_INTEGER>(_maxSize1));
704  CMN_ASSERT(lWork <= static_cast<CISSTNETLIB_INTEGER>(_lWork));
705 
706  CISSTNETLIB_INTEGER info;
707  CISSTNETLIB_INTEGER lda = _maxSize1;
708  CISSTNETLIB_INTEGER size = _size;
709  CISSTNETLIB_INTEGER lwork = lWork;
710 
711  /* call the LAPACK C function */
712 #if defined(CISSTNETLIB_VERSION_MAJOR)
713 #if (CISSTNETLIB_VERSION_MAJOR >= 3)
714  cisstNetlib_dgetrf_(&size, &size,
715  A.Pointer(), &lda,
716  pivotIndices.Pointer(),
717  &info);
718  cisstNetlib_dgetri_(&size,
719  A.Pointer(), &lda,
720  pivotIndices.Pointer(),
721  workspace.Pointer(),
722  &lwork,
723  &info);
724 #endif
725 #else // no major version
726  dgetrf_(&size, &size,
727  A.Pointer(), &lda,
728  pivotIndices.Pointer(),
729  &info);
730  dgetri_(&size,
731  A.Pointer(), &lda,
732  pivotIndices.Pointer(),
733  workspace.Pointer(),
734  &lwork,
735  &info);
736 #endif // CISSTNETLIB_VERSION
737  return info;
738 }
739 
740 
758 template <vct::size_type _size, bool _storageOrder>
761 {
763  return nmrInverse(A, dataFriend.PivotIndices(), dataFriend.Workspace());
764 }
765 
766 
775 template <vct::size_type _size, bool _storageOrder>
777 {
779  return nmrInverse(A, data);
780 }
781 
782 #endif // SWIG
783 
785 
786 
787 #endif // _nmrInverse_h
788 
vctDynamicVectorRef< CISSTNETLIB_DOUBLE > & Workspace(void)
Definition: nmrInverse.h:249
VectorTypeWorkspace & Workspace(void)
Definition: nmrInverse.h:457
nmrInverseFixedSizeData()
Definition: nmrInverse.h:466
Friend(nmrInverseFixedSizeData< _size, _storageOrder > &data)
Definition: nmrInverse.h:452
void SetDimension(size_type size, bool storageOrder)
Definition: nmrInverse.h:120
Declaration of vctDynamicMatrix.
#define CMN_ASSERT(expr)
Definition: cmnAssert.h:90
bool StorageOrderMember
Definition: nmrInverse.h:113
nmrInverseDynamicData()
Definition: nmrInverse.h:270
Definition: vctDynamicMatrixBase.h:42
VectorTypeWorkspace WorkspaceMember
Definition: nmrInverse.h:438
const bool VCT_ROW_MAJOR
Definition: vctForwardDeclarations.h:43
void Allocate(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A)
Definition: nmrInverse.h:340
vctDynamicVector< CISSTNETLIB_DOUBLE > WorkspaceMemory
Definition: nmrInverse.h:99
vctFixedSizeVector< CISSTNETLIB_INTEGER, MAX_SIZE_1 > VectorTypePivotIndices
Definition: nmrInverse.h:431
Definition: nmrInverse.h:423
vctDynamicVector< CISSTNETLIB_INTEGER > PivotIndicesMemory
Definition: nmrInverse.h:96
Declaration of vctFixedSizeMatrix.
vctFixedSizeVector< CISSTNETLIB_DOUBLE, LWORK > VectorTypeWorkspace
Definition: nmrInverse.h:434
void AllocatePivotIndicesWorkspace(bool allocatePivotIndices, bool allocateWorkspace)
Definition: nmrInverse.h:139
size_type SizeMember
Definition: nmrInverse.h:112
size_t size_type
Definition: vctContainerTraits.h:35
nmrInverseDynamicData(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A)
Definition: nmrInverse.h:302
bool StorageOrder(void) const
Definition: vctDynamicConstMatrixBase.h:656
VectorTypePivotIndices & PivotIndices(void)
Definition: nmrInverse.h:454
VectorTypePivotIndices PivotIndicesMember
Definition: nmrInverse.h:437
Data for Inverse problem (Fixed size).
Definition: nmrInverse.h:416
Friend(nmrInverseDynamicData &data)
Definition: nmrInverse.h:244
void SetRef(size_type size, pointer data, stride_type stride=1)
Definition: vctDynamicVectorRef.h:156
void SetSize(size_type size)
Definition: vctDynamicVector.h:315
Definition: nmrInverse.h:422
Definition: vctDynamicConstMatrixBase.h:77
static size_type WorkspaceSize(const vctDynamicConstMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A)
Definition: nmrInverse.h:226
void SetRef(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A, vctDynamicVectorBase< _vectorOwnerTypePivotIndices, CISSTNETLIB_INTEGER > &pivotIndices, vctDynamicVectorBase< _vectorOwnerTypeWorkspace, CISSTNETLIB_DOUBLE > &workspace)
Definition: nmrInverse.h:373
void Allocate(size_type size, bool storageOrder)
Definition: nmrInverse.h:352
void ThrowUnlessWorkspaceSizeIsCorrect(vctDynamicVectorBase< _vectorOwnerTypeWorkspace, CISSTNETLIB_DOUBLE > &workspace)
Definition: nmrInverse.h:190
size_type size(void) const
Definition: vctDynamicConstVectorBase.h:164
CISSTNETLIB_INTEGER nmrInverse(vctDynamicMatrixBase< _matrixOwnerType, CISSTNETLIB_DOUBLE > &A, nmrInverseDynamicData &data)
Definition: nmrInverse.h:574
Definition: nmrInverse.h:240
size_type Size(void)
Definition: nmrInverse.h:252
vctDynamicVectorRef< CISSTNETLIB_INTEGER > & PivotIndices(void)
Definition: nmrInverse.h:246
size_type StorageOrder(void)
Definition: nmrInverse.h:255
vctDynamicVectorRef< CISSTNETLIB_INTEGER > PivotIndicesReference
Definition: nmrInverse.h:105
size_type rows() const
Definition: vctDynamicConstMatrixBase.h:238
vctFixedSizeMatrix< CISSTNETLIB_DOUBLE, _size, _size, _storageOrder > MatrixTypeA
Definition: nmrInverse.h:428
vct::size_type size_type
Definition: nmrInverse.h:420
#define cmnThrow(a)
Definition: MinimalCmn.h:4
Implementation of a fixed-size matrix using template metaprogramming.
Definition: vctFixedSizeMatrix.h:52
nmrInverseDynamicData(size_type size, bool storageOrder)
Definition: nmrInverse.h:287
pointer Pointer(index_type index=0)
Definition: vctDynamicVectorBase.h:155
Data for Inverse problem (Dynamic).
Definition: nmrInverse.h:82
nmrInverseDynamicData(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A, vctDynamicVectorBase< _vectorOwnerTypePivotIndices, CISSTNETLIB_INTEGER > &pivotIndices, vctDynamicVectorBase< _vectorOwnerTypeWorkspace, CISSTNETLIB_DOUBLE > &workspace)
Definition: nmrInverse.h:322
Definition: nmrInverse.h:92
Definition: nmrInverse.h:448
static size_type PivotIndicesSize(const vctDynamicConstMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A)
Definition: nmrInverse.h:213
Declaration of the template function cmnThrow.
Definition: nmrInverse.h:421
vct::size_type size_type
Definition: nmrInverse.h:90
Rules of exporting.
void ThrowUnlessPivotIndicesSizeIsCorrect(vctDynamicVectorBase< _vectorOwnerTypePivotIndices, CISSTNETLIB_INTEGER > &pivotIndices)
Definition: nmrInverse.h:169
Definition: vctDynamicVectorBase.h:61
vctDynamicVectorRef< CISSTNETLIB_DOUBLE > WorkspaceReference
Definition: nmrInverse.h:106