15 # include <vcl_msvc_warnings.h> 24 inline void vnl_linpack_svdc(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_test_heavily =
false;
67 constexpr
long job = 21;
68 vnl_linpack_svdc((T*)X, &n, &n, &p,
106 std::cerr << __FILE__
": suspicious return value (" << info <<
") from SVDC\n" 107 << __FILE__
": M is " << M.
rows() <<
'x' << M.
cols() << std::endl;
118 for (
int j = 0; j < p; ++j)
119 for (
int i = 0; i < n; ++i)
123 for (
int j = 0; j < mm; ++j)
126 for (
int j = mm; j <
n_; ++j)
131 for (
int j = 0; j < p; ++j)
132 for (
int i = 0; i < p; ++i)
137 if (vnl_svd_test_heavily)
143 abs_t thresh = abs_t(
m_) * abs_t(vnl_math::eps) * n;
144 if (recomposition_residual > thresh)
146 std::cerr <<
"vnl_svd<T>::vnl_svd<T>() -- Warning, recomposition_residual = " 147 << recomposition_residual << std::endl
148 <<
"fro_norm(M) = " << n << std::endl
149 <<
"eps*fro_norm(M) = " << thresh << std::endl
150 <<
"Press return to continue\n";
152 std::cin.get(&x, 1,
'\n');
156 if (zero_out_tol >= 0)
169 <<
"U = [\n" << svd.
U() <<
"]\n" 170 <<
"W = " << svd.
W() <<
'\n' 171 <<
"V = [\n" << svd.
V() <<
"]\n" 172 <<
"rank = " << svd.
rank() << std::endl;
186 for (
unsigned k = 0; k < W_.rows(); k++)
205 zero_out_absolute(tol *
std::abs(sigma_max()));
209 inline bool vnl_svn_warned() {
if (w)
return true;
else { w=
true;
return false; } }
216 std::cerr << __FILE__
": called determinant_magnitude() on SVD of non-square matrix\n" 217 <<
"(This warning is displayed only once)\n";
219 for (
unsigned long k = 1; k < W_.columns(); k++)
235 if (rnk > rank_) rnk=rank_;
238 for (
unsigned int i=0;i<rnk;++i)
241 return U_*Wmatr*V_.conjugate_transpose();
249 if (rnk > rank_) rnk=rank_;
250 vnl_matrix<T> W_inverse(Winverse_.rows(),Winverse_.columns());
251 W_inverse.
fill(T(0));
252 for (
unsigned int i=0;i<rnk;++i)
253 W_inverse(i,i)=Winverse_(i,i);
255 return V_ * W_inverse * U_.conjugate_transpose();
263 if (rnk > rank_) rnk=rank_;
264 vnl_matrix<T> W_inverse(Winverse_.rows(),Winverse_.columns());
265 W_inverse.
fill(T(0));
266 for (
unsigned int i=0;i<rnk;++i)
267 W_inverse(i,i)=Winverse_(i,i);
269 return U_ * W_inverse * V_.conjugate_transpose();
278 if (U_.rows() < U_.columns()) {
285 for (
unsigned long i = 0; i < x.
rows(); ++i) {
288 weight = T(1) / weight;
289 for (
unsigned long j = 0; j < x.
columns(); ++j)
301 if (y.
size() != U_.rows())
303 std::cerr << __FILE__ <<
": size of rhs is incompatible with no. of rows in U_\n" 304 <<
"y =" << y <<
'\n' 305 <<
"m_=" << m_ <<
'\n' 306 <<
"n_=" << n_ <<
'\n' 313 if (U_.rows() < U_.columns()) {
315 if (yy.size()<y.
size()) {
316 std::cerr <<
"yy=" << yy << std::endl
317 <<
"y =" << y << std::endl;
321 x = U_.conjugate_transpose() * yy;
324 x = U_.conjugate_transpose() * y;
326 for (
unsigned i = 0; i < x.size(); i++) {
327 T weight = W_(i, i), zero_(0);
348 if (U_.rows() < U_.columns()) {
349 std::cout <<
"vnl_svd<T>::solve_preinverted() -- Augmenting y\n";
352 x = U_.conjugate_transpose() * yy;
355 x = U_.conjugate_transpose() * y;
356 for (
unsigned i = 0; i < x.
size(); i++)
369 std::cerr <<
"vnl_svd<T>::nullspace() -- Matrix is full rank." << last_tol_ << std::endl;
370 return nullspace(n_-k);
378 return V_.extract(V_.rows(), required_nullspace_dimension, 0, n_ - required_nullspace_dimension);
388 std::cerr <<
"vnl_svd<T>::left_nullspace() -- Matrix is full rank." << last_tol_ << std::endl;
389 return U_.extract(U_.rows(), n_-k, 0, k);
397 return left_nullspace();
409 for (
int i = 0; i < n_; ++i)
410 ret(i) = V_(i, n_-1);
422 for (
int i = 0; i < m_; ++i)
429 #undef VNL_SVD_INSTANTIATE 430 #define VNL_SVD_INSTANTIATE(T) \ 431 template class VNL_ALGO_EXPORT vnl_svd<T >; \ 432 template VNL_ALGO_EXPORT std::ostream& operator<<(std::ostream &, vnl_svd<T > const &) 434 #endif // vnl_svd_hxx_ unsigned int cols() const
Return the number of columns.
void assert_finite() const
abort if matrix contains any INFs or NANs.
Print matrices and vectors in nice MATLAB format.
unsigned int rank() const
vnl_vector< T > & update(vnl_vector< T > const &, size_t start=0)
Replaces elements with index beginning at start, by values of v. O(n).
vnl_matrix< T > recompose(unsigned int rank=~0u) const
Recompose SVD to U*W*V', using desired rank.
vnl_matrix< T > conjugate_transpose() const
Return conjugate transpose.
void solve_preinverted(vnl_vector< T > const &rhs, vnl_vector< T > *out) const
Solve the matrix-vector system M x = y.
vnl_vector< T > nullvector() const
Return the rightmost column of V.
abs_t fro_norm() const
Return Frobenius norm of matrix (sqrt of sum of squares of its elements).
vnl_matrix< T > & U()
Return the matrix U.
size_t size() const
Return the length, number of elements, dimension of this vector.
T const * data_block() const
Access the contiguous block storing the elements in the vector. O(1).
Namespace with standard math functions.
vnl_matrix< T > left_nullspace() const
Return N such that M' * N = 0.
std::ostream & operator<<(std::ostream &s, vnl_decnum const &r)
decimal output.
vnl_diag_matrix< singval_t > W_
vnl_matrix< T > solve(vnl_matrix< T > const &B) const
Solve the matrix equation M X = B, returning X.
void zero_out_relative(double tol=1e-8)
find weights below tol*max(w) and zero them out.
void zero_out_absolute(double tol=1e-8)
find weights below threshold tol, zero them out, and update W_ and Winverse_.
Convert row-stored matrix to column-stored.
vnl_matrix< T > tinverse(unsigned int rank=~0u) const
Calculate inverse of transpose, using desired rank.
singval_t determinant_magnitude() const
Calculate determinant as product of diagonals in W.
vnl_vector< T > left_nullvector() const
Return the rightmost column of U.
VNL_EXPORT std::ostream & vnl_matlab_print(std::ostream &, T const *array, unsigned length, vnl_matlab_print_format=vnl_matlab_print_format_default)
print a 1D array.
An ordinary mathematical matrix.
Declare in a central place the list of symbols from netlib.
vnl_matrix & fill(T const &)
Sets all elements of matrix to specified value, and returns "*this".
Convert row-stored matrix to column-stored.
vnl_svd(vnl_matrix< T > const &M, double zero_out_tol=0.0)
Construct a vnl_svd<T> object from matrix .
Mathematical vector class, templated by type of element.
vnl_bignum abs(vnl_bignum const &x)
unsigned int rows() const
Return the number of rows.
vnl_matrix< T > & V()
Return the matrix V.
Holds the singular value decomposition of a vnl_matrix.
vnl_decnum min(vnl_decnum const &x, vnl_decnum const &y)
vnl_matrix< T > nullspace() const
Return N such that M * N = 0.
Holds the singular value decomposition of a vnl_matrix.
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].
unsigned int columns() const
Return the number of columns.
vnl_numeric_traits< T >::abs_t singval_t
The singular values of a matrix of complex<T> are of type T, not complex<T>.
vnl_matrix< T > pinverse(unsigned int rank=~0u) const
pseudo-inverse (for non-square matrix) of desired rank.
vnl_diag_matrix< singval_t > & W()
Get at DiagMatrix (q.v.) of singular values, sorted from largest to smallest.