#ifndef LMVMMAT_H
#define LMVMMAT_H

#include "taomat.h"

class TaoLMVMMat: public TaoMat{

 protected:

  int lm;
  int lmnow;
  int iter;
  int rejects;
	
  double eps;

  TaoVec ** S;
  TaoVec ** Y;
  TaoVec *Gprev;
  TaoVec *Xprev;

  TaoTruth H0default;
  TaoMat *H0;
  TaoVec *H0Vec;

  double y0normsquared;
  double *rho;
  double *beta;
		
 public:
  
  TaoLMVMMat( TaoVec *, int nlm );
  ~TaoLMVMMat();

  inline int countrejects(){ return(rejects);}

  int reset();
  int update(TaoVec*, TaoVec*);
  int InitialApproximation(TaoVec*);
  int SetH0(TaoMat*);

  int Presolve();
  int Solve(TaoVec*, TaoVec*, TaoTruth*);
  int minQuadraticTrustRegion(TaoVec*,TaoVec*,double, TaoTruth*);
  int GetX0(TaoVec*);

  int Clone(TaoMat**);
  int CopyFrom(TaoMat*);

  /** Get the dimension of the vector spaces */
  int GetDimensions( int*, int * );

  int Multiply(TaoVec*,TaoVec*);
  int MultiplyAdd(TaoVec*,TaoVec*,TaoVec*);
  int MultiplyTranspose(TaoVec*,TaoVec*);
  int MultiplyTransposeAdd(TaoVec*,TaoVec*,TaoVec*);

  int SetDiagonal(TaoVec*);
  int AddDiagonal(TaoVec*);
  int GetDiagonal(TaoVec*);
  int ShiftDiagonal(double);

  int View();
  int extractSubMatrix(TaoMat**,TaoIndexSet*,TaoIndexSet*);

  int RowScale(TaoVec*);
  int ColScale(TaoVec*);

  int D_Fischer(TaoVec *, TaoVec *, TaoVec *, TaoVec *, 
		TaoVec *, TaoVec *, TaoVec *, TaoVec *);
  int D_SFischer(TaoVec *, TaoVec *, TaoVec *, TaoVec *, double,
		 TaoVec *, TaoVec *, TaoVec *, TaoVec *, TaoVec *);

};

#endif

