Beispiel #1
0
    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)
                ]
Beispiel #2
0
        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])
Beispiel #4
0
        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
Beispiel #5
0
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
Beispiel #6
0
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)
Beispiel #7
0
    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