Eigenproblem.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. #include "Eigenproblem.h"
  2. #include <iostream>
  3. using namespace OBJREC;
  4. using namespace std;
  5. static Eigenproblem* eigen=NULL;
  6. static void op(int* nrow, int* ncol, double* xin, int* ldx, double* xout, int* ldy){
  7. eigen->sparseMult(xin,xout,*ldy);
  8. }
  9. void Eigenproblem::sparseMult(double* xin, double* xout,int ldy){
  10. memset(xout,0,ldy*sizeof(double));
  11. for(uint i=0;i<mat.size();i++){
  12. xout[mat[i].x]+=mat[i].val * xin[mat[i].y];
  13. }
  14. }
  15. typedef void (*OpFunc) (int* nrow,int* ncol, double* xin,int* ldx, double* xout, int* ldy);
  16. extern "C" void trlan77_(OpFunc op, int ipar[32], int* nrowl, int* mev, double* eval,
  17. double* evec, int* nrow2, double* wrk, int* lwrk);
  18. void Eigenproblem::solve(vector<element> mat, int mat_size, vector<double> &evals,
  19. vector< vector<double> > &evecs, int k, int magnitude,
  20. int restarting_scheme, double tolerance, int max_mult,
  21. int mult_flops){
  22. this->mat=mat;
  23. if(max_mult<=0) max_mult=10*mat_size;
  24. if(mult_flops<=0) mult_flops=10*mat_size;
  25. eigen=this;
  26. int computed_eigenpairs=k;
  27. int ipar[32]={0,magnitude,computed_eigenpairs,0,0,restarting_scheme,max_mult,0,1,99,-1,98,mult_flops};
  28. double* evalbuff=new double[k];
  29. memset(evalbuff,0,k*sizeof(double));
  30. double* evecbuff=new double[k*mat_size];
  31. memset(evecbuff,1,k*mat_size*sizeof(double));
  32. int ritz_size=(computed_eigenpairs<3 ? 2*computed_eigenpairs : computed_eigenpairs+6);
  33. int workspace_size=ritz_size*(ritz_size+10);
  34. double* workspace=new double[workspace_size];
  35. workspace[0]=tolerance;
  36. trlan77_(op,ipar,&mat_size,&k,evalbuff,evecbuff,&mat_size,workspace,&workspace_size);
  37. if(ipar[0]!=0)
  38. {
  39. fprintf(stderr,"EigValuesTRLAN: Error occured by calling TRLAN Eigenvalue Computation.\n");
  40. fprintf(stderr,"EigValuesTRLAN: %d converged eigenvectors \n",ipar[3]);
  41. }
  42. //copy eigenvectors in evecbuff to stl vector
  43. for(int i=0;i<k;i++){
  44. vector<double> vec;
  45. for(int j=0;j<mat_size;j++){
  46. vec.push_back(evecbuff[i*mat_size+j]);
  47. }
  48. evecs.push_back(vec);
  49. }
  50. for(int i=0;i<k;i++){
  51. evals.push_back(evalbuff[i]);
  52. }
  53. delete[] evalbuff;
  54. delete[] evecbuff;
  55. }