CosmicFish  Reference documentation for version 1.0
Looking into future Cosmology
012_Fisher_calculator_derived.f90
Go to the documentation of this file.
1 !----------------------------------------------------------------------------------------
2 !
3 ! This file is part of CosmicFish.
4 !
5 ! Copyright (C) 2015-2016 by the CosmicFish authors
6 !
7 ! The CosmicFish code is free software;
8 ! You can use it, redistribute it, and/or modify it under the terms
9 ! of the GNU General Public License as published by the Free Software Foundation;
10 ! either version 3 of the License, or (at your option) any later version.
11 ! The full text of the license can be found in the file LICENSE at
12 ! the top level of the CosmicFish distribution.
13 !
14 !----------------------------------------------------------------------------------------
15 
19 
20 !----------------------------------------------------------------------------------------
23 
25 
27 
28  use constants, only: k_b, ev, mass_ratio_he_h
29  use precision
30  use transfer, only: transfer_sortandindexredshifts, transfer_output_sig8, mt
31  use modelparams
33  use omp_lib
36  use camb
37 
38 #ifdef COSMICFISH_EFTCAMB
39  use eftinitialization
40 #endif
41 
42  implicit none
43 
44  private
45 
48 
49 contains
50 
51  ! ---------------------------------------------------------------------------------------------
54  subroutine derived_fisher_parameter_compatibility( P, FP )
55 
56  implicit none
57 
58  Type(cambparams) :: p
59  Type(cosmicfish_params) :: fp
60 
61  integer :: i
62 
63  integer :: j
64  character(LEN=20) :: str, str2
65 
66  ! if we want tomography for the derived parameters fix the transfer functions parameters accorgingly:
67  if ( fp%fisher_der%want_sigma8 ) then
68  ! write the relevant quantities in Transfer:
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)
75  end do
76  ! ensure ordering in redshift:
77  call transfer_sortandindexredshifts(p%Transfer)
78  ! copy back the redshift:
79  do i=1, fp%fisher_der%FD_num_redshift
80  fp%fisher_der%FD_redshift(i) = p%transfer%PK_redshifts(i)
81  end do
82  end if
83 
84  ! we do not want other things to be computed:
85  num_redshiftwindows = 0
86 
87  end subroutine derived_fisher_parameter_compatibility
88 
89  ! ---------------------------------------------------------------------------------------------
91  subroutine dimension_derived_parameters( P, FP, num )
92 
93  implicit none
94 
95  Type(cambparams) , intent(in) :: P
96  Type(cosmicfish_params), intent(in) :: FP
97  integer , intent(out) :: num
98 
99  ! start with the base derived parameters:
100  num = 0
101  if ( fp%fisher_der%want_omegab ) then
102  num = num + 1
103  end if
104  if ( fp%fisher_der%want_omegac ) then
105  num = num + 1
106  end if
107  if ( fp%fisher_der%want_omegan ) then
108  num = num + 1
109  end if
110  if ( fp%fisher_der%want_omegav ) then
111  num = num + 1
112  end if
113  if ( fp%fisher_der%want_omegak ) then
114  num = num + 1
115  end if
116  if ( fp%fisher_der%want_omegam ) then
117  num = num + 1
118  end if
119  if ( fp%fisher_der%want_theta ) then
120  num = num + 1
121  end if
122  if ( fp%fisher_der%want_mnu ) then
123  num = num + 1
124  end if
125  if ( fp%fisher_der%want_zre ) then
126  num = num + 1
127  end if
128  if ( fp%fisher_der%want_neff ) then
129  num = num + 1
130  end if
131 
132  ! add sigma8 if wanted:
133  if ( fp%fisher_der%want_sigma8 ) then
134  num = num + fp%fisher_der%FD_num_redshift
135  end if
136  ! add Hubble if wanted:
137  if ( fp%fisher_der%want_loghubble ) then
138  num = num + fp%fisher_der%FD_num_redshift
139  end if
140  ! add DA if wanted:
141  if ( fp%fisher_der%want_logDA ) then
142  num = num + fp%fisher_der%FD_num_redshift
143  end if
144 
145  end subroutine dimension_derived_parameters
146 
147  ! ---------------------------------------------------------------------------------------------
149  subroutine compute_derived_parameters( P, FP, derived, num, err )
151  implicit none
152 
153  Type(cambparams) , intent(in) :: P
154  Type(cosmicfish_params), intent(in) :: FP
155  real(dl), dimension(:), intent(out) :: derived
156  integer , intent(in) :: num
157  integer, intent(out) :: err
163 
164  ! other definitions:
165  integer :: i, j, nu_i, ind, error
166  logical :: EFTsuccess
167  real(dl) :: conv, z
168  type(cambdata) :: outdata
169  ! initialization:
170  derived = 0._dl
171  err = 0
172 
173  ! set the camb parameters:
174  call cambparams_set(p)
175 
176 #ifdef COSMICFISH_EFTCAMB
177  ! check stability if EFTCAMB is used:
178  if (p%EFTflag /= 0) then
179  call eftcamb_initialization(eftsuccess)
180  if (.not. eftsuccess) then
181  write(*,*) 'EFTCAMB: unstable model'
182  err = 4
183  return
184  end if
185  end if
186 #endif
187 
188  ! get the transfer functions for sigma_8
189  if ( fp%fisher_der%want_sigma8 ) then
190  error = 0
191  call camb_gettransfers(p, outdata, error)
192  ! test for errors in the computation
193  if (error/=0) then
194  write (*,*) 'Error result '//trim(global_error_message)
195  err = 2
196  return
197  endif
198  end if
199 
200  ! write the parameter array:
201  ind = 0
202  if ( fp%fisher_der%want_omegab ) then
203  ind = ind + 1
204  derived(ind) = cp%omegab ! Baryons density
205  end if
206  if ( fp%fisher_der%want_omegac ) then
207  ind = ind + 1
208  derived(ind) = cp%omegac ! CDM density
209  end if
210  if ( fp%fisher_der%want_omegan ) then
211  ind = ind + 1
212  derived(ind) = cp%omegan ! Neutrino density
213  end if
214  if ( fp%fisher_der%want_omegav ) then
215  ind = ind + 1
216  derived(ind) = cp%omegav ! DE density
217  end if
218  if ( fp%fisher_der%want_omegak ) then
219  ind = ind + 1
220  derived(ind) = cp%omegak ! Curvature density
221  end if
222  if ( fp%fisher_der%want_omegam ) then
223  ind = ind + 1
224  derived(ind) = 1-cp%omegak-cp%omegav ! Matter density
225  end if
226  if ( fp%fisher_der%want_theta ) then
227  ind = ind + 1
228  derived(ind) = 100*cosmomctheta() ! Theta CosmoMC
229  end if
230  if ( fp%fisher_der%want_mnu ) then
231  ind = ind + 1
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 !approx 1.68e-4
236  derived(ind) = conv*nu_masses(nu_i)
237  end do
238  else
239  derived(ind) = 0._dl ! m_nu in eV
240  end if
241  end if
242  if ( fp%fisher_der%want_zre ) then
243  ind = ind + 1
244  derived(ind) = cp%Reion%redshift ! reionization redshift
245  end if
246  if ( fp%fisher_der%want_neff ) then
247  ind = ind + 1
248  derived(ind) = cp%Num_Nu_massless + cp%Num_Nu_massive
249  end if
250 
251  ! add sigma8 if wanted:
252  if ( fp%fisher_der%want_sigma8 ) then
253  do i=1, fp%fisher_der%FD_num_redshift
254  ind = ind + 1
255  j = p%Transfer%PK_redshifts_index(i)
256  derived(ind) = outdata%MTrans%sigma_8(i,1)
257  end do
258  end if
259  ! add Hubble if wanted:
260  if ( fp%fisher_der%want_loghubble ) then
261  do i=1, fp%fisher_der%FD_num_redshift
262  ind = ind + 1
263  z = fp%fisher_der%FD_redshift(i)
264  derived(ind) = log10(hofz(z))
265  end do
266  end if
267  ! add DA if wanted:
268  if ( fp%fisher_der%want_logDA ) then
269  do i=1, fp%fisher_der%FD_num_redshift
270  ind = ind + 1
271  z = fp%fisher_der%FD_redshift(i)
272  if (angulardiameterdistance(z)==0._dl) then
273  derived(ind) = -16._dl ! protection against redshift zero...
274  else
275  derived(ind) = log10(angulardiameterdistance(z))
276  end if
277  end do
278  end if
279 
280  if ( num/=ind ) then
281  write(*,*) 'ERROR: Compute_Derived_Parameters num is not: ', num
282  write(*,*) 'If you added a parameter change also dimension_derived_parameters'
283  stop
284  end if
285 
286  end subroutine compute_derived_parameters
287 
288  ! ---------------------------------------------------------------------------------------------
290  subroutine fisher_derived_param_names(P, FP, param_number, param_name, param_name_latex)
292  implicit none
293 
294  Type(cambparams) , intent(in) :: P
295  Type(cosmicfish_params), intent(in) :: FP
296  integer , intent(in) :: param_number
297  character(*) , intent(out) :: param_name
298  character(*) , intent(out), optional :: param_name_latex
299 
300  integer :: i, j, ind, num_param
301  character(len=20) str
302  real(dl) :: z
303 
304  num_param = 0
305 
306  ! standard parameters:
307 
308  if ( fp%fisher_der%want_omegab ) num_param = num_param + 1 ! omegab
309  if ( param_number == num_param ) then; param_name = 'omegab'; if ( present(param_name_latex) ) param_name_latex = '\Omega_b'; return ;
310  end if
311  if ( fp%fisher_der%want_omegac ) num_param = num_param + 1 ! omegac
312  if ( param_number == num_param ) then; param_name = 'omegac'; if ( present(param_name_latex) ) param_name_latex = '\Omega_c'; return ;
313  end if
314  if ( fp%fisher_der%want_omegan ) num_param = num_param + 1 ! omegan
315  if ( param_number == num_param ) then; param_name = 'omeganu'; if ( present(param_name_latex) ) param_name_latex = '\Omega_{\nu}'; return ;
316  end if
317  if ( fp%fisher_der%want_omegav ) num_param = num_param + 1 ! omegav
318  if ( param_number == num_param ) then; param_name = 'omegav'; if ( present(param_name_latex) ) param_name_latex = '\Omega_{\Lambda}'; return ;
319  end if
320  if ( fp%fisher_der%want_omegak ) num_param = num_param + 1 ! omegak
321  if ( param_number == num_param ) then; param_name = 'omegak'; if ( present(param_name_latex) ) param_name_latex = '\Omega_{K}'; return ;
322  end if
323  if ( fp%fisher_der%want_omegam ) num_param = num_param + 1 ! omegam
324  if ( param_number == num_param ) then; param_name = 'omegam'; if ( present(param_name_latex) ) param_name_latex = '\Omega_{m}'; return ;
325  end if
326  if ( fp%fisher_der%want_theta ) num_param = num_param + 1 ! theta
327  if ( param_number == num_param ) then; param_name = 'theta'; if ( present(param_name_latex) ) param_name_latex = '100\theta_{MC}'; return ;
328  end if
329  if ( fp%fisher_der%want_mnu ) num_param = num_param + 1 ! mnu
330  if ( param_number == num_param ) then; param_name = 'mnu'; if ( present(param_name_latex) ) param_name_latex = '\Sigma m_\nu'; return ;
331  end if
332  if ( fp%fisher_der%want_zre ) num_param = num_param + 1 ! zre
333  if ( param_number == num_param ) then; param_name = 'z_re'; if ( present(param_name_latex) ) param_name_latex = 'z_{\rm re}'; return ;
334  end if
335  if ( fp%fisher_der%want_neff ) num_param = num_param + 1 ! neff
336  if ( param_number == num_param ) then; param_name = 'Neff'; if ( present(param_name_latex) ) param_name_latex = 'N_{\rm eff}'; return ;
337  end if
338 
339  ind = num_param
340  ! add sigma8 if wanted:
341  if ( fp%fisher_der%want_sigma8 ) then
342  do i=1, fp%fisher_der%FD_num_redshift
343  ind = ind + 1
344  if ( param_number == ind ) then
345  j = p%Transfer%PK_redshifts_index(i)
346  write (str, *) i
347  str = adjustl(str)
348  param_name = 'sigma8_'//trim(str)
349  write (str,'(F20.2)') p%Transfer%redshifts(j)
350  str = adjustl(str)
351  if ( present(param_name_latex) ) param_name_latex = '\sigma_{8}('//trim(str)//')'
352  return
353  end if
354  end do
355  end if
356  ! add Hubble if wanted:
357  if ( fp%fisher_der%want_loghubble ) then
358  do i=1, fp%fisher_der%FD_num_redshift
359  ind = ind + 1
360  if ( param_number == ind ) then
361  z = fp%fisher_der%FD_redshift(i)
362  write (str, *) i
363  str = adjustl(str)
364  param_name = 'logHoz_'//trim(str)
365  write (str, '(F20.2)') z
366  str = adjustl(str)
367  if ( present(param_name_latex) ) param_name_latex = '\log_{10}H('//trim(str)//')'
368  return
369  end if
370  end do
371  end if
372  ! add DA if wanted:
373  if ( fp%fisher_der%want_logDA ) then
374  do i=1, fp%fisher_der%FD_num_redshift
375  ind = ind + 1
376  if ( param_number == ind ) then
377  z = fp%fisher_der%FD_redshift(i)
378  write (str, *) i
379  str = adjustl(str)
380  param_name = 'logDAz_'//trim(str)
381  write (str, '(F20.2)') z
382  str = adjustl(str)
383  if ( present(param_name_latex) ) param_name_latex = '\log_{10}D_{\rm A}('//trim(str)//')'
384  return
385  end if
386  end do
387  end if
388 
389  end subroutine fisher_derived_param_names
390 
391  ! ---------------------------------------------------------------------------------------------
395  subroutine derived_parameter_derivative( P, FP, param_num, &
396  & derived_initial, derived_derivative, derived_der_error, &
397  & initial_step, &
398  & num_param, &
399  & error_code )
401  implicit none
402 
403  Type(cambparams) , intent(in) :: P
404  Type(cosmicfish_params) , intent(in) :: FP
405 
406  integer , intent(in) :: param_num
407  integer , intent(in) :: num_param
408 
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
412 
413  real(dl), intent(in) :: initial_step
414  integer , intent(out) :: error_code
419 
420  ! definitions:
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
425  ! parameters of the algorithm:
426  real(dl), parameter :: con = 1.4_dl ! parameter that decides the decrease in the stepsize h
427  real(dl), parameter :: big = 1.d+30 ! a big number used to fill the error array initially
428  real(dl), parameter :: safe = 2._dl ! parameter used to define the stopping cryterium
429  integer , parameter :: ntab = 30 ! maximum number of Cls computation
430  real(dl) :: con2 = con*con
431  integer :: i, j, k, l, m, side, err, AllocateStatus
432  real(dl) :: fac, hh
433  real(dl) :: temp1, temp2, temp3
434  Type(cambparams) :: P_temp
435  Type(cosmicfish_params) :: FP_temp
436  integer :: accepted
437  real(dl) :: acceptance
438  integer :: derived_param_size
439 
440  ! initialize output variables:
441  error_code = 0
442  derived_derivative = 0._dl
443  derived_der_error = 0._dl
444 
445  ! check input values are correct
446  if ( initial_step == 0._dl ) then
447  stop 'Derived_Parameter_Derivative initial stepsize is zero'
448  end if
449 
450  call dimension_derived_parameters( p, fp, derived_param_size )
451 
452  ! allocate the arrays:
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"
462  else
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"
469  end if
470 
471  ! initialize the parameter array:
472  p_temp = p
473  fp_temp = fp
474 
475  call camb_params_to_params_array( p_temp, fp, num_param, param_vector )
476 
477  fiducial_param_vector = param_vector
478  temp_param_vector = param_vector
479 
480  ! initialize the computation:
481  hh = initial_step
482  derived_der_error = big
483  side = 0 ! both sides
484  if ( fp%adaptivity ) accept_mask = 0
485 
486  ! do the initial step on the right:
487  param_vector(param_num) = fiducial_param_vector(param_num) + hh
488  call params_array_to_camb_param( p_temp, fp_temp, num_param, param_vector )
489  call compute_derived_parameters( p_temp, fp_temp, der_temp_1, derived_param_size, err )
490  ! if on the right we cannot go we go to the left:
491  if ( err /= 0 ) side = 1
492  ! do the initial step on the left:
493  temp_param_vector(param_num) = fiducial_param_vector(param_num) - hh
494  call params_array_to_camb_param( p_temp, fp_temp, num_param, temp_param_vector )
495  call compute_derived_parameters( p_temp, fp_temp, der_temp_2, derived_param_size, err )
496 
497  ! if on the left we cannot go decide what to do:
498  if ( err /= 0 ) then
499  if ( side == 1 ) then ! we cannot go to the left nor to the right. Return derivative zero with error code.
500  error_code = 4
501  derived_der_error = 0.0_dl
502  derived_derivative = 0.0_dl
503  return
504  else if ( side == 0 ) then ! we cannot go to the left but we can go to the right:
505  side = 2
506  end if
507  end if
508 
509  ! store the results based on the side we decided to go:
510  if (side == 0) then ! both sides
511  a(1,1,:) = (der_temp_1(:) - der_temp_2(:))/(2.0_dl*hh)
512  else if (side == 1) then ! left side: increment negative
513  a(1,1,:) = (der_temp_2(:) - derived_initial(:))/(-hh)
514  else if (side == 2) then ! right side: increment positive
515  a(1,1,:) = (der_temp_1(:) - derived_initial(:))/(hh)
516  end if
517 
518  ! fixed stepsize derivative if adaptivity is not wanted:
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 )
523  return
524  end if
525 
526  ! start the derivative computation:
527  do i = 2, ntab
528 
529  ! feedback for the adaptive derivative:
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
536  end if
537 
538  ! decrease the stepsize:
539  hh = hh/con
540 
541  ! compute the finite difference:
542  if (side == 0) then
543  param_vector(param_num) = fiducial_param_vector(param_num) + hh
544  temp_param_vector(param_num) = fiducial_param_vector(param_num) - hh
545  ! compute for + hh
546  call params_array_to_camb_param( p_temp, fp_temp, num_param, param_vector )
547  call compute_derived_parameters( p_temp, fp_temp, der_temp_1, derived_param_size, err )
548  if ( err /= 0 ) then
549  error_code = 4
550  derived_der_error = 0.0_dl
551  derived_derivative = 0.0_dl
552  return
553  end if
554  ! compute for - hh
555  call params_array_to_camb_param( p_temp, fp_temp, num_param, temp_param_vector )
556  call compute_derived_parameters( p_temp, fp_temp, der_temp_2, derived_param_size, err )
557  if ( err /= 0 ) then
558  error_code = 4
559  derived_der_error = 0.0_dl
560  derived_derivative = 0.0_dl
561  return
562  end if
563  ! store the result
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
567  call params_array_to_camb_param( p_temp, fp_temp, num_param, param_vector )
568  call compute_derived_parameters( p_temp, fp_temp, der_temp_1, derived_param_size, err )
569  if ( err /= 0 ) then
570  error_code = 4
571  derived_der_error = 0.0_dl
572  derived_derivative = 0.0_dl
573  return
574  end if
575  ! store the result
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
579  call params_array_to_camb_param( p_temp, fp_temp, num_param, param_vector )
580  call compute_derived_parameters( p_temp, fp_temp, der_temp_1, derived_param_size, err )
581  if ( err /= 0 ) then
582  error_code = 4
583  derived_der_error = 0.0_dl
584  derived_derivative = 0.0_dl
585  return
586  end if
587  ! store the result
588  a(1,i,:) = (der_temp_1(:) - derived_initial(:))/(hh)
589  end if
590 
591  ! now do the extrapolation table:
592  fac=con2
593  do j = 2, i
594 
595  forall ( k = 1:derived_param_size, accept_mask(k) == 0 )
596  ! compute the interpolation table:
597  a(j,i,k) = (a(j-1,i,k)*fac-a(j-1,i-1,k))/(fac-1._dl)
598  ! estimate the error:
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)))
601  end forall
602 
603  fac=con2*fac
604 
605  ! if there is an improvement save the result:
606 
607  forall ( k = 1:derived_param_size, &
608  & errt(k) .le. derived_der_error(k) .and. accept_mask(k) == 0 )
609 
610  derived_der_error(k) = errt(k)
611  derived_derivative(k) = a(j,i,k)
612  end forall
613 
614  end do
615  ! accept a value of the derivative if the value of the extrapolation is stable
616  ! Store this information into the mask matrix
617  ! so that the value contained in cl_error and cl_derivative is not overwritten.
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) )
621 
622  accept_mask(k) = 1
623  end forall
624 
625  ! if all the entries match the required accuracy exit the loop
626  if ( sum(accept_mask) == derived_param_size ) exit
627 
628  end do
629 
630  ! quality check on the results:
631  if ( sum(accept_mask) /= derived_param_size ) then
632  error_code = 3
633  end if
634 
635  ! deallocate the arrays:
636  if ( fp%adaptivity ) then
637  deallocate( der_temp_1, der_temp_2, errt, accept_mask, a )
638  end if
639 
640  return
641 
642  end subroutine derived_parameter_derivative
643 
644  ! ---------------------------------------------------------------------------------------------
646  subroutine fisher_derived( P_in, FP_in, num_param, num_derived, Derived_Matrix, outroot )
648  implicit none
649 
650  Type(cambparams) , intent(in) :: P_in
651  Type(cosmicfish_params) , intent(in) :: FP_in
652 
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
657 
658  Type(cambparams) :: P
659  Type(cosmicfish_params) :: FP
660 
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
668 
669  ! copy input parameters:
670  p = p_in
671  fp = fp_in
672 
673  ! enforce parameter compatibility:
674  call derived_fisher_parameter_compatibility( p, fp )
675 
676  ! warning against 1 parameter derived:
677  if ( num_derived==1 ) then
678  write(*,*) 'WARNING: for better compatibility with CosmicFish PyLib use at least two derived parameters.'
679  end if
680 
681  ! allocate a parameter array:
682  allocate( param_array(num_param) )
683  ! write the parameters in the parameter array:
684  call camb_params_to_params_array( p, fp, num_param, param_array )
685 
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"
690 
691  ! compute the fiducial:
692  time_1 = omp_get_wtime()
693  call compute_derived_parameters( p, fp, derived_fiducial, num_derived, err )
694  time_2 = omp_get_wtime() - time_1
695 
696  if ( err == 0 ) then
697  else if ( err == 4 ) then
698  write(*,*) 'Fiducial model unstable. Calculation cannot proceed.'
699  stop
700  else
701  write(*,*) 'Error in computing the fiducial. Calculation cannot proceed.'
702  stop
703  end if
704 
705  ! print some feedback
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)'
714  else
715  write(*,'(a,f10.3,a)') 'Estimated completion time : ', time_2*2._dl*num_param, ' (s)'
716  end if
717  write(*,'(a)') '**************************************************************'
718  end if
719 
720  ! compute the derivatives of the Cls:
721  if ( fp%cosmicfish_feedback >= 1 ) then
722  write(*,'(a)') 'Computation of the derived parameters derivatives'
723  end if
724 
725  time_1 = omp_get_wtime()
726  do ind = 1, num_param
727 
728  if ( fp%cosmicfish_feedback >= 1 ) then
729  write(*,'(a,i5,a,E15.5)') 'Doing parameter number: ', ind, ' value: ', param_array(ind)
730  end if
731 
732  if ( param_array(ind) /= 0._dl ) then
733  initial_step = param_array(ind)*3.0_dl/100._dl
734  else
735  initial_step = 3.0_dl/100._dl
736  end if
737 
738  call derived_parameter_derivative( p, fp, ind, &
739  & derived_fiducial, derived_derivative, derived_temp, &
740  & initial_step, &
741  & num_param, &
742  & err )
743 
744  if (err /= 0) print*, 'WARNING: something went wrong with the Derived derivative of parameter:', ind, 'Error code:', err
745 
746  derived_derivative_array(ind,:) = derived_derivative(:)
747 
748  end do
749  time_2 = omp_get_wtime() - time_1
750 
751  if ( fp%cosmicfish_feedback >= 1 ) then
752  write(*,*)
753  write(*,'(a,f8.3,a)') 'Time to compute all the derivatives:', time_2, ' (s)'
754  end if
755 
756  ! compute the Fisher:
757  do ind = 1, num_param
758  do ind2 = 1, num_derived
759 
760  derived_matrix(ind, ind2) = derived_derivative_array(ind, ind2)
761 
762  end do
763  end do
764  time_2 = omp_get_wtime() - time_1
765 
766  if ( fp%cosmicfish_feedback >= 1 ) then
767  write(*,'(a,f8.3,a)') 'Time to compute the derived matrix:', time_2, ' (s)'
768  end if
769 
770  end subroutine fisher_derived
771 
772  ! ---------------------------------------------------------------------------------------------
775  subroutine save_derived_fisher_to_file( P_in, FP_in, num_params, num_derived, matrix, filename )
777  implicit none
778 
779  Type(cambparams) :: P_in
780  Type(cosmicfish_params) :: FP_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
785 
786  Type(cambparams) :: P
787  Type(cosmicfish_params) :: FP
788  integer :: ind, err
789  character(LEN=500) :: param_name
790  character(LEN=500) :: param_name_latex
791 
792  real(dl), allocatable, dimension(:) :: parameters, parameters_derived
793 
794  ! copy input parameters:
795  p = p_in
796  fp = fp_in
797  ! enforce parameter compatibility:
798  call derived_fisher_parameter_compatibility( p, fp )
799 
800  allocate( parameters(num_params), parameters_derived(num_derived) )
801  call camb_params_to_params_array( p, fp, num_params, parameters )
802  call compute_derived_parameters( p, fp, parameters_derived, num_derived, err )
803  if ( err /= 0 ) stop 'Error: Compute_Derived_Parameters failed when save_derived_Fisher_to_file'
804 
805  open(unit=666, file=filename, action="write", status="replace")
806 
807  ! write the header:
808  write(666,'(a)') '#'
809  write(666,'(a)') '# This file contains a Fisher matrix created with the CosmicFish code.'
810  ! write the parameter names:
811  write(666,'(a)') '#'
812  write(666,'(a)') '# The parameters of this derived parameters Fisher matrix are:'
813  write(666,'(a)') '#'
814 
815  do ind = 1, num_params
816  call fisher_param_names(p, fp, ind, param_name, param_name_latex)
817  write(666,'(a,I5,a,a,a,a,a,E25.16)') '# ', ind, ' ', trim(param_name), ' ', trim(param_name_latex), ' ', parameters(ind)
818  end do
819  ! write the parameter names:
820  write(666,'(a)') '#'
821  write(666,'(a)') '# The derived parameters of this matrix are:'
822  write(666,'(a)') '#'
823 
824  do ind = 1, num_derived
825  call fisher_derived_param_names(p, fp, ind, param_name, param_name_latex)
826  write(666,'(a,I5,a,a,a,a,a,E25.16)') '# ', ind, ' ', trim(param_name), ' ', trim(param_name_latex), ' ', parameters_derived(ind)
827  end do
828  write(666,'(a)') '#'
829  write(666,'(a)')
830 
831  ! write the Fisher matrix:
832  do ind = 1, num_params
833  write(666,'(2x,*(E25.16,2x))') matrix(ind, :)
834  end do
835 
836  close(666)
837 
838  end subroutine save_derived_fisher_to_file
839 
840  ! ---------------------------------------------------------------------------------------------
842  subroutine save_derived_paramnames_to_file( P_in, FP_in, num_params, num_derived, filename )
844  implicit none
845 
846  Type(cambparams) :: P_in
847  Type(cosmicfish_params) :: FP_in
848  integer , intent(in) :: num_params
849  integer , intent(in) :: num_derived
850  character(len=*), intent(in) :: filename
851 
852  Type(cambparams) :: P
853  Type(cosmicfish_params) :: FP
854  integer :: ind, err
855  character(LEN=500) :: param_name
856  character(LEN=500) :: param_name_latex
857 
858  real(dl), allocatable, dimension(:) :: parameters, parameters_derived
859 
860  ! copy input parameters:
861  p = p_in
862  fp = fp_in
863  ! enforce parameter compatibility:
864  call derived_fisher_parameter_compatibility( p, fp )
865  allocate( parameters(num_params), parameters_derived(num_derived) )
866  call camb_params_to_params_array( p, fp, num_params, parameters )
867 
868  call compute_derived_parameters( p, fp, parameters_derived, num_derived, err )
869 
870  if ( err /= 0 ) stop 'Error: Compute_Derived_Parameters failed when save_derived_Fisher_to_file'
871 
872  open(unit=666, file=filename, action="write", status="replace")
873 
874  ! write the header:
875 
876  write(666,'(a)') '#'
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.'
879  write(666,'(a)') '#'
880  ! write the parameter names:
881  do ind = 1, num_params
882  call fisher_param_names(p, fp, ind, param_name, param_name_latex)
883  write(666,'(a,a,a,a,E25.16)') trim(param_name), ' ', trim(param_name_latex), ' ', parameters(ind)
884  end do
885  do ind = 1, num_derived
886  call fisher_derived_param_names(p, fp, ind, param_name, param_name_latex)
887  write(666,'(a,a,a,a,E25.16)') trim(param_name)//'*', ' ', trim(param_name_latex), ' ', parameters_derived(ind)
888  end do
889 
890  close(666)
891 
892  end subroutine save_derived_paramnames_to_file
893 
894 end module fisher_calculator_derived
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...