vnl_svd_fixed.h
Go to the documentation of this file.
1 // This is core/vnl/algo/vnl_svd_fixed.h
2 #ifndef vnl_svd_fixed_h_
3 #define vnl_svd_fixed_h_
4 //:
5 // \file
6 // \brief Holds the singular value decomposition of a vnl_matrix_fixed.
7 // \author Andrew W. Fitzgibbon, Ian Scott
8 // \date 12 Oct 2009
9 //
10 
11 #include <iosfwd>
12 #include <vnl/vnl_numeric_traits.h>
13 #include <vnl/vnl_vector_fixed.h>
14 #include <vnl/vnl_matrix_fixed.h>
16 #include <vnl/algo/vnl_algo_export.h>
17 #ifdef _MSC_VER
18 # include <vcl_msvc_warnings.h>
19 #endif
20 
21 //: Holds the singular value decomposition of a vnl_matrix_fixed.
22 //
23 // The class holds three matrices U, W, V such that the original matrix
24 // $M = U W V^\top$. The DiagMatrix W stores the singular values in decreasing
25 // order. The columns of U which correspond to the nonzero singular values
26 // form a basis for range of M, while the columns of V corresponding to the
27 // zero singular values are the nullspace.
28 //
29 // The SVD is computed at construction time, and inquiries may then be made
30 // of the SVD. In particular, this allows easy access to multiple
31 // right-hand-side solves without the bother of putting all the RHS's into a
32 // Matrix.
33 //
34 
35 template <class T, unsigned int R, unsigned int C>
37 {
38  public:
39  //: The singular values of a matrix of complex<T> are of type T, not complex<T>
41 
42  //:
43  // Construct a vnl_svd_fixed<T> object from $m \times n$ matrix $M$. The
44  // vnl_svd_fixed<T> object contains matrices $U$, $W$, $V$ such that
45  // $U W V^\top = M$.
46  //
47  // Uses linpack routine DSVDC to calculate an ``economy-size'' SVD
48  // where the returned $U$ is the same size as $M$, while $W$
49  // and $V$ are both $n \times n$. This is efficient for
50  // large rectangular solves where $m > n$, typical in least squares.
51  //
52  // The optional argument zero_out_tol is used to mark the zero singular
53  // values: If nonnegative, any s.v. smaller than zero_out_tol in
54  // absolute value is set to zero. If zero_out_tol is negative, the
55  // zeroing is relative to |zero_out_tol| * sigma_max();
56 
57  vnl_svd_fixed(vnl_matrix_fixed<T,R,C> const &M, double zero_out_tol = 0.0);
58  ~vnl_svd_fixed() = default;
59 
60  // Data Access---------------------------------------------------------------
61 
62  //: find weights below threshold tol, zero them out, and update W_ and Winverse_
63  void zero_out_absolute(double tol = 1e-8); //sqrt(machine epsilon)
64 
65  //: find weights below tol*max(w) and zero them out
66  void zero_out_relative(double tol = 1e-8); //sqrt(machine epsilon)
67  int singularities () const { return W_.rows() - rank(); }
68  unsigned int rank () const { return rank_; }
69  singval_t well_condition () const { return sigma_min()/sigma_max(); }
70 
71  //: Calculate determinant as product of diagonals in W.
73  singval_t norm() const;
74 
75  //: Return the matrix U.
76  vnl_matrix_fixed<T,R,C> & U() { return U_; }
77 
78  //: Return the matrix U.
79  vnl_matrix_fixed<T,R,C> const& U() const { return U_; }
80 
81  //: Return the matrix U's (i,j)th entry (to avoid svd.U()(i,j); ).
82  T U(int i, int j) const { return U_(i,j); }
83 
84  //: Get at DiagMatrix (q.v.) of singular values, sorted from largest to smallest
86 
87  //: Get at DiagMatrix (q.v.) of singular values, sorted from largest to smallest
88  vnl_diag_matrix_fixed<singval_t, C> const & W() const { return W_; }
91  singval_t & W(int i, int j) { return W_(i,j); }
92  singval_t & W(int i) { return W_(i,i); }
93  singval_t sigma_max() const { return W_(0,0); } // largest
94  singval_t sigma_min() const { return W_(C-1,C-1); } // smallest
95 
96  //: Return the matrix V.
97  vnl_matrix_fixed<T,C,C> & V() { return V_; }
98 
99  //: Return the matrix V.
100  vnl_matrix_fixed<T,C,C> const& V() const { return V_; }
101 
102  //: Return the matrix V's (i,j)th entry (to avoid svd.V()(i,j); ).
103  T V(int i, int j) const { return V_(i,j); }
104 
105  //:
106  inline vnl_matrix_fixed<T,C,R> inverse () const { return pinverse(); }
107 
108  //: pseudo-inverse (for non-square matrix) of desired rank.
109  vnl_matrix_fixed<T,C,R> pinverse (unsigned int rank = ~0u) const; // ~0u == (unsigned int)-1
110 
111  //: Calculate inverse of transpose, using desired rank.
112  vnl_matrix_fixed<T,R,C> tinverse (unsigned int rank = ~0u) const; // ~0u == (unsigned int)-1
113 
114  //: Recompose SVD to U*W*V', using desired rank.
115  vnl_matrix_fixed<T,R,C> recompose (unsigned int rank = ~0u) const; // ~0u == (unsigned int)-1
116 
117  //: Solve the matrix equation M X = B, returning X
118  vnl_matrix<T> solve (vnl_matrix<T> const& B) const;
119 
120  //: Solve the matrix-vector system M x = y, returning x.
122  void solve (T const *rhs, T *lhs) const; // min ||A*lhs - rhs||
123 
124  //: Solve the matrix-vector system M x = y.
125  // Assuming that the singular values W have been preinverted by the caller.
127 
128  //: Return N such that M * N = 0
129  vnl_matrix<T> nullspace() const;
130 
131  //: Return N such that M' * N = 0
133 
134  //: Return N such that M * N = 0
135  vnl_matrix<T> nullspace(int required_nullspace_dimension) const;
136 
137  //: Implementation to be done yet; currently returns left_nullspace(). - PVR.
138  vnl_matrix<T> left_nullspace(int required_nullspace_dimension) const;
139 
140  //: Return the rightmost column of V.
141  // Does not check to see whether or not the matrix actually was rank-deficient -
142  // the caller is assumed to have examined W and decided that to his or her satisfaction.
144 
145  //: Return the rightmost column of U.
146  // Does not check to see whether or not the matrix actually was rank-deficient.
148 
149  bool valid() const { return valid_; }
150 
151  private:
152 
153  vnl_matrix_fixed<T, R, C> U_; // Columns Ui are basis for range of M for Wi != 0
154  vnl_diag_matrix_fixed<singval_t, C> W_;// Singular values, sorted in decreasing order
156  vnl_matrix_fixed<T, C, C> V_; // Columns Vi are basis for nullspace of M for Wi = 0
157  unsigned rank_;
158  bool have_max_;
160  bool have_min_;
162  double last_tol_;
163  bool valid_; // false if the NETLIB call failed.
164 
165  // Disallow assignment.
168 };
169 
170 template <class T, unsigned int R, unsigned int C>
171 inline
173 {
174  return vnl_svd_fixed<T,R,C>(m).inverse();
175 }
176 
177 template <class T, unsigned int R, unsigned int C>
178 std::ostream& operator<<(std::ostream&, vnl_svd_fixed<T,R,C> const& svd);
179 
180 #endif // vnl_svd_fixed_h_
vnl_diag_matrix_fixed< singval_t, C > & Winverse()
Definition: vnl_svd_fixed.h:89
singval_t norm() const
bool valid() const
T V(int i, int j) const
Return the matrix V's (i,j)th entry (to avoid svd.V()(i,j); ).
vnl_numeric_traits< T >::abs_t singval_t
The singular values of a matrix of complex<T> are of type T, not complex<T>.
Definition: vnl_svd_fixed.h:40
int singularities() const
Definition: vnl_svd_fixed.h:67
vnl_matrix< T > solve(vnl_matrix< T > const &B) const
Solve the matrix equation M X = B, returning X.
unsigned rank_
singval_t determinant_magnitude() const
Calculate determinant as product of diagonals in W.
Templated zero/one/precision.
vnl_matrix_fixed< T, C, R > pinverse(unsigned int rank=~0u) const
pseudo-inverse (for non-square matrix) of desired rank.
#define m
Definition: vnl_vector.h:43
T U(int i, int j) const
Return the matrix U's (i,j)th entry (to avoid svd.U()(i,j); ).
Definition: vnl_svd_fixed.h:82
vnl_matrix_fixed< T, R, C > & U()
Return the matrix U.
Definition: vnl_svd_fixed.h:76
singval_t max_
vnl_diag_matrix_fixed< singval_t, C > const & Winverse() const
Definition: vnl_svd_fixed.h:90
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.
singval_t well_condition() const
Definition: vnl_svd_fixed.h:69
vnl_matrix_fixed< T, C, C > V_
vnl_svd_fixed< T, R, C > & operator=(vnl_svd_fixed< T, R, C > const &)
vnl_matrix_fixed< T, C, R > vnl_svd_fixed_inverse(vnl_matrix_fixed< T, R, C > const &m)
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.
Definition: vnl_svd_fixed.h:97
std::ostream & operator<<(std::ostream &s, vnl_decnum const &r)
decimal output.
Definition: vnl_decnum.h:393
singval_t sigma_min() const
Definition: vnl_svd_fixed.h:94
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.
Definition: vnl_svd_fixed.h:85
singval_t & W(int i, int j)
Definition: vnl_svd_fixed.h:91
vnl_diag_matrix_fixed< singval_t, C > W_
void zero_out_relative(double tol=1e-8)
find weights below tol*max(w) and zero them out.
unsigned int rows() const
Return the number of rows.
vnl_matrix< T > left_nullspace() const
Return N such that M' * N = 0.
unsigned int rank() const
Definition: vnl_svd_fixed.h:68
An ordinary mathematical matrix.
Definition: vnl_adjugate.h:22
vnl_diag_matrix_fixed< singval_t, C > const & W() const
Get at DiagMatrix (q.v.) of singular values, sorted from largest to smallest.
Definition: vnl_svd_fixed.h:88
vnl_matrix_fixed< T, R, C > tinverse(unsigned int rank=~0u) const
Calculate inverse of transpose, using desired rank.
vnl_diag_matrix_fixed< singval_t, C > Winverse_
singval_t & W(int i)
Definition: vnl_svd_fixed.h:92
Fixed length stack-stored, space-efficient vector.
Definition: vnl_fwd.h:22
vnl_matrix_fixed< T, C, R > inverse() const
singval_t sigma_max() const
Definition: vnl_svd_fixed.h:93
fixed size matrix
Fixed length stack-stored vector.
~vnl_svd_fixed()=default
vnl_matrix_fixed< T, R, C > const & U() const
Return the matrix U.
Definition: vnl_svd_fixed.h:79
void zero_out_absolute(double tol=1e-8)
find weights below threshold tol, zero them out, and update W_ and Winverse_.
Holds the singular value decomposition of a vnl_matrix_fixed.
Definition: vnl_svd_fixed.h:36
vnl_vector_fixed< T, R > left_nullvector() const
Return the rightmost column of U.
vnl_matrix< T > nullspace() const
Return N such that M * N = 0.
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 .
singval_t min_
vnl_matrix_fixed< T, C, C > const & V() const
Return the matrix V.
vnl_matrix_fixed< T, R, C > U_
Contains class for diagonal matrices.