vnl_rank.hxx
Go to the documentation of this file.
1 // This is core/vnl/vnl_rank.hxx
2 #ifndef vnl_rank_hxx_
3 #define vnl_rank_hxx_
4 
5 #include "vnl_rank.h"
6 
7 template <class T>
9 {
10  vnl_matrix<T> a = mat;
11  bool changed = true;
12  unsigned int m = a.rows(), n=a.columns();
13  while (changed)
14  {
15  changed = false;
16  for (unsigned int r=0; r<m; ++r)
17  {
18  unsigned int c=0; while (c<n && a[r][c] != 1 && a[r][c] != -1) ++c;
19  if (c==n) continue;
20  for (unsigned int s=0; s<m; ++s)
21  {
22  if (s==r || a[s][c] == 0) continue;
23  for (unsigned int d=0; d<n; ++d)
24  if (d!=c) a[s][d] -= a[r][d] * a[r][c] * a[s][c];
25  a[s][c] = T(0);
26  changed = true;
27  }
28  }
29  }
30  if (t == vnl_rank_pivot_one) return a;
31  changed = true;
32  while (changed)
33  {
34  changed = false;
35  for (unsigned int r=0; r<m; ++r)
36  {
37  unsigned int c=0; while (c<n && a[r][c] == 0) ++c;
38  if (c==n) continue; // zero row
39  for (unsigned int s=0; s<m; ++s)
40  {
41  if (s==r) continue;
42  T scale = a[s][c] / a[r][c];
43  // Note that this can possibly be an integer division, so
44  // it is *not* guaranteed that a[r][c] * scale == a[s][c] .
45  if (scale == 0) continue;
46  for (unsigned int d=0; d<n; ++d)
47  if (d!=c) a[s][d] -= a[r][d] * scale;
48  a[s][c] -= a[r][c] * scale;
49  changed = true;
50  }
51  }
52  }
53  return a;
54 }
55 
56 template <class T>
58 {
59  vnl_matrix<T> a = mat;
60  bool changed = true;
61  unsigned int m = a.rows(), n=a.columns();
62  while (changed)
63  {
64  changed = false;
65  for (unsigned int c=0; c<n; ++c)
66  {
67  unsigned int r=0; while (r<m && a[r][c] != 1 && a[r][c] != -1) ++r;
68  if (r==m) continue;
69  for (unsigned int d=0; d<n; ++d)
70  {
71  if (d==c || a[r][d] == 0) continue;
72  for (unsigned int s=0; s<m; ++s)
73  if (s!=r) a[s][d] -= a[s][c] * a[r][c] * a[r][d];
74  a[r][d] = T(0);
75  changed = true;
76  }
77  }
78  }
79  if (t == vnl_rank_pivot_one) return a;
80  changed = true;
81  while (changed)
82  {
83  changed = false;
84  for (unsigned int c=0; c<n; ++c)
85  {
86  unsigned int r=0; while (r<m && a[r][c] == 0) ++r;
87  if (r==m) continue; // zero row
88  for (unsigned int d=0; d<n; ++d)
89  {
90  if (d==c) continue;
91  T scale = a[r][d] / a[r][c];
92  // Note that this can possibly be an integer division, so
93  // it is *not* guaranteed that a[r][c] * scale == a[r][d] .
94  if (scale == 0) continue;
95  for (unsigned int s=0; s<m; ++s)
96  if (s!=r) a[s][d] -= a[s][c] * scale;
97  a[r][d] -= a[r][c] * scale;
98  changed = true;
99  }
100  }
101  }
102  return a;
103 }
104 
105 template <class T>
107 {
108  vnl_matrix<T> a = mat;
109  bool changed = true;
110  unsigned int m = a.rows(), n=a.columns();
111  while (changed)
112  {
113  changed = false;
114  for (unsigned int r=0; r<m; ++r)
115  {
116  unsigned int c=0; while (c<n && a[r][c] != 1 && a[r][c] != -1) ++c;
117  if (c==n) continue;
118  for (unsigned int s=0; s<m; ++s)
119  {
120  if (s==r || a[s][c] == 0) continue;
121  for (unsigned int d=0; d<n; ++d)
122  if (d!=c) a[s][d] -= a[r][d] * a[r][c] * a[s][c];
123  a[s][c] = T(0);
124  changed = true;
125  }
126  }
127  for (unsigned int c=0; c<n; ++c)
128  {
129  unsigned int r=0; while (r<m && a[r][c] != 1 && a[r][c] != -1) ++r;
130  if (r==m) continue;
131  for (unsigned int d=0; d<n; ++d)
132  {
133  if (d==c || a[r][d] == 0) continue;
134  for (unsigned int s=0; s<m; ++s)
135  if (s!=r) a[s][d] -= a[s][c] * a[r][c] * a[r][d];
136  a[r][d] = T(0);
137  changed = true;
138  }
139  }
140  }
141  if (t == vnl_rank_pivot_one) return a;
142  changed = true;
143  while (changed)
144  {
145  changed = false;
146  for (unsigned int r=0; r<m; ++r)
147  {
148  unsigned int c=0; while (c<n && a[r][c] == 0) ++c;
149  if (c==n) continue; // zero row
150  for (unsigned int s=0; s<m; ++s)
151  {
152  if (s==r) continue;
153  T scale = a[s][c] / a[r][c];
154  // Note that this can possibly be an integer division, so
155  // it is *not* guaranteed that a[r][c] * scale == a[s][c] .
156  if (scale == 0) continue;
157  for (unsigned int d=0; d<n; ++d)
158  if (d!=c) a[s][d] -= a[r][d] * scale;
159  a[s][c] -= a[r][c] * scale;
160  changed = true;
161  }
162  }
163  for (unsigned int c=0; c<n; ++c)
164  {
165  unsigned int r=0; while (r<m && a[r][c] == 0) ++r;
166  if (r==m) continue; // zero row
167  for (unsigned int d=0; d<n; ++d)
168  {
169  if (d==c) continue;
170  T scale = a[r][d] / a[r][c];
171  // Note that this can possibly be an integer division, so
172  // it is *not* guaranteed that a[r][c] * scale == a[r][d] .
173  if (scale == 0) continue;
174  for (unsigned int s=0; s<m; ++s)
175  if (s!=r) a[s][d] -= a[s][c] * scale;
176  a[r][d] -= a[r][c] * scale;
177  changed = true;
178  }
179  }
180  }
181  return a;
182 }
183 
184 template <class T>
185 unsigned int vnl_rank(vnl_matrix<T> const& mat, vnl_rank_type t)
186 {
187  unsigned int rank = 0;
188  if (t == vnl_rank_row)
189  {
191  for (unsigned int r=0; r<a.rows(); ++r)
192  {
193  unsigned int c=0;
194  while (c<a.columns() && a[r][c] == 0) ++c;
195  if (c!=a.columns()) ++rank; // not all elements in row r are 0
196  }
197  }
198  else
199  {
202  for (unsigned int c=0; c<a.columns(); ++c)
203  {
204  unsigned int r=0;
205  while (r<a.rows() && a[r][c] == 0) ++r;
206  if (r!=a.rows()) ++rank; // not all elements in column c are 0
207  }
208  }
209  return rank;
210 }
211 
212 #undef VNL_RANK_INSTANTIATE
213 #define VNL_RANK_INSTANTIATE(T) \
214 template VNL_EXPORT vnl_matrix<T > vnl_rank_row_reduce(vnl_matrix<T > const&, vnl_rank_pivot_type);\
215 template VNL_EXPORT vnl_matrix<T > vnl_rank_column_reduce(vnl_matrix<T > const&, vnl_rank_pivot_type);\
216 template VNL_EXPORT vnl_matrix<T > vnl_rank_row_column_reduce(vnl_matrix<T > const&, vnl_rank_pivot_type);\
217 template VNL_EXPORT unsigned int vnl_rank(vnl_matrix<T > const&, vnl_rank_type)
218 
219 #endif // vnl_rank_hxx_
Direct computation of the rank of a matrix, without using svd.
VNL_EXPORT vnl_matrix< T > vnl_rank_row_reduce(vnl_matrix< T > const &mat, vnl_rank_pivot_type=vnl_rank_pivot_all)
Row reduce a matrix.
#define m
Definition: vnl_vector.h:43
vnl_rank_type
Definition: vnl_rank.h:19
VNL_EXPORT vnl_matrix< T > vnl_rank_column_reduce(vnl_matrix< T > const &mat, vnl_rank_pivot_type=vnl_rank_pivot_all)
Column reduce a matrix.
An ordinary mathematical matrix.
Definition: vnl_adjugate.h:22
unsigned int rows() const
Return the number of rows.
Definition: vnl_matrix.h:179
vnl_rank_pivot_type
Definition: vnl_rank.h:20
VNL_EXPORT unsigned int vnl_rank(vnl_matrix< T > const &mat, vnl_rank_type=vnl_rank_both)
Returns the rank of a matrix.
VNL_EXPORT vnl_matrix< T > vnl_rank_row_column_reduce(vnl_matrix< T > const &mat, vnl_rank_pivot_type=vnl_rank_pivot_all)
Row and column reduce a matrix.
unsigned int columns() const
Return the number of columns.
Definition: vnl_matrix.h:187