2 #ifndef vnl_svd_fixed_hxx_ 3 #define vnl_svd_fixed_hxx_ 15 # include <vcl_msvc_warnings.h> 24 inline void vnl_linpack_svdc_fixed(vnl_netlib_svd_proto(T)) \ 25 { v3p_netlib_##p##svdc_(vnl_netlib_svd_params); } 28 macro(c, std::complex<float>);
29 macro(z, std::complex<double>);
34 static bool vnl_svd_fixed_test_heavily =
false;
37 template <
class T,
unsigned int R,
unsigned int C>
42 const unsigned mm =
std::min(R+1u,C);
57 constexpr
long job = 21;
58 vnl_linpack_svdc_fixed((T*)X, &n, &n, &p,
96 std::cerr << __FILE__
": suspicious return value (" << info <<
") from SVDC\n" 97 << __FILE__
": M is " << M.
rows() <<
'x' << M.
cols() << std::endl;
108 for (
long j = 0; j < p; ++j)
109 for (
long i = 0; i < n; ++i)
113 for (
unsigned j = 0; j < mm; ++j)
116 for (
unsigned j = mm; j < C; ++j)
121 for (
unsigned j = 0; j < C; ++j)
122 for (
unsigned i = 0; i < C; ++i)
127 if (vnl_svd_fixed_test_heavily)
131 abs_t recomposition_residual =
std::abs((recompose() - M).fro_norm());
133 abs_t thresh = abs_t(R) * abs_t(vnl_math::eps) * n;
134 if (recomposition_residual > thresh)
136 std::cerr <<
"vnl_svd_fixed<T>::vnl_svd_fixed<T>() -- Warning, recomposition_residual = " 137 << recomposition_residual << std::endl
138 <<
"fro_norm(M) = " << n << std::endl
139 <<
"eps*fro_norm(M) = " << thresh << std::endl
140 <<
"Press return to continue\n";
142 std::cin.get(&x, 1,
'\n');
146 if (zero_out_tol >= 0)
148 zero_out_absolute(
double(+zero_out_tol));
151 zero_out_relative(
double(-zero_out_tol));
154 template <
class T,
unsigned int R,
unsigned int C>
157 s <<
"vnl_svd_fixed<T,R,C>:\n" 158 <<
"U = [\n" << svd.
U() <<
"]\n" 159 <<
"W = " << svd.
W() <<
'\n' 160 <<
"V = [\n" << svd.
V() <<
"]\n" 161 <<
"rank = " << svd.
rank() << std::endl;
169 template <
class T,
unsigned int R,
unsigned int C>
174 for (
unsigned k = 0; k < C; k++)
191 template <
class T,
unsigned int R,
unsigned int C>
194 zero_out_absolute(tol *
std::abs(sigma_max()));
197 static bool wf=
false;
198 inline bool warned_f() {
if (wf)
return true;
else { wf=
true;
return false; } }
201 template <
class T,
unsigned int R,
unsigned int C>
205 std::cerr << __FILE__
": called determinant_magnitude() on SVD of non-square matrix\n" 206 <<
"(This warning is displayed only once)\n";
208 for (
unsigned long k = 1; k < C; k++)
214 template <
class T,
unsigned int R,
unsigned int C>
221 template <
class T,
unsigned int R,
unsigned int C>
224 if (rnk > rank_) rnk=rank_;
226 for (
unsigned int i=rnk;i<C;++i)
229 return U_*Wmatr*V_.conjugate_transpose();
234 template <
class T,
unsigned int R,
unsigned int C>
237 if (rnk > rank_) rnk=rank_;
239 for (
unsigned int i=rnk;i<C;++i)
242 return V_ * W_inverse * U_.conjugate_transpose();
247 template <
class T,
unsigned int R,
unsigned int C>
250 if (rnk > rank_) rnk=rank_;
252 for (
unsigned int i=rnk;i<C;++i)
255 return U_ * W_inverse * V_.conjugate_transpose();
260 template <
class T,
unsigned int R,
unsigned int C>
264 if (U_.rows() < U_.columns()) {
271 for (
unsigned long i = 0; i < x.
rows(); ++i) {
274 weight = T(1) / weight;
275 for (
unsigned long j = 0; j < x.
columns(); ++j)
283 template <
class T,
unsigned int R,
unsigned int C>
287 x = U_.conjugate_transpose() * y;
289 for (
unsigned i = 0; i < C; i++) {
290 T weight = W_(i, i), zero_(0);
299 template <
class T,
unsigned int R,
unsigned int C>
307 template <
class T,
unsigned int R,
unsigned int C>
311 x = U_.conjugate_transpose() * y;
312 for (
unsigned i = 0; i < C; i++)
320 template <
class T,
unsigned int R,
unsigned int C>
325 std::cerr <<
"vnl_svd_fixed<T>::nullspace() -- Matrix is full rank." << last_tol_ << std::endl;
326 return nullspace(C-k);
331 template <
class T,
unsigned int R,
unsigned int C>
334 return V_.extract(V_.rows(), required_nullspace_dimension, 0, C - required_nullspace_dimension);
339 template <
class T,
unsigned int R,
unsigned int C>
344 std::cerr <<
"vnl_svd_fixed<T>::left_nullspace() -- Matrix is full rank." << last_tol_ << std::endl;
345 return U_.extract(U_.rows(), C-k, 0, k);
350 template <
class T,
unsigned int R,
unsigned int C>
353 return left_nullspace();
361 template <
class T,
unsigned int R,
unsigned int C>
365 for (
unsigned i = 0; i < C; ++i)
373 template <
class T,
unsigned int R,
unsigned int C>
377 const unsigned col =
std::min(R, C) - 1;
378 for (
unsigned i = 0; i < R; ++i)
385 #undef VNL_SVD_FIXED_INSTANTIATE 386 #define VNL_SVD_FIXED_INSTANTIATE(T , R , C ) \ 387 template class VNL_ALGO_EXPORT vnl_svd_fixed<T, R, C >; \ 388 template VNL_ALGO_EXPORT std::ostream& operator<<(std::ostream &, vnl_svd_fixed<T, R, C > const &) 390 #endif // vnl_svd_fixed_hxx_
Print matrices and vectors in nice MATLAB format.
vnl_numeric_traits< T >::abs_t singval_t
The singular values of a matrix of complex<T> are of type T, not complex<T>.
unsigned int cols() const
Return the number of columns.
vnl_matrix< T > solve(vnl_matrix< T > const &B) const
Solve the matrix equation M X = B, returning X.
VNL_EXPORT std::ostream & vnl_matlab_print(std::ostream &, vnl_diag_matrix< T > const &, char const *variable_name=nullptr, vnl_matlab_print_format=vnl_matlab_print_format_default)
print a vnl_diagonal_matrix<T>.
vnl_matrix< T > conjugate_transpose() const
Return conjugate transpose.
singval_t determinant_magnitude() const
Calculate determinant as product of diagonals in W.
abs_t fro_norm() const
Return Frobenius norm of matrix (sqrt of sum of squares of its elements).
vnl_matrix_fixed< T, C, R > pinverse(unsigned int rank=~0u) const
pseudo-inverse (for non-square matrix) of desired rank.
void assert_finite() const
abort if matrix contains any INFs or NANs.
Namespace with standard math functions.
vnl_matrix_fixed< T, R, C > & U()
Return the matrix U.
void solve_preinverted(vnl_vector_fixed< T, R > const &rhs, vnl_vector_fixed< T, C > *out) const
Solve the matrix-vector system M x = y.
unsigned int rows() const
Return the number of rows.
vnl_matrix_fixed< T, R, C > recompose(unsigned int rank=~0u) const
Recompose SVD to U*W*V', using desired rank.
vnl_matrix_fixed< T, C, C > & V()
Return the matrix V.
std::ostream & operator<<(std::ostream &s, vnl_decnum const &r)
decimal output.
Convert row-stored matrix to column-stored.
vnl_vector_fixed< T, C > nullvector() const
Return the rightmost column of V.
vnl_diag_matrix_fixed< singval_t, C > & W()
Get at DiagMatrix (q.v.) of singular values, sorted from largest to smallest.
void zero_out_relative(double tol=1e-8)
find weights below tol*max(w) and zero them out.
vnl_matrix< T > left_nullspace() const
Return N such that M' * N = 0.
unsigned int rank() const
An ordinary mathematical matrix.
vnl_matrix_fixed< T, R, C > tinverse(unsigned int rank=~0u) const
Calculate inverse of transpose, using desired rank.
Declare in a central place the list of symbols from netlib.
Convert row-stored matrix to column-stored.
T const * data_block() const
Access the contiguous block storing the elements in the vector.
Fixed length stack-stored, space-efficient vector.
vnl_bignum abs(vnl_bignum const &x)
unsigned int rows() const
Return the number of rows.
stores a diagonal matrix as a single vector.
void zero_out_absolute(double tol=1e-8)
find weights below threshold tol, zero them out, and update W_ and Winverse_.
vnl_decnum min(vnl_decnum const &x, vnl_decnum const &y)
Holds the singular value decomposition of a vnl_matrix_fixed.
vnl_vector_fixed< T, R > left_nullvector() const
Return the rightmost column of U.
Holds the singular value decomposition of a vnl_matrix_fixed.
vnl_matrix< T > nullspace() const
Return N such that M * N = 0.
vnl_matrix< T > & update(vnl_matrix< T > const &, unsigned top=0, unsigned left=0)
Set values of this matrix to those of M, starting at [top,left].
vnl_svd_fixed(vnl_matrix_fixed< T, R, C > const &M, double zero_out_tol=0.0)
Construct a vnl_svd_fixed<T> object from matrix .
unsigned int columns() const
Return the number of columns.