cisst-saw
Loading...
Searching...
No Matches
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 Author(s): Anton Deguet
6 Created on: 2006-01-27
7
8 (C) Copyright 2006-2019 Johns Hopkins University (JHU), All Rights Reserved.
9
10--- begin cisst license - do not edit ---
11
12This software is provided "as is" under an open source license, with
13no warranty. The complete license can be found in license.txt and
14http://www.cisst.org/cisst/license.txt.
15
16--- end cisst license ---
17*/
18
19
24
25
26#ifndef _nmrInverse_h
27#define _nmrInverse_h
28
33
34// Always include last
36
37
81
82public:
89
90 enum {NB = 64};
91
92protected:
95
98
106
113
118 inline void SetDimension(size_type size, bool storageOrder)
119 {
121 StorageOrderMember = storageOrder;
122 }
123
137 inline void AllocatePivotIndicesWorkspace(bool allocatePivotIndices, bool allocateWorkspace)
138 {
139 const size_type maxSize1 = (SizeMember > 1) ? SizeMember : 1;
140
141 // allocate PivotIndices
142 if (allocatePivotIndices) {
143 this->PivotIndicesMemory.SetSize(maxSize1);
144 this->PivotIndicesReference.SetRef(this->PivotIndicesMemory);
145 } else {
146 this->PivotIndicesMemory.SetSize(0);
147 }
148
149 // allocate Workspace
150 if (allocateWorkspace) {
151 this->WorkspaceMemory.SetSize(maxSize1 * NB);
152 this->WorkspaceReference.SetRef(this->WorkspaceMemory);
153 } else {
154 this->WorkspaceMemory.SetSize(0);
155 }
156 }
157
158
166 template <class _vectorOwnerTypePivotIndices>
168 CISST_THROW(std::runtime_error)
169 {
170 // check sizes and compacity
171 const size_type maxSize1 = (SizeMember > 1) ? SizeMember : 1;
172 if (maxSize1 > pivotIndices.size()) {
173 cmnThrow(std::runtime_error("nmrInverseDynamicData: Size of vector pivotIndices is incorrect."));
174 }
175 if (!pivotIndices.IsCompact()) {
176 cmnThrow(std::runtime_error("nmrInverseDynamicData: Vector pivotIndices must be compact."));
177 }
178 }
179
180
187 template <class _vectorOwnerTypeWorkspace>
189 CISST_THROW(std::runtime_error)
190 {
191 // check sizes and compacity
192 const size_type maxSize1 = (SizeMember > 1) ? SizeMember : 1;
193 if (maxSize1 * NB > workspace.size()) {
194 cmnThrow(std::runtime_error("nmrInverseDynamicData: Size of vector workspace is incorrect."));
195 }
196 if (!workspace.IsCompact()) {
197 cmnThrow(std::runtime_error("nmrInverseDynamicData: Vector workspace must be compact."));
198 }
199 }
200
201
202public:
203
209 template <class _matrixOwnerTypeA>
210 static inline
212 {
213 return ((A.rows() > 1) ? A.rows() : 1);
214 }
215
216
222 template <class _matrixOwnerTypeA>
223 static inline
225 {
226 return ((A.rows() > 1) ? A.rows() : 1) * NB;
227 }
228
229
230#ifndef SWIG
231#ifndef DOXYGEN
238 class Friend {
239 private:
241 public:
242 Friend(nmrInverseDynamicData &data): Data(data) {
243 }
245 return Data.PivotIndicesReference;
246 }
248 return Data.WorkspaceReference;
249 }
250 inline size_type Size(void) {
251 return Data.SizeMember;
252 }
253 inline size_type StorageOrder(void) {
254 return Data.StorageOrderMember;
255 }
256 };
257 friend class Friend;
258#endif // DOXYGEN
259#endif // SWIG
260
274
286 {
287 this->Allocate(size, storageOrder);
288 }
289
299 template <class _matrixOwnerTypeA>
304
317 template <class _matrixOwnerTypeA,
318 class _vectorOwnerTypePivotIndices,
319 class _vectorOwnerTypeWorkspace>
326
337 template <class _matrixOwnerTypeA>
339 {
340 this->Allocate(A.rows(), A.StorageOrder());
341 }
342
350 void Allocate(size_type size, bool storageOrder)
351 {
352 this->SetDimension(size, storageOrder);
353 this->AllocatePivotIndicesWorkspace(true, true);
354 }
355
368 template <class _matrixOwnerTypeA,
369 class _vectorOwnerTypePivotIndices,
370 class _vectorOwnerTypeWorkspace>
374 CISST_THROW(std::runtime_error)
375 {
376 this->SetDimension(A.rows(), A.StorageOrder());
377 this->AllocatePivotIndicesWorkspace(false, false);
378 this->ThrowUnlessPivotIndicesSizeIsCorrect(pivotIndices);
379 this->PivotIndicesReference.SetRef(pivotIndices);
380 this->ThrowUnlessWorkspaceSizeIsCorrect(workspace);
381 this->WorkspaceReference.SetRef(workspace);
382
383 }
384};
385
386
387
412#ifndef SWIG
413template <vct::size_type _size, bool _storageOrder>
415{
416public:
417#ifndef DOXYGEN
419 enum {MAX_SIZE_1 = (_size > 1) ? _size : 1};
420 enum {NB = 64};
421 enum {LWORK = _size * NB};
422
423#endif // DOXYGEN
433
434protected:
437
438public:
439#ifndef DOXYGEN
446 class Friend {
447 private:
449 public:
453 return Data.PivotIndicesMember;
454 }
456 return Data.WorkspaceMember;
457 }
458 };
459 friend class Friend;
460#endif // DOXYGEN
461
465};
466#endif // SWIG
467
468
553
554
571template <class _matrixOwnerType>
574 CISST_THROW(std::runtime_error)
575{
576 typename nmrInverseDynamicData::Friend dataFriend(data);
577 CISSTNETLIB_INTEGER info;
578
579 /* check that the matrix is square */
580 if (!A.IsSquare()) {
581 cmnThrow(std::runtime_error("nmrInverse: Input must be a square matrix."));
582 }
583 /* check sizes */
584 if (dataFriend.Size() != A.rows()) {
585 cmnThrow(std::runtime_error("nmrInverse: Size used for Allocate was different."));
586 }
587 /* check that the matrices are compact */
588 if (! A.IsCompact()) {
589 cmnThrow(std::runtime_error("nmrInverse: Requires a compact matrix."));
590 }
591
592 CISSTNETLIB_INTEGER size = dataFriend.Size();
593 CISSTNETLIB_INTEGER lda = (size > 1) ? size : 1;
594 CISSTNETLIB_INTEGER lwork = dataFriend.Workspace().size();
595 /* call the LAPACK C function */
596#if defined(CISSTNETLIB_VERSION_MAJOR)
597#if (CISSTNETLIB_VERSION_MAJOR >= 3)
598 cisstNetlib_dgetrf_(&size, &size,
599 A.Pointer(), &lda,
600 dataFriend.PivotIndices().Pointer(),
601 &info);
602 cisstNetlib_dgetri_(&size,
603 A.Pointer(), &lda,
604 dataFriend.PivotIndices().Pointer(),
605 dataFriend.Workspace().Pointer(),
606 &lwork,
607 &info);
608#endif
609#else // no major version
610 dgetrf_(&size, &size,
611 A.Pointer(), &lda,
612 dataFriend.PivotIndices().Pointer(),
613 &info);
614 dgetri_(&size,
615 A.Pointer(), &lda,
616 dataFriend.PivotIndices().Pointer(),
617 dataFriend.Workspace().Pointer(),
618 &lwork,
619 &info);
620#endif // CISSTNETLIB_VERSION
621 return info;
622}
623
624
625
641template <class _matrixOwnerTypeA,
642 class _vectorOwnerTypePivotIndices,
643 class _vectorOwnerTypeWorkspace>
651
652
661template <class _matrixOwnerTypeA>
663{
664 nmrInverseDynamicData data(A);
665 return nmrInverse(A, data);
666}
667
668
669#ifndef SWIG // don't have fixed size containers in Python
670
693template <vct::size_type _size, vct::size_type _maxSize1, vct::size_type _lWork, bool _storageOrder>
697{
698#if CMN_ASSERT_IS_DEFINED
699 const CISSTNETLIB_INTEGER maxSize1 = static_cast<CISSTNETLIB_INTEGER>(nmrInverseFixedSizeData<_size, _storageOrder>::MAX_SIZE_1);
700#endif
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
758template <vct::size_type _size, bool _storageOrder>
765
766
775template <vct::size_type _size, bool _storageOrder>
781
782#endif // SWIG
783
785
786
787#endif // _nmrInverse_h
Definition nmrInverse.h:238
vctDynamicVectorRef< CISSTNETLIB_INTEGER > & PivotIndices(void)
Definition nmrInverse.h:244
vctDynamicVectorRef< CISSTNETLIB_DOUBLE > & Workspace(void)
Definition nmrInverse.h:247
Friend(nmrInverseDynamicData &data)
Definition nmrInverse.h:242
size_type StorageOrder(void)
Definition nmrInverse.h:253
size_type Size(void)
Definition nmrInverse.h:250
Data for Inverse problem (Dynamic).
Definition nmrInverse.h:80
vctDynamicVector< CISSTNETLIB_INTEGER > PivotIndicesMemory
Definition nmrInverse.h:94
void SetDimension(size_type size, bool storageOrder)
Definition nmrInverse.h:118
nmrInverseDynamicData(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A)
Definition nmrInverse.h:300
void ThrowUnlessWorkspaceSizeIsCorrect(vctDynamicVectorBase< _vectorOwnerTypeWorkspace, CISSTNETLIB_DOUBLE > &workspace) CISST_THROW(std
Definition nmrInverse.h:188
void Allocate(size_type size, bool storageOrder)
Definition nmrInverse.h:350
bool StorageOrderMember
Definition nmrInverse.h:111
nmrInverseDynamicData(size_type size, bool storageOrder)
Definition nmrInverse.h:285
vctDynamicVectorRef< CISSTNETLIB_DOUBLE > WorkspaceReference
Definition nmrInverse.h:104
void SetRef(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A, vctDynamicVectorBase< _vectorOwnerTypePivotIndices, CISSTNETLIB_INTEGER > &pivotIndices, vctDynamicVectorBase< _vectorOwnerTypeWorkspace, CISSTNETLIB_DOUBLE > &workspace) CISST_THROW(std
Definition nmrInverse.h:371
nmrInverseDynamicData(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A, vctDynamicVectorBase< _vectorOwnerTypePivotIndices, CISSTNETLIB_INTEGER > &pivotIndices, vctDynamicVectorBase< _vectorOwnerTypeWorkspace, CISSTNETLIB_DOUBLE > &workspace)
Definition nmrInverse.h:320
nmrInverseDynamicData()
Definition nmrInverse.h:268
void ThrowUnlessPivotIndicesSizeIsCorrect(vctDynamicVectorBase< _vectorOwnerTypePivotIndices, CISSTNETLIB_INTEGER > &pivotIndices) CISST_THROW(std
Definition nmrInverse.h:167
static size_type PivotIndicesSize(const vctDynamicConstMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A)
Definition nmrInverse.h:211
void AllocatePivotIndicesWorkspace(bool allocatePivotIndices, bool allocateWorkspace)
Definition nmrInverse.h:137
@ NB
Definition nmrInverse.h:90
vctDynamicVectorRef< CISSTNETLIB_INTEGER > PivotIndicesReference
Definition nmrInverse.h:103
static size_type WorkspaceSize(const vctDynamicConstMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A)
Definition nmrInverse.h:224
size_type SizeMember
Definition nmrInverse.h:110
vctDynamicVector< CISSTNETLIB_DOUBLE > WorkspaceMemory
Definition nmrInverse.h:97
vct::size_type size_type
Definition nmrInverse.h:88
void Allocate(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A)
Definition nmrInverse.h:338
Definition nmrInverse.h:446
VectorTypeWorkspace & Workspace(void)
Definition nmrInverse.h:455
Friend(nmrInverseFixedSizeData< _size, _storageOrder > &data)
Definition nmrInverse.h:450
VectorTypePivotIndices & PivotIndices(void)
Definition nmrInverse.h:452
Data for Inverse problem (Fixed size).
Definition nmrInverse.h:415
vctFixedSizeMatrix< CISSTNETLIB_DOUBLE, _size, _size, _storageOrder > MatrixTypeA
Definition nmrInverse.h:426
vct::size_type size_type
Definition nmrInverse.h:418
@ LWORK
Definition nmrInverse.h:421
VectorTypeWorkspace WorkspaceMember
Definition nmrInverse.h:436
nmrInverseFixedSizeData()
Definition nmrInverse.h:464
VectorTypePivotIndices PivotIndicesMember
Definition nmrInverse.h:435
vctFixedSizeVector< CISSTNETLIB_DOUBLE, LWORK > VectorTypeWorkspace
Definition nmrInverse.h:432
vctFixedSizeVector< CISSTNETLIB_INTEGER, MAX_SIZE_1 > VectorTypePivotIndices
Definition nmrInverse.h:429
@ NB
Definition nmrInverse.h:420
@ MAX_SIZE_1
Definition nmrInverse.h:419
Definition vctForwardDeclarations.h:145
Definition vctDynamicMatrixBase.h:43
Definition vctDynamicVectorBase.h:62
pointer Pointer(index_type index=0)
Definition vctDynamicVectorBase.h:155
Definition vctForwardDeclarations.h:131
Dynamic vector referencing existing memory.
Definition vctDynamicVectorRef.h:78
void SetRef(size_type size, pointer data, stride_type stride=1)
Definition vctDynamicVectorRef.h:156
pointer Pointer(size_type rowIndex, size_type colIndex)
Definition vctFixedSizeMatrixBase.h:161
Implementation of a fixed-size matrix using template metaprogramming.
Definition vctFixedSizeMatrix.h:54
pointer Pointer(size_type index=0)
Definition vctFixedSizeVectorBase.h:226
Implementation of a fixed-size vector using template metaprogramming.
Definition vctFixedSizeVector.h:54
#define CMN_ASSERT(expr)
Definition cmnAssert.h:97
#define CISST_THROW(exceptionParameter)
Somewhat portable compilation warning message. This works with very recent versions of gcc (4....
Definition cmnPortability.h:559
Declaration of the template function cmnThrow.
void cmnThrow(const _exceptionType &except, cmnLogLevel lod=CMN_LOG_LEVEL_INIT_ERROR)
Definition cmnThrow.h:76
size_t size_type
Definition vctContainerTraits.h:35
Rules of exporting.
CISSTNETLIB_INTEGER nmrInverse(vctDynamicMatrixBase< _matrixOwnerType, CISSTNETLIB_DOUBLE > &A, nmrInverseDynamicData &data) CISST_THROW(std
Definition nmrInverse.h:572
size_type size(void) const
Definition vctDynamicConstMatrixBase.h:228
Declaration of vctDynamicMatrix.
Declaration of vctFixedSizeMatrix.
const bool VCT_ROW_MAJOR
Definition vctForwardDeclarations.h:41