Changeset 3157 in Sophya for trunk/Cosmo/SimLSS/geneutils.cc
- Timestamp:
- Jan 25, 2007, 6:04:48 PM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Cosmo/SimLSS/geneutils.cc
r3115 r3157 19 19 // Classe d'interpolation lineaire: 20 20 // Le vecteur y a n elements y_i tels que y_i = f(x_i) 21 // Les x_i sont regulierement espaces22 // et x_0=xmin et x_{n-1}=xmax 21 // ou les x_i sont regulierement espaces 22 // et x_0=xmin et x_{n-1}=xmax (xmax inclus!) 23 23 InterpFunc::InterpFunc(double xmin,double xmax,vector<double>& y) 24 24 : _xmin(xmin), _xmax(xmax), _y(y) … … 29 29 } 30 30 _nm1 = _y.size()-1; 31 _xlarg = _xmax-_xmin; 32 _dx = _xlarg/(double)_nm1; 31 _dx = (_xmax-_xmin)/(double)_nm1; 33 32 } 34 33 … … 37 36 ok=0; if(x<_xmin) ok=1; else if(x>_xmax) ok=2; 38 37 x -= _xmin; 39 long i = long(x/_ xlarg*_nm1); // On prend le "i" juste en dessous38 long i = long(x/_dx); // On prend le "i" juste en dessous 40 39 if(i<0) i=0; else if(i>=_nm1) i=_nm1-1; 41 40 return _y[i] + (_y[i+1]-_y[i])/_dx*(x-i*_dx); … … 46 45 ok=0; if(x<_xmin) ok=1; else if(x>_xmax) ok=2; 47 46 x -= _xmin; 48 long i = long(x/_ xlarg*_nm1+0.5); // On prend le "i" le + proche47 long i = long(x/_dx+0.5); // On prend le "i" le + proche 49 48 if(i<1) i=1; else if(i>=_nm1-1) i=_nm1-2; 50 49 double a = (_y[i+1]-2.*_y[i]+_y[i-1])/(2.*_dx*_dx); 51 50 double b = (_y[i+1]-_y[i-1])/(2.*_dx); 52 51 return _y[i] + (x-i*_dx)*(a*(x-i*_dx)+b); 52 } 53 54 //------------------------------------------------------------------- 55 // Classe d'inversion d'une fonction STRICTEMENT MONOTONE CROISSANTE 56 // - Le vecteur y a "Nin" elements y_i tels que "y_i = f(x_i)" 57 // - On a x(i) < x(i+1) et y(i) < y(i+1) 58 // - La classe renvoie ymin=y(0) , ymax=y(Nin -1) 59 // et le vecteur x = f^-1(y) de "Nout" elements 60 // Les y_i sont regulierement espaces et ymin et ymax 61 // La re-interpolation inverse est faite par lineaire 62 InverseFunc::InverseFunc(vector<double>& x,vector<double>& y) 63 : _ymin(0.) , _ymax(0.) , _x(x) , _y(y) 64 { 65 int_4 ns = _x.size(); 66 if(ns<3 || _y.size()<=0 || ns!=_y.size()) 67 throw ParmError("InverseFunc::InverseFunc_Error: bad array size"); 68 69 // Check "x" strictement monotone croissant 70 for(int_4 i=0;i<ns-1;i++) 71 if(_x[i+1]<=_x[i]) { 72 cout<<"InverseFunc::InverseFunc_Error: _x array not stricly growing"<<endl; 73 throw ParmError("InverseFunc::InverseFunc_Error: _x array not stricly growing"); 74 } 75 76 // Check "y" monotone croissant 77 for(int_4 i=0;i<ns-1;i++) 78 if(_y[i+1]<_y[i]) { 79 cout<<"InverseFunc::InverseFunc_Error: _y array not growing"<<endl; 80 throw ParmError("InverseFunc::InverseFunc_Error: _y array not growing"); 81 } 82 83 // define limits 84 _ymin = _y[0]; 85 _ymax = _y[ns-1]; 86 87 } 88 89 InverseFunc::~InverseFunc(void) 90 { 91 } 92 93 int InverseFunc::ComputeLinear(long n,vector<double>& xfcty) 94 { 95 if(n<3) return -1; 96 97 xfcty.resize(n); 98 99 long i1,i2; 100 double x; 101 for(int_4 i=0;i<n;i++) { 102 double y = _ymin + i*(_ymax-_ymin)/(n-1.); 103 find_in_y(y,i1,i2); 104 double dy = _y[i2]-_y[i1]; 105 if(dy==0.) { 106 x = (_x[i2]+_x[i1])/2.; // la fct a inverser est plate! 107 } else { 108 x = _x[i1] + (_x[i2]-_x[i1])/dy * (y-_y[i1]); 109 } 110 xfcty[i] = x; 111 } 112 113 return 0; 114 } 115 116 int InverseFunc::ComputeParab(long n,vector<double>& xfcty) 117 { 118 if(n<3) return -1; 119 120 xfcty.resize(n); 121 122 long i1,i2,i3; 123 double x; 124 for(int_4 i=0;i<n;i++) { 125 double y = _ymin + i*(_ymax-_ymin)/(n-1.); 126 find_in_y(y,i1,i2); 127 // On cherche le 3ieme point selon la position de y / au 2 premiers 128 double my = (_y[i1]+_y[i2])/2.; 129 if(y<my) {i3=i2; i2=i1; i1--;} else {i3=i2+1;} 130 // Protection 131 if(i1<0) {i1++; i2++; i3++;} 132 if(i3==_y.size()) {i1--; i2--; i3--;} 133 // Interpolation parabolique 134 double dy = _y[i3]-_y[i1]; 135 if(dy==0.) { 136 x = (_x[i3]+_x[i1])/2.; // la fct a inverser est plate! 137 } else { 138 double X1=_x[i1]-_x[i2], X3=_x[i3]-_x[i2]; 139 double Y1=_y[i1]-_y[i2], Y3=_y[i3]-_y[i2]; 140 double den = Y1*Y3*dy; 141 double a = (X3*Y1-X1*Y3)/den; 142 double b = (X1*Y3*Y3-X3*Y1*Y1)/den; 143 y -= _y[i2]; 144 x = (a*y+b)*y + _x[i2]; 145 } 146 xfcty[i] = x; 147 } 148 149 return 0; 53 150 } 54 151
Note:
See TracChangeset
for help on using the changeset viewer.