00001 #ifndef RSYMDIAG_HEADER
00002 #define RSYMDIAG_HEADER
00003
00004
00005
00014
00015
00016
00017
00018 #include <stdlib.h>
00019 #include <math.h>
00020
00021 #ifdef _STANDARD_C_PLUS_PLUS
00022 #include <list>
00023 using namespace std;
00024 #else
00025 #include <list.h>
00026 #endif
00027
00028
00029
00030 #include"Vector.hh"
00031 #include"Rectmat.hh"
00032 #include"Symmat.hh"
00033 #include "Fparch.hh"
00034
00035
00036
00037 namespace RazorBack {
00038
00046 class Rsymdiag_
00047 {
00048
00049 private:
00050
00051 static const Fparch_<double> Fpdbl;
00052 static const Fparch_<float> Fpflo;
00053 static const double EPSILON;
00054
00055
00056 private:
00057
00062 struct Eigidx_
00063 {
00064 double Eig;
00065 size_t Idx;
00066
00067 friend bool operator<(const Eigidx_& E1, const Eigidx_& E2)
00068 { return (E1.Eig>E2.Eig); }
00069 };
00070
00071 struct Evaloc_;
00072 friend struct Evaloc_;
00079 struct Evaloc_
00080 {
00081 double Low, Up;
00082 double Eval;
00083 size_t Lowno, Upno, No;
00084
00086 Evaloc_(double L, size_t Ln, double U, size_t Un):
00087 Low(L), Lowno(Ln), Up(U), Upno(Un), No(Un-Ln), Eval(0.0) {}
00088
00093 bool bracket_loose() const
00094 {
00095 return fabs(Up-Low)>EPSILON*(fabs(Up)+fabs(Low));
00096 }
00097 };
00098
00099
00100 private:
00101
00102 size_t Size;
00103 Rmatdbl_ Q;
00104 Vecdbl_ Diag, Subdiag;
00105 Vecdbl_ Beta, Gamma;
00106 bool Tridiagdone,
00107 Qdone,
00108 QLdone;
00109
00110
00111 public:
00112
00114 Rsymdiag_(): Size(0), Tridiagdone(false), Qdone(false), QLdone(false) {}
00115
00117 explicit Rsymdiag_(const Smatdbl_& Mat) { re_init(Mat); }
00118
00124 size_t re_init(const Smatdbl_& Mat);
00125
00127 size_t size() const { return Size; }
00128
00129
00130
00131
00132
00143 int all_evalevec(Vecdbl_& Eval, Rmatdbl_& Evec, bool Sortevals=true);
00144
00154 int all_eval(Vecdbl_& Eval, bool Sortevals=true);
00155
00156
00157
00158
00159
00169 int range_evalevec(double Low, double Up,
00170 Vecdbl_& Eval, Rmatdbl_& Evec, bool Descend=false);
00171
00180 int range_eval(double Low, double Up,
00181 Vecdbl_& Eval, bool Descend=false);
00182
00191 int largest_evalevec(size_t N, Vecdbl_& Eval,
00192 Rmatdbl_& Evec, bool Descend=false);
00193
00202 int largest_eval(size_t N, Vecdbl_& Eval, bool Descend=false);
00203
00213 int evalevec_above(double Thr, Vecdbl_& Eval,
00214 Rmatdbl_& Evec, bool Descend=false);
00215
00225 int eval_above(double Thr, Vecdbl_& Eval, bool Descend=false);
00226
00235 void gershgorin_limits(double& Low, double& Up);
00236
00237
00238 protected:
00239
00240 void housholder_tridiag(bool Wantevec);
00241 int implicit_ql(int Itno, bool Wantevec);
00242
00243 void largest_range(size_t N, double& Low, double& Up);
00244 size_t sturm_seq(double X) const;
00245 double sturm_newton(double X) const;
00246 void bisect_evals(list<Evaloc_>& Evalist,
00247 list<Evaloc_>::iterator Iv);
00248 int inverse_iter(double Eval, Vecdbl_& Evec, double& Tol);
00249 void inverse_iter(double Eval, size_t Multiple, Rmatdbl_& Evecs);
00250 static void gram_schmidt(Rmatdbl_& Mat);
00251 static double subspace_diff(const Rmatdbl_& V, const Rmatdbl_& W);
00252
00253 int tridiag_decomp(const Vecdbl_& Diagshift);
00254 void tridiag_solve(const Vecdbl_& Rhs, Vecdbl_& X) const;
00255
00256 static void random_vector(Vecdbl_& Vec);
00257 static void random_matrix(Rmatdbl_& Mat);
00258 static double round_tozero(double X)
00259 { return ((fabs(X)<EPSILON)? 0.0: X); }
00260 };
00261
00262
00267 class Rsymdiagexc_: public Utilsexc_
00268 {
00269 public:
00270 explicit Rsymdiagexc_(const char *Thnm, const char *Msg, bool F=false):
00271 Utilsexc_(Thnm, F, Msg) {}
00272 private:
00273 Rsymdiagexc_();
00274 };
00275
00276
00277 }
00278
00279
00280
00281 #endif // RSYMDIAG_HEADER