source: Sophya/trunk/Cosmo/SimLSS/geneutils.cc@ 3120

Last change on this file since 3120 was 3115, checked in by ansari, 19 years ago

Creation initiale du groupe Cosmo avec le repertoire SimLSS de
simulation de distribution de masse 3D des galaxies par CMV+Rz
18/12/2006

File size: 4.2 KB
Line 
1#include "sopnamsp.h"
2#include "machdefs.h"
3#include <iostream>
4#include <stdlib.h>
5#include <stdio.h>
6#include <string.h>
7#include <math.h>
8#include <vector>
9
10#include "pexceptions.h"
11
12#include "histos.h"
13#include "hisprof.h"
14#include "srandgen.h"
15
16#include "geneutils.h"
17
18//-------------------------------------------------------------------
19// Classe d'interpolation lineaire:
20// 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
23InterpFunc::InterpFunc(double xmin,double xmax,vector<double>& y)
24 : _xmin(xmin), _xmax(xmax), _y(y)
25{
26 if(_xmin>=_xmax || _y.size()<=2) { // au moins 3 points!
27 cout<<"InterpFunc::InterpFunc : bad arguments values"<<endl;
28 throw ParmError("InterpFunc::InterpFunc : bad arguments values");
29 }
30 _nm1 = _y.size()-1;
31 _xlarg = _xmax-_xmin;
32 _dx = _xlarg/(double)_nm1;
33}
34
35double InterpFunc::Linear(double x,unsigned short& ok)
36{
37 ok=0; if(x<_xmin) ok=1; else if(x>_xmax) ok=2;
38 x -= _xmin;
39 long i = long(x/_xlarg*_nm1); // On prend le "i" juste en dessous
40 if(i<0) i=0; else if(i>=_nm1) i=_nm1-1;
41 return _y[i] + (_y[i+1]-_y[i])/_dx*(x-i*_dx);
42}
43
44double InterpFunc::Parab(double x,unsigned short& ok)
45{
46 ok=0; if(x<_xmin) ok=1; else if(x>_xmax) ok=2;
47 x -= _xmin;
48 long i = long(x/_xlarg*_nm1+0.5); // On prend le "i" le + proche
49 if(i<1) i=1; else if(i>=_nm1-1) i=_nm1-2;
50 double a = (_y[i+1]-2.*_y[i]+_y[i-1])/(2.*_dx*_dx);
51 double b = (_y[i+1]-_y[i-1])/(2.*_dx);
52 return _y[i] + (x-i*_dx)*(a*(x-i*_dx)+b);
53}
54
55//-------------------------------------------------------------------
56int FuncToHisto(GenericFunc& func,Histo& h,bool logaxex)
57// Remplit l'histo 1D "h" avec la fonction "func"
58// INPUT:
59// logaxex = false : remplissage lineaire
60// les abscisses "x" des bins sont remplis avec f(x)
61// logaxex = true : remplissage logarithmique (base 10)
62// les abscisses "x" des bins sont remplis avec f(10^x)
63// RETURN:
64// 0 = OK
65// 1 = error
66{
67 if(h.NBins()<=0) return 1;
68
69 h.Zero();
70
71 for(int_4 i=0;i<h.NBins();i++) {
72 double x = h.BinCenter(i);
73 if(logaxex) x = pow(10.,x);
74 h.SetBin(i,func(x));
75 }
76
77 return 0;
78}
79
80int FuncToVec(GenericFunc& func,TVector<r_8>& v,double xmin,double xmax,bool logaxex)
81// Remplit le TVector avec la fonction "func"
82// INPUT:
83// logaxex = false : remplissage lineaire
84// les abscisses "x" des bins sont remplis avec f(x)
85// logaxex = true : remplissage logarithmique (base 10)
86// les abscisses "x" des bins sont remplis avec f(10^x)
87// RETURN:
88// 0 = OK
89// 1 = error
90// Remarque:
91// v(i) = f(xmin+i*dx) avec dx = (xmax-xmin)/v.NElts()
92{
93 if(v.NElts()<=0 || xmax<=xmin) return 1;
94
95 v = 0.;
96 double dx = (xmax-xmin)/v.NElts();
97
98 for(int_4 i=0;i<v.NElts();i++) {
99 double x = xmin + i * dx;;
100 if(logaxex) x = pow(10.,x);
101 v(i) = func(x);
102 }
103
104 return 0;
105}
106
107//-------------------------------------------------------------------
108double AngSol(double dtheta,double dphi,double theta0)
109// Retourne l'angle solide d'un "rectangle" et coordonnees spheriques
110// de DEMI-COTE "dtheta" x "dphi" et centre en "theta0"
111// Attention: Le "theta0" de l'equateur est Pi/2 (et non pas zero)
112// Les unites des angles sont en radians
113// theta0 in [0,Pi]
114// dtheta in [0,Pi]
115// dphi in [0,2Pi]
116// Return: l'angle solide en steradian
117{
118 double theta1 = theta0-dtheta, theta2 = theta0+dtheta;
119 if(theta1<0.) theta1=0.;
120 if(theta2>M_PI) theta2=M_PI;
121
122 return 2.*dphi * (cos(theta1)-cos(theta2));
123}
124
125double AngSol(double dtheta)
126// Retourne l'angle solide d'une calotte spherique de demi-ouverture "dtheta"
127// Attention: Les unites des angles sont en radians
128// dtheta in [0,Pi]
129// Return: l'angle solide en steradian
130// Approx pour theta petit: PI theta^2
131{
132 return 2.*M_PI * (1.-cos(dtheta));
133}
134
135//-------------------------------------------------------------------
136unsigned long PoissRandLimit(double mu,double mumax)
137{
138 double pp,ppi,x;
139 unsigned long n;
140
141 if(mu>=mumax) {
142 pp = sqrt(mu);
143 while( (x=pp*NorRand()) < -mu );
144 return (unsigned long)(mu+x+0.5);
145 }
146
147 ppi = pp = exp(-mu);
148 x = drand01();
149 n = 0;
150 while (x > ppi) {
151 n++;
152 pp = mu*pp/(double)n;
153 ppi += pp;
154 }
155 return n;
156}
Note: See TracBrowser for help on using the repository browser.