def set_marginals(self, bw_method=None): """ Generates marginal PDFs of theta and (q1, q2, q3), for prior and posterior distributions. If there exist samples, uses KDE. For priors on (q1, q2, q3), uses openturns. ----------------------------------------------------------------------- bw_method: bandwidth method (see SciPy documentation) """ # Log density def kde(sample): k = gaussian_kde(np.transpose(sample), bw_method=bw_method) return lambda X: k.logpdf(np.array(X))[0] for para in ["theta", "q"]: for typ in ["prior", "post"]: sample = getattr(self, typ)[para]["sample"] if sample is None: getattr(self, typ)[para]["marginal"] = [ None for I in util.marg_1_2 ] continue getattr(self, typ)[para]["marginal"] = [ kde(sample[:, I]) for I in util.marg_1_2 ] if self.hyperpara[0] == 3: if self.hyperpara[1] == "i": qu_diff_dist = [ TruncatedDistribution( Normal(self.para[i, 0], self.para[i, 1]), 0.0, TruncatedDistribution.LOWER) for i in range(3) ] qu_dist = [ qu_diff_dist[0], qu_diff_dist[0] + qu_diff_dist[1], qu_diff_dist[0] + qu_diff_dist[1] + qu_diff_dist[2] ] self.prior["q"]["marginal"][:3] = [ qu_dist[i].computeLogPDF for i in range(3) ] elif self.hyperpara[1] == "me": self.prior["q"]["marginal"][:3] = [ TruncatedDistribution( Normal(self.para[i, 0], self.para[i, 1]), 0.0, TruncatedDistribution.LOWER).computeLogPDF for i in range(3) ]
def KL_tn(par): mu, logsigma = par mu = float(mu) logsigma = float(logsigma) dist = TruncatedDistribution(Normal(mu, np.exp(logsigma)), 0.0, TruncatedDistribution.LOWER) upper_bound = max(target_tn[i].getRange().getUpperBound()[0], dist.getRange().getUpperBound()[0]) def integrand(x): pdf1 = dist.computePDF(x) pdf2 = target_tn[i].computePDF(x) pdf1 = max(pdf1, 1e-140) pdf2 = max(pdf2, 1e-140) return pdf1 * np.log(pdf1 / pdf2) X = np.linspace(0.0, upper_bound, 100) return upper_bound * np.mean([integrand(x) for x in X])
alpha = (Z_m - Z_v)/L H = (Q/(K_s*B*sqrt(alpha)))**(3.0/5.0) Z_c = H + Z_v return [Z_c - Z_d] # Creation of the problem function inputDim = 4 # Input dimension f = PythonFunction(inputDim, 1, functionCrue) f.enableHistory() # Random vector definition Qmu=1013. Qsigma=558. Q = Gumbel(1./Qsigma, Qmu) Q = TruncatedDistribution(Q, 0, inf) K_s = Normal(30.0, 7.5) K_s = TruncatedDistribution(K_s, 0, inf) Z_v = Uniform(49.0, 51.0) Z_m = Uniform(54.0, 56.0) Q.setDescription(["Q (m3/s)"]) K_s.setDescription(["Ks (m^(1/3)/s)"]) Z_v.setDescription(["Zv (m)"]) Z_m.setDescription(["Zm (m)"]) View(Q.drawPDF()).show() View(K_s.drawPDF()).show() View(Z_v.drawPDF()).show() View(Z_m.drawPDF()).show() inputRandomVector = ComposedDistribution([Q, K_s, Z_v, Z_m])
S = Z_c - self._Z_d return [S] H_d = 3.0 # Hauteur de la digue Z_b = 55.5 # Côte de la berge L = 5.0e3 # Longueur de la rivière B = 300.0 # Largeur de la rivière myParametricWrapper = CrueFunction(H_d, Z_b, L, B) myWrapper = Function(myParametricWrapper) # 2. Random vector definition Q = Gumbel(1.0 / 558.0, 1013.0) Q = TruncatedDistribution(Q, 0.0, TruncatedDistribution.LOWER) K_s = Normal(30.0, 7.5) K_s = TruncatedDistribution(K_s, 0.0, TruncatedDistribution.LOWER) Z_v = Uniform(49.0, 51.0) Z_m = Uniform(54.0, 56.0) # 3. Create the joint distribution function, # the output and the event. inputDistribution = ComposedDistribution([Q, K_s, Z_v, Z_m]) inputRandomVector = RandomVector(inputDistribution) outputRandomVector = RandomVector(myWrapper, inputRandomVector) # 4. Get a sample of the output sampleS = outputRandomVector.getSample(500) # 5. Plot the histogram
def create_normal_distribution(correlation): # Generating 2D gaussian data with correlation of 0.8 cm = CorrelationMatrix([[1, correlation], [correlation, 1]]) distribution = Normal([0, 0], [1, 1], cm) return distribution
def para_for_quantiles(para_tn): """ Given parameters for TN distribution of quantile differences, computes distribution of quantiles, and finds TN distributions which best approximate these distributions. --------------------------------------------------------------------------- para_tn: Parameters of distribution of quantile differences [parent mean, parent standard deviation] --------------------------------------------------------------------------- Returns: Parameters of distribution of quantiles [parent mean, parent standard deviation] """ # TN mu_tn = para_tn[:, 0] sigma_tn = para_tn[:, 1] # Marginals of q_tilde q_tilde_marg_tn = [ TruncatedDistribution(Normal(mu_tn[i], sigma_tn[i]), 0.0, TruncatedDistribution.LOWER) for i in range(3) ] # Marginals of q target_tn = [ q_tilde_marg_tn[0], q_tilde_marg_tn[0] + q_tilde_marg_tn[1], q_tilde_marg_tn[0] + q_tilde_marg_tn[1] + q_tilde_marg_tn[2] ] par_tn = [None for _ in range(3)] for i in range(3): # Truncated normal def KL_tn(par): mu, logsigma = par mu = float(mu) logsigma = float(logsigma) dist = TruncatedDistribution(Normal(mu, np.exp(logsigma)), 0.0, TruncatedDistribution.LOWER) upper_bound = max(target_tn[i].getRange().getUpperBound()[0], dist.getRange().getUpperBound()[0]) def integrand(x): pdf1 = dist.computePDF(x) pdf2 = target_tn[i].computePDF(x) pdf1 = max(pdf1, 1e-140) pdf2 = max(pdf2, 1e-140) return pdf1 * np.log(pdf1 / pdf2) X = np.linspace(0.0, upper_bound, 100) return upper_bound * np.mean([integrand(x) for x in X]) res = minimize(KL_tn, (35.0, 1.0)) mu, logsigma = res.x mu = float(mu) logsigma = float(logsigma) par_tn[i] = [mu, np.exp(logsigma)] return np.array(par_tn)
def __init__(self, p, hyperpara, para, inst_name=""): """ Prior from specification of quantiles or quantile differences. ----------------------------------------------------------------------- p: probabilities [p_1, p_2, p_3] (np.ndarray). hyperpara: list [x, y]: x: 2 (k = 2) or 3 (k = 3) y: "i" (independent copula) or "me" (maximum entropy copula). para: 2d numpy array, whose i-th row are parameters [parent mean, parent standard deviation] of the i-th marginal. ----------------------------------------------------------------------- Returns: PriorTheta. """ self.hyperpara = hyperpara self.para = para s = -np.log(-np.log(1.0 - p)) k, cop = hyperpara # Sets colour colour = [None, None, {"i": 2, "me": 3}, {"i": 0, "me": 1}][k][cop] if cop == "i": if k == 3: def f(X): q1, q2, q3 = X Y = np.array([q1, q2 - q1, q3 - q2]) if np.any(Y <= 0.0): return None return -0.5 * np.sum(((Y - para[:, 0]) / para[:, 1])**2) elif k == 2: def f(X): sigma, q1, q2 = X if sigma <= 0: return None Y = np.array([q1, q2 - q1]) if np.any(Y <= 0.0): return None a = -0.5 * np.sum(((Y - para[:, 0]) / para[:, 1])**2) return a - np.log(sigma) elif cop == "me": q_marg = [None for _ in range(k)] for i in range(k): dist = Normal(para[i, 0], para[i, 1]) q_marg[i] = TruncatedDistribution(dist, 0.0, TruncatedDistribution.LOWER) ot = MaximumEntropyOrderStatisticsDistribution(q_marg) if k == 3: def f(X): q1, q2, q3 = X if np.any(np.array([q1, q2 - q1, q3 - q2]) <= 0.0): return None Y = ot.computePDF(X) if Y <= 0: return None return np.log(Y) elif k == 2: def f(X): sigma, q1, q2 = X if sigma <= 0 or q1 <= 0.0 or q2 <= q1: return None Y = ot.computePDF([q1, q2]) if Y <= 0: return None return np.log(Y) - np.log(sigma) if k == 3: # Transformation (mu, theta, xi) -> (q1, q2, q3) def g(X): mu, sigma, xi = X if sigma <= 0: return None # When xi is close enough to 0, we consider it equal to 0 if abs(xi) < 1e-300: q = mu + sigma * s else: q = mu + sigma * (np.exp(xi * s) - 1.0) / xi if q[0] < 0.0: return None return q # Log of determinant of g def g_det(X): mu, sigma, xi = X if abs(xi) < 1e-300: return np.log(sigma) e = np.exp(s * xi) sm = [ s[i] * e[i] * (e[(i + 2) % 3] - e[(i + 1) % 3]) for i in range(3) ] return np.log(sigma) + np.log(sum(sm)) - np.log(xi**2.0) elif k == 2: # Transformation (mu, sigma, xi) -> (sigma, q1, q2) def g(X): mu, sigma, xi = X # When xi is close enough to 0, we consider it equal to 0 if abs(xi) < 1e-300: q = mu + sigma * s else: q = mu + sigma * (np.exp(xi * s) - 1.0) / xi if q[0] < 0.0: return None return np.concatenate(([sigma], q)) # Log of determinant of g def g_det(X): mu, sigma, xi = X if abs(xi) < 1e-300: return np.log(sigma) e = (s * xi - 1.0) * np.exp(s * xi) f = np.log(abs(e[0] - e[1])) return np.log(sigma) + f - np.log(xi**2.0) super().__init__(util.log_transform(f, g, g_det), colour=colour, inst_name=inst_name) if k == 2: self.prior["proper"] = False