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

Last change on this file since 3157 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: 16.6 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 <unistd.h>
9
10#include "pexceptions.h"
11
12#include "constcosmo.h"
13#include "integfunc.h"
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
246GrowthFactor::GrowthFactor(double OmegaMatter0,double OmegaLambda0)
247 : O0_(OmegaMatter0) , Ol_(OmegaLambda0) , Ok_(1.-OmegaMatter0-OmegaLambda0)
248{
249 if(OmegaMatter0==0.) {
250 cout<<"GrowthFactor::GrowthFactor: Error bad OmegaMatter0 value : "<<OmegaMatter0<<endl;
251 throw ParmError("GrowthFactor::GrowthFactor: Error badOmegaMatter0 value");
252 }
253 norm_ = 1.; // puisque (*this)(0.) a besoin de norm_
254 norm_ = (*this)(0.);
255 cout<<"GrowthFactor::GrowthFactor : norm="<<norm_<<endl;
256}
257
258GrowthFactor::GrowthFactor(GrowthFactor& d1)
259 : O0_(d1.O0_) , Ol_(d1.Ol_) , Ok_(d1.Ok_) , norm_(d1.norm_)
260{
261}
262
263GrowthFactor::~GrowthFactor(void)
264{
265}
266
267double GrowthFactor::operator() (double z)
268// see Formulae A4 + A5 + A6 page 614
269{
270 z += 1.;
271 double z2 = z*z, z3 = z2*z;
272 double den = Ol_ + Ok_*z2 + O0_*z3;
273 double o0z = O0_ *z3 / den;
274 double olz = Ol_ / den;
275
276 // 4./7. = 0.571429
277 double D1z = pow(o0z,0.571429) - olz + (1.+o0z/2.)*(1.+olz/70.);
278 D1z = 2.5*o0z / z / D1z;
279
280 return D1z / norm_;
281}
282
283
284///////////////////////////////////////////////////////////
285//************** PkSpectrum0 et PkSpectrumZ *************//
286///////////////////////////////////////////////////////////
287
288PkSpectrum0::PkSpectrum0(InitialSpectrum& pkinf,TransfertEisenstein& tf)
289 : pkinf_(pkinf) , tf_(tf)
290{
291}
292
293PkSpectrum0::PkSpectrum0(PkSpectrum0& pk0)
294 : pkinf_(pk0.pkinf_) , tf_(pk0.tf_)
295{
296}
297
298PkSpectrum0::~PkSpectrum0(void)
299{
300}
301
302double PkSpectrum0::operator() (double k)
303{
304 double tf = tf_(k);
305 double pkinf = pkinf_(k);
306 return pkinf *tf*tf;
307}
308
309//------------------------------------
310PkSpectrumZ::PkSpectrumZ(PkSpectrum0& pk0,GrowthFactor& d1,double zref)
311 : pk0_(pk0) , d1_(d1) , zref_(zref) , scale_(1.) , typspec_(0)
312 , zold_(-1.) , d1old_(1.)
313{
314}
315
316PkSpectrumZ::PkSpectrumZ(PkSpectrumZ& pkz)
317 : pk0_(pkz.pk0_) , d1_(pkz.d1_) , zref_(pkz.zref_) , scale_(pkz.scale_) , typspec_(0)
318 , zold_(pkz.zold_) , d1old_(pkz.d1old_)
319{
320}
321
322PkSpectrumZ::~PkSpectrumZ(void)
323{
324}
325
326void PkSpectrumZ::SetTypSpec(unsigned short typspec)
327 // typsec = 0 : compute Pk(k)
328 // = 1 : compute Delta^2(k) = k^3*Pk(k)/2Pi^2
329{
330 if(typspec>1) {
331 cout<<"PkSpectrumZ::SetTypSpec: Error bad typspec value: "<<typspec<<endl;
332 throw ParmError("PkSpectrumZ::SetTypSpec: Error bad typspec value");
333 }
334 typspec_ = typspec;
335}
336
337double PkSpectrumZ::operator() (double k)
338{
339 return (*this)(k,zref_);
340}
341
342double PkSpectrumZ::operator() (double k,double z)
343{
344 double d1;
345 if(z == zold_) d1 = d1old_;
346 else {d1 = d1old_ = d1_(z); zold_ = z;}
347
348 double v = pk0_(k) * d1*d1;
349 if(typspec_) v *= k*k*k/(2.*M_PI*M_PI);
350
351 return scale_ * v;
352}
353
354
355
356///////////////////////////////////////////////////////////
357//******************* VarianceSpectrum ******************//
358///////////////////////////////////////////////////////////
359
360VarianceSpectrum::VarianceSpectrum(GenericFunc& pk,unsigned short typfilter=0)
361 : pk_(pk) , R_(0.)
362{
363 SetFilter(typfilter);
364}
365
366VarianceSpectrum::VarianceSpectrum(VarianceSpectrum& vpk)
367 : pk_(vpk.pk_) , R_(vpk.R_)
368{
369 SetFilter(vpk.typfilter_);
370}
371
372VarianceSpectrum::~VarianceSpectrum(void)
373{
374}
375
376//------------------------------------
377void VarianceSpectrum::SetFilter(unsigned short typfilter)
378// typfilter = 0 : spherical 3D top-hat
379// = 1 : spherical 3D gaussian
380// = 2 : no filter juste integrate spectrum)
381{
382 if(typfilter>2) {
383 cout<<"VarianceSpectrum::SetFilter: Error bad value for type of filter"<<endl;
384 throw ParmError("VarianceSpectrum::SetFilter: Error bad value for type of filter");
385 }
386 typfilter_ = typfilter;
387}
388
389void VarianceSpectrum::SetInteg(double dperc,double dlogkinc,double dlogkmax,unsigned short glorder)
390// ATTENTION: on n'integre pas f(k)*dk mais k*f(k)*d(log10(k))
391// see argument details in function IntegrateFuncLog (integfunc.cc)
392{
393 dperc_ = dperc; if(dperc_<=0.) dperc_ = 0.1;
394 dlogkinc_ = dlogkinc;
395 dlogkmax_ = dlogkmax;
396 glorder_ = glorder;
397}
398
399
400//------------------------------------
401double VarianceSpectrum::Filter2(double x)
402// ATTENTION: c'est le filtre au carre qui est renvoye
403{
404 // Just integrate the spectrum without filtering
405 if(typfilter_ == 2) return 1.;
406
407 double x2 = x*x;
408 // Filtre gaussien G(x) = exp(-x^2/2)
409 // remarque G(x)^2 = exp(-x^2)
410 // on prend le DL de G(x)^2 pour x->0 a l'ordre O(x^6)
411 // DL(x) = 1-x^2*(1-x^2/2)
412 // pour x<0.01 |DL(x)-G(X)^2|<2.0e-13
413 if(typfilter_ == 1)
414 if(x<0.01) return 1.-x2*(1.-x2/2.); else return exp(-x2);
415
416 // Filtre top-hat T(x) = 3*(sin(x)-x*cos(x))/x^3
417 // --- Gestion de la pseudo-divergence pour x->0
418 // on prend le DL de T(x)^2 pour x->0 a l'ordre O(x^7)
419 // DL(x) = 1-x^2/5*(1-3*x^2/35*(1-4*x^2/81))
420 // pour x<0.1 |DL(x)-T(X)^2|<2.5e-13
421 double f2=0.;
422 if(x<0.1) {
423 f2 = 1.-x2/5.*(1.-3.*x2/35.*(1.-4.*x2/81.));
424 } else {
425 f2 = 3.*(sin(x)-x*cos(x))/(x2*x);
426 f2 *= f2;
427 }
428 return f2;
429
430}
431
432double VarianceSpectrum::Variance(double R,double kmin,double kmax)
433// Compute variance of spectrum pk_ by integration
434// Input:
435// R = taille du filter top-hat ou gaussien
436// kmin,kmax = bornes en k de l'integrale pour calculer la variance
437// Return:
438// valeur de la variance (sigma^2)
439// Remarque:
440// la meilleure approximation du filtre top-hat (R) est un filtre gaussien avec (Rg=R/sqrt(5))
441// la variance renvoyee est la variance de la masse
442{
443 if(R<=0. || kmin<=0 || kmax<=0. || kmin>=kmax) {
444 cout<<"VarianceSpectrum::Variance: Error R<=0 or kmin<=0 or kmax<=0 or kmin>=kmax"<<endl;
445 throw ParmError("VarianceSpectrum::Variance: Error R<=0 or kmin<=0 or kmax<=0 or kmin>=kmax");
446 }
447
448 R_ = R;
449 double lkmin = log10(kmin), lkmax = log10(kmax);
450
451 double var = IntegrateFuncLog(*this,lkmin,lkmax,dperc_,dlogkinc_,dlogkmax_,glorder_);
452
453 return var;
454}
455
456//------------------------------------
457double VarianceSpectrum::FindMaximum(double R,double kmin,double kmax,double eps)
458// Retourne le maximum de la fonction a integrer
459// La recherche a lieu entre [kmin,kmax] par pas logarithmiques
460// Input:
461// R : taille du filter top-hat ou gaussien
462// kmin,kmax : intervalle de recherche
463// eps : precision requise sur les valeurs
464// Return:
465// position (en k) du maximum
466{
467 if(R<=0. || kmin<=0 || kmax<=0. || kmin>=kmax) {
468 cout<<"VarianceSpectrum::FindMaximum: Error R<=0 or kmin<=0 or kmax<=0 or kmin>=kmax || eps<=0"<<endl;
469 throw ParmError("VarianceSpectrum::FindMaximum: Error R<=0 or kmin<=0 or kmax<=0 or kmin>=kmax || eps<=0");
470 }
471
472 R_ = R;
473
474 int n = 10; // toujours >2
475 double lkmin = log10(kmin), lkmax = log10(kmax), dlk = (lkmax-lkmin)/n;
476
477 double lkfind=lkmin, pkfind=-1.;
478 while(1) {
479 for(int i=0; i<=n; i++) {
480 double lk = lkmin + i*dlk;
481 double v = (*this)(pow(10.,lk));
482 if(v<pkfind) continue;
483 pkfind = v; lkfind = lk;
484 }
485 //cout<<"VarianceSpectrum::FindMaximum: lkfind="<<lkfind<<" pkfind="<<pkfind
486 // <<" lkmin,max="<<lkmin<<","<<lkmax<<" dlk="<<dlk<<endl;
487 // --- Convergence si l'encadrement de "kfind" est tel que "dk/kfind<eps"
488 // On a dk = 10^(lkfind+dlk) - 10^(lkfind-dlk) = kfind * (10^(dlk) - 10^(-dlk))
489 if( pow(10.,dlk)-pow(10.,-dlk) < eps ) break;
490 if(lkfind-dlk>lkmin) lkmin = lkfind-dlk;
491 if(lkfind+dlk<lkmax) lkmax = lkfind+dlk;
492 dlk = (lkmax-lkmin)/n;
493 }
494
495 return pow(10.,lkfind);
496}
497
498int VarianceSpectrum::FindLimits(double R,double high,double &kmin,double &kmax,double eps)
499// Retourne "[kmin,kmax]" tel que la fonction a integrer soit "f(k) <= high"
500// La recherche a lieu entre [kmin,kmax] par pas logarithmiques
501// Input:
502// R : taille du filter top-hat ou gaussien
503// kmin,kmax : intervalle de recherche
504// eps : precision requise sur les valeurs kmin et kmax
505// Output:
506// kmin,kmax telles que "f(k) <= high"
507// Return:
508// rc = 0 si OK
509// rc |= 1 "f(kmin) >= high" (bit0 =1)
510// rc |= 2 "f(kmax) >= high" (bit1 =1)
511// rc |= 4 "f(k) < high pour tout k" (bit2 =1)
512{
513 if(R<=0. || kmin<=0 || kmax<=0. || kmin>=kmax || eps<=0.) {
514 cout<<"VarianceSpectrum::FindLimits: Error R<=0 or kmin<=0 or kmax<=0 or kmin>=kmax or eps<=0"<<endl;
515 throw ParmError("VarianceSpectrum::FindLimits: Error R<=0 or kmin<=0 or kmax<=0 or kmin>=kmax || eps<=0");
516 }
517
518 R_ = R;
519 int n = 10; // toujours >2
520
521 int rc = 0;
522 double lkmin,lkmax,dlk,lkfind;
523
524 // --- Find kmin
525 lkmin=log10(kmin); lkmax=log10(kmax); dlk=(lkmax-lkmin)/n;
526 while(1) {
527 lkfind = lkmin;
528 for(int i=0;i<=n;i++) {
529 if( (*this)(pow(10,lkfind)) >= high ) break; //cmvbug
530 lkfind = lkmin + i*dlk;
531 }
532 //cout<<"VarianceSpectrum::FindLimits[kmin]: lkfind="<<lkfind
533 // <<" lkmin,max="<<lkmin<<","<<lkmax<<" dlk="<<dlk<<endl;
534 if(fabs(lkfind-lkmax)<dlk/2.) {rc |= 4; return rc;} // protect against f(k)<high for all k
535 if( pow(10.,dlk)-pow(10.,-dlk) < eps ) break;
536 if(lkfind-dlk>lkmin) lkmin = lkfind-dlk;
537 if(lkfind+dlk<lkmax) lkmax = lkfind+dlk;
538 dlk = (lkmax-lkmin)/n;
539 }
540 if(lkfind-lkmin<dlk/2.) rc |= 1; // f(kmin) >= high
541 else kmin = pow(10.,lkmin);
542 //cout<<"rc="<<rc<<" lkmin="<<lkmin<<" pk="<<(*this)(pow(10.,lkmin))<<endl;
543
544 // --- Find kmax
545 lkmin=log10(kmin); lkmax=log10(kmax); dlk=(lkmax-lkmin)/n;
546 while(1) {
547 lkfind=lkmax;
548 for(int i=0;i<=n;i++) {
549 if( (*this)(pow(10,lkfind)) >= high ) break; //cmvbug
550 lkfind -= dlk;
551 lkfind = lkmax - i*dlk;
552 }
553 //cout<<"VarianceSpectrum::FindLimits[kmax]: lkfind="<<lkfind
554 // <<" lkmin,max="<<lkmin<<","<<lkmax<<" dlk="<<dlk<<endl;
555 if( pow(10.,dlk)-pow(10.,-dlk) < eps ) break;
556 if(lkfind-dlk>lkmin) lkmin = lkfind-dlk;
557 if(lkfind+dlk<lkmax) lkmax = lkfind+dlk;
558 dlk = (lkmax-lkmin)/n;
559 }
560 if(lkmax-lkfind<dlk/2.) rc |= 2; // f(kmax) >= high
561 else kmax = pow(10.,lkmax);
562 //cout<<"rc="<<rc<<" lkmax="<<lkmax<<" pk="<<(*this)(pow(10.,lkmax))<<endl;
563
564 return rc;
565}
Note: See TracBrowser for help on using the repository browser.