Changeset 3157 in Sophya for trunk/Cosmo/SimLSS/geneutils.cc


Ignore:
Timestamp:
Jan 25, 2007, 6:04:48 PM (19 years ago)
Author:
cmv
Message:

intro du facteur de croissance dans la simul cmv 25/01/2007

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Cosmo/SimLSS/geneutils.cc

    r3115 r3157  
    1919// Classe d'interpolation lineaire:
    2020// Le vecteur y a n elements y_i tels que y_i = f(x_i)
    21 // Les x_i sont regulierement espaces
    22 //   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!)
    2323InterpFunc::InterpFunc(double xmin,double xmax,vector<double>& y)
    2424  : _xmin(xmin), _xmax(xmax), _y(y)
     
    2929  }
    3030  _nm1   = _y.size()-1;
    31   _xlarg = _xmax-_xmin;
    32   _dx    = _xlarg/(double)_nm1;
     31  _dx    = (_xmax-_xmin)/(double)_nm1;
    3332}
    3433
     
    3736  ok=0; if(x<_xmin) ok=1; else if(x>_xmax) ok=2;
    3837  x -= _xmin;
    39   long i = long(x/_xlarg*_nm1);  // On prend le "i" juste en dessous
     38  long i = long(x/_dx);  // On prend le "i" juste en dessous
    4039  if(i<0) i=0; else if(i>=_nm1) i=_nm1-1;
    4140  return _y[i] + (_y[i+1]-_y[i])/_dx*(x-i*_dx);
     
    4645  ok=0; if(x<_xmin) ok=1; else if(x>_xmax) ok=2;
    4746  x -= _xmin;
    48   long i = long(x/_xlarg*_nm1+0.5);  // On prend le "i" le + proche
     47  long i = long(x/_dx+0.5);  // On prend le "i" le + proche
    4948  if(i<1) i=1; else if(i>=_nm1-1) i=_nm1-2;
    5049  double a = (_y[i+1]-2.*_y[i]+_y[i-1])/(2.*_dx*_dx);
    5150  double b = (_y[i+1]-_y[i-1])/(2.*_dx);
    5251  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
     62InverseFunc::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
     89InverseFunc::~InverseFunc(void)
     90{
     91}
     92
     93int 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
     116int 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;
    53150}
    54151
Note: See TracChangeset for help on using the changeset viewer.