Changeset 3320 in Sophya for trunk/Cosmo/SimLSS/schechter.cc


Ignore:
Timestamp:
Sep 5, 2007, 9:58:05 AM (18 years ago)
Author:
cmv
Message:

intro SchechterMassDist pour accelerer la simulations cmv 05/09/2007

File:
1 edited

Legend:

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

    r3196 r3320  
    88
    99#include "pexceptions.h"
     10#include "histos.h"
     11#include "perandom.h"
     12#include "tvector.h"
     13#include "fioarr.h"
    1014
    1115#include "constcosmo.h"
     16#include "geneutils.h"
    1217#include "schechter.h"
    1318
     
    2732Schechter::Schechter(Schechter& f)
    2833  : nstar_(f.nstar_) , mstar_(f.mstar_) , alpha_(f.alpha_) , outvalue_(f.outvalue_)
     34{
     35}
     36
     37Schechter::Schechter(void)
     38  : nstar_(0.) , mstar_(0.) , alpha_(0.) , outvalue_(0)
    2939{
    3040}
     
    4555}
    4656
     57unsigned short Schechter::GetOutValue(void)
     58{
     59  return outvalue_;
     60}
     61
     62void Schechter::SetParam(double nstar,double mstar,double alpha)
     63{
     64  nstar_ = nstar; mstar_ = mstar; alpha_ = alpha;
     65}
     66
     67void Schechter::GetParam(double& nstar,double& mstar,double& alpha)
     68{
     69  nstar = nstar_; mstar = mstar_; alpha = alpha_;
     70}
     71
    4772double Schechter::operator() (double m)
    4873// Return : "dn/dm = f(m)" or "m*dn/dm = f(m)"
     
    5277  if(outvalue_) dndm *= m;  // on veut m*dn/dm
    5378  return dndm;
     79}
     80
     81
     82double Schechter::Integrate(double massmin,double massmax,int npt)
     83// Integrate from massmin to massmax with at least npt points log10 spaced
     84{
     85 if(massmin<=0. || massmax<=0. || massmax<=massmin) return 0.;
     86 if(npt<1) npt = 100;
     87 double lmassmin = log10(massmin), lmassmax = log10(massmax);
     88 double perc=0.01, dlxinc=(lmassmax-lmassmin)/npt, dlxmax=10.*dlxinc; unsigned short glorder=4;
     89 double sum = IntegrateFuncLog(*this,lmassmin,lmassmax,perc,dlxinc,dlxmax,glorder);
     90 return sum;
    5491}
    5592
     
    63100  cout<<endl;
    64101}
     102
     103///////////////////////////////////////////////////////////
     104//******* Les facilites pour tirer sur Schechter ********//
     105///////////////////////////////////////////////////////////
     106
     107SchechterMassDist::SchechterMassDist(Schechter sch,double massmin,double massmax,int nbinmass)
     108// On veut une fonction de tirage aleatoire de la masse de N galaxies sur une Schechter
     109// Pour optimiser on cree (eventuellement) des histos de tirage
     110// ATTENTION: on donne les limites en masses pour les histos mais leurs abscisses
     111//   sont en log10(masse): histo [log10(massmin),log10(massmax)] avec nbinmass bins
     112// Si nbinmass<0 alors c'est le nombre de points par decade
     113  : sch_(sch) , sch_outvalue_(sch.GetOutValue())
     114  , massmin_(massmin) , massmax_(massmax) , nbinmass_(nbinmass)
     115  , ngalmin_(0) , ngalmax_(0) , nvalngal_(0)
     116  , ntrial_dir(0) , ntrial_tab(0)
     117  , hmdndm_(NULL) , tirhmdndm_(NULL)
     118{
     119  if(massmin_>massmax_  || massmin_<=0. || massmax_<=0.|| nbinmass_==0) {
     120    cout<<"SchechterMassDist::SchechterMassDist: error in input values"<<endl;
     121    throw ParmError("SchechterMassDist::SchechterMassDist: error in input values");
     122  }
     123
     124  // Creation du tirage aleatoire sur la Schechter
     125  sch_outvalue_ = sch.GetOutValue();  // on sauve la configuration de la schechter
     126  sch.SetOutValue(1);  // on veut m*dN/dm
     127  double lnx1 = log10(massmin_), lnx2 = log10(massmax_); // Binning en log10 de la masse
     128  if(nbinmass_<0) nbinmass_ = int((-nbinmass_)*(lnx2-lnx1+1.));
     129  hmdndm_ = new Histo(lnx1,lnx2,nbinmass_); hmdndm_->ReCenterBin();
     130  FuncToHisto(sch,*hmdndm_,true);  // true -> bin en log10(x)
     131  tirhmdndm_ = new FunRan(*hmdndm_,true);  // true -> histo est pdf
     132  sch.SetOutValue(sch_outvalue_);  // on remet a la valeur initiale
     133}
     134
     135SchechterMassDist::SchechterMassDist(void)
     136  : sch_outvalue_(0)
     137  , massmin_(0.) , massmax_(0.) , nbinmass_(0)
     138  , ngalmin_(0) , ngalmax_(0) , nvalngal_(0)
     139  , ntrial_dir(0) , ntrial_tab(0)
     140  , hmdndm_(NULL) , tirhmdndm_(NULL)
     141{
     142}
     143
     144SchechterMassDist::~SchechterMassDist(void)
     145{
     146 Delete();
     147}
     148
     149void SchechterMassDist::Delete(void)
     150{
     151 if(hmdndm_) delete hmdndm_;
     152 if(tirhmdndm_) delete tirhmdndm_;
     153 hmass_.resize(0);
     154 tmass_.resize(0);
     155 ntrial_dir = ntrial_tab = 0;
     156}
     157
     158int SchechterMassDist::GetMassLim(double& massmin,double& massmax)
     159{
     160 massmin = massmin_;
     161 massmax = massmax_;
     162 return nbinmass_;
     163}
     164
     165int SchechterMassDist::SetNgalLim(int ngalmax,int ngalmin,unsigned long nalea)
     166// Creation des Histos de tirage pour ngalmin a ngalmax galaxies
     167{
     168 int lp=2;
     169 ngalmin_=ngalmax_=nvalngal_=0;
     170 if(ngalmin<=0) ngalmin=1;
     171 if(ngalmax<ngalmin || ngalmax==1) return 0;
     172 ngalmin_ = ngalmin;
     173 ngalmax_ = ngalmax;
     174 nvalngal_ = ngalmax-ngalmin+1;
     175 
     176 if(nalea<1) nalea = 100000;
     177
     178 if(lp>0) cout<<"SchechterMassDist::SetNgalLim: ngal=["
     179              <<ngalmin_<<","<<ngalmax_<<"] n="<<nvalngal_
     180              <<" filling with "<<nalea<<" trials"<<endl;
     181
     182 //------- Construct histo
     183 double lnx1 = log10(massmin_), lnx2 = log10(massmax_);
     184 if(lp>0) cout<<"> Creating "<<nvalngal_<<" histos ["<<lnx1<<","<<lnx2<<"] n="<<nbinmass_<<endl;
     185 for(int i=ngalmin_;i<=ngalmax_;i++) {
     186   Histo h(*hmdndm_); h.Zero();
     187   hmass_.push_back(h);
     188 }
     189 if(lp>1) cout<<"...number of histos is "<<hmass_.size()<<endl;
     190
     191 //------- Remplissage random
     192 sch_.SetOutValue(1);  // on veut m*dN/dm
     193 int lpmod = nalea/20; if(lpmod<=0) lpmod=1;
     194 double s1=0., sc1=0.; unsigned long ns1=0;
     195 double sax=0., scax=0.; unsigned long nsax=0;
     196 for(unsigned long ia=0;ia<nalea;ia++) {
     197   if(lp>1 && ia%lpmod==0) cout<<"...tirage "<<ia<<endl;
     198   double sum = 0.;
     199   for(int i=1;i<=ngalmax_;i++) {
     200     //double l10m = tirhmdndm_->Random();
     201     double l10m = tirhmdndm_->RandomInterp();
     202     double m = pow(10.,l10m);
     203     sum += m;
     204     s1 += m; sc1 += m*m; ns1++;
     205     int ipo = i-ngalmin_;
     206     if(ipo<0) continue;
     207     // ATTENTION: l'histo de tirage stoque le log10(moyenne=somme_masses/ngal).
     208     //            Ca permet d'avoir le meme binning quelque soit ngal
     209     double v = log10(sum/(double)i);
     210     hmass_[ipo].Add(v);
     211     if(i==ngalmax) {sax += sum/(double)i; scax += sum/(double)i*sum/(double)i; nsax++;}
     212   }
     213 }
     214 sch_.SetOutValue(sch_outvalue_);  // on remet a la valeur initiale
     215
     216 if(ns1>1) {
     217   s1 /= ns1; sc1 = sc1/ns1 - s1*s1;
     218   cout<<"...Mean mass for ngal=1: "<<s1<<" ("<<log10(fabs(s1))<<")"
     219       <<" s="<<sqrt(fabs(sc1))<<" (ntrials "<<ns1<<")"<<endl;
     220 }
     221 if(nsax>1) {
     222   sax /= nsax; scax = scax/nsax - sax*sax;
     223   cout<<"...Mean mass for ngal="<<ngalmax_<<": "<<sax<<" ("<<log10(fabs(sax))<<")"
     224       <<" s="<<sqrt(fabs(scax))<<" (ntrials "<<nsax<<")"<<endl;
     225 }
     226
     227 //------- Generation des classes de tirage aleatoire et des histos de verif
     228 if(lp>0) cout<<"> Creating "<<nvalngal_<<" FunRan"<<endl;
     229 for(unsigned int i=0;i<hmass_.size();i++) {
     230   FunRan t(hmass_[i],true);
     231   tmass_.push_back(t);
     232 }
     233 if(lp>1) cout<<"...number of funran is "<<tmass_.size()<<endl;
     234
     235 return nvalngal_;
     236}
     237
     238int SchechterMassDist::GetNgalLim(int& ngalmax,int& ngalmin)
     239{
     240 ngalmax = ngalmax_;
     241 ngalmin = ngalmin_;
     242 return nvalngal_;
     243}
     244
     245Histo SchechterMassDist::GetHmDnDm(void) const
     246{
     247  return *hmdndm_;
     248}
     249
     250FunRan SchechterMassDist::GetTmDnDm(void) const
     251{
     252  return *tirhmdndm_;
     253}
     254
     255Histo SchechterMassDist::GetHisto(int i) const
     256{
     257  if(i<0 || i>=nvalngal_) {
     258    cout<<"SchechterMassDist::GetHisto: error in input values"<<endl;
     259    throw ParmError("SchechterMassDist::GetHisto: error in input values");
     260  }
     261  return hmass_[i];
     262}
     263
     264FunRan SchechterMassDist::GetFunRan(int i) const
     265{
     266  if(i<0 || i>=nvalngal_) {
     267    cout<<"SchechterMassDist::GetFunRan: error in input values"<<endl;
     268    throw ParmError("SchechterMassDist::GetFunRan: error in input values");
     269  }
     270  return tmass_[i];
     271}
     272
     273double SchechterMassDist::TirMass(int ngal)
     274{
     275 if(ngal<1) return 0.;
     276
     277 int ipo = IndexFrNGal(ngal);
     278 double masse_des_ngal = 0.;
     279 if(ipo<0) {  // Pas d'histos de tirage pour ce nombre de galaxies
     280   for(long i=0;i<ngal;i++) {  // On tire donc ngal fois sur la Schechter
     281     // double lm = tirhmdndm_->Random();
     282     double lm = tirhmdndm_->RandomInterp();
     283     masse_des_ngal += pow(10.,lm);  // ATTENTION abscisse en log10(masse)
     284   }
     285   ntrial_dir++;
     286 } else {
     287   // ATTENTION l'histo de tirage stoque le log10(moyenne=somme_masses/ngal)
     288   //double lmngal = tmass_[ipo].Random();
     289   double lmngal = tmass_[ipo].RandomInterp();
     290   masse_des_ngal = pow(10.,lmngal) * ngal;
     291   ntrial_tab++;
     292 }
     293
     294 return masse_des_ngal;
     295}
     296
     297void SchechterMassDist::Print(void)
     298{
     299 cout<<"SchechterMassDist::Print: mass=["<<massmin_<<","<<massmax_<<"] n="<<nbinmass_<<endl
     300     <<"                 ngal=["<<ngalmin_<<","<<ngalmax_<<"] n="<<nvalngal_<<endl;
     301 sch_.Print();
     302}
     303
     304void SchechterMassDist::PrintStatus(void)
     305{
     306 cout<<"SchechterMassDist::PrintStatus: number of trials: direct="<<ntrial_dir
     307     <<" tabulated="<<ntrial_tab<<endl;
     308}
     309
     310void SchechterMassDist::WritePPF(string ppfname)
     311{
     312 char str[64];
     313 cout<<"SchechterMassDist::WritePPF into "<<ppfname<<endl;
     314 POutPersist pos(ppfname.c_str());
     315
     316 double nstar,mstar,alpha;
     317 sch_.GetParam(nstar,mstar,alpha);
     318 TVector<r_8> tdum(20); tdum = 0.;
     319 tdum(0) = nstar;
     320 tdum(1) = mstar;
     321 tdum(2) = alpha;
     322 tdum(3) = sch_outvalue_;
     323 tdum(4) = massmin_;
     324 tdum(5) = massmax_;
     325 tdum(6) = nbinmass_;
     326 tdum(7) = ngalmin_;
     327 tdum(8) = ngalmax_;
     328 tdum(9) = nvalngal_;
     329 tdum(10) = hmass_.size();
     330 tdum(11) = tmass_.size();
     331 pos << PPFNameTag("SMDparam") << tdum;
     332
     333 pos << PPFNameTag("SMDhmdndm") << *hmdndm_;
     334 pos << PPFNameTag("SMDtirhmdndm") << *tirhmdndm_;
     335
     336 if(hmass_.size()>0) {
     337   for(unsigned int i=0;i<hmass_.size();i++) {
     338     sprintf(str,"SMDh%d",NGalFrIndex(i));
     339     pos << PPFNameTag(str) << hmass_[i];
     340   }
     341 }
     342
     343 if(tmass_.size()>0) {
     344   for(unsigned int i=0;i<tmass_.size();i++) {
     345     sprintf(str,"SMDt%d",NGalFrIndex(i));
     346     Histo hdum(tmass_[i]);
     347     pos << PPFNameTag(str) << hdum;
     348   }
     349 }
     350
     351}
     352
     353void SchechterMassDist::ReadPPF(string ppfname)
     354{
     355 Delete(); // On des-alloue si deja remplit!
     356
     357 char str[64];
     358 cout<<"SchechterMassDist::ReadPPF from "<<ppfname<<endl;
     359 PInPersist pis(ppfname.c_str());
     360
     361 TVector<r_8> tdum;
     362 pis >> PPFNameTag("SMDparam") >> tdum;
     363 sch_.SetParam(tdum(0),tdum(1),tdum(2));
     364 sch_.SetOutValue((unsigned short)(tdum(3)+0.1));
     365 massmin_ = tdum(4);
     366 massmax_ = tdum(5);
     367 nbinmass_ = int(tdum(6)+0.1);
     368 ngalmin_ = int(tdum(7)+0.1);
     369 ngalmax_ = int(tdum(8)+0.1);
     370 nvalngal_ = int(tdum(9)+0.1);
     371 unsigned int nhmass = (unsigned int)(tdum(10)+0.1);
     372 unsigned int ntmass = (unsigned int)(tdum(11)+0.1);
     373
     374 {
     375 Histo hdum;
     376 pis >> PPFNameTag("SMDhmdndm") >> hdum;
     377 hmdndm_ = new Histo(hdum);
     378 pis >> PPFNameTag("SMDtirhmdndm") >> hdum;
     379 tirhmdndm_ = new FunRan(hdum,false);
     380 }
     381
     382 if(nhmass>0) {
     383   for(unsigned int i=0;i<nhmass;i++) {
     384     sprintf(str,"SMDh%d",NGalFrIndex(i));
     385     Histo hdum;
     386     pis >> PPFNameTag(str) >> hdum;
     387     hmass_.push_back(hdum);
     388   }
     389 }
     390
     391 if(ntmass>0) {
     392   for(unsigned int i=0;i<ntmass;i++) {
     393     sprintf(str,"SMDt%d",NGalFrIndex(i));
     394     Histo hdum;
     395     pis >> PPFNameTag(str) >> hdum;
     396     FunRan fdum(hdum,false);
     397     tmass_.push_back(fdum);
     398   }
     399 }
     400
     401}
     402
     403
     404///////////////////////////////////////////////////////////
     405//***************** Fonctions de Check ******************//
     406///////////////////////////////////////////////////////////
     407
     408bool IsCompatible(Schechter& sch1,Schechter& sch2,double eps)
     409// on compare les differences a eps pres
     410{
     411  if(eps<=0.) eps=1.e-4;
     412  double nstar1,mstar1,alpha1;
     413  sch1.GetParam(nstar1,mstar1,alpha1);
     414  double nstar2,mstar2,alpha2;
     415  sch2.GetParam(nstar2,mstar2,alpha2);
     416
     417  if(fabs(nstar1-nstar2)>fabs(nstar1+nstar2)/2.*eps) return false;
     418  if(fabs(mstar1-mstar2)>fabs(mstar1+mstar2)/2.*eps) return false;
     419  if(fabs(alpha1-alpha2)>fabs(alpha1+alpha2)/2.*eps) return false;
     420  return true;
     421}
     422
    65423
    66424///////////////////////////////////////////////////////////
     
    98456  return f *d*d / 2.0e-28;
    99457}
     458
Note: See TracChangeset for help on using the changeset viewer.