00001 #ifndef __RVL_ALG_LINEAR_SOLVER_H_
00002 #define __RVL_ALG_LINEAR_SOLVER_H_
00003
00004 #include "linop.hh"
00005 #include "alg.hh"
00006
00007 namespace RVLUmin {
00008
00009 using namespace RVL;
00010
00020 template<class Scalar>
00021 class ArnoldiSolverStep : public Algorithm {
00022 protected:
00023 LinearOp<Scalar> & A;
00024 int k;
00025 Vector<Scalar> v;
00026 Vector<Scalar> f;
00027 CartesianPowerSpace<Scalar> vspc;
00028 ProductVector<Scalar> V;
00029 valarray<Scalar> H;
00030 int hcount;
00031 int iter;
00032
00033 ArnoldiSolverStep();
00034
00035 public:
00036 ArnoldiSolverStep(LinearOp<Scalar> & _A, int num_eigs, const Vector<Scalar> & init_guess)
00037 :A(_A), k(num_eigs), v(init_guess), f(A.getRange()),
00038 vspc(k, A.getDomain()), V(vspc), H(k*(k+1)/2+k), hcount(0), iter(0) {
00039 Vector<Scalar> w(A.getRange());
00040 v.scale(Scalar(1.0/v.norm()));
00041 A.applyOp(v,w);
00042 Scalar alpha = v.inner(w);
00043 f.copy(w); f.linComb(-alpha, v);
00044 Scalar c = v.inner(f);
00045 f.linComb(-c, v);
00046 alpha+=c;
00047 V[iter].copy(v);
00048 H[0] = alpha;
00049 hcount++;
00050 }
00051
00052 void run() {
00053
00054 if( iter >= k-1 ) return;
00055 int i = 0;
00056 Vector<Scalar> w(A.getRange());
00057 iter++;
00058 Scalar beta = f.norm();
00059 H[hcount] = beta;
00060 hcount++;
00061 v.scale(Scalar(1.0)/beta, f);
00062 V[iter].copy(v);
00063 A.applyOp(v,w);
00064 valarray<Scalar> h(iter+1), c(iter+1);
00065
00066 for(i=0; i <= iter; i++)
00067 h[i] = V[i].inner(w);
00068
00069 f.copy(w);
00070 for(i=0; i<= iter; i++)
00071 f.linComb(-h[i], V[i]);
00072
00073 for(i=0; i <= iter; i++)
00074 c[i] = V[i].inner(f);
00075
00076 for(i=0; i<= iter; i++)
00077 f.linComb(-c[i], V[i]);
00078
00079
00080 for(i = 0; i < c.size(); i++, hcount++) {
00081 H[hcount] = c[i]+h[i];
00082 }
00083 }
00084
00091 const valarray<Scalar> & getHessenberg() { return H; }
00092
00094 int getHNumEntries() { return hcount; }
00095
00099 const ProductVector<Scalar> & getOrthogonalVecs() { return V; }
00100
00101 int getIterationCount() { return iter; }
00102 int getMaxIter() { return k; }
00103 };
00104
00105 template<typename Scalar>
00106 class Arnoldi: public Algorithm {
00107
00108
00109
00110 }
00111 #endif