Runs some statistical tests on the PRNG.
186 type(PRNG) :: test_rng
187 type(time_type) :: Time
189 real :: mean, var, ar1, std
191 integer,
parameter :: n_samples = 800
192 integer :: i, j, ni, nj
194 type(hor_index_type),
pointer :: HI => null()
195 real,
dimension(:,:),
allocatable :: r2d
210 random_unit_tests = .false.
212 write(stdunit,
'(1x,a)')
'==== MOM_random: random_unit_tests =======================' 214 if (verbose)
write(stdunit,
'(1x,"random: ",a)')
'-- Time-based seeds ---------------------' 216 time = set_date(1903, 11, 21, 13, 47, 29)
217 i = seed_from_time(time)
218 random_unit_tests = random_unit_tests .or. &
219 test_fn(verbose, i==212584341,
'time seed 1903/11/21 13:47:29', ivalue=i)
220 time = set_date(1903, 11, 22, 13, 47, 29)
221 i = seed_from_time(time)
222 random_unit_tests = random_unit_tests .or.&
223 test_fn(verbose, i==212584342,
'time seed 1903/11/22 13:47:29', ivalue=i)
224 time = set_date(1903, 11, 21, 13, 47, 30)
225 i = seed_from_time(time)
226 random_unit_tests = random_unit_tests .or.&
227 test_fn(verbose, i==212596634,
'time seed 1903/11/21 13:47:30', ivalue=i)
229 if (verbose)
write(stdunit,
'(1x,"random: ",a)')
'-- PRNG tests ---------------------------' 231 call random_0d_constructor(test_rng, time, 1)
232 r1 = random_01(test_rng)
233 random_unit_tests = random_unit_tests .or. &
234 test_fn(verbose, abs(r1-4.75310122e-2)<1.e-9,
'first call', r1)
237 r2 = random_01(test_rng)
238 random_unit_tests = random_unit_tests .or. &
239 test_fn(verbose, abs(r2-2.71289742e-1)<1.e-9,
'consecutive test', r2)
242 call random_0d_constructor(test_rng, time, 1)
243 r2 = random_01(test_rng)
244 random_unit_tests = random_unit_tests .or. &
245 test_fn(verbose, abs(r2-r1)==0.,
'reproduce test', r2)
248 call random_0d_constructor(test_rng, time, 2)
249 r2 = random_01(test_rng)
250 random_unit_tests = random_unit_tests .or. &
251 test_fn(verbose, abs(r2-7.15508473e-1)<1.e-9,
'different seed test', r2)
254 time = set_date(1903, 11, 21, 13, 0, 29)
255 call random_0d_constructor(test_rng, time, 1)
256 r2 = random_01(test_rng)
257 random_unit_tests = random_unit_tests .or. &
258 test_fn(verbose, abs(r2-9.56667163e-1)<1.e-9,
'different date test', r2)
260 if (verbose)
write(stdunit,
'(1x,"random: ",a)')
'-- index-based seeds --------------------' 262 i = seed_from_index(hi,1,1)
263 random_unit_tests = random_unit_tests .or. test_fn(verbose, i==1,
'seed from index (1,1)', ivalue=i)
264 j = seed_from_index(hi,ni+1,1)
265 random_unit_tests = random_unit_tests .or. test_fn(verbose, j==i,
'seed from index (n+1,1)', ivalue=j)
266 i = seed_from_index(hi,ni,1)
267 random_unit_tests = random_unit_tests .or. test_fn(verbose, i==6,
'seed from index (n,1)', ivalue=i)
268 j = seed_from_index(hi,0,1)
269 random_unit_tests = random_unit_tests .or. test_fn(verbose, j==i,
'seed from index (0,1)', ivalue=j)
270 i = seed_from_index(hi,1,nj)
271 random_unit_tests = random_unit_tests .or. test_fn(verbose, i==49,
'seed from index (1,n)', ivalue=i)
272 j = seed_from_index(hi,ni,nj+1)
273 random_unit_tests = random_unit_tests .or. test_fn(verbose, j==i,
'seed from index (n,n+1)', ivalue=j)
274 i = seed_from_index(hi,ni,nj)
275 random_unit_tests = random_unit_tests .or. test_fn(verbose, i==54,
'seed from index (n,n)', ivalue=i)
276 j = seed_from_index(hi,1,nj+1)
277 random_unit_tests = random_unit_tests .or. test_fn(verbose, j==i,
'seed from index (1,n+1)', ivalue=j)
279 if (.not.random_unit_tests)
write(stdunit,
'(1x,a)')
'Passed unit tests' 284 mean = 0. ; var = 0. ; ar1 = 0. ; r2 = 0.
286 r1 = random_01(test_rng) - 0.5
292 mean = mean /
real(n_samples) 293 var = var /
real(n_samples) 294 ar1 = ar1 /
real(n_samples-1) 296 r2 = mean*sqrt(
real(12*n_samples))
298 r1 = ( ar1 * sqrt(
real(n_samples-1)) ) / var
300 write(stdunit,
'(1x,"random: ",a)')
'-- Uniform -0.5 .. 0.5 generator --------' 301 write(stdunit,
'(1x,"random: ",a,f12.9)')
'mean =',mean,
'std =',std,
'AR1 =',ar1
302 write(stdunit,
'(1x,"random: ",a,f12.9)')
'norm. mean =',r2, &
303 'norm. std =',r3,
'norm. AR1 =',r1
305 random_unit_tests = random_unit_tests .or. &
306 test_fn(verbose, abs(r2)<2., &
307 'n>>1, mean within 2 sigma [uniform]', r2)
308 random_unit_tests = random_unit_tests .or. &
309 test_fn(verbose, abs(r3-1.)<1./sqrt(
real(n_samples)), &
310 'n>>1, std ~ 1/sqrt(12) [uniform]', r3-1.)
311 random_unit_tests = random_unit_tests .or. &
312 test_fn(verbose, abs(r1)<2., &
313 'n>>1, AR1 < std/sqrt(n) [uniform]', r1)
316 mean = 0. ; var = 0. ; ar1 = 0. ; r2 = 0.
318 r1 = random_norm(test_rng)
324 mean = mean /
real(n_samples)
325 var = var /
real(n_samples)
326 ar1 = ar1 /
real(n_samples)
328 r3 = 1./sqrt(
real(n_samples))
329 r2 = mean*sqrt(
real(n_samples))
331 r1 = ( ar1 * sqrt(
real(n_samples-1)) ) / var
333 write(stdunit,
'(1x,"random: ",a)')
'-- Normal distribution generator --------' 334 write(stdunit,
'(1x,"random: ",a,f12.9)')
'mean =',mean,
'std =',std,
'AR1 =',ar1
335 write(stdunit,
'(1x,"random: ",a,f12.9)')
'norm. error in mean =',r2, &
336 'norm. standard deviation =',r3,
'norm. AR1 =',r1
338 random_unit_tests = random_unit_tests .or. &
339 test_fn(verbose, abs(r2)<2., &
340 'n>>1, mean within 2 sigma [norm]', r2)
341 random_unit_tests = random_unit_tests .or. &
342 test_fn(verbose, abs(r3-1.)<1./sqrt(
real(n_samples)), &
343 'n>>1, std ~ 1 [norm]', r3-1.)
344 random_unit_tests = random_unit_tests .or. &
345 test_fn(verbose, abs(r1)<2., &
346 'n>>1, AR1 < std/sqrt(n) [norm]', r1)
348 if (verbose)
write(stdunit,
'(1x,"random: ",a)')
'-- 2d PRNG ------------------------------' 350 allocate( r2d(hi%isd:hi%ied,hi%jsd:hi%jed) )
351 call random_2d_constructor(test_rng, hi, time, 123)
353 call random_2d_01(test_rng, hi, r2d)
354 if (any(abs(r2d(:,:)+999.)<=0.)) random_unit_tests=.true.
357 random_unit_tests = random_unit_tests .or. test_fn(verbose, r1>=0.,
'2d all set', r1)
358 random_unit_tests = random_unit_tests .or. test_fn(verbose, r2<=1.,
'2d all valid', r2)
359 mean = sum( r2d(1:ni,1:nj) - 0.5 )/
real(ni*nj)
360 var = sum( (r2d(1:ni,1:nj) - 0.5 - mean)**2 )/
real(ni*nj)
362 r3 = 1./sqrt(
real(12*ni*nj))
363 r2 = mean*sqrt(
real(12*ni*nj))
366 write(stdunit,
'(1x,"random: ",a)')
'2D uniform 0..1 generator' 367 write(stdunit,
'(1x,"random: ",a,f12.9)')
'mean =',mean,
'std =',std
368 write(stdunit,
'(1x,"random: ",a,f12.9)')
'norm. error in mean =',r2
369 write(stdunit,
'(1x,"random: ",a,f12.9)')
'norm. standard deviation =',r3
371 random_unit_tests = random_unit_tests .or. &
372 test_fn(verbose, abs(r2)<2., &
373 '2d, mean within 2 sigma [uniform]', r2)
374 random_unit_tests = random_unit_tests .or. &
375 test_fn(verbose, abs(r3-1.)<1./sqrt(
real(ni*nj)), &
376 '2d, std ~ 1/sqrt(12) [uniform]', r3-1.)
378 write(stdunit,
'(1x,"random:")')
379 write(stdunit,
'(1x,"random:",8f8.5)') r2d
380 write(stdunit,
'(1x,"random:")')
384 call random_2d_norm(test_rng, hi, r2d)
385 mean = sum( r2d(1:ni,1:nj) )/
real(ni*nj)
386 var = sum( r2d(1:ni,1:nj)**2 )/
real(ni*nj)
388 r3 = 1./sqrt(
real(ni*nj))
389 r2 = mean*sqrt(
real(ni*nj))
392 write(stdunit,
'(1x,"random: ",a)')
'2D normal generator' 393 write(stdunit,
'(1x,"random: ",a,f12.9)')
'mean =',mean,
'std =',std
394 write(stdunit,
'(1x,"random: ",a,f12.9)')
'norm. error in mean =',r2
395 write(stdunit,
'(1x,"random: ",a,f12.9)')
'norm. standard deviation =',r3
397 random_unit_tests = random_unit_tests .or. &
398 test_fn(verbose, abs(r2)<2., &
399 '2d, mean within 2 sigma [norm]', r2)
400 random_unit_tests = random_unit_tests .or. &
401 test_fn(verbose, abs(r3-1.)<1./sqrt(
real(ni*nj)), &
402 '2d, std ~ 1/sqrt(12) [norm]', r3-1.)
408 if (.not.random_unit_tests)
write(stdunit,
'(1x,a)')
'Passed statistical tests'