16 #include "image_processing.h"
26 #include <eigen3/Eigen/Dense>
27 #include <eigen3/Eigen/StdVector>
28 #include <boost/math/special_functions/gamma.hpp>
60 LensHalo(PosType z,
const COSMOLOGY &cosmo);
82 inline float getRsize()
const {
return Rsize; }
88 inline PosType
getZlens()
const {
return zlens; }
96 void getX(PosType * MyPosHalo)
const {
98 MyPosHalo[0] = posHalo[0]*Dist;
99 MyPosHalo[1] = posHalo[1]*Dist;
101 Point_2d getX()
const {
return Point_2d(posHalo[0]*Dist , posHalo[1]*Dist); }
107 void setTheta(PosType PosX, PosType PosY) { posHalo[0] = PosX ; posHalo[1] = PosY ; }
109 void setTheta(PosType *PosXY) { posHalo[0] = PosXY[0] ; posHalo[1] = PosXY[1] ; }
113 void getTheta(PosType * MyPosHalo)
const { MyPosHalo[0] = posHalo[0] ; MyPosHalo[1] = posHalo[1]; }
118 void setDist(COSMOLOGY &co){Dist = co.angDist(zlens);}
126 void displayPos() { std::cout <<
"Halo PosX = " << posHalo[0] <<
" ; Halo PosY = " << posHalo[1] << std::endl; }
129 virtual void initFromFile(
float my_mass,
long *seed,
float vmax,
float r_halfmass){};
131 virtual void initFromMassFunc(
float my_mass,
float my_Rsize,
float my_rscale, PosType my_slope,
long *seed);
134 virtual void set_RsizeRmax(
float my_Rsize){Rmax = Rmax*my_Rsize/Rsize; Rsize = my_Rsize; xmax = Rsize/
rscale;};
141 void setZlens(PosType my_zlens,
const COSMOLOGY &cosmo){
143 Dist=cosmo.angDist(my_zlens);
145 void setRsize(PosType R){Rsize = R;}
148 void setZlensDist(PosType my_zlens,
const COSMOLOGY &cos){
150 Dist = cos.angDist(zlens);
152 void setMass(PosType m){mass = m;}
156 virtual void set_slope(PosType my_slope){beta=my_slope;};
161 void set_flag_elliptical(
bool ell){elliptical_flag=ell;};
162 bool get_switch_flag(){
return switch_flag;};
192 ,
bool subtract_point=
false
193 ,PosType screening=1.0
217 std::vector<double>
get_mod() { std::vector<double> fmodes(Nmod);
for(
int i=0;i<Nmod;i++){fmodes[i]= mod[i] ;} ;
return fmodes;}
222 virtual std::size_t
Nparams()
const;
224 virtual PosType
getParam(std::size_t p)
const;
226 virtual PosType
setParam(std::size_t p, PosType value);
229 virtual void printCSV(std::ostream&,
bool header =
false)
const;
237 PosType test_average_kappa(PosType R);
245 float get_rsize(){
return Rsize;};
252 size_t getID()
const {
return idnumber;}
253 void setID(
size_t id){idnumber = id;}
255 PosType renormalization(PosType r_max);
299 PosType norm_int(PosType r_max);
301 void force_halo_sym(PosType *alpha,KappaType *kappa,KappaType *gamma,KappaType *phi,PosType
const *xcm,
bool subtract_point=
false,PosType screening = 1.0);
302 void force_halo_asym(PosType *alpha,KappaType *kappa,KappaType *gamma,KappaType *phi,PosType
const *xcm,
bool subtract_point=
false,PosType screening = 1.0);
304 bool force_point(PosType *alpha,KappaType *kappa,KappaType *gamma
305 ,KappaType *phi,PosType
const *xcm,PosType rcm2
306 ,
bool subtract_point,PosType screening);
309 norm_func(
LensHalo& halo, PosType my_r_max): halo(halo), r_max(my_r_max){};
313 PosType operator ()(PosType theta) {
return halo.alpha_ell(r_max, theta);}
317 Ialpha_func(
LensHalo& halo): halo(halo){};
319 PosType operator ()(PosType x) {
return halo.
alpha_h(x)/x ;}
323 Ig_func(
const LensHalo& halo): halo(halo){};
325 PosType operator ()(PosType x) {
return halo.gfunction(x)/x ;}
381 virtual PosType
inline alpha_h(PosType x)
const {
return -1;};
382 virtual KappaType
inline kappa_h(PosType x)
const {
return 0;};
383 virtual KappaType
inline gamma_h(PosType x)
const {
return -2;};
384 virtual KappaType
inline phi_h(PosType x)
const {
return 1;};
385 virtual KappaType
inline phi_int(PosType x)
const {
return 1;};
386 virtual PosType
inline ffunction(PosType x)
const {
return 0;};
387 virtual PosType
inline gfunction(PosType x)
const {
return -1;};
388 virtual PosType
inline dgfunctiondx(PosType x){
return 0;};
389 virtual PosType
inline bfunction(PosType x){
return -1;};
390 virtual PosType
inline dhfunction(PosType x)
const {
return 1;};
391 virtual PosType
inline ddhfunction(PosType x,
bool numerical){
return 0;};
392 virtual PosType
inline dddhfunction(PosType x,
bool numerical){
return 0;};
393 virtual PosType
inline bnumfunction(PosType x){
return -1;};
394 virtual PosType
inline dbfunction(PosType x){
return 0;};
395 virtual PosType
inline ddbfunction(PosType x){
return 0;};
396 virtual PosType
inline dmoddb(
int whichmod, PosType q, PosType b){
return 0;};
397 virtual PosType
inline ddmoddb(
int whichmod, PosType q, PosType b){
return 0;};
398 virtual PosType
inline dmoddq(
int whichmod, PosType q, PosType b){
return 0;};
399 virtual PosType
inline ddmoddq(
int whichmod, PosType q, PosType b){
return 0;};
408 bool elliptical_flag =
false;
409 bool switch_flag =
false;
412 void faxial(PosType x,PosType theta,PosType f[]);
413 void faxial0(PosType theta,PosType f0[]);
414 void faxial1(PosType theta,PosType f1[]);
415 void faxial2(PosType theta,PosType f2[]);
416 void gradial(PosType r,PosType g[]);
417 void gradial2(PosType r,PosType mu, PosType sigma,PosType g[]);
419 void felliptical(PosType x, PosType q, PosType theta, PosType f[], PosType g[]);
421 virtual void gamma_asym(PosType x,PosType theta, PosType gamma[]);
422 virtual PosType
kappa_asym(PosType x,PosType theta);
424 ,PosType *kappa,PosType gamma[],PosType *phi);
426 ,PosType *kappa,PosType gamma[],PosType *phi);
427 virtual void alphakappagamma2asym(PosType x,PosType theta, PosType alpha[2]
428 ,PosType *kappa,PosType gamma[],PosType *phi);
429 virtual void alphakappagamma3asym(PosType x,PosType theta, PosType alpha[2]
430 ,PosType *kappa,PosType gamma[],PosType *phi);
432 virtual PosType alpha_ell(PosType x,PosType theta);
435 double IDAXDM(
double lambda,
double a2,
double b2,
double x[],
double rmax,
double mo);
436 double IDAYDM(
double lambda,
double a2,
double b2,
double x[],
double rmax,
double mo);
437 double SCHRAMMKN(
double n,
double x[],
double rmax);
438 double SCHRAMMJN(
double n,
double x[],
double rmax);
439 double SCHRAMMI(
double x[],
double rmax);
442 void calcModes(
double q,
double beta,
double rottheta, PosType newmod[]);
443 void calcModesB(PosType x,
double q,
double beta,
double rottheta, PosType newmod[]);
444 void calcModesC(PosType beta_r,
double q,
double rottheta, PosType newmod[]);
446 virtual PosType
inline InterpolateModes(
int whichmod, PosType q, PosType b){
return 0;};
448 void analModes(
int modnumber, PosType my_beta, PosType q, PosType amod[3]);
451 fourier_func(
double my_n,
double my_q,
double my_beta): n(my_n),q(my_q),beta(my_beta){};
455 double operator ()(
double theta) {
return cos(n*theta)/pow(cos(theta)*cos(theta) + 1/q/q*sin(theta)*sin(theta),beta/2) ;}
458 struct SCHRAMMJ_func{
459 SCHRAMMJ_func(
double my_n,
double my_x[],
double my_rmax,
LensHalo *my_halo): n(my_n), x(my_x), rmx(my_rmax), halo(my_halo){};
461 double operator ()(
double u) {
464 PosType xisq=sqrt((x[0]*x[0]+x[1]*x[1]/(1-u*(1-halo->fratio*halo->fratio))));
466 if(xisq*xisq < 1e-20) xisq = 1.0e-10;
467 KappaType kappa=halo->kappa_h(xisq)/PI/xisq/xisq;
469 return kappa*halo->mass/pow((1.-(1.-halo->fratio*halo->fratio)*u),n+0.5);
475 struct SCHRAMMK_func{
476 SCHRAMMK_func(
double my_n,
double my_x[],
double my_rmax,
LensHalo *my_halo): n(my_n), x(my_x), rmx(my_rmax), halo(my_halo){};
478 double operator ()(
double u) {
481 PosType xisq=sqrt((x[0]*x[0]+x[1]*x[1]/(1-u*(1-halo->fratio*halo->fratio))));
482 if(xisq*xisq < 1e-20) xisq = 1.0e-10;
484 PosType kp1=halo->kappa_h(xisq+h)/((xisq+h)*(xisq+h));
485 PosType km1=halo->kappa_h(xisq-h)/((xisq-h)*(xisq-h));
486 PosType kp2=halo->kappa_h(xisq+2*h)/((xisq+2*h)*(xisq+2*h));
487 PosType km2=halo->kappa_h(xisq-2*h)/((xisq-2*h)*(xisq-2*h));
488 PosType dkdxi=(8*kp1-8*km1-kp2+km2)/12/h/PI;
493 return u*dkdxi/pow((1.-(1.-halo->fratio*halo->fratio)*u),n+0.5);
500 struct SCHRAMMI_func{
501 SCHRAMMI_func(
double my_x[],
double my_rmax,
LensHalo *my_halo): x(my_x), rmx(my_rmax), halo(my_halo){};
503 double operator ()(
double u) {
506 PosType xisq=sqrt((x[0]*x[0]+x[1]*x[1]/(1-u*(1-halo->fratio*halo->fratio))));
508 if(xisq*xisq < 1e-20) xisq = 1.0e-10;
509 PosType alpha=halo->
alpha_h(xisq)/PI/xisq;
511 return xisq*alpha*halo->mass/pow((1.-(1.-halo->fratio*halo->fratio)*u),0.5);
519 IDAXDM_func(
double my_lambda,
double my_a2,
double my_b2,
double my_x[],
double my_rmax,
LensHalo *my_halo): lambda(my_lambda), a2(my_a2), b2(my_b2), x(my_x), rmx(my_rmax), halo(my_halo){};
520 double lambda, a2,b2, *x, rmx;
521 double operator ()(
double m) {
522 double ap = m*m*a2 + lambda,bp = m*m*b2 + lambda;
523 double p2 = x[0]*x[0]/ap/ap/ap/ap + x[1]*x[1]/bp/bp/bp/bp;
525 if(tmp*tmp < 1e-20) tmp = 1.0e-10;
526 PosType xiso=tmp/halo->
rscale;
527 KappaType kappa=halo->kappa_h(xiso)/PI/xiso/xiso;
529 PosType alpha[2]={0,0},tm[2] = {m*rmx,0};
530 KappaType kappam=0,gamma[2]={0,0},phi=0;
535 double integrandA=m*kappa/(ap*ap*ap*bp*p2)*halo->mass;
536 double integrandB=m*kappam/(ap*ap*ap*bp*p2);
538 assert( std::abs((integrandA - integrandB)/integrandA)<1E-5);
540 assert(kappa >= 0.0);
550 IDAYDM_func(
double my_lambda,
double my_a2,
double my_b2,
double my_x[],
double my_rmax,
LensHalo *my_halo): lambda(my_lambda), a2(my_a2), b2(my_b2), x(my_x), rmx(my_rmax), halo(my_halo){};
551 double lambda, a2,b2, *x, rmx;
552 double operator ()(
double m) {
553 double ap = m*m*a2 + lambda,bp = m*m*b2 + lambda;
554 double p2 = x[0]*x[0]/ap/ap/ap/ap + x[1]*x[1]/bp/bp/bp/bp;
556 if(tmp*tmp < 1e-20) tmp = 1.0e-10;
557 PosType xiso=tmp/halo->
rscale;
558 KappaType kappa=halo->kappa_h(xiso)/PI/xiso/xiso;
560 PosType alpha[2]={0,0},tm[2] = {m*rmx,0};
561 KappaType kappam=0,gamma[2]={0,0},phi=0;
564 double integrandA=m*kappa/(ap*ap*ap*bp*p2)*halo->mass;
565 double integrandB=m*kappam/(ap*bp*bp*bp*p2);
566 assert( std::abs((integrandA - integrandB)/integrandA)<1E-5);
568 assert(kappa >= 0.0);
577 const static int Nmod = 32;
602 test_gt_func(PosType my_r,
LensHalo *halo): r(my_r),halo(halo){};
603 double operator ()(PosType t) {
604 PosType alpha[2] = {0,0},x[2] = {0,0};
605 KappaType kappa = 0,gamma[3] = {0,0,0},phi =0 ;
609 assert(gamma[0]==gamma[0]);
610 assert(gamma[1]==gamma[1]);
611 return (gamma[0]*cos(2*t)+gamma[1]*sin(2*t));}
629 struct test_kappa_func{
630 test_kappa_func(PosType my_r,
LensHalo *halo): r(my_r),halo(halo){};
631 double operator ()(PosType t) {
632 PosType alpha[2] = {0,0},x[2] = {0,0};
633 KappaType kappa = 0,gamma[3] = {0,0,0},phi =0 ;
637 assert(kappa==kappa);
645 DMDTHETA(PosType R,
LensHalo *halo): R(R),halo(halo){};
646 PosType operator()(PosType theta){
647 PosType alpha[2] = {0,0},x[2] = {0,0};
648 KappaType kappa = 0,gamma[3] = {0,0,0},phi =0 ;
655 PosType alpha_r = -alpha[0]*cos(theta) - alpha[1]*sin(theta);
657 assert( alpha_r == alpha_r );
667 DMDRDTHETA(PosType R,
LensHalo *halo): R(R),halo(halo){};
668 PosType operator()(PosType theta){
670 PosType alpha[2] = {0,0},x[2] = {0,0};
671 KappaType kappa = 0,gamma[3] = {0,0,0} ,phi=0;
677 assert(kappa == kappa);
678 assert(kappa != INFINITY);
688 PosType operator()(PosType logR){
690 LensHalo::DMDRDTHETA dmdrdtheta(exp(logR),halo);
693 if(exp(2*logR) == 0.0)
return 0.0;
694 return Utilities::nintegrate<LensHalo::DMDRDTHETA,PosType>(dmdrdtheta,0,2*PI,1.0e-7)
713 DALPHAXDM(PosType lambda,PosType a2,PosType b2,PosType X[],
LensHalo* myisohalo)
714 :lambda(lambda),a2(a2),b2(b2),x(X),isohalo(myisohalo){};
716 PosType operator()(PosType m);
725 DALPHAYDM(PosType lambda,PosType a2,PosType b2,PosType X[],
LensHalo* isohalo)
726 :lambda(lambda),a2(a2),b2(b2),x(X),isohalo(isohalo){};
728 PosType operator()(PosType m);
756 ,
float my_concentration
759 ,
const COSMOLOGY &cosmo
789 PosType ffunction(PosType x)
const;
790 PosType gfunction(PosType x)
const;
791 PosType dgfunctiondx(PosType x);
792 PosType g2function(PosType x)
const;
793 PosType hfunction(PosType x)
const;
794 PosType dhfunction(PosType x)
const;
795 PosType ddhfunction(PosType x,
bool numerical);
796 PosType dddhfunction(PosType x,
bool numerical);
797 PosType bfunction(PosType x);
798 PosType dbfunction(PosType x);
799 PosType ddbfunction(PosType x);
800 PosType
dmoddb(
int whichmod, PosType q, PosType b);
801 PosType ddmoddb(
int whichmod, PosType q, PosType b);
802 PosType dmoddq(
int whichmod, PosType q, PosType b);
803 PosType ddmoddq(
int whichmod, PosType q, PosType b);
810 void alphaNFW(PosType *alpha,PosType *x,PosType Rtrunc,PosType mass,PosType r_scale
811 ,PosType *center,PosType Sigma_crit);
812 KappaType
kappaNFW(PosType *x,PosType Rtrunc,PosType mass,PosType r_scale
813 ,PosType *center,PosType Sigma_crit);
814 void gammaNFW(KappaType *gamma,PosType *x,PosType Rtrunc,PosType mass,PosType r_scale
815 ,PosType *center,PosType Sigma_crit);
817 void initFromFile(
float my_mass,
long *seed,
float vmax,
float r_halfmass);
818 void initFromMassFunc(
float my_mass,
float my_Rsize,
float my_rscale, PosType my_slope,
long *seed);
834 static PosType *
ftable,*gtable,*g2table,*htable,*xtable,*xgtable,***modtable;
839 PosType InterpolateModes(
int whichmod, PosType q, PosType b);
851 inline KappaType kappa_h(PosType x)
const{
854 inline KappaType gamma_h(PosType x)
const{
858 inline KappaType phi_h(PosType x)
const{
863 inline KappaType phi_int(PosType x)
const{
889 LensHaloPseudoNFW(
float my_mass,
float my_Rsize,PosType my_zlens,
float my_rscale,PosType my_beta,
float my_fratio,
float my_pa,
const COSMOLOGY &cosmo,
EllipMethod my_ellip_method=EllipMethod::Pseudo);
893 PosType
mhat(PosType y, PosType beta)
const;
894 PosType gfunction(PosType x)
const;
897 void set_slope(PosType my_slope){beta=my_slope; make_tables();};
903 void initFromMassFunc(
float my_mass,
float my_Rsize,
float my_rscale, PosType my_slope,
long *seed);
907 static const long NTABLE;
909 static const PosType maxrm;
914 static PosType *mhattable,*xtable;
918 PosType InterpolateFromTable(PosType y)
const;
928 inline PosType alpha_h(PosType x)
const {
929 return -1.0*InterpolateFromTable(x)/InterpolateFromTable(xmax);
931 inline KappaType kappa_h(PosType x)
const {
932 return 0.5*x*x/InterpolateFromTable(xmax)/pow(1+x,beta);
934 inline KappaType gamma_h(PosType x)
const {
936 return (x*x/pow(1+x,beta) - 2*InterpolateFromTable(x))/InterpolateFromTable(xmax);
938 inline KappaType phi_h(PosType x)
const {
939 return -1.0*
alpha_int(x)/InterpolateFromTable(xmax) ;
945 inline KappaType phi_int(PosType x)
const{
946 return -1.0*
alpha_int(x)/InterpolateFromTable(xmax) ;
960 LensHaloPowerLaw(
float my_mass,
float my_Rsize,PosType my_zlens,PosType my_beta
961 ,
float my_fratio,
float my_pa,
const COSMOLOGY &cosmo
973 void initFromMassFunc(
float my_mass,
float my_Rsize,
float my_rscale, PosType my_slope,
long *seed);
984 inline PosType alpha_h(
987 if(x<xmax*1.0e-6) x=1e-6*xmax;
988 return -1.0*pow(x/xmax,-beta+2);
991 inline KappaType kappa_h(
994 if(x==0) x=1e-6*xmax;
996 return 0.5*(-beta+2)*pow(tmp,2-beta);
999 inline KappaType gamma_h(PosType x)
const {
1000 if(x==0) x=1e-6*xmax;
1001 return -beta*pow(x/xmax,-beta+2);
1004 inline KappaType phi_h(PosType x)
const {
1005 if(x==0) x=1e-6*xmax;
1008 inline KappaType phi_int(PosType x)
const{
1010 return -1.0*pow(x/xmax,-beta+2)/(2-beta);
1033 ,
float my_rcore,
float my_fratio,
float my_pa,
const COSMOLOGY &cosmo);
1050 if(&h ==
this)
return *
this;
1063 void force_halo(PosType *alpha,KappaType *kappa,KappaType *gamma,KappaType *phi,PosType
const *xcm,
bool subtract_point=
false,PosType screening = 1.0);
1087 void setZlens(PosType my_zlens,
const COSMOLOGY &cosmo){
1096 static size_t objectCount;
1097 static std::vector<double> q_table;
1098 static std::vector<double> Fofq_table;
1121 void construct_ellip_tables();
1124 NormFuncer(
double my_q):q(my_q){};
1126 double operator()(
double t){
1127 return 1.0/sqrt( 1 + (q*q-1)*sin(t)*sin(t));
1149 ,
const COSMOLOGY &cosmo
1165 if(&h ==
this)
return *
this;
1180 return lightspeed*sqrt( Grav*mass*sqrt(
fratio) / (Rtrunc-Rcore) / PI);
1184 void force_halo(PosType *alpha,KappaType *kappa,KappaType *gamma,KappaType *phi,PosType
const *xcm,
bool subtract_point=
false,PosType screening = 1.0);
1199 void setZlens(PosType my_zlens,
const COSMOLOGY &cosmo){
1238 ,
const COSMOLOGY &cosmo
1248 q_prime = h.q_prime;
1251 mass_pi = h.mass_pi;
1256 if(&h ==
this)
return *
this;
1262 q_prime = h.q_prime;
1265 mass_pi = h.mass_pi;
1275 void force_halo(PosType *alpha,KappaType *kappa,KappaType *gamma,KappaType *phi,PosType
const *xcm,
bool subtract_point=
false,PosType screening = 1.0);
1286 void set_pa(
double p){pa = p;}
1288 void deflection(std::complex<double> &z
1289 ,std::complex<double> &a
1290 ,std::complex<double> &g
1291 ,KappaType &sigma)
const;
1304 std::complex<double> R;
1306 std::complex<double> F(
double r_e,
double t,std::complex<double> z)
const;
1312 class LensHaloTEBPL :
public LensHalo{
1315 LensHaloTEBPL(
float my_mass
1323 ,
const COSMOLOGY &cosmo
1329 LensHaloTEBPL(
const LensHaloTEBPL &h):
1330 LensHalo(h),h1(h.h1),h2(h.h2),h3(h.h3)
1344 LensHaloTEBPL &
operator=(
const LensHaloTEBPL &h){
1345 if(&h ==
this)
return *
this;
1366 float get_fratio(){
return q;};
1368 float get_pa(){
return pa;};
1370 float get_rtrunc(){
return rt;};
1372 float get_rbreak(){
return rb;};
1374 float get_t1(){
return h1.get_t();}
1376 float get_t2(){
return h2.get_t();}
1378 void set_pa(
double p){pa = p;}
1380 void force_halo(PosType *alpha,KappaType *kappa,KappaType *gamma,KappaType *phi,PosType
const *xcm,
bool subtract_point=
false,PosType screening = 1.0);
1396 std::complex<PosType> R;
1407 class LensHaloGaussian :
public LensHalo{
1410 LensHaloGaussian(
float my_mass
1415 ,
const COSMOLOGY &cosmo
1419 LensHaloGaussian(
const LensHaloGaussian &h):
1424 q_prime = h.q_prime;
1434 one_sqpi = h.one_sqpi;
1437 LensHaloGaussian &
operator=(
const LensHaloGaussian &h){
1438 if(&h ==
this)
return *
this;
1443 q_prime = h.q_prime;
1453 one_sqpi = h.one_sqpi;
1458 ~LensHaloGaussian(){};
1462 void force_halo(PosType *alpha,KappaType *kappa,KappaType *gamma,KappaType *phi,PosType
const *xcm,
bool subtract_point=
false,PosType screening = 1.0);
1465 float get_fratio(){
return q;};
1467 float get_pa(){
return pa;};
1469 float get_scalehight(){
return Rhight;};
1472 float get_SigmaCentral(){
return SigmaO;};
1474 void set_pa(
double p){pa = p;}
1476 void deflection(std::complex<double> &z
1477 ,std::complex<double> &a
1478 ,std::complex<double> &g
1479 ,KappaType &sigma)
const;
1484 std::complex<double> dwdz(std::complex<double> z)
const{
1485 return 2.0*(I_sqpi - z*wF(z));
1488 std::complex<double> wF(std::complex<double> z)
const;
1489 std::complex<double> my_erfc(std::complex<double> z)
const;
1508 std::complex<double> R;
1515 std::complex<double> erfi(std::complex<double> z)
const{
1516 return I*(1. - exp(z*z)*wF(z));
1569 std::complex<double> I;
1570 std::complex<double> I_sqpi;
1582 namespace MultiGauss{
1585 virtual double operator()(
double r) = 0;
1586 virtual double cum(
double r) = 0;
1589 struct POWERLAW :
public PROFILE
1595 std::cerr <<
"power-law index <= 2 give unbounded mass!" << std::endl;
1596 throw std::runtime_error(
"bad mass");
1600 double operator()(
double r){
return pow(r,gamma);}
1601 double cum(
double r){
return 2*PI*pow(r,gamma + 2)/(gamma+2);}
1603 void reset(
float g){gamma = g;}
1607 struct SERSIC :
public PROFILE
1609 SERSIC(){reset(0,0);}
1610 SERSIC(
float nn,
float Re){
1613 double cum(
double r){
1614 return cum_norm * boost::math::tgamma_lower(2*n, bn*pow(r/re,t) );
1616 double operator()(
double r){
1617 return exp(-bn*pow(r/re,t) );
1620 void reset(
float nn,
float Re){
1623 bn = 1.9992*n - 0.3271;
1625 cum_norm = 2*PI*n/pow(bn,2*n)*re*re;
1636 struct NFW:
public PROFILE
1638 NFW(
float rs):rs(rs){
1640 double cum(
double r){
1643 double ans=log(x/2);
1644 if(x==1.0) ans += 1.0;
1645 if(x>1.0) ans += 2*atan(sqrt((x-1)/(x+1)))/sqrt(x*x-1);
1646 if(x<1.0) ans += 2*atanh(sqrt((1-x)/(x+1)))/sqrt(1-x*x);
1648 return 2*PI*rs*rs*ans;
1650 double operator()(
double r){
1653 if(x==1.0){
return 1.0/3.0;}
1654 if(x>1.0)
return (1-2*atan(sqrt((x-1)/(x+1)))/sqrt(x*x-1))/(x*x-1);
1655 return (1-2*atanh(sqrt((1-x)/(x+1)))/sqrt(1-x*x))/(x*x-1);
1658 void reset(
double Rs){rs = Rs;}
1679 class LensHaloMultiGauss:
public LensHalo{
1689 std::vector<double> sigmas;
1690 std::vector<double> radii;
1691 std::complex<double> Rotation;
1692 std::vector<LensHaloGaussian> gaussians;
1693 std::vector<double> A;
1703 ,MultiGauss::PROFILE &profile
1711 ,
const COSMOLOGY &cosmo
1713 ,
bool verbose =
false
1721 ,
const std::vector<double> &relative_scales
1722 ,
const std::vector<double> &relative_masses
1726 ,
const COSMOLOGY &cosmo
1728 ,
bool verbose =
false
1733 LensHaloMultiGauss(LensHaloMultiGauss &&halo);
1734 LensHaloMultiGauss(
const LensHaloMultiGauss &halo);
1736 LensHaloMultiGauss &
operator=(
const LensHaloMultiGauss &&halo);
1737 LensHaloMultiGauss &
operator=(
const LensHaloMultiGauss &halo);
1739 ~LensHaloMultiGauss(){};
1742 void set_pa(
double my_pa);
1763 static void calc_masses_scales(MultiGauss::PROFILE &profile
1770 ,
double &totalmass_out
1771 ,std::vector<double> &scales
1772 ,std::vector<double> &masses
1777 scales.resize(Ngaussians);
1779 double tmp = pow(r_max/r_min,1.0/(Ngaussians-2));
1780 scales[0] = r_min/5;
1782 for(
int i=2 ; i < Ngaussians ; ++i){
1783 scales[i] = tmp*scales[i-1];
1787 std::vector<double> radii(Nradii);
1789 double tmp = pow(r_max/r_min,1.0/(Nradii-1));
1791 for(
int i=1 ; i < Nradii ; ++i){
1792 radii[i] = tmp*radii[i-1];
1796 Eigen::MatrixXd M(Nradii,Ngaussians);
1800 double cp = profile.cum(radii[0]);
1801 for(
int n=0 ; n < Ngaussians ; ++n){
1802 M(0,n) = 2*PI*scales[n] * scales[n]
1803 * ( 1 -exp(-radii[0]*radii[0] / 2 / scales[n] /scales[n]) )
1809 for(
int m=1 ; m < Nradii ; ++m){
1810 double p = profile(radii[m]);
1811 for(
int n=0 ; n < Ngaussians ; ++n){
1812 M(m,n) = exp( - radii[m]*radii[m] / 2 / scales[n] /scales[n])
1819 masses.resize(Ngaussians);
1821 std::vector<double> b(Nradii,1);
1822 Eigen::Map<Eigen::VectorXd> v(b.data(),Nradii);
1823 Eigen::Map<Eigen::VectorXd> a(masses.data(),Ngaussians);
1826 a = M.bdcSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(v);
1828 if(verbose) std::cout <<
"test in LensHaloMultiGauss::calc_masses_scales()" << std::endl << M*a << std::endl;
1834 for(
int m=0 ; m < 1 ; ++m){
1836 for(
int n=0 ; n < Ngaussians ; ++n){
1837 surf += masses[n] * scales[n] * scales[n]
1838 * 2*PI*( 1 - exp(-radii[m]*radii[m] / 2 / scales[n] /scales[n]) );
1840 double tmp = profile.cum(radii[m]);
1841 if(verbose) std::cout << tmp <<
" " << surf << std::endl;
1843 rms_error += (surf - tmp )*(surf - tmp) / tmp / tmp;
1846 for(
int m=1 ; m < Nradii ; ++m){
1848 for(
int n=0 ; n < Ngaussians ; ++n){
1849 surf += masses[n] * exp(-radii[m]*radii[m] / 2 / scales[n] /scales[n]) ;
1851 double tmp = profile(radii[m]);
1852 if(verbose) std::cout << tmp <<
" " << surf << std::endl;
1854 rms_error += (surf - tmp )*(surf - tmp ) / tmp /tmp;
1856 rms_error = sqrt(rms_error)/Ngaussians;
1857 if(verbose) std::cout <<
" MSE error " << rms_error << std::endl;
1862 double mass_tmp = 0;
1863 for(
int n=0 ; n<Ngaussians ; ++n){
1864 mass_tmp += scales[n]*scales[n]*masses[n]
1865 *( 1 - exp(-r_norm*r_norm / 2 / scales[n] /scales[n]) );
1869 double tmp = (mass_norm/mass_tmp);
1871 for(
int n=0 ; n<Ngaussians ; ++n) masses[n] *= tmp*scales[n]*scales[n];
1876 for(
int n=0 ; n<Ngaussians ; ++n) totalmass_out += masses[n];
1879 double profile(
double r);
1882 double mass_cum(
double r);
1887 void force_halo(PosType *alpha,KappaType *kappa,KappaType *gamma,KappaType *phi,PosType
const *xcm,
bool subtract_point=
false,PosType screening = 1);
1905 class LensHaloHernquist:
public LensHalo{
1908 LensHaloHernquist(
float my_mass,
float my_Rsize,PosType my_zlens,
float my_rscale,
float my_fratio,
float my_pa,
const COSMOLOGY &cosmo,
EllipMethod my_ellip_method=EllipMethod::Pseudo);
1910 virtual ~LensHaloHernquist();
1912 PosType ffunction(PosType x)
const;
1913 PosType gfunction(PosType x)
const;
1914 PosType hfunction(PosType x)
const;
1915 PosType g2function(PosType x)
const;
1933 static const long NTABLE;
1935 static const PosType maxrm;
1940 static PosType *ftable,*gtable,*g2table,*htable,*xtable,*xgtable;
1944 PosType InterpolateFromTable(PosType *table, PosType y)
const;
1951 inline PosType
alpha_h(PosType x)
const {
1952 return -0.25*InterpolateFromTable(gtable,x)/gmax;
1954 inline KappaType kappa_h(PosType x)
const {
1955 return 0.25*x*x*InterpolateFromTable(ftable,x)/gmax;
1957 inline KappaType gamma_h(PosType x)
const {
1958 return -0.5*x*x*InterpolateFromTable(g2table,x)/gmax;
1960 inline KappaType phi_h(PosType x)
const {
1961 return -0.25*InterpolateFromTable(htable,x)/gmax;
1964 inline KappaType phi_int(PosType x)
const{
1965 return -0.25*InterpolateFromTable(xgtable,x)/gmax;
1983 class LensHaloJaffe:
public LensHalo{
1986 LensHaloJaffe(
float my_mass,
float my_Rsize,PosType my_zlens,
float my_rscale,
float my_fratio
1987 ,
float my_pa,
const COSMOLOGY &cosmo
1988 ,
EllipMethod my_ellip_method=EllipMethod::Pseudo);
1990 virtual ~LensHaloJaffe();
1995 PosType ffunction(PosType x)
const;
1996 PosType gfunction(PosType x)
const;
1997 PosType hfunction(PosType x)
const;
1998 PosType g2function(PosType x)
const;
1999 PosType bfunction(PosType x);
2000 PosType dbfunction(PosType x);
2001 PosType ddbfunction(PosType x);
2006 static const long NTABLE;
2008 static const PosType maxrm;
2013 static PosType *ftable,*gtable,*g2table,*htable,*xtable,*xgtable;
2017 PosType InterpolateFromTable(PosType *table, PosType y)
const;
2024 inline PosType
alpha_h(PosType x)
const{
2025 return -0.25*InterpolateFromTable(gtable,x)/gmax;
2027 inline KappaType kappa_h(PosType x)
const {
2028 return 0.125*x*x*InterpolateFromTable(ftable,x)/gmax;
2030 inline KappaType gamma_h(PosType x)
const {
2032 return -0.25*x*x*InterpolateFromTable(g2table,x)/gmax;
2035 inline KappaType phi_h(PosType x)
const {
2036 return -0.25*InterpolateFromTable(xgtable,x)/gmax;
2038 inline KappaType phi_int(PosType x)
const{
2039 return -0.25*InterpolateFromTable(xgtable,x)/gmax;
2062 LensHaloDummy(
float my_mass,
float my_Rsize,PosType my_zlens,
float my_rscale,
const COSMOLOGY &cosmo);
2067 void force_halo(PosType *alpha,KappaType *kappa,KappaType *gamma,KappaType *phi,PosType
const *xcm,
bool subtract_point=
false,PosType screening = 1.0);
2071 void initFromMassFunc(
float my_mass,
float my_Rsize,
float my_rscale, PosType my_slope,
long *seed);
2077 inline PosType alpha_h(PosType x)
const {
return 0.;}
2078 inline KappaType kappa_h(PosType x)
const {
return 0.;}
2079 inline KappaType gamma_h(PosType x)
const {
return 0.;}