diff --git a/docs/code/sensitivity/generalised_sobol/README.rst b/docs/code/sensitivity/generalised_sobol/README.rst index 88a5bec5..78ede798 100644 --- a/docs/code/sensitivity/generalised_sobol/README.rst +++ b/docs/code/sensitivity/generalised_sobol/README.rst @@ -1,12 +1,14 @@ Generalised Sobol Sensitivity indices ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -We demonstrate the computation of GSI for 2 examples with multiple outputs: +These examples serve as a guide for using the GSI sensitivity module. They have been taken from various papers to enable validation of the implementation and have been referenced accordingly. -1. Mechanical oscillator (analytical solution): Example from [1] page 2 -2. Mechanical oscillator ODE (numerical solution): Example from [2] page 19 -3. Toy example (analytical solution): Example from [2] +1. **Mechanical oscillator ODE** -.. [1] Alexanderian, Alen, Gremaud, Pierre A and Smith, Ralph C. Variance-based sensitivity analysis for time-dependent processes. + The GSI sensitivity indices are computed for a mechanical oscillator governed by a second-order differential equation [1]_. The model outputs the displacement of the oscillator for a given time period. Unlike the pointwise-in-time Sobol indices, which provide the sensitivity of the model parameters at each point in time, the GSI indices summarise the sensitivities of the model parameters over the entire time period. -.. [2] Gamboa F, Janon A, Klein T, Lagnoux A, others. Sensitivity analysis for multidimensional and functional outputs. Electronic journal of statistics 2014; 8(1): 575-603. \ No newline at end of file +2. **Toy example** + + The GSI sensitivity indices are computed for a toy model whose analytical solution is given in [1]_. + +.. [1] Gamboa F, Janon A, Klein T, Lagnoux A, others. Sensitivity analysis for multidimensional and functional outputs. Electronic journal of statistics 2014; 8(1): 575-603. \ No newline at end of file diff --git a/docs/code/sensitivity/generalised_sobol/plot_generalised_sobol_mechcanical_oscillator_ODE.py b/docs/code/sensitivity/generalised_sobol/plot_generalised_sobol_mechanical_oscillator_ODE.py similarity index 71% rename from docs/code/sensitivity/generalised_sobol/plot_generalised_sobol_mechcanical_oscillator_ODE.py rename to docs/code/sensitivity/generalised_sobol/plot_generalised_sobol_mechanical_oscillator_ODE.py index 62a19d96..361bde6a 100644 --- a/docs/code/sensitivity/generalised_sobol/plot_generalised_sobol_mechcanical_oscillator_ODE.py +++ b/docs/code/sensitivity/generalised_sobol/plot_generalised_sobol_mechanical_oscillator_ODE.py @@ -16,6 +16,10 @@ .. math:: m \sim \mathcal{U}(10, 12), c \sim \mathcal{U}(0.4, 0.8), k \sim \mathcal{U}(70, 90), \ell \sim \mathcal{U}(-1, -0.25). +Unlike the pointwise-in-time Sobol indices, which provide the sensitivity of the model +parameters at each point in time, the GSI indices summarise the sensitivities of the +model parameters over the entire time period. + """ # %% @@ -27,7 +31,9 @@ from UQpy.distributions.collection.JointIndependent import JointIndependent from UQpy.sensitivity.generalised_sobol import GeneralisedSobol -# %% +# %% [markdown] +# **Define the model and input distributions** + # Create Model object model = PythonModel( model_script="local_mechanical_oscillator_ODE.py", @@ -45,24 +51,32 @@ L = Uniform(-1, (-0.25 - -1)) dist_object = JointIndependent([M, C, K, L]) -# %% +# %% [markdown] +# **Compute generalised Sobol indices** + +# %% [markdown] SA = GeneralisedSobol(runmodel_obj, dist_object) computed_indices = SA.run(n_samples=500) # %% [markdown] +# **First order Generalised Sobol indices** +# # Expected generalised Sobol indices: # -# $GS_{m}$ = 0.0826 +# :math:`GS_{m}` = 0.0826 # -# $GS_{c}$ = 0.0020 +# :math:`GS_{c}` = 0.0020 # -# $GS_{k}$ = 0.2068 +# :math:`GS_{k}` = 0.2068 # -# $GS_{\ell}$ = 0.0561 +# :math:`GS_{\ell}` = 0.0561 # %% computed_indices["gen_sobol_i"] +# %% [markdown] +# **Total order Generalised Sobol indices** + # %% computed_indices["gen_sobol_total_i"] diff --git a/docs/code/sensitivity/generalised_sobol/plot_generalised_sobol_multioutput.py b/docs/code/sensitivity/generalised_sobol/plot_generalised_sobol_multioutput.py index d89cfec1..1b673ddc 100644 --- a/docs/code/sensitivity/generalised_sobol/plot_generalised_sobol_multioutput.py +++ b/docs/code/sensitivity/generalised_sobol/plot_generalised_sobol_multioutput.py @@ -10,10 +10,10 @@ \end{array}\right) .. math:: - \text{case 1: } X_1, X_2 \sim \mathcal{U}(0, 1) + \text{case 1: } X_1, X_2 \sim \mathcal{N}(0, 1) .. math:: - \text{case 2: } X_1, X_2 \sim \mathcal{N}(0, 1) + \text{case 2: } X_1, X_2 \sim \mathcal{U}(0, 1) """ @@ -24,7 +24,9 @@ from UQpy.distributions.collection.JointIndependent import JointIndependent from UQpy.sensitivity.generalised_sobol import GeneralisedSobol -# %% +# %% [markdown] +# **Define the model and input distributions** + # Create Model object model = PythonModel( model_script="local_multioutput.py", @@ -37,9 +39,11 @@ # Define distribution object dist_object_1 = JointIndependent([Normal(0, 1)] * 2) -dist_object_2 = JointIndependent([Uniform(0, 1)] * 2) -# %% +# %% [markdown] +# **Compute generalised Sobol indices** + +# %% [markdown] SA = GeneralisedSobol(runmodel_obj, dist_object_1) computed_indices = SA.run( @@ -47,11 +51,15 @@ ) # %% [markdown] +# **First order Generalised Sobol indices** +# +# Expected generalised Sobol indices: +# # Gaussian case # -# $S_1$ = 0.2941 +# :math:`GS_1` = 0.2941 # -# $S_2$ = 0.1179 +# :math:`GS_2` = 0.1179 # %% computed_indices["gen_sobol_i"] @@ -59,17 +67,26 @@ # %% computed_indices["gen_sobol_total_i"] -# %% +# %% [markdown] +# **Compute generalised Sobol indices** + +# %% [markdown] +dist_object_2 = JointIndependent([Uniform(0, 1)] * 2) + SA = GeneralisedSobol(runmodel_obj, dist_object_2) computed_indices = SA.run(n_samples=100_000) # %% [markdown] -# Gaussian case +# **First order Generalised Sobol indices** +# +# Expected generalised Sobol indices: +# +# Uniform case # -# $S_1$ = 0.6084 +# :math:`GS_1` = 0.6084 # -# $S_2$ = 0.3566 +# :math:`GS_2` = 0.3566 # %% computed_indices["gen_sobol_i"] diff --git a/docs/source/sensitivity/generalised_sobol.rst b/docs/source/sensitivity/generalised_sobol.rst index 3515a744..402b3190 100644 --- a/docs/source/sensitivity/generalised_sobol.rst +++ b/docs/source/sensitivity/generalised_sobol.rst @@ -11,16 +11,27 @@ As the inputs :math:`X_{1}, \ldots, X_{d}` are independent, :math:`f` may be dec f(X) = c + f_{\mathbf{u}}\left(X_{\mathbf{u}}\right)+f_{\sim \mathbf{u}}\left(X_{\sim \mathbf{u}}\right) + f_{\mathbf{u}, \sim \mathbf{u}}\left(X_{\mathbf{u}}, X_{\sim \mathbf{u}}\right) where :math:`c \in \mathbb{R}^{k}, f_{\mathbf{u}}: E_{\mathbf{u}} \rightarrow \mathbb{R}^{k}, f_{\sim \mathbf{u}}: E_{\sim \mathbf{u}} \rightarrow \mathbb{R}^{k}` and :math:`f_{\mathbf{u}, \sim \mathbf{u}}: E \rightarrow \mathbb{R}^{k}` are given by -:math:`c=\mathbb{E}(Y), f_{\mathbf{u}}=\mathbb{E}\left(Y \mid X_{\mathbf{u}}\right)-c, f_{\sim \mathbf{u}}=\mathbb{E}\left(Y \mid X_{\sim \mathbf{u}}\right)-c, f_{u, \sim \mathbf{u}}=Y-f_{\mathbf{u}}-f_{\sim \mathbf{u}}-c` + +.. math:: + c = \mathbb{E}(Y), + +.. math:: + f_{\mathbf{u}}=\mathbb{E}\left(Y \mid X_{\mathbf{u}}\right)-c, + +.. math:: + f_{\sim \mathbf{u}}=\mathbb{E}\left(Y \mid X_{\sim \mathbf{u}}\right)-c, + +.. math:: + f_{u, \sim \mathbf{u}}=Y-f_{\mathbf{u}}-f_{\sim \mathbf{u}}-c. Thanks to :math:`L^{2}`-orthogonality, computing the covariance matrix of both sides of the above equation leads to .. math:: \Sigma = C_{\mathbf{u}}+C_{\sim \mathbf{u}}+C_{\mathbf{u}, \sim \mathbf{u}}. -Here, :math:`\Sigma, C_{\mathbf{u}}, C_{\sim \mathbf{u}}` and :math:`C_{\mathbf{u}, \sim \mathbf{u}}` are denoting respectively the covariance matrices of :math:`Y, f_{\mathbf{u}}\left(X_{\mathbf{u}}\right), f_{\sim \mathbf{u}}\left(X_{\sim \mathbf{u}}\right)` and :math:`f_{\mathbf{u}, \sim \mathbf{u}}\left(X_{\mathbf{u}}, X_{\sim \mathbf{u}}\right)`. +Here, :math:`\Sigma, C_{\mathbf{u}}, C_{\sim \mathbf{u}}` and :math:`C_{\mathbf{u}, \sim \mathbf{u}}` are denoting the covariance matrices of :math:`Y, f_{\mathbf{u}}\left(X_{\mathbf{u}}\right), f_{\sim \mathbf{u}}\left(X_{\sim \mathbf{u}}\right)` and :math:`f_{\mathbf{u}, \sim \mathbf{u}}\left(X_{\mathbf{u}}, X_{\sim \mathbf{u}}\right)` respectively. -The First order generalised Sobol indices can be computed using the Pick-and-Freeze approach as follows, where :math:`\mathbf{u}` is a variable :math:`i` of the independent random variables. +The first order generalised Sobol indices can be computed using the Pick-and-Freeze approach as follows, where :math:`\mathbf{u}` is a variable :math:`i` of the independent random variables. .. math:: S_{i, N}=\frac{\operatorname{Tr}\left(C_{i, N}\right)}{\operatorname{Tr}\left(\Sigma_{N}\right)}