Download notebook · Download runnable bundle
Dependencies: PySTRA core.
Reliability sensitivities#
Calculate the sensitivity of a FORM reliability index to marginal parameters and physical correlations.
Before you start: the introductory FORM tutorial and probability transformations.
Problem and approach#
PySTRA can compute the sensitivity of the FORM reliability index \(\beta\) with respect to the distribution parameters (mean and standard deviation) of each random variable, and with respect to the correlation coefficients.
Two methods are available, selected with the method constructor argument of SensitivityAnalysis. Call run() on the configured analysis:
Method |
Constructor argument |
Cost |
Correlation sensitivities |
|---|---|---|---|
Finite difference (FD) |
|
\(p+1\) FORM runs for \(p\) perturbed parameters |
No |
Closed-form (CF) |
|
1 FORM run |
Yes |
The closed-form approach follows Bourinet (2017), differentiating the Nataf transformation chain analytically. The key equation (Eq. 17) decomposes the sensitivity into two terms:
where \(\boldsymbol{\alpha}\) is the FORM direction cosine vector, \(\mathbf{L}_0\) is the Cholesky factor of the modified (Nataf) correlation matrix, and \(\mathbf{z}\) is the correlated standard normal design point.
The two terms have distinct physical meanings:
First term — captures how the marginal CDF transformation shifts at the design point when a distribution parameter changes. For example, increasing the mean of a variable moves where that variable’s CDF maps into standard normal space, pulling the design point closer to or further from the origin. This term is present even for independent variables.
Second term — captures how the Nataf correlation structure changes. The modified correlation matrix \(\mathbf{R}_0\) depends (through double integration) on the marginal distributions, so perturbing a marginal parameter alters \(\mathbf{L}_0\) and hence the isoprobabilistic transformation. For uncorrelated normal variables \(\mathbf{R}_0 = \mathbf{I}\) regardless of the marginals, so this term vanishes identically. For correlated non-normal variables it can be the dominant contribution — and it is also the term that makes the finite-difference method numerically unstable, as demonstrated in the examples below.
[1]:
import numpy as np
import pandas as pd
import pystra as ra
CalRel example (Bourinet 2017, §4.1, example 1)#
This example, taken from the CalRel software manual (Liu et al., 1989), has three correlated random variables and a nonlinear limit state function:
Variable |
Distribution |
Mean \(\mu\) |
Std. dev. \(\sigma\) |
|---|---|---|---|
\(X_1\) |
Lognormal |
500 |
100 |
\(X_2\) |
Lognormal |
2000 |
400 |
\(X_3\) |
Uniform |
5 |
0.5 |
The correlation matrix is:
The limit-state function is:
FORM gives \(\beta = 1.7728\) and \(p_f^{\text{FORM}} = 3.81 \times 10^{-2}\).
[11]:
def lsf_calrel(X1, X2, X3):
return 1 - X2 / (1000 * X3) - (X1 / (200 * X3)) ** 2
ls1 = ra.LimitState(lsf_calrel)
model1 = ra.StochasticModel()
model1.add_variable(ra.Lognormal("X1", 500, 100))
model1.add_variable(ra.Lognormal("X2", 2000, 400))
model1.add_variable(ra.Uniform("X3", 5, 0.5))
R1 = np.array(
[
[1.0, 0.3, 0.2],
[0.3, 1.0, 0.2],
[0.2, 0.2, 1.0],
]
)
model1.set_correlation(ra.CorrelationMatrix(R1))
[12]:
opts1 = ra.FORMOptions()
form1 = ra.FORM(
model=model1,
limit_state=ls1,
options=opts1,
)
form1_result = form1.run()
print(form1_result.summary())
FORM result
Status converged
Message Converged
Failure probability 0.0381339
Reliability index 1.77276
Iterations 16
Limit-state evaluations 154
Closed-form sensitivities#
[13]:
sa1 = ra.SensitivityAnalysis(
model=model1,
limit_state=ls1,
options=opts1,
)
cf1 = ra.SensitivityAnalysis(model=model1, limit_state=ls1, options=opts1, method="closed_form").run()
[14]:
# Reference values from Bourinet (2017), Table 2
ref1 = {
"X1": {"mean": -0.0059, "std": -0.0079},
"X2": {"mean": -0.0009, "std": -0.0006},
"X3": {"mean": 1.2602, "std": -1.1942},
}
rows = []
for var in ["X1", "X2", "X3"]:
for p in ["mean", "std"]:
sym = "\u03bc" if p == "mean" else "\u03c3"
rows.append(
{
"Parameter": f"\u2202\u03b2/\u2202{sym}_{var}",
"Reference": ref1[var][p],
"CF": cf1.marginal[var][p],
}
)
pd.DataFrame(rows).set_index("Parameter").style.format("{:+.4f}")
[14]:
| Reference | CF | |
|---|---|---|
| Parameter | ||
| ∂β/∂μ_X1 | -0.0059 | -0.0059 |
| ∂β/∂σ_X1 | -0.0079 | -0.0079 |
| ∂β/∂μ_X2 | -0.0009 | -0.0009 |
| ∂β/∂σ_X2 | -0.0006 | -0.0006 |
| ∂β/∂μ_X3 | +1.2602 | +1.2603 |
| ∂β/∂σ_X3 | -1.1942 | -1.1948 |
[15]:
# Reference values from Bourinet (2017), Table 3
ref_corr = {
(1, 0): -0.5151,
(2, 0): 0.8916,
(2, 1): 0.4688,
}
names1 = ["X1", "X2", "X3"]
rows = []
for (i, j), r in ref_corr.items():
rows.append(
{
"Parameter": f"\u2202\u03b2/\u2202\u03c1({names1[i]},{names1[j]})",
"Reference": r,
"CF": cf1.correlation[i, j],
}
)
pd.DataFrame(rows).set_index("Parameter").style.format("{:+.4f}")
[15]:
| Reference | CF | |
|---|---|---|
| Parameter | ||
| ∂β/∂ρ(X2,X1) | -0.5151 | -0.5150 |
| ∂β/∂ρ(X3,X1) | +0.8916 | +0.8914 |
| ∂β/∂ρ(X3,X2) | +0.4688 | +0.4687 |
This example includes a Uniform distribution (\(X_3\)), for which cdf_gradient is evaluated numerically via the base-class finite-difference fallback. The closed-form method handles this seamlessly — no analytical CDF derivative is needed for the Uniform distribution.
Summary#
Finite difference |
Closed-form |
|
|---|---|---|
FORM runs |
\(p + 1\) (\(p\) parameters) |
1 |
Marginal sens. |
Yes |
Yes |
Correlation sens. |
No |
Yes |
Accuracy |
Depends on step size \(\delta\) |
FORM-gradient approximation |
Stability |
Can be noisy for correlated non-normal variables |
Stable |
Distribution support |
Supported probability models |
Supported Nataf models; numerical marginal derivatives where needed |
Recommendation: Use the closed-form method (method="closed_form") when accuracy and correlation sensitivities are needed. The FD method remains useful as an independent verification tool.
Continue: User guide · API reference · Theory