[Dart-dev] DART/branches Revision: 12915
dart at ucar.edu
dart at ucar.edu
Thu Oct 25 09:59:43 MDT 2018
nancy at ucar.edu
2018-10-25 09:59:42 -0600 (Thu, 25 Oct 2018)
199
test for minimum inflation stddev by using abs() and TINY
instead of a straight <= comparison. there can be small
roundoff errors in the min sd value since it comes from an
ascii namelist setting.
Modified: DART/branches/rma_trunk/assimilation_code/modules/assimilation/adaptive_inflate_mod.f90
===================================================================
--- DART/branches/rma_trunk/assimilation_code/modules/assimilation/adaptive_inflate_mod.f90 2018-10-25 15:32:48 UTC (rev 12914)
+++ DART/branches/rma_trunk/assimilation_code/modules/assimilation/adaptive_inflate_mod.f90 2018-10-25 15:59:42 UTC (rev 12915)
@@ -669,45 +669,53 @@
call linear_bayes(dist_2, sigma_p_2, sigma_o_2, lambda_mean, lambda_sd_2, gamma_corr, &
new_cov_inflate)
-! Bail out to save cost when lower bound is reached on lambda standard deviation
-if(lambda_sd <= sd_lower_bound_in) then
- new_cov_inflate_sd = lambda_sd
-else
- ! Compute by forcing a Gaussian fit at one positive SD
-! First compute the new_max value for normalization purposes
- new_max = compute_new_density(dist_2, sigma_p_2, sigma_o_2, lambda_mean, lambda_sd, &
- gamma_corr, new_cov_inflate)
-
-! Find value at a point one OLD sd above new mean value
+ ! Bail out to save cost when lower bound is reached on lambda standard deviation
+ ! The original test to see if lambda_sd was less than the lower bound
+ ! would sometimes return false because of roundoff error and the computation
+ ! would go through the expensive part of the code when the minimum was
+ ! really reached. (sd_lower_bound comes from a namelist and precision
+ ! errors may be because of the conversion between ascii, single precision
+ ! and double precision.) In any case, the test was changed to return if
+ ! the value is within TINY of the limit.
+ if(abs(lambda_sd - sd_lower_bound_in) <= TINY(0.0_r8)) then
+ new_cov_inflate_sd = lambda_sd
+ return
+ else
+ ! Compute by forcing a Gaussian fit at one positive SD
+ ! First compute the new_max value for normalization purposes
+ new_max = compute_new_density(dist_2, sigma_p_2, sigma_o_2, lambda_mean, lambda_sd, &
+ gamma_corr, new_cov_inflate)
+
+ ! Find value at a point one OLD sd above new mean value
new_1_sd = compute_new_density(dist_2, sigma_p_2, sigma_o_2, lambda_mean, lambda_sd, gamma_corr, &
new_cov_inflate + lambda_sd)
-
- ! If either the numerator or denominator of the following computation
- ! of 'ratio' is going to be zero (or almost so), return the original incoming
- ! inflation value. The computation would have resulted in either Inf or NaN.
- if (abs(new_max) <= TINY(0.0_r8) .or. abs(new_1_sd) <= TINY(0.0_r8)) then
- new_cov_inflate_sd = lambda_sd
- return
+
+ ! If either the numerator or denominator of the following computation
+ ! of 'ratio' is going to be zero (or almost so), return the original incoming
+ ! inflation value. The computation would have resulted in either Inf or NaN.
+ if (abs(new_max) <= TINY(0.0_r8) .or. abs(new_1_sd) <= TINY(0.0_r8)) then
+ new_cov_inflate_sd = lambda_sd
+ return
+ endif
+
+ ratio = new_1_sd / new_max
+
+ ! Another error for numerical issues; if ratio is larger than 0.99, bail out
+ if(ratio > 0.99) then
+ new_cov_inflate_sd = lambda_sd
+ return
+ endif
+
+ ! Can now compute the standard deviation consistent with this as
+ ! sigma = sqrt(-x^2 / (2 ln(r)) where r is ratio and x is lambda_sd (distance from mean)
+ new_cov_inflate_sd = sqrt( -1.0_r8 * lambda_sd_2 / (2.0_r8 * log(ratio)))
+
+ ! Prevent an increase in the sd of lambda???
+ ! For now, this is mostly countering numerical errors in this computation
+ if(new_cov_inflate_sd > lambda_sd) new_cov_inflate_sd = lambda_sd
+
endif
- ratio = new_1_sd / new_max
-
- ! Another error for numerical issues; if ratio is larger than 0.99, bail out
- if(ratio > 0.99) then
- new_cov_inflate_sd = lambda_sd
- return
- endif
-
- ! Can now compute the standard deviation consistent with this as
- ! sigma = sqrt(-x^2 / (2 ln(r)) where r is ratio and x is lambda_sd (distance from mean)
- new_cov_inflate_sd = sqrt( -1.0_r8 * lambda_sd_2 / (2.0_r8 * log(ratio)))
-
- ! Prevent an increase in the sd of lambda???
- ! For now, this is mostly countering numerical errors in this computation
- if(new_cov_inflate_sd > lambda_sd) new_cov_inflate_sd = lambda_sd
-
-endif
-
else if (inf_type == GHA2017) then
! Transform Gaussian prior to Inverse Gamma
@@ -718,9 +726,10 @@
gamma_corr, ens_size, rate, new_cov_inflate)
! Bail out to save cost when lower bound is reached on lambda standard deviation
- if(lambda_sd <= sd_lower_bound_in) then
+ ! See comment in Anderson case for why we use abs and TINY for this comparison.
+ if(abs(lambda_sd - sd_lower_bound_in) <= TINY(0.0_r8)) then
new_cov_inflate_sd = lambda_sd
More information about the Dart-dev
mailing list