main.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #include "RBFInterp.hpp"
  2. #include "interp.hpp"
  3. #include "gnuplot.hpp"
  4. #include <iostream>
  5. #include <fstream>
  6. #include <cstdlib>
  7. #include <ctime>
  8. #include <algorithm>
  9. #include <string>
  10. #include "time_mes.hpp"
  11. using namespace std;
  12. // Fonction à interpoler z= f(x,y)
  13. float finit(int x,int y)
  14. {
  15. return 1.0+float(x*sin(float(x)/1000.)+2*y)/1000.;
  16. }
  17. int main()
  18. {
  19. typedef float real;
  20. //
  21. typedef typename RBFInterp<real,Gauss<real>>::PointValue PointValue;
  22. // taille de l'"image":
  23. int nx=1500,ny=1500;
  24. cout<<"nx : "<<nx<<" ny : "<<ny<<endl;
  25. real* image= new real[nx*ny];
  26. //
  27. std::srand(std::time(nullptr)); // seed with current time.
  28. // Choisir npts points d'interpolation au hasard dans l'image:
  29. PointValue Values;
  30. int npts= 50;
  31. for(int i=0;i<npts;i++)
  32. {
  33. auto vrand=float(std::rand())/RAND_MAX;
  34. int xx= static_cast<int>(nx*vrand);
  35. vrand=float(std::rand())/RAND_MAX;
  36. int yy= static_cast<int>(ny*vrand);
  37. auto k=make_pair(xx,yy);
  38. Values[k]=finit(xx,yy);
  39. if(xx<0 || xx>=nx||yy<0 || yy>=ny)
  40. // vérifier que les points sont dans l'image.
  41. throw "pas bien";
  42. }
  43. cout<<"nb. values : "<<Values.size()<<endl;
  44. //
  45. double start,stop;
  46. // Choisir au hasard une partie des points d'interpolation:
  47. PointValue Test,NoTest;
  48. float portion_in_Notest = 0.8;
  49. for(typename PointValue::const_iterator I =Values.begin();I!=Values.end();I++)
  50. {
  51. float srand=float(std::rand())/RAND_MAX;
  52. if(srand<portion_in_Notest)
  53. // les points qui vont servir a construire l'interpolation.
  54. NoTest[I->first]= I->second;
  55. else
  56. // les points de test.
  57. Test[I->first]= I->second;
  58. }
  59. cout<<"estimation d'epsilon. nb. noeuds : "<<NoTest.size()<<
  60. " nb. points de test : "<<Test.size()<<endl;
  61. // interpolant:
  62. typedef MQI<real> typRad;
  63. // typedef TPS<real> typRad;
  64. //typedef TPSD<real> typRad;
  65. //typedef Gauss<real> typRad;
  66. real eps= 0.01;
  67. RBFInterp<real,typRad> A(eps);
  68. //
  69. // Les points d'interpolation :
  70. gnuplotfile(Values,"points");
  71. //--1--- Détermination d'un epsilon "optimal" pour les RBF.
  72. ofstream f; f.open("eps-err");
  73. start=get_time();
  74. real epsm= eps;
  75. real testm=1.e10;
  76. for(int iter=1;iter<=25;iter++)
  77. {
  78. eps/= 10.;
  79. A.set_epsilon(eps);
  80. bool calcond=false; // on calcule ou non le conditionnement (pas
  81. // nécessaire, mais peut donner un renseignement
  82. //utile).
  83. try{
  84. A.build(NoTest,calcond);
  85. }
  86. catch(const LapackException& e )
  87. {
  88. // normalement quand epsilon est trop petit, le système
  89. // linéaire devient singulier. On va donc à priori venir ici
  90. // plutôt que de sortir normalement de la boucle.
  91. eps*=10;
  92. break;
  93. }
  94. auto test= A.test(NoTest,Test);
  95. cout<<"eps : "<<eps<<" test : "<<test<<endl;;
  96. if(calcond)
  97. {
  98. // si on a calculé le conditionnement de la matrice:
  99. if(calcond)
  100. {
  101. cout<<"norme matrice : "<<A.norme_matrice();
  102. cout<<" conditionnement : "<<A.cond();
  103. cout<<endl<<endl;
  104. }
  105. }
  106. f<<eps<<" "<<test<<endl;
  107. if(test<testm)
  108. {
  109. testm=test;
  110. epsm=eps;
  111. }
  112. }
  113. stop=get_time();
  114. cout <<endl<<"--- (durée) preparation :"<<stop-start<<endl;
  115. f.close();
  116. cout<<"estimation ok"<<endl;
  117. // On introduit le meilleur epsilon trouvé pour les RBF.
  118. A.set_epsilon(epsm);
  119. cout<<"epsilon utilisé : "<<epsm<<endl;
  120. start=get_time();
  121. try{
  122. A.build(Values);
  123. }
  124. catch(const LapackException& e )
  125. {
  126. cout<<"Lapack exception: "<<e.Info<<endl;
  127. throw;
  128. }
  129. stop=get_time();
  130. cout <<"--- (durée) interpolants : "<<stop-start<<endl;
  131. cout<<"interpolants ok"<<endl;
  132. start=get_time();
  133. int increment=2;
  134. A.Interp(Values,image,nx,ny,increment);
  135. stop=get_time();
  136. cout <<"--- (durée) interpolation RBF : "<<stop-start<<endl;
  137. cout<<"interpolation ok"<<endl;
  138. start=get_time();
  139. interpquad(image,nx,ny);
  140. stop=get_time();
  141. cout <<"--- (durée) interpolation quad. : "<<stop-start<<endl;
  142. string aa;cout<<"g pour sortir les fichiers gnuplot ou tout autre caractère sinon :";
  143. cin>>aa;
  144. if(aa=="g")
  145. {
  146. cout<<"gnuplot files :"<<endl;
  147. // interpolation sur la grille :
  148. gnuplotfile(nx,ny,image,"image");
  149. }
  150. // erreur :
  151. real* diff= new real[nx*ny];
  152. auto indix= [nx](int i, int j){return i*nx+j;};
  153. #pragma omp parallel for
  154. for(int i=0;i<nx;i++)
  155. for(int j=0;j<ny;j++)
  156. diff[indix(i,j)]=abs(image[indix(i,j)]-finit(i,j));
  157. if(aa=="g")
  158. gnuplotfile(nx,ny,diff,"diff");
  159. // erreur relative
  160. #pragma omp parallel for
  161. for(int i=0;i<nx;i++)
  162. for(int j=0;j<ny;j++)
  163. diff[indix(i,j)]/=abs(finit(i,j));
  164. auto vmax=max_element(diff,diff+nx*ny);
  165. cout<<"erreur relative max: "<<*vmax<<endl;
  166. if(aa=="g")
  167. gnuplotfile(nx,ny,diff,"diffrel");
  168. delete[] image;
  169. delete[] diff;
  170. }