cisst-saw
Loading...
Searching...
No Matches
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-2018 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 _nmrPInverseEconomy_h
27#define _nmrPInverseEconomy_h
28
34
35// Always include last
37
118
119
120/*
121 ****************************************************************************
122 DYNAMIC SIZE
123 ****************************************************************************
124 */
125
129
130public:
136 typedef unsigned int size_type;
137
138protected:
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) {
198 OutputMemory.SetSize(MMember * NMember);
202 OutputMemory.Pointer());
203 } else {
204 OutputMemory.SetSize(0);
205 }
206 // allocate workspace
207 if (allocateWorkspace) {
208 this->WorkspaceMemory.SetSize(WorkspaceSize(MMember, NMember));
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;
228 (StorageOrderMember) ? minmn : 1,
230 workspace.Pointer(current));
231 current += (MMember * minmn);
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 CISST_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 CISST_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
289public:
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>
316
317#ifndef SWIG
318#ifndef DOXYGEN
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>
406
418 template <class _matrixOwnerTypeA,
419 class _matrixOwnerTypePInverse,
420 class _vectorOwnerTypeWorkspace>
427
441 template <class _matrixOwnerTypeA, class _matrixOwnerTypePInverse>
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
548public:
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 }
569
570};
571
589template <class _matrixOwnerType>
591 nmrPInverseEconomyDynamicData &data) CISST_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
645template <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
668template <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
static Type Tolerance(void)
Definition cmnTypeTraits.h:170
Definition nmrPInverseEconomy.h:325
size_type M(void)
Definition nmrPInverseEconomy.h:346
vctDynamicVectorRef< CISSTNETLIB_DOUBLE > & S(void)
Definition nmrPInverseEconomy.h:331
vctDynamicMatrixRef< CISSTNETLIB_DOUBLE > & Vt(void)
Definition nmrPInverseEconomy.h:340
Friend(nmrPInverseEconomyDynamicData &data)
Definition nmrPInverseEconomy.h:329
vctDynamicVectorRef< CISSTNETLIB_DOUBLE > & Workspace(void)
Definition nmrPInverseEconomy.h:343
bool StorageOrder(void)
Definition nmrPInverseEconomy.h:352
vctDynamicMatrixRef< CISSTNETLIB_DOUBLE > & U(void)
Definition nmrPInverseEconomy.h:337
vctDynamicMatrixRef< CISSTNETLIB_DOUBLE > & PInverse(void)
Definition nmrPInverseEconomy.h:334
size_type N(void)
Definition nmrPInverseEconomy.h:349
Definition nmrPInverseEconomy.h:128
static size_type WorkspaceSize(size_type m, size_type n)
Definition nmrPInverseEconomy.h:295
void AllocateOutputWorkspace(bool allocateOutput, bool allocateWorkspace)
Definition nmrPInverseEconomy.h:194
vctDynamicVectorRef< CISSTNETLIB_DOUBLE > WorkspaceReference
Definition nmrPInverseEconomy.h:159
nmrPInverseEconomyDynamicData(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &CMN_UNUSED(A), vctDynamicMatrixBase< _matrixOwnerTypePInverse, CISSTNETLIB_DOUBLE > &pInverse)
Definition nmrPInverseEconomy.h:442
unsigned int size_type
Definition nmrPInverseEconomy.h:136
void SetRefWorkspace(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A, vctDynamicVectorBase< _vectorOwnerTypeWorkspace, CISSTNETLIB_DOUBLE > &workspace)
Definition nmrPInverseEconomy.h:487
vctDynamicMatrixRef< CISSTNETLIB_DOUBLE > PInverseReference
Definition nmrPInverseEconomy.h:155
vctDynamicMatrixRef< CISSTNETLIB_DOUBLE > VtReference
Definition nmrPInverseEconomy.h:157
vctDynamicVectorRef< CISSTNETLIB_DOUBLE > SReference
Definition nmrPInverseEconomy.h:158
nmrPInverseEconomyDynamicData(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &CMN_UNUSED(A), vctDynamicMatrixBase< _matrixOwnerTypePInverse, CISSTNETLIB_DOUBLE > &pInverse, vctDynamicVectorBase< _vectorOwnerTypeWorkspace, CISSTNETLIB_DOUBLE > &workspace)
Definition nmrPInverseEconomy.h:421
const vctDynamicVectorRef< CISSTNETLIB_DOUBLE > & S(void) const
Definition nmrPInverseEconomy.h:557
size_type MMember
Definition nmrPInverseEconomy.h:165
nmrPInverseEconomyDynamicData(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A, vctDynamicVectorBase< _vectorOwnerTypeWorkspace, CISSTNETLIB_DOUBLE > &workspace)
Definition nmrPInverseEconomy.h:401
vctDynamicVector< CISSTNETLIB_DOUBLE > WorkspaceMemory
Definition nmrPInverseEconomy.h:146
nmrPInverseEconomyDynamicData()
Definition nmrPInverseEconomy.h:366
const vctDynamicMatrixRef< CISSTNETLIB_DOUBLE > & PInverse(void) const
Definition nmrPInverseEconomy.h:566
const vctDynamicMatrixRef< CISSTNETLIB_DOUBLE > & Vt(void) const
Definition nmrPInverseEconomy.h:563
size_type NMember
Definition nmrPInverseEconomy.h:166
void SetDimension(size_type m, size_type n, bool storageOrder)
Definition nmrPInverseEconomy.h:174
nmrPInverseEconomyDynamicData(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A)
Definition nmrPInverseEconomy.h:384
vctDynamicMatrixRef< CISSTNETLIB_DOUBLE > UReference
Definition nmrPInverseEconomy.h:156
void Allocate(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A)
Definition nmrPInverseEconomy.h:461
vctDynamicVector< CISSTNETLIB_DOUBLE > OutputMemory
Definition nmrPInverseEconomy.h:150
void ThrowUnlessWorkspaceSizeIsCorrect(vctDynamicVectorBase< _vectorOwnerTypeWorkspace, CISSTNETLIB_DOUBLE > &workspace) const CISST_THROW(std
Definition nmrPInverseEconomy.h:276
void SetRef(vctDynamicMatrixBase< _matrixOwnerTypePInverse, CISSTNETLIB_DOUBLE > &pInverse, vctDynamicVectorBase< _vectorOwnerTypeWorkspace, CISSTNETLIB_DOUBLE > &workspace)
Definition nmrPInverseEconomy.h:510
bool StorageOrderMember
Definition nmrPInverseEconomy.h:167
void SetRefSVD(vctDynamicVectorBase< _vectorOwnerTypeWorkspace, CISSTNETLIB_DOUBLE > &workspace)
Definition nmrPInverseEconomy.h:223
const vctDynamicMatrixRef< CISSTNETLIB_DOUBLE > & U(void) const
Definition nmrPInverseEconomy.h:560
static size_type WorkspaceSize(vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A)
Definition nmrPInverseEconomy.h:312
void ThrowUnlessOutputSizeIsCorrect(vctDynamicMatrixBase< _matrixOwnerTypePInverse, CISSTNETLIB_DOUBLE > &pInverse) const CISST_THROW(std
Definition nmrPInverseEconomy.h:255
void SetRefOutput(vctDynamicMatrixBase< _matrixOwnerTypePInverse, CISSTNETLIB_DOUBLE > &pInverse)
Definition nmrPInverseEconomy.h:538
static size_type WorkspaceSize(size_type m, size_type n)
Definition nmrSVDEconomy.h:281
Definition vctDynamicMatrixBase.h:43
reference at(size_type index) CISST_THROW(std
Definition vctDynamicMatrixBase.h:171
value_type SetAll(const value_type value)
Definition vctDynamicMatrixBase.h:452
Dynamic matrix referencing existing memory.
Definition vctDynamicMatrixRef.h:75
void SetRef(size_type rows, size_type cols, stride_type rowStride, stride_type colStride, pointer dataPointer)
Definition vctDynamicMatrixRef.h:217
Definition vctDynamicVectorBase.h:62
pointer Pointer(index_type index=0)
Definition vctDynamicVectorBase.h:155
reference at(index_type index) CISST_THROW(std
Definition vctDynamicVectorBase.h:170
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
#define CMN_UNUSED(argument)
Definition cmnPortability.h:497
#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
Rules of exporting.
CISSTNETLIB_INTEGER nmrPInverseEconomy(vctDynamicMatrixBase< _matrixOwnerType, CISSTNETLIB_DOUBLE > &A, nmrPInverseEconomyDynamicData &data) CISST_THROW(std
Definition nmrPInverseEconomy.h:590
Declaration of nmrSVDEconomy.
CISSTNETLIB_INTEGER nmrSVDEconomy(vctDynamicMatrixBase< _matrixOwnerType, CISSTNETLIB_DOUBLE > &A, nmrSVDEconomyDynamicData &data) CISST_THROW(std
Definition nmrSVDEconomy.h:800
size_type cols() const
Definition vctDynamicConstMatrixBase.h:243
size_type rows() const
Definition vctDynamicConstMatrixBase.h:238
Declaration of vctDynamicMatrix.
Declaration of vctFixedSizeMatrix.
const bool VCT_COL_MAJOR
Definition vctForwardDeclarations.h:44