cisst-saw
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes
nmrPInverse.h File Reference

Declaration of nmrPInverse. More...

#include <cisstCommon/cmnThrow.h>
#include <cisstVector/vctFixedSizeMatrix.h>
#include <cisstVector/vctDynamicMatrix.h>
#include <cisstNumerical/nmrNetlib.h>
#include <cisstNumerical/nmrSVD.h>
#include <cisstNumerical/nmrExport.h>

Go to the source code of this file.

Classes

class  nmrPInverseDynamicData
 
class  nmrPInverseDynamicData::Friend
 
class  nmrPInverseFixedSizeData< _rows, _cols, _storageOrder >
 
class  nmrPInverseFixedSizeData< _rows, _cols, _storageOrder >::Friend
 

Functions

Algorithm P-Inverse: Moore-Penrose pseudo-inverse.

Calculates the Moore-Penrose pseudo-inverse of the M by N matrix A, and stores the result in PInverse. The singular values of A are returned in S. The left singular vectors are returned in U, and the right singular vectors are returned in V.

$ A^{+} = V * \Sigma^{+} * U^{T}$

where $ \Sigma^{+} $ is a $ N \times M $ matrix which is zero except for its min(m,n) diagonal elements, U is a $ M \times M $ orthogonal matrix, and V is a $ N \times N $ orthogonal matrix. The diagonal elements of $ \Sigma^{+} $ are the reciprocal ofc non-zero singular values of A; they are real and non-negative, andc are returned in descending order. The first $ \mbox{min}(m,n) $ columns of U and V are the left and right singular vectors of A.

Note
This routine returns $ V^{T}$, not $V$.
On exit, the content of A is altered.

There are three ways to call this method to compute the pseudo-inverse of the matrix A.

  1. User provides matrices $A$ and $A^{+}$. The user first allocates memory for these matrices and vector.

    The user can then call the P-Inverse routine

    nmrPInverse(A, PInverse);

    The PInverse method verifies that the size of the data objects matches the input, and allocates workspace memory, which is deallocated when the function ends. Remember that nmrPInverse alters the content of matrix A. For fixed size the function call is templated by size and row/column major, e.g.

    nmrPInverse<4, 3, VCT_COL_MAJOR>(A, PInverse);

  2. Using a preallocated data object. The user first creates the input matrix.

    The user creates a data object which could be of type nmrPInverseFixedSizeData or nmrPInverseDynamicData corresponding to fixed size, dynamic matrix.

    Finally, call the nmrPInverse function:

    nmrPInverse(input, data);

    The contents of input matrix is modified by this routine. The matrices U, Vt and vector S are available through the following methods:

    std::cout << data.U()
    << data.S()
    << data.Vt()
    << data.PInverse()
    << std::endl;

  3. User provides matrix PInverse with workspace required by pseudo-inverse routine of LAPACK. User creates matrices:

    User also needs to allocate memory for workspace. This method is particularly useful when the user is using more than one numerical methods from the library and is willing to share the workspace between them. In such as case, the user can allocate the a memory greater than the maximum required by different methods. To aid the user determine the minimum workspace required (and not spend time digging LAPACK documentation) the library provides helper function nmrPInverseDynamicData::WorkspaceSize(input).

    Call the SVD function

    nmrPInverse(A, PInverse, Work);

    For fixed size the above two steps are replaced by

    nmrPInverse<4, 3, VCT_COL_MAJOR>(A, PInverse, Work);

nmrPInverse uses nmrSVD and returns the error code of nmrSVD. See nmrSVD for further details.

Note
The PInverse functions make use of LAPACK routines. To activate this code, set the CISST_HAS_CISSTNETLIB flag to ON during the configuration of cisst with CMake.
The general rule for numerical functions which depend on LAPACK is that column-major matrices should be used everywhere, and that all matrices should be compact.
For the specific case of PInverse, a valid result is also obtained if all the matrices are stored in row-major order. This is an exeption to the general rule. However, mixed-order is not tolerated.
template<class _matrixOwnerType >
CISSTNETLIB_INTEGER nmrPInverse (vctDynamicMatrixBase< _matrixOwnerType, CISSTNETLIB_DOUBLE > &A, nmrPInverseDynamicData &data) throw (std::runtime_error)
 
template<class _matrixOwnerTypeA , class _matrixOwnerTypePInverse , class _vectorOwnerTypeWorkspace >
CISSTNETLIB_INTEGER nmrPInverse (vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A, vctDynamicMatrixBase< _matrixOwnerTypePInverse, CISSTNETLIB_DOUBLE > &PInverse, vctDynamicVectorBase< _vectorOwnerTypeWorkspace, CISSTNETLIB_DOUBLE > &Workspace)
 
template<class _matrixOwnerTypeA , class _matrixOwnerTypePInverse >
CISSTNETLIB_INTEGER nmrPInverse (vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &A, vctDynamicMatrixBase< _matrixOwnerTypePInverse, CISSTNETLIB_DOUBLE > &PInverse)
 
template<vct::size_type _rows, vct::size_type _cols, vct::size_type _work, bool _storageOrder, class _dataPtrType >
CISSTNETLIB_INTEGER nmrPInverse (vctFixedSizeMatrix< CISSTNETLIB_DOUBLE, _rows, _cols, _storageOrder > &A, vctFixedSizeMatrix< CISSTNETLIB_DOUBLE, _cols, _rows, _storageOrder > &pInverse, vctFixedSizeVectorBase< _work, 1, CISSTNETLIB_DOUBLE, _dataPtrType > &workspace)
 
template<vct::size_type _rows, vct::size_type _cols, bool _storageOrder>
CISSTNETLIB_INTEGER nmrPInverse (vctFixedSizeMatrix< CISSTNETLIB_DOUBLE, _rows, _cols, _storageOrder > &A, vctFixedSizeMatrix< CISSTNETLIB_DOUBLE, _cols, _rows, _storageOrder > &pInverse)
 
template<vct::size_type _rows, vct::size_type _cols, bool _storageOrder>
CISSTNETLIB_INTEGER nmrPInverse (vctFixedSizeMatrix< CISSTNETLIB_DOUBLE, _rows, _cols, _storageOrder > &A, nmrPInverseFixedSizeData< _rows, _cols, _storageOrder > &data)
 

Detailed Description

Declaration of nmrPInverse.

Function Documentation

template<class _matrixOwnerType >
CISSTNETLIB_INTEGER nmrPInverse ( vctDynamicMatrixBase< _matrixOwnerType, CISSTNETLIB_DOUBLE > &  A,
nmrPInverseDynamicData data 
)
throw (std::runtime_error
)
inline

This function checks for valid input and calls the LAPACK function. The approach behind this defintion of the function is that the user creates a data object from a code wherein it is safe to do memory allocation. This data object is then passed on to this method along with the matrix whose PInverse is to be computed. The data object has members S, U, Vt and PInverse, which can be accessed through calls to method get*() along with adequate workspace for LAPACK. This function modifies the contents of matrix A. For details about nature of the data matrices see text above.

Parameters
AA matrix of size MxN, of one of vctDynamicMatrix or vctDynamicMatrixRef
dataA data object of one of the types corresponding to input matrix
Test:
nmrPInverseTest::TestDynamicColumnMajor nmrPInverseTest::TestDynamicRowMajor nmrPInverseTest::TestDynamicColumnMajorUserAlloc nmrPInverseTest::TestDynamicRowMajorUserAlloc
template<class _matrixOwnerTypeA , class _matrixOwnerTypePInverse , class _vectorOwnerTypeWorkspace >
CISSTNETLIB_INTEGER nmrPInverse ( vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &  A,
vctDynamicMatrixBase< _matrixOwnerTypePInverse, CISSTNETLIB_DOUBLE > &  PInverse,
vctDynamicVectorBase< _vectorOwnerTypeWorkspace, CISSTNETLIB_DOUBLE > &  Workspace 
)
inline

Basic version of PInverse where user provides the input matrix as well as storage for output and workspace needed by LAPACK. No mem allocation is done in this function, user allocates everything inlcuding workspace. The PInverse method verifies that the size of the data objects matchesc the input. See static methods in nmrPInverseDynamicData for helper functions that help determine the min workspace required. This function modifies the contents of matrix A. For sizes of other matrices see text above.

Parameters
Ais a reference to a dynamic matrix of size MxN
PInverseThe output matrix for PInverse
WorkspaceThe workspace for LAPACK.
Test:
nmrPInverseTest::TestDynamicColumnMajorUserAlloc nmrPInverseTest::TestDynamicRowMajorUserAlloc
template<class _matrixOwnerTypeA , class _matrixOwnerTypePInverse >
CISSTNETLIB_INTEGER nmrPInverse ( vctDynamicMatrixBase< _matrixOwnerTypeA, CISSTNETLIB_DOUBLE > &  A,
vctDynamicMatrixBase< _matrixOwnerTypePInverse, CISSTNETLIB_DOUBLE > &  PInverse 
)
inline

Basic version of PInverse where user provides the input matrix as well as storage for output. The PInverse method verifies that the size of the data objects matches the input and allocates workspace memory, which is deallocated when the function ends. This function modifies the contents of matrix A. For sizes of other matrices see text above.

Parameters
Ais a reference to a dynamic matrix of size MxN
PInverseThe output matrices and vector for PInverse
Test:
nmrPInverseTest::TestDynamicColumnMajorUserAlloc nmrPInverseTest::TestDynamicRowMajorUserAlloc
template<vct::size_type _rows, vct::size_type _cols, vct::size_type _work, bool _storageOrder, class _dataPtrType >
CISSTNETLIB_INTEGER nmrPInverse ( vctFixedSizeMatrix< CISSTNETLIB_DOUBLE, _rows, _cols, _storageOrder > &  A,
vctFixedSizeMatrix< CISSTNETLIB_DOUBLE, _cols, _rows, _storageOrder > &  pInverse,
vctFixedSizeVectorBase< _work, 1, CISSTNETLIB_DOUBLE, _dataPtrType > &  workspace 
)
inline

Basic version of pseudo inverse where user provides the input matrix as well as storage for output and workspace needed by LAPACK. No memory allocation is done in this function, user allocates everything including workspace. The nmrPInverse function verifies that the size of the S and workspace vector objects match the input. This function modifies the contents of matrix A. For sizes of other matrices see text above.

Parameters
AFixed size matrix of size MxN
pInverseThe output matrix for pseudo inverse
workspaceThe workspace for LAPACK.
Test:
nmrPInverseTest::TestFixedSizeColumnMajorMLeqN_T2 nmrPInverseTest::TestFixedSizeRowMajorMLeqN_T2 nmrPInverseTest::TestFixedSizeColumnMajorMGeqN_T2 nmrPInverseTest::TestFixedSizeRowMajorMGeqN_T2
template<vct::size_type _rows, vct::size_type _cols, bool _storageOrder>
CISSTNETLIB_INTEGER nmrPInverse ( vctFixedSizeMatrix< CISSTNETLIB_DOUBLE, _rows, _cols, _storageOrder > &  A,
vctFixedSizeMatrix< CISSTNETLIB_DOUBLE, _cols, _rows, _storageOrder > &  pInverse 
)
inline

Basic version of pseudo-inverse where user provides the input matrix as well as storage for output. The nmrPInverse function verifies that the size of the S vector object matches the input and allocates workspace memory, which is deallocated when the function ends. This function modifies the contents of matrix A. For sizes of other matrices see text above.

Parameters
AFixed size matrix of size MxN
pInverseThe output matrix for pseudo inverse
Test:
nmrPInverseTest::TestFixedSizeColumnMajorMLeqN_T2 nmrPInverseTest::TestFixedSizeRowMajorMLeqN_T2 nmrPInverseTest::TestFixedSizeColumnMajorMGeqN_T2 nmrPInverseTest::TestFixedSizeRowMajorMGeqN_T2
template<vct::size_type _rows, vct::size_type _cols, bool _storageOrder>
CISSTNETLIB_INTEGER nmrPInverse ( vctFixedSizeMatrix< CISSTNETLIB_DOUBLE, _rows, _cols, _storageOrder > &  A,
nmrPInverseFixedSizeData< _rows, _cols, _storageOrder > &  data 
)
inline

Specialized version of pseudo-inverse for Fixed Size Matrix. since all error checking is done at compile time. The approach behind this defintion of the function is that the user creates a data object from a code wherein it is safe to do memory allocation. This data object is then passed on to this method along with the matrix whose SVD is to be computed. The data object has members S, U, and Vt, which can be accessed through calls to method get*() along with adequate workspace for LAPACK. This function modifies the contents of matrix A. For details about nature of the data matrices see text above.

Parameters
AA matrix of size MxN
dataA data object of one of the types corresponding to input matrix
Test:
nmrPInverseTest::TestFixedSizeColumnMajorMLeqN nmrPInverseTest::TestFixedSizeRowMajorMLeqN nmrPInverseTest::TestFixedSizeColumnMajorMGeqN nmrPInverseTest::TestFixedSizeRowMajorMGeqN