arnoldi.hh

Go to the documentation of this file.
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; // length k.  Will push_back new column DC each iter.
00029     valarray<Scalar> H; // arranged columnwise.  Will add k+1 elements each iter.
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); // w <- Av
00042       Scalar alpha = v.inner(w); // alpha <- v'*Av
00043       f.copy(w); f.linComb(-alpha, v); // f<- Av - alpha v
00044       Scalar c = v.inner(f); // c <- v'*(Av-alpha v)
00045       f.linComb(-c, v); // f<- f-c v
00046       alpha+=c;
00047       V[iter].copy(v);
00048       H[0] = alpha;
00049       hcount++;
00050     }
00051 
00052     void run() {
00053       // note: no-op if you're done - needs coupling to terminator in driver
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; // fill in subdiagonal entry on previous column;
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       // h = V'*w
00066       for(i=0; i <= iter; i++)
00067     h[i] = V[i].inner(w);
00068       // f = w-V*h
00069       f.copy(w);
00070       for(i=0; i<= iter; i++)
00071     f.linComb(-h[i], V[i]);
00072       // c = V'*f
00073       for(i=0; i <= iter; i++)
00074     c[i] = V[i].inner(f);
00075       // f = f-V*c
00076       for(i=0; i<= iter; i++)
00077     f.linComb(-c[i], V[i]);
00078  
00079       // fill in upper triangle
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

Generated on 5 Jan 2017 for RvlUmin by  doxygen 1.4.7