source: Sophya/trunk/Cosmo/SimLSS/pkspectrum.cc@ 3196

Last change on this file since 3196 was 3196, checked in by cmv, 18 years ago

les AGN selon C.Jackson, une premiere approche simplifiee, recodage from Jim Rich. cmv 03/04/2007

File size: 16.7 KB
RevLine 
[3115]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 <unistd.h>
9
10#include "pexceptions.h"
11
12#include "constcosmo.h"
[3196]13#include "geneutils.h"
[3115]14#include "pkspectrum.h"
15
16
17///////////////////////////////////////////////////////////
18//******************** InitialSpectrum ******************//
19///////////////////////////////////////////////////////////
20
21InitialSpectrum::InitialSpectrum(double n,double a)
22 : n_(n), A_(a)
23{
24}
25
26InitialSpectrum::InitialSpectrum(InitialSpectrum& pkinf)
27 : n_(pkinf.n_), A_(pkinf.A_)
28{
29}
30
31InitialSpectrum::~InitialSpectrum(void)
32{
33}
34
35void InitialSpectrum::SetNorm(double a)
36{
37 A_ = a;
38}
39
40void InitialSpectrum::SetSlope(double n)
41{
42 n_ = n;
43}
44
45
46///////////////////////////////////////////////////////////
47//****************** TransfertEisenstein ****************//
48///////////////////////////////////////////////////////////
49
50// From Eisenstein & Hu ApJ 496:605-614 1998 April 1
51TransfertEisenstein::TransfertEisenstein(double h100,double OmegaCDM0,double OmegaBaryon0,double tcmb,bool nobaryon)
52 : Oc_(OmegaCDM0) , Ob_(OmegaBaryon0) , h_(h100) , tcmb_(tcmb)
53 , nobaryon_(nobaryon) , nooscenv_(0)
54{
55 if(nobaryon_ == false && Ob_>0.) Init_With_Baryons();
56 else Init_Without_Baryon();
57}
58
59TransfertEisenstein::TransfertEisenstein(TransfertEisenstein& tf)
60 : Oc_(tf.Oc_) , Ob_(tf.Ob_) , h_(tf.h_) , tcmb_(tf.tcmb_)
61 , nobaryon_(tf.nobaryon_) , nooscenv_(tf.nooscenv_)
62{
63 if(nobaryon_ == false && Ob_>0.) Init_With_Baryons();
64 else Init_Without_Baryon();
65}
66
67void TransfertEisenstein::Init_With_Baryons(void)
68{
69 int lp = 1;
70
71 nobaryon_ = false;
72 O0_ = Oc_ + Ob_;
73 if(lp) cout<<"Omatter="<<O0_<<" Ocdm="<<Oc_<<" Ob="<<Ob_<<endl;
74
75 double H0 = 100. * h_, h2 = h_*h_;
76
77 th2p7_ = tcmb_/2.7;
78 double th2p7P4 = th2p7_*th2p7_*th2p7_*th2p7_;
79
80 // Formule 2 p 606
81 zeq_ = 2.50e4 * O0_ * h2 / th2p7P4;
82 if(lp) cout<<"zeq = "<<zeq_<<endl;
83
84 // Formule 3 p 607
85 // (attention ici C=1 : H0 -> H0/C si on utilise la premiere formule)
86 // keq_ = sqrt(2.*O0_*H0*H0*zeq_) / SpeedOfLight_Cst;
87 keq_ = 7.46e-2 * O0_ * h2 / (th2p7_*th2p7_);
88 if(lp) cout<<"keq = "<<keq_<<" Mpc^-1"<<endl;
89
90 // Formule 4 p 607
91 double b1_eq4 = 0.313*pow(O0_*h2,-0.419)*(1. + 0.607*pow(O0_*h2,0.674));
92 double b2_eq4 = 0.238*pow(O0_*h2,0.223);
93 double zd_ = 1291. * pow(O0_*h2,0.251) / (1.+0.659* pow(O0_*h2,0.828))
94 * (1. + b1_eq4*pow(Ob_*h2,b2_eq4));
95 if(lp) cout<<"zd = "<<zd_<<endl;
96
97 // Formule 5 page 607
98 Req_ = 31.5*Ob_*h2 / th2p7P4 * (1.e3/zeq_);
99 Rd_ = 31.5*Ob_*h2 / th2p7P4 * (1.e3/zd_);
100 if(lp) cout<<"Req = "<<Req_<<" Rd = "<<Rd_<<endl;
101
102 // Formule 6 p 607
103 s_ = 2./(3.*keq_) * sqrt(6./Req_)
104 * log( (sqrt(1.+Rd_) + sqrt(Rd_+Req_)) / (1.+sqrt(Req_)) );
105 if(lp) cout<<"s = "<<s_<<" Mpc"<<endl;
106
107 // Formule 7 page 607
108 ksilk_ = 1.6*pow(Ob_*h2,0.52)*pow(O0_*h2,0.73) * (1. + pow(10.4*O0_*h2,-0.95));
109 if(lp) cout<<"ksilk = "<<ksilk_<<" Mpc^-1"<<endl;
110
111 // Formules 10 page 608
112 double a1 = pow(46.9*O0_*h2,0.670) * (1. + pow(32.1*O0_*h2,-0.532));
113 double a2 = pow(12.0*O0_*h2,0.424) * (1. + pow(45.0*O0_*h2,-0.582));
114 alphac_ = pow(a1,-Ob_/O0_) * pow(a2,-pow(Ob_/O0_,3.));
115 double b1 = 0.944 / (1. + pow(458.*O0_*h2,-0.708));
116 double b2 = pow(0.395*O0_*h2,-0.0266);
117 betac_ = 1 / ( 1. + b1*(pow(Oc_/O0_,b2) - 1.) );
118
119 // Formule 23 page 610
120 bnode_ = 8.41 * pow(O0_*h2,0.435);
121 if(lp) cout<<"bnode = "<<bnode_<<endl;
122
123 // Formule 14 page 608
124 double y = (1.+zeq_)/(1.+zd_);
125 double s1py = sqrt(1.+y);
126 double Gy = y*( -6.*s1py + (2.+3.*y)*log((s1py+1.)/(s1py-1.)) );
127 alphab_ = 2.07*keq_*s_*pow(1.+Rd_,-3./4.)*Gy;
128
129 // Formule 24 page 610
130 betab_ = 0.5 + Ob_/O0_
131 + (3.-2.*Ob_/O0_) * sqrt(pow(17.2*O0_*h2,2.) + 1.);
132
133 // Formule 31 page 612
134 alphag_ = 1.
135 - 0.328*log(431.*O0_*h2)*Ob_/O0_
136 + 0.38*log(22.3*O0_*h2)*pow(Ob_/O0_,2.);
137
138 // --- Pour la positon du premier pic acoustique
139 // Formule 26 page 611
140 double s_peak = 44.5*log(9.83/(O0_*h2)) / sqrt(1.+10.*pow(Ob_*h2,3./4.)); // Mpc
141 // Formule 25 page 611
142 kpeak_ = 5*M_PI/(2.*s_peak) * (1.+0.217*O0_*h2); // 1/Mpc
143 if(lp) cout<<"for 1er peak: s="<<s_peak<<" kpeak="<<kpeak_<<endl;
144
145 return;
146}
147
148void TransfertEisenstein::Init_Without_Baryon(void)
149{
150 int lp = 1;
151
152 nobaryon_ = true;
153 O0_ = Oc_;
154 if(lp) cout<<"Omatter="<<O0_<<" Ocdm="<<Oc_<<endl;
155 th2p7_ = tcmb_/2.7;
156}
157
158TransfertEisenstein::~TransfertEisenstein(void)
159{
160}
161
162void TransfertEisenstein::SetNoOscEnv(unsigned short nooscenv)
163// To obtain the non-oscillatory part of the spectrum
164// nooscenv = 0 : use the baryon oscillatory part of transfert function
165// nooscenv = 1 : use approx. paragraph 3.3 p610 (middle of right column)
166// nooscenv = 2 : use formulae 29+30+31 page 612
167{
168 if(nooscenv>2) {
169 cout<<"TransfertEisenstein::SetNoOscEnv: Error bad nooscenv value: "<<nooscenv<<endl;
170 throw ParmError("TransfertEisenstein::SetNoOscEnv: Error bad nooscenv value");
171 }
172 nooscenv_ = nooscenv;
173}
174
175double TransfertEisenstein::T0tild(double k,double alphac,double betac)
176{
177 // Formule 10 p 608
178 //double q = k*th2p7_*th2p7_/(O0_*h_*h_);
179 double q = k/(13.41*keq_);
180 // Formule 20 p 610
181 double C = (14.2/alphac) + 386./(1.+69.9*pow(q,1.08));
182 // Formule 19 p 610
183 double x = log(M_E+1.8*betac*q);
184 return x / (x + C*q*q);
185}
186
187double TransfertEisenstein::operator() (double k)
188{
189
190 // --- Pour zero baryon
191 // OU Pour function lissee sans oscillation baryon
192 if(nobaryon_ || nooscenv_ == 2) {
193 double gamma = O0_*h_;
194 // Formule 30 page 612 (pour fct lissee)
195 if( nobaryon_==false && nooscenv_ == 2 )
196 gamma = O0_*h_*(alphag_ + (1.-alphag_)/(1.+pow(0.43*k*s_,4.)));
197 // Formule 28 page 612
198 double q = k / h_ * th2p7_*th2p7_/gamma; // Mpc^-1
199 // Formules 29 page 612
200 double l0 = log(2.*M_E + 1.8*q);
201 double c0 = 14.2 + 731./(1.+62.5*q);
202 return l0 / (l0 + c0*q*q);
203 }
204
205 // --- CDM
206 double f = 1. / (1. + pow(k*s_/5.4,4.));
207 double Tc = f*T0tild(k,1.,betac_) + (1.-f)*T0tild(k,alphac_,betac_);
208
209 // --- Baryons
210 // Formule 22 page 610
211 double stk, ksbnode = k*s_/bnode_;
212 if(ksbnode<0.001) stk =s_ * ksbnode;
213 else stk = s_ / pow(1. + pow(1./ksbnode,3.), 1/.3);
214 // Formule 21 page 610
215 double j0kst = 0.;
216 if(nooscenv_ == 1) j0kst = pow(1.+pow(k*stk,4.) , -1./4.); //lissee sans oscillation baryon
217 else {
218 double x = k*stk;
219 if(x<0.01) j0kst = 1. - x*x/6.*(1.-x*x/20.);
220 else j0kst = sin(x)/x;
221 ////if(k>0.038&&k<0.07) cout<<"k="<<k<<" stk="<<stk<<" x="<<x<<endl;
222 }
223 double Tb = T0tild(k,1.,1.) / (1. + pow(k*s_/5.2,2.));
224 Tb += alphab_/(1.+pow(betab_/(k*s_),3.)) * exp(-pow(k/ksilk_,1/4.));
225 Tb *= j0kst;
226
227 // --- Total
228 double T = (Ob_/O0_)*Tb + (Oc_/O0_)*Tc;
229
230 return T;
231}
232
233double TransfertEisenstein::KPeak(void)
234// Position du premier pic acoustic
235{
236 if(nobaryon_) return -1.;
237 return kpeak_;
238}
239
240
241///////////////////////////////////////////////////////////
242//********************* GrowthFactor ********************//
243///////////////////////////////////////////////////////////
244
245// From Eisenstein & Hu ApJ 496:605-614 1998 April 1
[3193]246// Pour avoir D(z) = 1/(1+z) faire: OmegaMatter0=1 OmegaLambda0=0
[3115]247GrowthFactor::GrowthFactor(double OmegaMatter0,double OmegaLambda0)
248 : O0_(OmegaMatter0) , Ol_(OmegaLambda0) , Ok_(1.-OmegaMatter0-OmegaLambda0)
249{
250 if(OmegaMatter0==0.) {
251 cout<<"GrowthFactor::GrowthFactor: Error bad OmegaMatter0 value : "<<OmegaMatter0<<endl;
252 throw ParmError("GrowthFactor::GrowthFactor: Error badOmegaMatter0 value");
253 }
254 norm_ = 1.; // puisque (*this)(0.) a besoin de norm_
255 norm_ = (*this)(0.);
256 cout<<"GrowthFactor::GrowthFactor : norm="<<norm_<<endl;
257}
258
259GrowthFactor::GrowthFactor(GrowthFactor& d1)
260 : O0_(d1.O0_) , Ol_(d1.Ol_) , Ok_(d1.Ok_) , norm_(d1.norm_)
261{
262}
263
264GrowthFactor::~GrowthFactor(void)
265{
266}
267
268double GrowthFactor::operator() (double z)
269// see Formulae A4 + A5 + A6 page 614
270{
271 z += 1.;
272 double z2 = z*z, z3 = z2*z;
273 double den = Ol_ + Ok_*z2 + O0_*z3;
274 double o0z = O0_ *z3 / den;
275 double olz = Ol_ / den;
276
277 // 4./7. = 0.571429
278 double D1z = pow(o0z,0.571429) - olz + (1.+o0z/2.)*(1.+olz/70.);
279 D1z = 2.5*o0z / z / D1z;
280
281 return D1z / norm_;
282}
283
284
285///////////////////////////////////////////////////////////
286//************** PkSpectrum0 et PkSpectrumZ *************//
287///////////////////////////////////////////////////////////
288
289PkSpectrum0::PkSpectrum0(InitialSpectrum& pkinf,TransfertEisenstein& tf)
290 : pkinf_(pkinf) , tf_(tf)
291{
292}
293
294PkSpectrum0::PkSpectrum0(PkSpectrum0& pk0)
295 : pkinf_(pk0.pkinf_) , tf_(pk0.tf_)
296{
297}
298
299PkSpectrum0::~PkSpectrum0(void)
300{
301}
302
303double PkSpectrum0::operator() (double k)
304{
305 double tf = tf_(k);
306 double pkinf = pkinf_(k);
307 return pkinf *tf*tf;
308}
309
310//------------------------------------
311PkSpectrumZ::PkSpectrumZ(PkSpectrum0& pk0,GrowthFactor& d1,double zref)
312 : pk0_(pk0) , d1_(d1) , zref_(zref) , scale_(1.) , typspec_(0)
313 , zold_(-1.) , d1old_(1.)
314{
315}
316
317PkSpectrumZ::PkSpectrumZ(PkSpectrumZ& pkz)
318 : pk0_(pkz.pk0_) , d1_(pkz.d1_) , zref_(pkz.zref_) , scale_(pkz.scale_) , typspec_(0)
319 , zold_(pkz.zold_) , d1old_(pkz.d1old_)
320{
321}
322
323PkSpectrumZ::~PkSpectrumZ(void)
324{
325}
326
327void PkSpectrumZ::SetTypSpec(unsigned short typspec)
328 // typsec = 0 : compute Pk(k)
329 // = 1 : compute Delta^2(k) = k^3*Pk(k)/2Pi^2
330{
331 if(typspec>1) {
332 cout<<"PkSpectrumZ::SetTypSpec: Error bad typspec value: "<<typspec<<endl;
333 throw ParmError("PkSpectrumZ::SetTypSpec: Error bad typspec value");
334 }
335 typspec_ = typspec;
336}
337
338double PkSpectrumZ::operator() (double k)
339{
340 return (*this)(k,zref_);
341}
342
343double PkSpectrumZ::operator() (double k,double z)
344{
345 double d1;
346 if(z == zold_) d1 = d1old_;
347 else {d1 = d1old_ = d1_(z); zold_ = z;}
348
349 double v = pk0_(k) * d1*d1;
350 if(typspec_) v *= k*k*k/(2.*M_PI*M_PI);
351
352 return scale_ * v;
353}
354
355
356
357///////////////////////////////////////////////////////////
358//******************* VarianceSpectrum ******************//
359///////////////////////////////////////////////////////////
360
361VarianceSpectrum::VarianceSpectrum(GenericFunc& pk,unsigned short typfilter=0)
362 : pk_(pk) , R_(0.)
363{
364 SetFilter(typfilter);
365}
366
367VarianceSpectrum::VarianceSpectrum(VarianceSpectrum& vpk)
368 : pk_(vpk.pk_) , R_(vpk.R_)
369{
370 SetFilter(vpk.typfilter_);
371}
372
373VarianceSpectrum::~VarianceSpectrum(void)
374{
375}
376
377//------------------------------------
378void VarianceSpectrum::SetFilter(unsigned short typfilter)
379// typfilter = 0 : spherical 3D top-hat
380// = 1 : spherical 3D gaussian
381// = 2 : no filter juste integrate spectrum)
382{
383 if(typfilter>2) {
384 cout<<"VarianceSpectrum::SetFilter: Error bad value for type of filter"<<endl;
385 throw ParmError("VarianceSpectrum::SetFilter: Error bad value for type of filter");
386 }
387 typfilter_ = typfilter;
388}
389
390void VarianceSpectrum::SetInteg(double dperc,double dlogkinc,double dlogkmax,unsigned short glorder)
391// ATTENTION: on n'integre pas f(k)*dk mais k*f(k)*d(log10(k))
[3196]392// see argument details in function IntegrateFuncLog (geneutils.cc)
[3115]393{
394 dperc_ = dperc; if(dperc_<=0.) dperc_ = 0.1;
395 dlogkinc_ = dlogkinc;
396 dlogkmax_ = dlogkmax;
397 glorder_ = glorder;
398}
399
400
401//------------------------------------
402double VarianceSpectrum::Filter2(double x)
403// ATTENTION: c'est le filtre au carre qui est renvoye
404{
405 // Just integrate the spectrum without filtering
406 if(typfilter_ == 2) return 1.;
407
408 double x2 = x*x;
409 // Filtre gaussien G(x) = exp(-x^2/2)
410 // remarque G(x)^2 = exp(-x^2)
411 // on prend le DL de G(x)^2 pour x->0 a l'ordre O(x^6)
412 // DL(x) = 1-x^2*(1-x^2/2)
413 // pour x<0.01 |DL(x)-G(X)^2|<2.0e-13
414 if(typfilter_ == 1)
415 if(x<0.01) return 1.-x2*(1.-x2/2.); else return exp(-x2);
416
417 // Filtre top-hat T(x) = 3*(sin(x)-x*cos(x))/x^3
418 // --- Gestion de la pseudo-divergence pour x->0
419 // on prend le DL de T(x)^2 pour x->0 a l'ordre O(x^7)
420 // DL(x) = 1-x^2/5*(1-3*x^2/35*(1-4*x^2/81))
421 // pour x<0.1 |DL(x)-T(X)^2|<2.5e-13
422 double f2=0.;
423 if(x<0.1) {
424 f2 = 1.-x2/5.*(1.-3.*x2/35.*(1.-4.*x2/81.));
425 } else {
426 f2 = 3.*(sin(x)-x*cos(x))/(x2*x);
427 f2 *= f2;
428 }
429 return f2;
430
431}
432
433double VarianceSpectrum::Variance(double R,double kmin,double kmax)
434// Compute variance of spectrum pk_ by integration
435// Input:
436// R = taille du filter top-hat ou gaussien
437// kmin,kmax = bornes en k de l'integrale pour calculer la variance
438// Return:
439// valeur de la variance (sigma^2)
440// Remarque:
441// la meilleure approximation du filtre top-hat (R) est un filtre gaussien avec (Rg=R/sqrt(5))
442// la variance renvoyee est la variance de la masse
443{
444 if(R<=0. || kmin<=0 || kmax<=0. || kmin>=kmax) {
445 cout<<"VarianceSpectrum::Variance: Error R<=0 or kmin<=0 or kmax<=0 or kmin>=kmax"<<endl;
446 throw ParmError("VarianceSpectrum::Variance: Error R<=0 or kmin<=0 or kmax<=0 or kmin>=kmax");
447 }
448
449 R_ = R;
450 double lkmin = log10(kmin), lkmax = log10(kmax);
451
452 double var = IntegrateFuncLog(*this,lkmin,lkmax,dperc_,dlogkinc_,dlogkmax_,glorder_);
453
454 return var;
455}
456
457//------------------------------------
458double VarianceSpectrum::FindMaximum(double R,double kmin,double kmax,double eps)
459// Retourne le maximum de la fonction a integrer
460// La recherche a lieu entre [kmin,kmax] par pas logarithmiques
461// Input:
462// R : taille du filter top-hat ou gaussien
463// kmin,kmax : intervalle de recherche
464// eps : precision requise sur les valeurs
465// Return:
466// position (en k) du maximum
467{
468 if(R<=0. || kmin<=0 || kmax<=0. || kmin>=kmax) {
469 cout<<"VarianceSpectrum::FindMaximum: Error R<=0 or kmin<=0 or kmax<=0 or kmin>=kmax || eps<=0"<<endl;
470 throw ParmError("VarianceSpectrum::FindMaximum: Error R<=0 or kmin<=0 or kmax<=0 or kmin>=kmax || eps<=0");
471 }
472
473 R_ = R;
474
475 int n = 10; // toujours >2
476 double lkmin = log10(kmin), lkmax = log10(kmax), dlk = (lkmax-lkmin)/n;
477
478 double lkfind=lkmin, pkfind=-1.;
479 while(1) {
480 for(int i=0; i<=n; i++) {
481 double lk = lkmin + i*dlk;
482 double v = (*this)(pow(10.,lk));
483 if(v<pkfind) continue;
484 pkfind = v; lkfind = lk;
485 }
486 //cout<<"VarianceSpectrum::FindMaximum: lkfind="<<lkfind<<" pkfind="<<pkfind
487 // <<" lkmin,max="<<lkmin<<","<<lkmax<<" dlk="<<dlk<<endl;
488 // --- Convergence si l'encadrement de "kfind" est tel que "dk/kfind<eps"
489 // On a dk = 10^(lkfind+dlk) - 10^(lkfind-dlk) = kfind * (10^(dlk) - 10^(-dlk))
490 if( pow(10.,dlk)-pow(10.,-dlk) < eps ) break;
491 if(lkfind-dlk>lkmin) lkmin = lkfind-dlk;
492 if(lkfind+dlk<lkmax) lkmax = lkfind+dlk;
493 dlk = (lkmax-lkmin)/n;
494 }
495
496 return pow(10.,lkfind);
497}
498
499int VarianceSpectrum::FindLimits(double R,double high,double &kmin,double &kmax,double eps)
500// Retourne "[kmin,kmax]" tel que la fonction a integrer soit "f(k) <= high"
501// La recherche a lieu entre [kmin,kmax] par pas logarithmiques
502// Input:
503// R : taille du filter top-hat ou gaussien
504// kmin,kmax : intervalle de recherche
505// eps : precision requise sur les valeurs kmin et kmax
506// Output:
507// kmin,kmax telles que "f(k) <= high"
508// Return:
509// rc = 0 si OK
510// rc |= 1 "f(kmin) >= high" (bit0 =1)
511// rc |= 2 "f(kmax) >= high" (bit1 =1)
512// rc |= 4 "f(k) < high pour tout k" (bit2 =1)
513{
514 if(R<=0. || kmin<=0 || kmax<=0. || kmin>=kmax || eps<=0.) {
515 cout<<"VarianceSpectrum::FindLimits: Error R<=0 or kmin<=0 or kmax<=0 or kmin>=kmax or eps<=0"<<endl;
516 throw ParmError("VarianceSpectrum::FindLimits: Error R<=0 or kmin<=0 or kmax<=0 or kmin>=kmax || eps<=0");
517 }
518
519 R_ = R;
520 int n = 10; // toujours >2
521
522 int rc = 0;
523 double lkmin,lkmax,dlk,lkfind;
524
525 // --- Find kmin
526 lkmin=log10(kmin); lkmax=log10(kmax); dlk=(lkmax-lkmin)/n;
527 while(1) {
528 lkfind = lkmin;
529 for(int i=0;i<=n;i++) {
530 if( (*this)(pow(10,lkfind)) >= high ) break; //cmvbug
531 lkfind = lkmin + i*dlk;
532 }
533 //cout<<"VarianceSpectrum::FindLimits[kmin]: lkfind="<<lkfind
534 // <<" lkmin,max="<<lkmin<<","<<lkmax<<" dlk="<<dlk<<endl;
535 if(fabs(lkfind-lkmax)<dlk/2.) {rc |= 4; return rc;} // protect against f(k)<high for all k
536 if( pow(10.,dlk)-pow(10.,-dlk) < eps ) break;
537 if(lkfind-dlk>lkmin) lkmin = lkfind-dlk;
538 if(lkfind+dlk<lkmax) lkmax = lkfind+dlk;
539 dlk = (lkmax-lkmin)/n;
540 }
541 if(lkfind-lkmin<dlk/2.) rc |= 1; // f(kmin) >= high
542 else kmin = pow(10.,lkmin);
543 //cout<<"rc="<<rc<<" lkmin="<<lkmin<<" pk="<<(*this)(pow(10.,lkmin))<<endl;
544
545 // --- Find kmax
546 lkmin=log10(kmin); lkmax=log10(kmax); dlk=(lkmax-lkmin)/n;
547 while(1) {
548 lkfind=lkmax;
549 for(int i=0;i<=n;i++) {
550 if( (*this)(pow(10,lkfind)) >= high ) break; //cmvbug
551 lkfind -= dlk;
552 lkfind = lkmax - i*dlk;
553 }
554 //cout<<"VarianceSpectrum::FindLimits[kmax]: lkfind="<<lkfind
555 // <<" lkmin,max="<<lkmin<<","<<lkmax<<" dlk="<<dlk<<endl;
556 if( pow(10.,dlk)-pow(10.,-dlk) < eps ) break;
557 if(lkfind-dlk>lkmin) lkmin = lkfind-dlk;
558 if(lkfind+dlk<lkmax) lkmax = lkfind+dlk;
559 dlk = (lkmax-lkmin)/n;
560 }
561 if(lkmax-lkfind<dlk/2.) rc |= 2; // f(kmax) >= high
562 else kmax = pow(10.,lkmax);
563 //cout<<"rc="<<rc<<" lkmax="<<lkmax<<" pk="<<(*this)(pow(10.,lkmax))<<endl;
564
565 return rc;
566}
Note: See TracBrowser for help on using the repository browser.