28 use constants
, only: k_b, ev, mass_ratio_he_h
30 use transfer
, only: transfer_sortandindexredshifts, transfer_output_sig8, mt
38 #ifdef COSMICFISH_EFTCAMB
54 subroutine derived_fisher_parameter_compatibility( P, FP )
64 character(LEN=20) :: str, str2
67 if ( fp%fisher_der%want_sigma8 )
then
69 p%PK_WantTransfer = .true.
70 p%WantTransfer = .true.
71 p%Transfer%high_precision = .true.
72 p%Transfer%PK_num_redshifts = fp%fisher_der%FD_num_redshift
73 do i=1, fp%fisher_der%FD_num_redshift
74 p%transfer%PK_redshifts(i) = fp%fisher_der%FD_redshift(i)
77 call transfer_sortandindexredshifts(p%Transfer)
79 do i=1, fp%fisher_der%FD_num_redshift
80 fp%fisher_der%FD_redshift(i) = p%transfer%PK_redshifts(i)
85 num_redshiftwindows = 0
87 end subroutine derived_fisher_parameter_compatibility
95 Type(cambparams) ,
intent(in) :: P
97 integer ,
intent(out) :: num
101 if ( fp%fisher_der%want_omegab )
then
104 if ( fp%fisher_der%want_omegac )
then
107 if ( fp%fisher_der%want_omegan )
then
110 if ( fp%fisher_der%want_omegav )
then
113 if ( fp%fisher_der%want_omegak )
then
116 if ( fp%fisher_der%want_omegam )
then
119 if ( fp%fisher_der%want_theta )
then
122 if ( fp%fisher_der%want_mnu )
then
125 if ( fp%fisher_der%want_zre )
then
128 if ( fp%fisher_der%want_neff )
then
133 if ( fp%fisher_der%want_sigma8 )
then
134 num = num + fp%fisher_der%FD_num_redshift
137 if ( fp%fisher_der%want_loghubble )
then
138 num = num + fp%fisher_der%FD_num_redshift
141 if ( fp%fisher_der%want_logDA )
then
142 num = num + fp%fisher_der%FD_num_redshift
153 Type(cambparams) ,
intent(in) :: P
155 real(dl),
dimension(:),
intent(out) :: derived
156 integer ,
intent(in) :: num
157 integer,
intent(out) :: err
165 integer :: i, j, nu_i, ind, error
166 logical :: EFTsuccess
168 type(cambdata) :: outdata
174 call cambparams_set(p)
176 #ifdef COSMICFISH_EFTCAMB
178 if (p%EFTflag /= 0)
then
179 call eftcamb_initialization(eftsuccess)
180 if (.not. eftsuccess)
then
181 write(*,*)
'EFTCAMB: unstable model'
189 if ( fp%fisher_der%want_sigma8 )
then
191 call camb_gettransfers(p, outdata, error)
194 write (*,*)
'Error result '//trim(global_error_message)
202 if ( fp%fisher_der%want_omegab )
then
204 derived(ind) = cp%omegab
206 if ( fp%fisher_der%want_omegac )
then
208 derived(ind) = cp%omegac
210 if ( fp%fisher_der%want_omegan )
then
212 derived(ind) = cp%omegan
214 if ( fp%fisher_der%want_omegav )
then
216 derived(ind) = cp%omegav
218 if ( fp%fisher_der%want_omegak )
then
220 derived(ind) = cp%omegak
222 if ( fp%fisher_der%want_omegam )
then
224 derived(ind) = 1-cp%omegak-cp%omegav
226 if ( fp%fisher_der%want_theta )
then
228 derived(ind) = 100*cosmomctheta()
230 if ( fp%fisher_der%want_mnu )
then
232 if (cp%Num_Nu_Massive == 1)
then
233 do nu_i=1, cp%Nu_mass_eigenstates
234 conv = k_b*(8*grhor/grhog/7)**0.25*cp%tcmb/ev * &
235 (cp%nu_mass_degeneracies(nu_i)/cp%nu_mass_numbers(nu_i))**0.25
236 derived(ind) = conv*nu_masses(nu_i)
242 if ( fp%fisher_der%want_zre )
then
244 derived(ind) = cp%Reion%redshift
246 if ( fp%fisher_der%want_neff )
then
248 derived(ind) = cp%Num_Nu_massless + cp%Num_Nu_massive
252 if ( fp%fisher_der%want_sigma8 )
then
253 do i=1, fp%fisher_der%FD_num_redshift
255 j = p%Transfer%PK_redshifts_index(i)
256 derived(ind) = outdata%MTrans%sigma_8(i,1)
260 if ( fp%fisher_der%want_loghubble )
then
261 do i=1, fp%fisher_der%FD_num_redshift
263 z = fp%fisher_der%FD_redshift(i)
264 derived(ind) = log10(hofz(z))
268 if ( fp%fisher_der%want_logDA )
then
269 do i=1, fp%fisher_der%FD_num_redshift
271 z = fp%fisher_der%FD_redshift(i)
272 if (angulardiameterdistance(z)==0._dl)
then
273 derived(ind) = -16._dl
275 derived(ind) = log10(angulardiameterdistance(z))
281 write(*,*)
'ERROR: Compute_Derived_Parameters num is not: ', num
282 write(*,*)
'If you added a parameter change also dimension_derived_parameters'
294 Type(cambparams) ,
intent(in) :: P
296 integer ,
intent(in) :: param_number
297 character(*) ,
intent(out) :: param_name
298 character(*) ,
intent(out),
optional :: param_name_latex
300 integer :: i, j, ind, num_param
301 character(len=20) str
308 if ( fp%fisher_der%want_omegab ) num_param = num_param + 1
309 if ( param_number == num_param ) then; param_name =
'omegab';
if (
present(param_name_latex) ) param_name_latex =
'\Omega_b';
return ;
311 if ( fp%fisher_der%want_omegac ) num_param = num_param + 1
312 if ( param_number == num_param ) then; param_name =
'omegac';
if (
present(param_name_latex) ) param_name_latex =
'\Omega_c';
return ;
314 if ( fp%fisher_der%want_omegan ) num_param = num_param + 1
315 if ( param_number == num_param ) then; param_name =
'omeganu';
if (
present(param_name_latex) ) param_name_latex =
'\Omega_{\nu}';
return ;
317 if ( fp%fisher_der%want_omegav ) num_param = num_param + 1
318 if ( param_number == num_param ) then; param_name =
'omegav';
if (
present(param_name_latex) ) param_name_latex =
'\Omega_{\Lambda}';
return ;
320 if ( fp%fisher_der%want_omegak ) num_param = num_param + 1
321 if ( param_number == num_param ) then; param_name =
'omegak';
if (
present(param_name_latex) ) param_name_latex =
'\Omega_{K}';
return ;
323 if ( fp%fisher_der%want_omegam ) num_param = num_param + 1
324 if ( param_number == num_param ) then; param_name =
'omegam';
if (
present(param_name_latex) ) param_name_latex =
'\Omega_{m}';
return ;
326 if ( fp%fisher_der%want_theta ) num_param = num_param + 1
327 if ( param_number == num_param ) then; param_name =
'theta';
if (
present(param_name_latex) ) param_name_latex =
'100\theta_{MC}';
return ;
329 if ( fp%fisher_der%want_mnu ) num_param = num_param + 1
330 if ( param_number == num_param ) then; param_name =
'mnu';
if (
present(param_name_latex) ) param_name_latex =
'\Sigma m_\nu';
return ;
332 if ( fp%fisher_der%want_zre ) num_param = num_param + 1
333 if ( param_number == num_param ) then; param_name =
'z_re';
if (
present(param_name_latex) ) param_name_latex =
'z_{\rm re}';
return ;
335 if ( fp%fisher_der%want_neff ) num_param = num_param + 1
336 if ( param_number == num_param ) then; param_name =
'Neff';
if (
present(param_name_latex) ) param_name_latex =
'N_{\rm eff}';
return ;
341 if ( fp%fisher_der%want_sigma8 )
then
342 do i=1, fp%fisher_der%FD_num_redshift
344 if ( param_number == ind )
then
345 j = p%Transfer%PK_redshifts_index(i)
348 param_name =
'sigma8_'//trim(str)
349 write (str,
'(F20.2)') p%Transfer%redshifts(j)
351 if (
present(param_name_latex) ) param_name_latex =
'\sigma_{8}('//trim(str)//
')'
357 if ( fp%fisher_der%want_loghubble )
then
358 do i=1, fp%fisher_der%FD_num_redshift
360 if ( param_number == ind )
then
361 z = fp%fisher_der%FD_redshift(i)
364 param_name =
'logHoz_'//trim(str)
365 write (str,
'(F20.2)') z
367 if (
present(param_name_latex) ) param_name_latex =
'\log_{10}H('//trim(str)//
')'
373 if ( fp%fisher_der%want_logDA )
then
374 do i=1, fp%fisher_der%FD_num_redshift
376 if ( param_number == ind )
then
377 z = fp%fisher_der%FD_redshift(i)
380 param_name =
'logDAz_'//trim(str)
381 write (str,
'(F20.2)') z
383 if (
present(param_name_latex) ) param_name_latex =
'\log_{10}D_{\rm A}('//trim(str)//
')'
396 & derived_initial, derived_derivative, derived_der_error, &
403 Type(cambparams) ,
intent(in) :: P
406 integer ,
intent(in) :: param_num
407 integer ,
intent(in) :: num_param
409 real(dl),
dimension(:),
intent(in) :: derived_initial
410 real(dl),
dimension(:),
intent(out) :: derived_derivative
411 real(dl),
dimension(:),
intent(out) :: derived_der_error
413 real(dl),
intent(in) :: initial_step
414 integer ,
intent(out) :: error_code
421 real(dl),
dimension(:),
allocatable :: der_temp_1, der_temp_2, errt
422 integer ,
dimension(:),
allocatable :: accept_mask
423 real(dl),
dimension(:,:,:),
allocatable :: a
424 real(dl),
dimension(num_param) :: param_vector, fiducial_param_vector, temp_param_vector
426 real(dl),
parameter :: con = 1.4_dl
427 real(dl),
parameter :: big = 1.d+30
428 real(dl),
parameter :: safe = 2._dl
429 integer ,
parameter :: ntab = 30
430 real(dl) :: con2 = con*con
431 integer :: i, j, k, l, m, side, err, AllocateStatus
433 real(dl) :: temp1, temp2, temp3
434 Type(cambparams) :: P_temp
437 real(dl) :: acceptance
438 integer :: derived_param_size
442 derived_derivative = 0._dl
443 derived_der_error = 0._dl
446 if ( initial_step == 0._dl )
then
447 stop
'Derived_Parameter_Derivative initial stepsize is zero'
453 if ( fp%adaptivity )
then
454 allocate( der_temp_1(derived_param_size), &
455 & der_temp_2(derived_param_size), &
456 & errt(derived_param_size), &
457 & accept_mask(derived_param_size),&
458 & stat = allocatestatus )
459 if (allocatestatus /= 0) stop
"Derived_Parameter_Derivative: Allocation failed. Not enough memory"
460 allocate( a(ntab, ntab, derived_param_size) , stat = allocatestatus )
461 if (allocatestatus /= 0) stop
"Derived_Parameter_Derivative: Allocation failed. Not enough memory for the derivative array"
463 allocate( der_temp_1(derived_param_size), &
464 & der_temp_2(derived_param_size), &
465 & stat = allocatestatus )
466 if (allocatestatus /= 0) stop
"Derived_Parameter_Derivative: Allocation failed. Not enough memory"
467 allocate( a(1,1, derived_param_size) , stat = allocatestatus )
468 if (allocatestatus /= 0) stop
"Derived_Parameter_Derivative: Allocation failed. Not enough memory for the derivative array"
477 fiducial_param_vector = param_vector
478 temp_param_vector = param_vector
482 derived_der_error = big
484 if ( fp%adaptivity ) accept_mask = 0
487 param_vector(param_num) = fiducial_param_vector(param_num) + hh
491 if ( err /= 0 ) side = 1
493 temp_param_vector(param_num) = fiducial_param_vector(param_num) - hh
499 if ( side == 1 )
then
501 derived_der_error = 0.0_dl
502 derived_derivative = 0.0_dl
504 else if ( side == 0 )
then
511 a(1,1,:) = (der_temp_1(:) - der_temp_2(:))/(2.0_dl*hh)
512 else if (side == 1)
then
513 a(1,1,:) = (der_temp_2(:) - derived_initial(:))/(-hh)
514 else if (side == 2)
then
515 a(1,1,:) = (der_temp_1(:) - derived_initial(:))/(hh)
519 if ( .not. fp%adaptivity )
then
520 derived_derivative(:) = a(1,1,:)
521 derived_der_error = 0.0_dl
522 deallocate( der_temp_1, der_temp_2, a )
530 if ( fp%cosmicfish_feedback >= 2 )
then
531 accepted = sum(accept_mask)
532 acceptance =
REAL(accepted)/
REAL(derived_param_size)
533 print*,
'iteration:', i
534 print*,
' stepsize:', hh
535 print*,
' accepted elements', accepted,
'accepted ratio', acceptance
543 param_vector(param_num) = fiducial_param_vector(param_num) + hh
544 temp_param_vector(param_num) = fiducial_param_vector(param_num) - hh
550 derived_der_error = 0.0_dl
551 derived_derivative = 0.0_dl
559 derived_der_error = 0.0_dl
560 derived_derivative = 0.0_dl
564 a(1,i,:) = (der_temp_1(:) - der_temp_2(:))/(2.0_dl*hh)
565 else if (side==1)
then
566 param_vector(param_num) = fiducial_param_vector(param_num) - hh
571 derived_der_error = 0.0_dl
572 derived_derivative = 0.0_dl
576 a(1,i,:) = (der_temp_1(:) - derived_initial(:))/(-hh)
577 else if (side==2)
then
578 param_vector(param_num) = fiducial_param_vector(param_num) + hh
583 derived_der_error = 0.0_dl
584 derived_derivative = 0.0_dl
588 a(1,i,:) = (der_temp_1(:) - derived_initial(:))/(hh)
595 forall ( k = 1:derived_param_size, accept_mask(k) == 0 )
597 a(j,i,k) = (a(j-1,i,k)*fac-a(j-1,i-1,k))/(fac-1._dl)
599 errt(k) = max( abs(a(j,i,k)-a(j-1,i,k)), &
600 & abs(a(j,i,k)-a(j-1,i-1,k)))
607 forall ( k = 1:derived_param_size, &
608 & errt(k) .le. derived_der_error(k) .and. accept_mask(k) == 0 )
610 derived_der_error(k) = errt(k)
611 derived_derivative(k) = a(j,i,k)
618 forall ( k = 1:derived_param_size, &
619 & accept_mask(k) == 0 .and. &
620 & (a(i,i,k) - a(i-1,i-1,k)) .ge. safe*derived_der_error(k) )
626 if ( sum(accept_mask) == derived_param_size )
exit
631 if ( sum(accept_mask) /= derived_param_size )
then
636 if ( fp%adaptivity )
then
637 deallocate( der_temp_1, der_temp_2, errt, accept_mask, a )
646 subroutine fisher_derived( P_in, FP_in, num_param, num_derived, Derived_Matrix, outroot )
650 Type(cambparams) ,
intent(in) :: P_in
653 integer ,
intent(in) :: num_param
654 integer ,
intent(in) :: num_derived
655 real(dl),
dimension(num_param,num_derived),
intent(out) :: Derived_Matrix
656 character(len=*),
intent(in),
optional :: outroot
658 Type(cambparams) :: P
661 real(dl) :: time_1, time_2
662 real(dl) :: initial_step, temp, temp1, temp2
663 integer :: AllocateStatus, err, ind, ind2
664 integer :: i, j, k, l, number
665 real(dl),
allocatable :: param_array(:)
666 real(dl),
allocatable,
dimension(:) :: derived_fiducial, derived_derivative, derived_temp
667 real(dl),
allocatable,
dimension(:,:) :: derived_derivative_array
674 call derived_fisher_parameter_compatibility( p, fp )
677 if ( num_derived==1 )
then
678 write(*,*)
'WARNING: for better compatibility with CosmicFish PyLib use at least two derived parameters.'
682 allocate( param_array(num_param) )
686 allocate( derived_fiducial(num_derived), derived_derivative(num_derived), derived_temp(num_derived), stat = allocatestatus )
687 if (allocatestatus /= 0) stop
"Allocation failed. Not enough memory to allocate derived fiducial."
688 allocate( derived_derivative_array( num_param, num_derived ), stat = allocatestatus)
689 if (allocatestatus /= 0) stop
"Allocation failed. Not enough memory to allocate derived_derivative_array"
692 time_1 = omp_get_wtime()
694 time_2 = omp_get_wtime() - time_1
697 else if ( err == 4 )
then
698 write(*,*)
'Fiducial model unstable. Calculation cannot proceed.'
701 write(*,*)
'Error in computing the fiducial. Calculation cannot proceed.'
706 if ( fp%cosmicfish_feedback >= 1 )
then
707 write(*,
'(a)')
'**************************************************************'
708 write(*,
'(a,i10)')
'Number of derived parameters : ', num_derived
709 write(*,
'(a,i10)')
'Number of parameters : ', num_param
710 write(*,
'(a,f10.3,a)')
'Time for derived calculation : ', time_2,
' (s)'
711 write(*,
'(a,i10)')
'Number of omp processes : ', omp_get_max_threads()
712 if ( fp%adaptivity )
then
713 write(*,
'(a,f10.3,a)')
'Estimated completion time : ', time_2*20._dl*num_param,
' (s)'
715 write(*,
'(a,f10.3,a)')
'Estimated completion time : ', time_2*2._dl*num_param,
' (s)'
717 write(*,
'(a)')
'**************************************************************'
721 if ( fp%cosmicfish_feedback >= 1 )
then
722 write(*,
'(a)')
'Computation of the derived parameters derivatives'
725 time_1 = omp_get_wtime()
726 do ind = 1, num_param
728 if ( fp%cosmicfish_feedback >= 1 )
then
729 write(*,
'(a,i5,a,E15.5)')
'Doing parameter number: ', ind,
' value: ', param_array(ind)
732 if ( param_array(ind) /= 0._dl )
then
733 initial_step = param_array(ind)*3.0_dl/100._dl
735 initial_step = 3.0_dl/100._dl
739 & derived_fiducial, derived_derivative, derived_temp, &
744 if (err /= 0) print*,
'WARNING: something went wrong with the Derived derivative of parameter:', ind,
'Error code:', err
746 derived_derivative_array(ind,:) = derived_derivative(:)
749 time_2 = omp_get_wtime() - time_1
751 if ( fp%cosmicfish_feedback >= 1 )
then
753 write(*,
'(a,f8.3,a)')
'Time to compute all the derivatives:', time_2,
' (s)'
757 do ind = 1, num_param
758 do ind2 = 1, num_derived
760 derived_matrix(ind, ind2) = derived_derivative_array(ind, ind2)
764 time_2 = omp_get_wtime() - time_1
766 if ( fp%cosmicfish_feedback >= 1 )
then
767 write(*,
'(a,f8.3,a)')
'Time to compute the derived matrix:', time_2,
' (s)'
779 Type(cambparams) :: P_in
781 integer ,
intent(in) :: num_params
782 integer ,
intent(in) :: num_derived
783 real(dl),
intent(in),
dimension(num_params, num_derived) :: matrix
784 character(len=*),
intent(in) :: filename
786 Type(cambparams) :: P
789 character(LEN=500) :: param_name
790 character(LEN=500) :: param_name_latex
792 real(dl),
allocatable,
dimension(:) :: parameters, parameters_derived
798 call derived_fisher_parameter_compatibility( p, fp )
800 allocate( parameters(num_params), parameters_derived(num_derived) )
803 if ( err /= 0 ) stop
'Error: Compute_Derived_Parameters failed when save_derived_Fisher_to_file'
805 open(unit=666, file=filename, action=
"write", status=
"replace")
809 write(666,
'(a)')
'# This file contains a Fisher matrix created with the CosmicFish code.'
812 write(666,
'(a)')
'# The parameters of this derived parameters Fisher matrix are:'
815 do ind = 1, num_params
817 write(666,
'(a,I5,a,a,a,a,a,E25.16)')
'# ', ind,
' ', trim(param_name),
' ', trim(param_name_latex),
' ', parameters(ind)
821 write(666,
'(a)')
'# The derived parameters of this matrix are:'
824 do ind = 1, num_derived
826 write(666,
'(a,I5,a,a,a,a,a,E25.16)')
'# ', ind,
' ', trim(param_name),
' ', trim(param_name_latex),
' ', parameters_derived(ind)
832 do ind = 1, num_params
833 write(666,
'(2x,*(E25.16,2x))') matrix(ind, :)
846 Type(cambparams) :: P_in
848 integer ,
intent(in) :: num_params
849 integer ,
intent(in) :: num_derived
850 character(len=*),
intent(in) :: filename
852 Type(cambparams) :: P
855 character(LEN=500) :: param_name
856 character(LEN=500) :: param_name_latex
858 real(dl),
allocatable,
dimension(:) :: parameters, parameters_derived
864 call derived_fisher_parameter_compatibility( p, fp )
865 allocate( parameters(num_params), parameters_derived(num_derived) )
870 if ( err /= 0 ) stop
'Error: Compute_Derived_Parameters failed when save_derived_Fisher_to_file'
872 open(unit=666, file=filename, action=
"write", status=
"replace")
877 write(666,
'(a)')
'# This file contains the parameter names for a derived Fisher matrix.'
878 write(666,
'(a)')
'# Derived parameters are indicated with a * at the end of the name.'
881 do ind = 1, num_params
883 write(666,
'(a,a,a,a,E25.16)') trim(param_name),
' ', trim(param_name_latex),
' ', parameters(ind)
885 do ind = 1, num_derived
887 write(666,
'(a,a,a,a,E25.16)') trim(param_name)//
'*',
' ', trim(param_name_latex),
' ', parameters_derived(ind)
subroutine, public save_derived_fisher_to_file(P_in, FP_in, num_params, num_derived, matrix, filename)
This subroutine saves the Fisher derived matrix to file taking care of putting into the file all the ...
subroutine, public save_derived_paramnames_to_file(P_in, FP_in, num_params, num_derived, filename)
This subroutine saves a file containing the parameter names for the derived Fisher matrix run...
subroutine, public dimension_derived_parameters(P, FP, num)
This subroutine returns the number of derived parameters.
subroutine, public params_array_to_camb_param(P, FP, num_param, params_array)
This subroutine updates the values of the parameters P and FP based on the values contained in the pa...
subroutine, public camb_params_to_params_array(P, FP, num_param, params_array)
This subroutine updates the values of the parameters array based on the values of P and FP...
This module contains the definitions of derived data types used to store the informations about the f...
subroutine, public fisher_param_names(P, FP, param_number, param_name, param_name_latex)
This subroutine returns the name corresponding to a parameter number.
This module contains the interface layer between CosmicFish and CAMB.
This module contains several general purpose utilities.
This module contains the code that computes the matrix that can be used to compute the the Fisher mat...
subroutine, public fisher_derived_param_names(P, FP, param_number, param_name, param_name_latex)
This subroutine returns the name corresponding to a derived parameter number.
subroutine, public fisher_derived(P_in, FP_in, num_param, num_derived, Derived_Matrix, outroot)
This subroutine computes the Fisher matrix for derived parameters.
subroutine, public compute_derived_parameters(P, FP, derived, num, err)
This subroutine returns an array of derived parameters given CAMB parameters.
subroutine, public derived_parameter_derivative(P, FP, param_num, derived_initial, derived_derivative, derived_der_error, initial_step, num_param, error_code)
This subroutine computes the derivative of derived parameters. The calculation is carried out with a ...
This derived data type contains all the informations that the cosmicfish code needs to run...