struct QRdcmp { Int n; MatDoub qt, r; Bool sing; QRdcmp(MatDoub_I &a); void solve(VecDoub_I &b, VecDoub_O &x); void qtmult(VecDoub_I &b, VecDoub_O &x); void rsolve(VecDoub_I &b, VecDoub_O &x); void update(VecDoub_I &u, VecDoub_I &v); void rotate(const Int i, const Doub a, const Doub b); }; QRdcmp::QRdcmp(MatDoub_I &a) : n(a.nrows()), qt(n,n), r(a), sing(false) { Int i,j,k; VecDoub c(n), d(n); Doub scale,sigma,sum,tau; for (k=0;k=0;i--) { sum=b[i]; for (j=i+1;j=0;k--) if (w[k] != 0.0) break; if (k < 0) k=0; for (i=k-1;i>=0;i--) { rotate(i,w[i],-w[i+1]); if (w[i] == 0.0) w[i]=abs(w[i+1]); else if (abs(w[i]) > abs(w[i+1])) w[i]=abs(w[i])*sqrt(1.0+SQR(w[i+1]/w[i])); else w[i]=abs(w[i+1])*sqrt(1.0+SQR(w[i]/w[i+1])); } for (i=0;i= 0.0 ? 1.0 : -1.0); } else if (abs(a) > abs(b)) { fact=b/a; c=SIGN(1.0/sqrt(1.0+(fact*fact)),a); s=fact*c; } else { fact=a/b; s=SIGN(1.0/sqrt(1.0+(fact*fact)),b); c=fact*s; } for (j=i;j