cisst-saw
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
nmrLU.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-10
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 _nmrLU_h
29 #define _nmrLU_h
30 
31 #include <cisstCommon/cmnThrow.h>
35 
36 // Always include last
38 
39 
85 
86 public:
93 
95 
96 protected:
99 
104 
111 
116  inline void SetDimension(size_type m, size_type n)
117  {
118  MMember = m;
119  NMember = n;
120  }
121 
134  inline void AllocateOutput(bool allocateOutput)
135  {
136  // allocate output
137  if (allocateOutput) {
138  const size_type minmn = (MMember < NMember) ? MMember : NMember;
139  this->OutputMemory.SetSize(minmn);
141  } else {
142  this->OutputMemory.SetSize(0);
143  }
144  }
145 
146 
153  template <class _vectorOwnerTypePivotIndices>
155  throw(std::runtime_error)
156  {
157  // check sizes and compacity
158  const size_type minmn = (MMember < NMember) ? MMember : NMember;
159  if (minmn != pivotIndices.size()) {
160  cmnThrow(std::runtime_error("nmrLUDynamicData: Size of vector pivotIndices is incorrect."));
161  }
162  if (!pivotIndices.IsCompact()) {
163  cmnThrow(std::runtime_error("nmrLUDynamicData: Vector pivotIndices must be compact."));
164  }
165  }
166 
167 
168 public:
169 
177  template <class _matrixOwnerTypeA>
178  static inline
180  {
181  nsize_type matrixSize(A.rows(), A.rows());
182  return matrixSize;
183  }
184 
192  template <class _matrixOwnerTypeA>
193  static inline
195  {
196  const size_type minmn = (A.rows() < A.cols()) ? A.rows() : A.cols();
197  nsize_type matrixSize(A.rows(), minmn);
198  return matrixSize;
199  }
200 
208  template <class _matrixOwnerTypeA>
209  static inline
211  {
212  const size_type minmn = (A.rows() < A.cols()) ? A.rows() : A.cols();
213  nsize_type matrixSize(minmn, A.cols());
214  return matrixSize;
215  }
216 
226  template <class _matrixOwnerTypeA, class _vectorOwnerTypePivotIndices, class _matrixOwnerTypeP>
227  static inline
232  throw(std::runtime_error)
233  {
234  const size_type minmn = (A.rows() < A.cols()) ? A.rows() : A.cols();
235  // check sizes
236  if (pivotIndices.size() != minmn) {
237  cmnThrow(std::runtime_error("nmrLUDynamicData::UpdateMatrixP: Size of vector pivotIndices is incorrect."));
238  }
239  if (! P.IsSquare(A.rows())) {
240  cmnThrow(std::runtime_error("nmrLUDynamicData::UpdateMatrixP: Size of matrix P is incorrect."));
241  }
242  // update permutation matrix
243  P.SetAll(0.0);
244  P.Diagonal().SetAll(1.0);
245  size_type rowIndex, colIndex;
246  for (rowIndex = 0; rowIndex < minmn; ++rowIndex) {
247  colIndex = pivotIndices[rowIndex] - 1;
248  P.ExchangeColumns(rowIndex, colIndex);
249  }
250  return P;
251  }
252 
267  template <class _matrixOwnerTypeA, class _matrixOwnerTypeL, class _matrixOwnerTypeU>
268  static inline
272  throw(std::runtime_error)
273  {
274  const size_type rows = A.rows();
275  const size_type cols = A.cols();
276  size_type rowIndex, colIndex;
277  L.SetAll(0.0);
278  L.Diagonal().SetAll(1.0);
279  U.SetAll(0.0);
280  for (rowIndex = 0; rowIndex < rows; ++rowIndex) {
281  for (colIndex = 0; colIndex < cols; ++colIndex) {
282  if (rowIndex > colIndex) {
283  L.Element(rowIndex, colIndex) = A.Element(rowIndex, colIndex);
284  } else {
285  U.Element(rowIndex, colIndex) = A.Element(rowIndex, colIndex);
286  }
287  }
288  }
289 
290  }
291 
292 
293 #ifndef SWIG
294 #ifndef DOXYGEN
295 
301  class Friend {
302  private:
303  nmrLUDynamicData & Data;
304  public:
305  Friend(nmrLUDynamicData &data): Data(data) {
306  }
308  return Data.PivotIndicesReference;
309  }
310  inline size_type M(void) {
311  return Data.MMember;
312  }
313  inline size_type N(void) {
314  return Data.NMember;
315  }
316  };
317  friend class Friend;
318 #endif // DOXYGEN
319 #endif // SWIG
320 
329  MMember(static_cast<size_type>(0)),
330  NMember(static_cast<size_type>(0))
331  {
332  AllocateOutput(false);
333  }
334 
345  {
346  this->Allocate(m, n);
347  }
348 
358  template <class _matrixOwnerTypeA>
360  {
361  this->Allocate(A);
362  }
363 
375  template <class _matrixOwnerTypeA,
376  class _vectorOwnerTypePivotIndices>
379  {
380  this->SetRef(A, pivotIndices);
381  }
382 
392  template <class _matrixOwnerTypeA>
394  {
395  this->Allocate(A.rows(), A.cols());
396  }
397 
406  {
407  this->SetDimension(m, n);
408  this->AllocateOutput(true);
409  }
410 
422  template <class _matrixOwnerTypeA,
423  class _vectorOwnerTypePivotIndices>
426  throw(std::runtime_error)
427  {
428  this->SetDimension(A.rows(), A.cols());
429  this->AllocateOutput(false);
430  this->ThrowUnlessOutputSizeIsCorrect(pivotIndices);
431  this->PivotIndicesReference.SetRef(pivotIndices);
432  }
433 
438  return PivotIndicesReference;
439  }
440 };
441 
442 
443 
468 #ifndef SWIG
469 template <vct::size_type _rows, vct::size_type _cols>
471 {
472 public:
473 #ifndef DOXYGEN
475  enum {MIN_MN = (_rows < _cols) ? _rows : _cols};
476 #endif // DOXYGEN
477 
492 
493 protected:
494  VectorTypePivotIndices PivotIndicesMember;
496 public:
497 #ifndef DOXYGEN
498 
504  class Friend {
505  private:
507  public:
509  }
510  inline VectorTypePivotIndices & PivotIndices(void) {
511  return Data.PivotIndicesMember;
512  }
513  };
514  friend class Friend;
515 #endif // DOXYGEN
516 
520 
524  inline const VectorTypePivotIndices & PivotIndices(void) const {
525  return PivotIndicesMember;
526  }
527 
528 
537  inline static MatrixTypeP &
538  UpdateMatrixP(const VectorTypePivotIndices & pivotIndices,
539  MatrixTypeP & P)
540  throw(std::runtime_error)
541  {
542  // update permutation matrix
543  P.SetAll(0.0);
544  P.Diagonal().SetAll(1.0);
545  size_type rowIndex, colIndex;
546  for (rowIndex = 0; rowIndex < MIN_MN; ++rowIndex) {
547  colIndex = pivotIndices[rowIndex] - 1;
548  P.ExchangeColumns(rowIndex, colIndex);
549  }
550  return P;
551  }
552 
553 
568  static inline
569  void UpdateMatrixLU(const MatrixTypeA & A,
570  MatrixTypeL & L,
571  MatrixTypeU & U)
572  throw(std::runtime_error)
573  {
574  vct::size_type rowIndex, colIndex;
575  L.SetAll(0.0);
576  L.Diagonal().SetAll(1.0);
577  U.SetAll(0.0);
578  for (rowIndex = 0; rowIndex < _rows; ++rowIndex) {
579  for (colIndex = 0; colIndex < _cols; ++colIndex) {
580  if (rowIndex > colIndex) {
581  L.Element(rowIndex, colIndex) = A.Element(rowIndex, colIndex);
582  } else {
583  U.Element(rowIndex, colIndex) = A.Element(rowIndex, colIndex);
584  }
585  }
586  }
587  }
588 };
589 #endif // SWIG
590 
591 
592 
699 
700 
719 template <class _matrixOwnerType>
721  nmrLUDynamicData & data)
722  throw (std::runtime_error)
723 {
724  typename nmrLUDynamicData::Friend dataFriend(data);
725  CISSTNETLIB_INTEGER info;
726 
727  /* check that storage order is VCT_COL_MAJOR */
728  if (!A.IsColMajor()) {
729  cmnThrow(std::runtime_error("nmrLU: Input must use VCT_COL_MAJOR storage order."));
730  }
731  /* check sizes */
732  if ((dataFriend.M() != A.rows()) || (dataFriend.N() != A.cols())) {
733  cmnThrow(std::runtime_error("nmrLU: Size used for Allocate was different."));
734  }
735  /* check that the matrices are compact */
736  if (! A.IsCompact()) {
737  cmnThrow(std::runtime_error("nmrLU: Requires a compact matrix."));
738  }
739 
740  CISSTNETLIB_INTEGER m = dataFriend.M();
741  CISSTNETLIB_INTEGER n = dataFriend.N();
742  CISSTNETLIB_INTEGER lda = (m > 1) ? m : 1;
743 
744  /* call the LAPACK C function */
745 #if defined(CISSTNETLIB_VERSION_MAJOR)
746 #if (CISSTNETLIB_VERSION_MAJOR >= 3)
747  cisstNetlib_dgetrf_(&m, &n,
748  A.Pointer(), &lda,
749  dataFriend.PivotIndices().Pointer(), &info);
750 #endif
751 #else // no major version
752  dgetrf_(&m, &n,
753  A.Pointer(), &lda,
754  dataFriend.PivotIndices().Pointer(), &info);
755 #endif // CISSTNETLIB_VERSION
756  return info;
757 }
758 
759 
760 
774 template <class _matrixOwnerTypeA, class _vectorOwnerTypePivotIndices>
777 {
778  nmrLUDynamicData data(A, pivotIndices);
779  return nmrLU(A, data);
780 }
781 
782 
783 #ifndef SWIG // don't have fixed size containers in Python
784 
810 template <vct::size_type _rows, vct::size_type _cols, vct::size_type _minmn>
813 {
814  const CISSTNETLIB_INTEGER minmn = static_cast<CISSTNETLIB_INTEGER>(nmrLUFixedSizeData<_rows, _cols>::MIN_MN);
815  //Assert if requirement is equal to size provided!
816  CMN_ASSERT(minmn == static_cast<CISSTNETLIB_INTEGER>(_minmn));
817 
818  CISSTNETLIB_INTEGER info;
819  CISSTNETLIB_INTEGER lda = (_rows> 1) ? _rows : 1;
820  CISSTNETLIB_INTEGER m = _rows;
821  CISSTNETLIB_INTEGER n = _cols;
822 
823  /* call the LAPACK C function */
824 #if defined(CISSTNETLIB_VERSION_MAJOR)
825 #if (CISSTNETLIB_VERSION_MAJOR >= 3)
826  cisstNetlib_dgetrf_(&m, &n,
827  A.Pointer(), &lda,
828  pivotIndices.Pointer(), &info);
829 #endif
830 #else // no major version
831  dgetrf_(&m, &n,
832  A.Pointer(), &lda,
833  pivotIndices.Pointer(), &info);
834 #endif // CISSTNETLIB_VERSION
835  return info;
836 }
837 
838 
860 template <vct::size_type _rows, vct::size_type _cols>
863 {
864  typename nmrLUFixedSizeData<_rows, _cols>::Friend dataFriend(data);
865  return nmrLU(A, dataFriend.PivotIndices());
866 }
867 #endif // SWIG
868 
870 
871 
872 #endif // _nmrLU_h
873 
size_type N(void)
Definition: nmrLU.h:313
static MatrixTypeP & UpdateMatrixP(const VectorTypePivotIndices &pivotIndices, MatrixTypeP &P)
Definition: nmrLU.h:538
static void UpdateMatrixLU(const vctDynamicConstMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A, vctDynamicMatrixBase< _matrixOwnerTypeL, CISSTNETLIB_DOUBLE > &L, vctDynamicMatrixBase< _matrixOwnerTypeU, CISSTNETLIB_DOUBLE > &U)
Definition: nmrLU.h:269
VectorTypePivotIndices PivotIndicesMember
Definition: nmrLU.h:494
vctDynamicVector< CISSTNETLIB_INTEGER > OutputMemory
Definition: nmrLU.h:98
vctFixedSizeMatrix< CISSTNETLIB_DOUBLE, MIN_MN, _cols, VCT_COL_MAJOR > MatrixTypeU
Definition: nmrLU.h:491
vct::size_type size_type
Definition: nmrLU.h:474
Declaration of vctDynamicMatrix.
#define CMN_ASSERT(expr)
Definition: cmnAssert.h:90
void SetDimension(size_type m, size_type n)
Definition: nmrLU.h:116
static nsize_type MatrixLSize(const vctDynamicConstMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A)
Definition: nmrLU.h:194
Definition: vctDynamicMatrixBase.h:42
void SetRef(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A, vctDynamicVectorBase< _vectorOwnerTypePivotIndices, CISSTNETLIB_INTEGER > &pivotIndices)
Definition: nmrLU.h:424
Data of LU problem (Dynamic).
Definition: nmrLU.h:84
Friend(nmrLUDynamicData &data)
Definition: nmrLU.h:305
nmrLUDynamicData(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A, vctDynamicVectorBase< _vectorOwnerTypePivotIndices, CISSTNETLIB_INTEGER > &pivotIndices)
Definition: nmrLU.h:377
Declaration of vctFixedSizeMatrix.
Definition: nmrLU.h:475
size_type NMember
Definition: nmrLU.h:109
value_type SetAll(const value_type value)
Definition: vctFixedSizeMatrixBase.h:421
size_t size_type
Definition: vctContainerTraits.h:35
vctFixedSizeMatrix< CISSTNETLIB_DOUBLE, _rows, MIN_MN, VCT_COL_MAJOR > MatrixTypeL
Definition: nmrLU.h:488
Definition: nmrLU.h:504
void SetRef(size_type size, pointer data, stride_type stride=1)
Definition: vctDynamicVectorRef.h:156
VectorTypePivotIndices & PivotIndices(void)
Definition: nmrLU.h:510
static void UpdateMatrixLU(const MatrixTypeA &A, MatrixTypeL &L, MatrixTypeU &U)
Definition: nmrLU.h:569
void SetSize(size_type size)
Definition: vctDynamicVector.h:315
Definition: vctDynamicConstMatrixBase.h:77
Implementation of a fixed-size vector using template metaprogramming.
Definition: vctFixedSizeVector.h:52
vctFixedSizeVector< CISSTNETLIB_INTEGER, MIN_MN > VectorTypePivotIndices
Definition: nmrLU.h:482
nmrLUFixedSizeData()
Definition: nmrLU.h:519
vctFixedSizeVector< size_type, 2 > nsize_type
Definition: nmrLU.h:94
void ThrowUnlessOutputSizeIsCorrect(vctDynamicVectorBase< _vectorOwnerTypePivotIndices, CISSTNETLIB_INTEGER > &pivotIndices)
Definition: nmrLU.h:154
size_type rows() const
Definition: vctDynamicConstMatrixBase.h:238
size_type cols() const
Definition: vctDynamicConstMatrixBase.h:243
vctFixedSizeMatrix< CISSTNETLIB_DOUBLE, _rows, _cols, VCT_COL_MAJOR > MatrixTypeA
Definition: nmrLU.h:479
vctFixedSizeMatrix< CISSTNETLIB_DOUBLE, _rows, _rows, VCT_COL_MAJOR > MatrixTypeP
Definition: nmrLU.h:485
#define cmnThrow(a)
Definition: MinimalCmn.h:4
Implementation of a fixed-size matrix using template metaprogramming.
Definition: vctFixedSizeMatrix.h:52
Friend(nmrLUFixedSizeData< _rows, _cols > &data)
Definition: nmrLU.h:508
nmrLUDynamicData(size_type m, size_type n)
Definition: nmrLU.h:344
pointer Pointer(index_type index=0)
Definition: vctDynamicVectorBase.h:155
void Allocate(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A)
Definition: nmrLU.h:393
size_type M(void)
Definition: nmrLU.h:310
vct::size_type size_type
Definition: nmrLU.h:92
static nsize_type MatrixPSize(const vctDynamicConstMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A)
Definition: nmrLU.h:179
vctDynamicVectorRef< CISSTNETLIB_INTEGER > & PivotIndices(void)
Definition: nmrLU.h:307
Definition: vctDynamicConstVectorBase.h:77
Data of LU problem (Fixed size).
Definition: nmrLU.h:470
void Allocate(size_type m, size_type n)
Definition: nmrLU.h:405
CISSTNETLIB_INTEGER nmrLU(vctDynamicMatrixBase< _matrixOwnerType, CISSTNETLIB_DOUBLE > &A, nmrLUDynamicData &data)
Definition: nmrLU.h:720
nmrLUDynamicData()
Definition: nmrLU.h:328
static nsize_type MatrixUSize(const vctDynamicConstMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A)
Definition: nmrLU.h:210
Declaration of the template function cmnThrow.
size_type MMember
Definition: nmrLU.h:108
void AllocateOutput(bool allocateOutput)
Definition: nmrLU.h:134
Definition: nmrLU.h:301
nmrLUDynamicData(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A)
Definition: nmrLU.h:359
Rules of exporting.
static vctDynamicMatrixBase< _matrixOwnerTypeP, CISSTNETLIB_DOUBLE > & UpdateMatrixP(const vctDynamicConstMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A, const vctDynamicConstVectorBase< _vectorOwnerTypePivotIndices, CISSTNETLIB_INTEGER > &pivotIndices, vctDynamicMatrixBase< _matrixOwnerTypeP, CISSTNETLIB_DOUBLE > &P)
Definition: nmrLU.h:229
vctDynamicVectorRef< CISSTNETLIB_INTEGER > PivotIndicesReference
Definition: nmrLU.h:103
Definition: vctDynamicVectorBase.h:61
const VectorTypePivotIndices & PivotIndices(void) const
Definition: nmrLU.h:524
const vctDynamicVectorRef< CISSTNETLIB_INTEGER > & PivotIndices(void) const
Definition: nmrLU.h:437