15T pythag(
const T a,
const T b) {
16 T absa=std::abs(a), absb=std::abs(b);
17 return T((absa > absb ? absa*sqrt(1.0+(absb/absa)*(absb/absa)) :
18 (absb == 0.0 ? 0.0 : absb*sqrt(1.0+(absa/absb)*(absa/absb)))));
29bool svd(
const mat<T> &a, mat<T> &u, diag_mat<T> &w, mat<T> &v,
bool ordering=
true,
int maxiter=30)
37 T eps=std::numeric_limits<T>::epsilon();
40 int i,its,j,jj,k,l,nm;
41 T anorm,c,f,g,h,s,scale,x,y,z;
43 g = scale = anorm = 0.0;
49 for (k=i;k<m;k++) scale += std::abs(u(k,i));
56 g = -sign(std::sqrt(s),f);
60 for (s=0.0,k=i;k<m;k++) s += u(k,i)*u(k,j);
62 for (k=i;k<m;k++) u(k,j) += f*u(k,i);
64 for (k=i;k<m;k++) u(k,i) *= scale;
69 if (i+1 <= m && i+1 != n) {
70 for (k=l-1;k<n;k++) scale += std::abs(u(i,k));
77 g = -sign(std::sqrt(s),f);
80 for (k=l-1;k<n;k++) rv1[k]=u(i,k)/h;
82 for (s=0.0,k=l-1;k<n;k++) s += u(j,k)*u(i,k);
83 for (k=l-1;k<n;k++) u(j,k) += s*rv1[k];
85 for (k=l-1;k<n;k++) u(i,k) *= scale;
88 anorm=(std::max)(anorm,(std::abs(w[i])+std::abs(rv1[i])));
90 for (i=n-1;i>=0;i--) {
94 v(j,i)=(u(i,j)/u(i,l))/g;
96 for (s=0.0,k=l;k<n;k++) s += u(i,k)*v(k,j);
97 for (k=l;k<n;k++) v(k,j) += s*v(k,i);
100 for (j=l;j<n;j++) v(i,j)=v(j,i)=0.0;
106 for (i=(std::min)(m,n)-1;i>=0;i--) {
109 for (j=l;j<n;j++) u(i,j)=0.0;
113 for (s=0.0,k=l;k<m;k++) s += u(k,i)*u(k,j);
115 for (k=i;k<m;k++) u(k,j) += f*u(k,i);
117 for (j=i;j<m;j++) u(j,i) *= g;
118 }
else for (j=i;j<m;j++) u(j,i)=0.0;
121 for (k=n-1;k>=0;k--) {
122 for (its=0;its<maxiter;its++) {
126 if (l == 0 || std::abs(rv1[l]) <= eps*anorm) {
130 if (std::abs(w[nm]) <= eps*anorm)
break;
135 for (i=l;i<k+1;i++) {
138 if (std::abs(f) <= eps*anorm)
break;
157 for (j=0;j<n;j++) v(j,k) = -v(j,k);
161 if (its == maxiter-1)
168 f=((y-z)*(y+z)+(g-h)*(g+h))/((T)2.0*h*y);
170 f=((x-z)*(x+z)+h*((y/(f+sign(g,f)))-h))/x;
172 for (j=l;j<=nm;j++) {
186 for (jj=0;jj<n;jj++) {
201 for (jj=0;jj<m;jj++) {
218 do { inc *= 3; inc++; }
while (inc <= n);
221 for (i=inc;i<n;i++) {
223 for (k=0;k<m;k++) su[k] = u(k,i);
224 for (k=0;k<n;k++) sv[k] = v(k,i);
226 while (w[j-inc] < sw) {
228 for (k=0;k<m;k++) u(k,j) = u(k,j-inc);
229 for (k=0;k<n;k++) v(k,j) = v(k,j-inc);
234 for (k=0;k<m;k++) u(k,j) = su[k];
235 for (k=0;k<n;k++) v(k,j) = sv[k];
241 for (i=0;i<m;i++)
if (u(i,k) < 0.) s++;
242 for (j=0;j<n;j++)
if (v(j,k) < 0.) s++;
244 for (i=0;i<m;i++) u(i,k) = -u(i,k);
245 for (j=0;j<n;j++) v(j,k) = -v(j,k);
250 T tsh = (T)(0.5*sqrt(m+n+1.)*w[0]*eps);
259mat<T> null(
const mat<T>& a)
261 T eps =std::numeric_limits<T>::epsilon();
268 if(a.nrows() > a.ncols())
269 tol = (T)a.nrows()*eps;
271 tol = (T)a.ncols()*eps;
273 for(
unsigned i = 0; i < s.ncols(); i++)
281 mat<T> N = v.sub_mat(0, r,v.nrows(),a.ncols()-r);
282 for(
unsigned i = 0; i < N.nrows();i++)
283 for(
unsigned j = 0; j < N.ncols();j++)
284 if(std::abs(N(i,j)) < eps) N(i,j)=(T)0;
289 return zeros<T> (a.ncols(), 0);
294mat<T> pseudo_inv(
const mat<T>& a, T eps = std::numeric_limits<T>::epsilon())
299 for(
unsigned i = 0; i < s.ncols(); i++)
306 return v*s*transpose(u);
313mat<T> null(
const mat<T>& a, T tol)
315 T eps =std::numeric_limits<T>::epsilon();
322 for(
unsigned i = 0; i < s.ncols(); i++)
330 mat<T> N = v.submat(0, r,v.nrows(),a.ncols()-r);
331 for(
unsigned i = 0; i < N.nrows();i++)
332 for(
unsigned j = 0; j < N.ncols();j++)
333 if(std::abs(N(i,j)) < eps) N(i,j)=(T)0;
338 return zeros<T> (a.ncols(), 0);
345unsigned rank(
const mat<T>& a)
352 if(a.nrows() > a.ncols())
353 tol = (T)a.nrows()*std::numeric_limits<T>::epsilon();
355 tol = (T)a.ncols()*std::numeric_limits<T>::epsilon();
357 for(
unsigned i = 0; i < s.ncols(); i++)
367unsigned rank(
const mat<T>& a, T tol)
374 for(
unsigned i = 0; i < s.ncols(); i++)
389 T eps =std::numeric_limits<T>::epsilon();
397 tol = (T)A.
nrows()*eps;
399 tol = (T)A.
ncols()*eps;
401 for(
unsigned i = 0; i < s.ncols(); i++)
408 p=v*s*transpose(u)*b;
413 for(
unsigned i = 0; i < N.
nrows();i++)
414 for(
unsigned j = 0; j < N.
ncols();j++)
415 if(std::abs(N(i,j)) < eps) N(i,j)=(T)0;
421 N = zeros<T> (A.
ncols(), 0);
A matrix type (full column major storage) The matrix can be loaded directly into OpenGL without need ...
unsigned ncols() const
number of columns
mat< T > sub_mat(unsigned top, unsigned left, unsigned rows, unsigned cols) const
create submatrix m(top,left)...m(top+rows,left+cols)
unsigned nrows() const
number of rows