10 use iso_fortran_env,
only: int64
24 integer(kind=int64),
parameter :: a = 1103515245_int64
25 integer(kind=int64),
parameter ::
c = 12345_int64
26 integer(kind=int64),
parameter ::
m = 2147483648_int64
30 integer(kind=int64) :: seed
65 class(rng_type),
intent(inout) :: rng
66 type(mpl_type),
intent(in) :: mpl
67 type(nam_type),
intent(in) :: nam
73 if (nam%default_seed)
then 78 call system_clock(count=seed)
82 seed = seed+mpl%myproc
85 rng%seed = int(seed,kind=int64)
88 if (nam%default_seed)
then 89 write(mpl%info,
'(a7,a)')
'',
'Linear congruential generator initialized with a default seed' 91 write(mpl%info,
'(a7,a)')
'',
'Linear congruential generator initialized' 106 class(rng_type),
intent(inout) :: rng
107 type(mpl_type),
intent(in) :: mpl
116 seed = seed+mpl%myproc
119 rng%seed = int(seed,kind=int64)
132 class(rng_type),
intent(inout) :: rng
133 real(kind_real),
intent(out) :: x
136 rng%seed = mod(a*rng%seed+
c,
m)
139 x =
real(rng%seed,kind_real)/
real(m-1,kind_real)
152 class(rng_type),
intent(inout) :: rng
153 integer,
intent(in) :: binf
154 integer,
intent(in) :: bsup
155 integer,
intent(out) :: ir
164 x = x*
real(bsup-binf+1,kind_real)
180 class(rng_type),
intent(inout) :: rng
181 integer,
intent(in) :: binf
182 integer,
intent(in) :: bsup
183 integer,
intent(out) :: ir(:)
189 call rng%rand_integer(binf,bsup,ir(i))
203 class(rng_type),
intent(inout) :: rng
204 real(kind_real),
intent(in) :: binf
205 real(kind_real),
intent(in) :: bsup
206 real(kind_real),
intent(out) :: rr
231 class(rng_type),
intent(inout) :: rng
232 real(kind_real),
intent(in) :: binf
233 real(kind_real),
intent(in) :: bsup
234 real(kind_real),
intent(out) :: rr(:)
240 call rng%rand_real(binf,bsup,rr(i))
254 class(rng_type),
intent(inout) :: rng
255 real(kind_real),
intent(in) :: binf
256 real(kind_real),
intent(in) :: bsup
257 real(kind_real),
intent(out) :: rr(:,:)
264 call rng%rand_real(binf,bsup,rr(j,i))
279 class(rng_type),
intent(inout) :: rng
280 real(kind_real),
intent(in) :: binf
281 real(kind_real),
intent(in) :: bsup
282 real(kind_real),
intent(out) :: rr(:,:,:)
290 call rng%rand_real(binf,bsup,rr(k,j,i))
306 class(rng_type),
intent(inout) :: rng
307 real(kind_real),
intent(in) :: binf
308 real(kind_real),
intent(in) :: bsup
309 real(kind_real),
intent(out) :: rr(:,:,:,:)
318 call rng%rand_real(binf,bsup,rr(l,k,j,i))
335 class(rng_type),
intent(inout) :: rng
336 real(kind_real),
intent(in) :: binf
337 real(kind_real),
intent(in) :: bsup
338 real(kind_real),
intent(out) :: rr(:,:,:,:,:)
348 call rng%rand_real(binf,bsup,rr(m,l,k,j,i))
366 class(rng_type),
intent(inout) :: rng
367 real(kind_real),
intent(out) :: rr(:)
371 real(kind_real) :: gasdev,fac,gset,rsq,v1,v2
378 do while((rsq>=1.0).or.(rsq<=0.0))
379 call rng%rand_real(0.0_kind_real,1.0_kind_real,v1)
381 call rng%rand_real(0.0_kind_real,1.0_kind_real,v2)
385 fac = sqrt(-2.0*log(rsq)/rsq)
407 class(rng_type),
intent(inout) :: rng
408 real(kind_real),
intent(out) :: rr(:,:,:,:,:)
417 call rng%rand_gau(rr(:,l,k,j,i))
429 subroutine rng_initialize_sampling(rng,mpl,n,lon,lat,mask,rh,ntry,nrep,ns,ihor,fast)
434 class(rng_type),
intent(inout) :: rng
435 type(mpl_type),
intent(inout) :: mpl
436 integer,
intent(in) :: n
437 real(kind_real),
intent(in) :: lon(n)
438 real(kind_real),
intent(in) :: lat(n)
439 logical,
intent(in) :: mask(n)
440 real(kind_real),
intent(in) :: rh(n)
441 integer,
intent(in) :: ntry
442 integer,
intent(in) :: nrep
443 integer,
intent(in) :: ns
444 integer,
intent(out) :: ihor(ns)
445 logical,
intent(in),
optional :: fast
448 integer :: system_clock_start,system_clock_end,count_rate,count_max
449 integer :: is,js,i,irep,irmax,itry,irval,irvalmin,irvalmax,i_red,ir,ismin,nval,nrep_eff,nn_index(2)
450 integer,
allocatable :: val_to_full(:),ihor_tmp(:)
451 real(kind_real) :: elapsed
452 real(kind_real) :: d,distmax,distmin,nn_dist(2)
453 real(kind_real) :: nn_sdist_min,nn_sdist_max,nn_sdist_avg,nn_sdist_std
454 real(kind_real) :: cdf_norm,rr
455 real(kind_real),
allocatable :: cdf(:)
456 real(kind_real),
allocatable :: lon_rep(:),lat_rep(:),dist(:)
457 real(kind_real),
allocatable :: sdist(:,:),nn_sdist(:)
459 logical,
allocatable :: lmask(:),smask(:),rmask(:)
460 type(kdtree_type) :: kdtree
466 call mpl%abort(
'empty mask in initialize sampling')
467 elseif (nval<ns)
then 468 call mpl%abort(
'ns greater that mask size in initialize_sampling')
469 elseif (nval==ns)
then 470 write(mpl%info,
'(a)')
' all points are used' 481 call system_clock(count=system_clock_start)
485 nrep_eff =
min(nrep,n-ns)
486 allocate(ihor_tmp(ns+nrep_eff))
488 allocate(val_to_full(nval))
493 call msi(val_to_full)
498 val_to_full(i_red) = i
501 call mpl%prog_init(ns+nrep_eff)
503 if (
present(fast)) lfast = fast
512 i = val_to_full(i_red)
513 cdf(i_red) = cdf(i_red-1)+1.0/rh(i)**2
515 cdf_norm = 1.0/cdf(nval)
516 cdf(1:nval) = cdf(1:nval)*cdf_norm
520 call rng%rand_real(0.0_kind_real,1.0_kind_real,rr)
525 do while (irvalmax-irvalmin>1)
526 irval = (irvalmin+irvalmax)/2
527 if ((cdf(irvalmin)-rr)*(cdf(irval)-rr)>0.0)
then 535 ir = val_to_full(irval)
541 cdf(irval:nval-1) = cdf(irval+1:nval)
542 val_to_full(irval:nval-1) = val_to_full(irval+1:nval)
547 cdf_norm = 1.0/cdf(nval)
548 cdf(1:nval) = cdf(1:nval)*cdf_norm
551 call mpl%prog_print(is)
563 if (is>2)
call kdtree%create(mpl,n,lon,lat,mask=smask,sort=.false.)
574 call rng%rand_integer(1,nval,irval)
575 ir = val_to_full(irval)
585 call sphere_dist(lon(ir),lat(ir),lon(ihor_tmp(1)),lat(ihor_tmp(1)),d)
588 call kdtree%find_nearest_neighbors(lon(ir),lat(ir),1,nn_index(1:1),nn_dist(1:1))
589 d = nn_dist(1)**2/(rh(ir)**2+rh(nn_index(1))**2)
593 if (
sup(d,distmax))
then 602 if (is>2)
call kdtree%dealloc
608 lmask(irmax) = .false.
609 smask(irmax) = .true.
612 if (irvalmax<nval) val_to_full(irvalmax:nval-1) = val_to_full(irvalmax+1:nval)
617 call mpl%prog_print(is)
622 write(mpl%info,
'(a)',advance=
'no')
'100% => ' 626 allocate(rmask(ns+nrep_eff))
627 allocate(lon_rep(ns+nrep_eff))
628 allocate(lat_rep(ns+nrep_eff))
629 allocate(dist(ns+nrep_eff))
634 lon_rep(is) = lon(ihor_tmp(is))
635 lat_rep(is) = lat(ihor_tmp(is))
638 call mpl%prog_init(nrep_eff)
643 call kdtree%create(mpl,ns+nrep_eff,lon_rep,lat_rep,mask=rmask,sort=.false.)
649 call kdtree%find_nearest_neighbors(lon(ihor_tmp(is)),lat(ihor_tmp(is)),2,nn_index,nn_dist)
650 if (nn_index(1)==is)
then 651 dist(is) = nn_dist(2)
652 elseif (nn_index(2)==is)
then 653 dist(is) = nn_dist(1)
655 call mpl%abort(
'wrong index in replacement')
657 dist(is) = dist(is)**2/(rh(ihor_tmp(nn_index(1)))**2+rh(ihor_tmp(nn_index(2)))**2)
669 if (
inf(dist(is),distmin))
then 675 rmask(ismin) = .false.
678 call mpl%prog_print(irep)
686 ihor(js) = ihor_tmp(is)
693 write(mpl%info,
'(a)')
'100%' 698 call system_clock(count=system_clock_end)
699 call system_clock(count_rate=count_rate,count_max=count_max)
700 if (system_clock_end<system_clock_start)
then 701 elapsed =
real(system_clock_end-system_clock_start+count_max,kind_real) &
702 & /real(count_rate,kind_real)
704 elapsed =
real(system_clock_end-system_clock_start,kind_real) &
705 & /real(count_rate,kind_real)
709 allocate(sdist(ns,ns))
710 allocate(nn_sdist(ns))
714 sdist(is,is) = huge(1.0)
716 call sphere_dist(lon(ihor(is)),lat(ihor(is)),lon(ihor(js)),lat(ihor(js)),sdist(is,js))
717 sdist(is,js) = sdist(is,js)/sqrt(rh(ihor(is))**2+rh(ihor(js))**2)
718 sdist(js,is) = sdist(is,js)
724 nn_sdist(is) = minval(sdist(:,is))
728 nn_sdist_min = minval(nn_sdist)
729 nn_sdist_max = maxval(nn_sdist)
730 nn_sdist_avg = sum(nn_sdist)/
real(ns,kind_real)
731 nn_sdist_std = sqrt(sum((nn_sdist-nn_sdist_avg)**2)/
real(ns-1,kind_real))
734 write(mpl%info,
'(a10,a)')
'',
'Nearest neighbor normalized distance statistics:' 735 write(mpl%info,
'(a13,a,e9.2)')
'',
'Minimum: ',nn_sdist_min
736 write(mpl%info,
'(a13,a,e9.2)')
'',
'Maximum: ',nn_sdist_max
737 write(mpl%info,
'(a13,a,e9.2)')
'',
'Average: ',nn_sdist_avg
738 write(mpl%info,
'(a13,a,e9.2)')
'',
'Std-dev: ',nn_sdist_std
739 write(mpl%info,
'(a10,a,f8.3,a)')
'',
'Elapsed time to compute the subsampling: ',elapsed,
' s' 743 write(mpl%info,
'(a)')
'' 747 call mpl%f_comm%broadcast(ihor,mpl%ioproc-1)
subroutine rng_rand_real_2d(rng, binf, bsup, rr)
logical, parameter nn_stats
subroutine rng_rand_integer_0d(rng, binf, bsup, ir)
subroutine rng_rand_real_5d(rng, binf, bsup, rr)
integer(kind=int64), parameter m
subroutine rng_rand_real_0d(rng, binf, bsup, rr)
subroutine rng_rand_real_4d(rng, binf, bsup, rr)
subroutine rng_rand_gau_1d(rng, rr)
subroutine rng_reseed(rng, mpl)
subroutine rng_lcg(rng, x)
subroutine rng_rand_gau_5d(rng, rr)
integer(kind=int64), parameter c
integer, parameter default_seed
subroutine rng_rand_real_3d(rng, binf, bsup, rr)
subroutine rng_initialize_sampling(rng, mpl, n, lon, lat, mask, rh, ntry, nrep, ns, ihor, fast)
subroutine rng_rand_integer_1d(rng, binf, bsup, ir)
subroutine rng_rand_real_1d(rng, binf, bsup, rr)
subroutine rng_init(rng, mpl, nam)
integer, parameter, public kind_real
real(fp), parameter, public pi