#include "sopnamsp.h" #include "machdefs.h" #include #include #include #include #include #include #include "pexceptions.h" #include "histos.h" #include "hisprof.h" #include "srandgen.h" #include "geneutils.h" //------------------------------------------------------------------- // Classe d'interpolation lineaire: // Le vecteur y a n elements y_i tels que y_i = f(x_i) // ou les x_i sont regulierement espaces // et x_0=xmin et x_{n-1}=xmax (xmax inclus!) InterpFunc::InterpFunc(double xmin,double xmax,vector& y) : _xmin(xmin), _xmax(xmax), _y(y) { if(_xmin>=_xmax || _y.size()<=2) { // au moins 3 points! cout<<"InterpFunc::InterpFunc : bad arguments values"<_xmax) ok=2; x -= _xmin; long i = long(x/_dx); // On prend le "i" juste en dessous if(i<0) i=0; else if(i>=_nm1) i=_nm1-1; return _y[i] + (_y[i+1]-_y[i])/_dx*(x-i*_dx); } double InterpFunc::Parab(double x,unsigned short& ok) { ok=0; if(x<_xmin) ok=1; else if(x>_xmax) ok=2; x -= _xmin; long i = long(x/_dx+0.5); // On prend le "i" le + proche if(i<1) i=1; else if(i>=_nm1-1) i=_nm1-2; double a = (_y[i+1]-2.*_y[i]+_y[i-1])/(2.*_dx*_dx); double b = (_y[i+1]-_y[i-1])/(2.*_dx); return _y[i] + (x-i*_dx)*(a*(x-i*_dx)+b); } //------------------------------------------------------------------- // Classe d'inversion d'une fonction STRICTEMENT MONOTONE CROISSANTE // - Le vecteur y a "Nin" elements y_i tels que "y_i = f(x_i)" // - On a x(i) < x(i+1) et y(i) < y(i+1) // - La classe renvoie ymin=y(0) , ymax=y(Nin -1) // et le vecteur x = f^-1(y) de "Nout" elements // Les y_i sont regulierement espaces et ymin et ymax // La re-interpolation inverse est faite par lineaire InverseFunc::InverseFunc(vector& x,vector& y) : _ymin(0.) , _ymax(0.) , _x(x) , _y(y) { int_4 ns = _x.size(); if(ns<3 || _y.size()<=0 || ns!=_y.size()) throw ParmError("InverseFunc::InverseFunc_Error: bad array size"); // Check "x" strictement monotone croissant for(int_4 i=0;i& xfcty) { if(n<3) return -1; xfcty.resize(n); long i1,i2; double x; for(int_4 i=0;i& xfcty) { if(n<3) return -1; xfcty.resize(n); long i1,i2,i3; double x; for(int_4 i=0;i& v,double xmin,double xmax,bool logaxex) // Remplit le TVector avec la fonction "func" // INPUT: // logaxex = false : remplissage lineaire // les abscisses "x" des bins sont remplis avec f(x) // logaxex = true : remplissage logarithmique (base 10) // les abscisses "x" des bins sont remplis avec f(10^x) // RETURN: // 0 = OK // 1 = error // Remarque: // v(i) = f(xmin+i*dx) avec dx = (xmax-xmin)/v.NElts() { if(v.NElts()<=0 || xmax<=xmin) return 1; v = 0.; double dx = (xmax-xmin)/v.NElts(); for(int_4 i=0;iM_PI) theta2=M_PI; return 2.*dphi * (cos(theta1)-cos(theta2)); } double AngSol(double dtheta) // Retourne l'angle solide d'une calotte spherique de demi-ouverture "dtheta" // Attention: Les unites des angles sont en radians // dtheta in [0,Pi] // Return: l'angle solide en steradian // Approx pour theta petit: PI theta^2 { return 2.*M_PI * (1.-cos(dtheta)); } //------------------------------------------------------------------- unsigned long PoissRandLimit(double mu,double mumax) { double pp,ppi,x; unsigned long n; if(mu>=mumax) { pp = sqrt(mu); while( (x=pp*NorRand()) < -mu ); return (unsigned long)(mu+x+0.5); } ppi = pp = exp(-mu); x = drand01(); n = 0; while (x > ppi) { n++; pp = mu*pp/(double)n; ppi += pp; } return n; }