Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef EIGEN_SVD_H
00016 #define EIGEN_SVD_H
00017
00018 namespace Eigen {
00045 template<typename _MatrixType>
00046 class SVDBase
00047 {
00048
00049 public:
00050 typedef _MatrixType MatrixType;
00051 typedef typename MatrixType::Scalar Scalar;
00052 typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
00053 typedef typename MatrixType::Index Index;
00054 enum {
00055 RowsAtCompileTime = MatrixType::RowsAtCompileTime,
00056 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
00057 DiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime,ColsAtCompileTime),
00058 MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
00059 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,
00060 MaxDiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(MaxRowsAtCompileTime,MaxColsAtCompileTime),
00061 MatrixOptions = MatrixType::Options
00062 };
00063
00064 typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime,
00065 MatrixOptions, MaxRowsAtCompileTime, MaxRowsAtCompileTime>
00066 MatrixUType;
00067 typedef Matrix<Scalar, ColsAtCompileTime, ColsAtCompileTime,
00068 MatrixOptions, MaxColsAtCompileTime, MaxColsAtCompileTime>
00069 MatrixVType;
00070 typedef typename internal::plain_diag_type<MatrixType, RealScalar>::type SingularValuesType;
00071 typedef typename internal::plain_row_type<MatrixType>::type RowType;
00072 typedef typename internal::plain_col_type<MatrixType>::type ColType;
00073 typedef Matrix<Scalar, DiagSizeAtCompileTime, DiagSizeAtCompileTime,
00074 MatrixOptions, MaxDiagSizeAtCompileTime, MaxDiagSizeAtCompileTime>
00075 WorkMatrixType;
00076
00077
00078
00079
00090 SVDBase& compute(const MatrixType& matrix, unsigned int computationOptions);
00091
00098
00099 SVDBase& compute(const MatrixType& matrix);
00100
00110 const MatrixUType& matrixU() const
00111 {
00112 eigen_assert(m_isInitialized && "SVD is not initialized.");
00113 eigen_assert(computeU() && "This SVD decomposition didn't compute U. Did you ask for it?");
00114 return m_matrixU;
00115 }
00116
00126 const MatrixVType& matrixV() const
00127 {
00128 eigen_assert(m_isInitialized && "SVD is not initialized.");
00129 eigen_assert(computeV() && "This SVD decomposition didn't compute V. Did you ask for it?");
00130 return m_matrixV;
00131 }
00132
00138 const SingularValuesType& singularValues() const
00139 {
00140 eigen_assert(m_isInitialized && "SVD is not initialized.");
00141 return m_singularValues;
00142 }
00143
00144
00145
00147 Index nonzeroSingularValues() const
00148 {
00149 eigen_assert(m_isInitialized && "SVD is not initialized.");
00150 return m_nonzeroSingularValues;
00151 }
00152
00153
00155 inline bool computeU() const { return m_computeFullU || m_computeThinU; }
00157 inline bool computeV() const { return m_computeFullV || m_computeThinV; }
00158
00159
00160 inline Index rows() const { return m_rows; }
00161 inline Index cols() const { return m_cols; }
00162
00163
00164 protected:
00165
00166 bool allocate(Index rows, Index cols, unsigned int computationOptions) ;
00167
00168 MatrixUType m_matrixU;
00169 MatrixVType m_matrixV;
00170 SingularValuesType m_singularValues;
00171 bool m_isInitialized, m_isAllocated;
00172 bool m_computeFullU, m_computeThinU;
00173 bool m_computeFullV, m_computeThinV;
00174 unsigned int m_computationOptions;
00175 Index m_nonzeroSingularValues, m_rows, m_cols, m_diagSize;
00176
00177
00182 SVDBase()
00183 : m_isInitialized(false),
00184 m_isAllocated(false),
00185 m_computationOptions(0),
00186 m_rows(-1), m_cols(-1)
00187 {}
00188
00189
00190 };
00191
00192
00193 template<typename MatrixType>
00194 bool SVDBase<MatrixType>::allocate(Index rows, Index cols, unsigned int computationOptions)
00195 {
00196 eigen_assert(rows >= 0 && cols >= 0);
00197
00198 if (m_isAllocated &&
00199 rows == m_rows &&
00200 cols == m_cols &&
00201 computationOptions == m_computationOptions)
00202 {
00203 return true;
00204 }
00205
00206 m_rows = rows;
00207 m_cols = cols;
00208 m_isInitialized = false;
00209 m_isAllocated = true;
00210 m_computationOptions = computationOptions;
00211 m_computeFullU = (computationOptions & ComputeFullU) != 0;
00212 m_computeThinU = (computationOptions & ComputeThinU) != 0;
00213 m_computeFullV = (computationOptions & ComputeFullV) != 0;
00214 m_computeThinV = (computationOptions & ComputeThinV) != 0;
00215 eigen_assert(!(m_computeFullU && m_computeThinU) && "SVDBase: you can't ask for both full and thin U");
00216 eigen_assert(!(m_computeFullV && m_computeThinV) && "SVDBase: you can't ask for both full and thin V");
00217 eigen_assert(EIGEN_IMPLIES(m_computeThinU || m_computeThinV, MatrixType::ColsAtCompileTime==Dynamic) &&
00218 "SVDBase: thin U and V are only available when your matrix has a dynamic number of columns.");
00219
00220 m_diagSize = (std::min)(m_rows, m_cols);
00221 m_singularValues.resize(m_diagSize);
00222 if(RowsAtCompileTime==Dynamic)
00223 m_matrixU.resize(m_rows, m_computeFullU ? m_rows
00224 : m_computeThinU ? m_diagSize
00225 : 0);
00226 if(ColsAtCompileTime==Dynamic)
00227 m_matrixV.resize(m_cols, m_computeFullV ? m_cols
00228 : m_computeThinV ? m_diagSize
00229 : 0);
00230
00231 return false;
00232 }
00233
00234 }
00235
00236 #endif // EIGEN_SVD_H