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