Bayesian inversion including truncated distributions

Hello everyone,

UQLab version : 2.0

We were performing a Bayesian inversion for a geotechnical problem when my colleague and I noticed something unusual.

We have defined an input containing bounds as follow :

Input.Marginals(1).Name = 'Lambda';
Input.Marginals(1).Type = 'Gaussian';
Input.Marginals(1).Moments=[0.4082,0.105];
Input.Marginals(1).Bounds = [0.35,0.7];

After creating myBayesianAnalysis, we checked the maximum and minimum values of myBayesianAnalysis.Results.Sample which gave ~ [0.9,0]. The problem is that these values are outside the input range, is this normal?

We also noticed that in myBayesianAnalysis.PriorDist or myBayesianAnalysis.Internal.FullPrior the bounds do not appear anymore. It is not in fact included in the uq_remove_constants_from_input which writes only ‘Name’, ‘Parameters’, ‘Type’.

Best regards

Hi @Jocelyn.Minini

This is strange…can you provide a minimal working example that reproduces this issue?

Hi @paulremo !

Consider the simply-supported beam example in the documentation of the Bayesian module :

% Initialisation
clc % Nettoye la console
clear all % Supprime les variables actuelles
uqlab % Demarre l'environnement UQLAB

%% Model definition

addpath('C:\Program Files\UQLab\UQLab_Rel2.0.0\Examples\SimpleTestFunctions')
ModelOpts.Name = 'Forward model';
ModelOpts.mFile = 'uq_SimplySupportedBeam';
myModel = uq_createModel(ModelOpts);
clear ModelOpts


%% Input definition

PriorOpts.Name = 'Model parameters prior';
PriorOpts.Marginals(1).Name = 'b';
PriorOpts.Marginals(1).Type = 'Constant';
PriorOpts.Marginals(1).Parameters = 0.15; % (m)

PriorOpts.Marginals(2).Name = 'h';
PriorOpts.Marginals(2).Type = 'Constant';
PriorOpts.Marginals(2).Parameters = 0.3; % (m)

PriorOpts.Marginals(3).Name = 'L';
PriorOpts.Marginals(3).Type = 'Constant';
PriorOpts.Marginals(3).Parameters = 5; % (m)

PriorOpts.Marginals(4).Name = 'E';
PriorOpts.Marginals(4).Type = 'Lognormal';
PriorOpts.Marginals(4).Moments = [30 4.5]*1e9 ; % (N/mˆ2)
PriorOpts.Marginals(4).Bounds = [21,30]*1e9;

PriorOpts.Marginals(5).Name = 'p';
PriorOpts.Marginals(5).Type = 'Constant';
PriorOpts.Marginals(5).Parameters = 12000; % (N/m)

myPriorInput = uq_createInput(PriorOpts);
clear PriorOpts


%% Measurments
V_mid = [12.84; 13.12; 12.13; 12.19; 12.67]/1000; % (m)
myData.Name = 'Beam mid-span deflection';
myData.y = V_mid;


%% Inversion

BayesOpts.Type = 'Inversion';
BayesOpts.Data = myData;
clear myData

BayesOpts.Prior = myPriorInput;

BayesOpts.Solver.MCMC.Steps = 1000;
BayesOpts.Solver.MCMC.NChains = 100;
BayesOpts.Solver.MCMC.Sampler = 'AM';

BayesOpts.Discrepancy.Type = 'Gaussian';
BayesOpts.Discrepancy.Parameters = 1e-7;

myBayesian = uq_createAnalysis(BayesOpts);
uq_postProcessInversion(myBayesian,'gelmanRubin',true)
clear BayesOpts

%% Check the bounds of the sampling 

% Samples
Sampling_E_Sample=myBayesian.Results.Sample;
Sampling_E_Sample=reshape(Sampling_E_Sample,1,[]);
Sampling_Bayes_Sample=[max(Sampling_E_Sample)/10^9,min(Sampling_E_Sample)/10^9]; % take the max and min value from Bayes' Sample

% Prior samples
Sampling_E_Prior=myBayesian.Results.PostProc.PriorSample;
Sampling_E_Prior=reshape(Sampling_E_Prior,1,[]);
Sampling_Bayes_Prior=[max(Sampling_E_Prior)/10^9,min(Sampling_E_Prior)/10^9]; % take the max and min value from Bayes' sampling

% Input distribution samples
Sampling_test=uq_getSample(myPriorInput,100000);
Sampling_test=[max(Sampling_test(:,4))/10^9,min(Sampling_test(:,4))/10^9]; % take the max and min value from Input sampling


As you will notice, the maximum and minimum value of the two sets “myBayesian.Results.PostProc.PriorSample” and “myBayesian.Results.Sample” are not contained within the bounds defined in the input, whereas those from uq_getSample() do. On my machine I got :

Sampling_test = [29.9999 ; 20.002] %OK with the Input
Sampling_Bayes_Prior = [49.5657 ; 17.9774] %Outside the bounds
Sampling_Bayes_Sample= [40.9093 ; 20.65] %Outside the bounds

I must admit I have not been in depth with the theory behind the MCMC algorithm but the fact that values are outside the bounds in the prior’s sampling seems odd to me.

Best regards

1 Like

Dear @Jocelyn.Minini

Sorry for the late reply - I checked your input script and it looks fine to me. Unfortunately, I cannot debug it at the moment, but I have a suspect :grin:.

First of all, is there a small typo in the bounds you report for Sampling_test? The lower bound is also outside the set lower bound of 21.

Secondly, I suspect the problem is inside the uq_remove_constants_from_input function that unintentionally removes the bounds of the original prior. I couldn’t test the following, so please backup the file before proceeding:

Add the following lines after line 81 and after line 102 of the existing file:

if isfield(Marginals(rv), 'Bounds')
    newOpts.Marginals(nrMargs+kk).Bounds= Marginals(rv).Bounds;
end

After doing this, add a debug point in line 370 of uq_initialize_uq_inversion and verify that the bounds you specified are still present in the generated ModelPrior_noConstants object.

Let me know if this solves your problem!

Hi @paulremo !

  1. You’re right, typing error on my part

PriorOpts.Marginals(4).Name = ‘E’;
PriorOpts.Marginals(4).Type = ‘Lognormal’;
PriorOpts.Marginals(4).Moments = [30 4.5]*1e9 ; % (N/mˆ2)
PriorOpts.Marginals(4).Bounds = [20,30]*1e9;

sorry for that =)

  1. I tested your solution in uq_remove_constants_from_input, it works well. However, be careful because this seems to have an impact on other modules like the Polynomial Choas Kriging module. Unfortunately I couldn’t simulate this effect on the minimal example I gave you, so I’ll give you the original code:
clear all % Supprime les variables actuelles
uqlab % Demarre l'environnement UQLAB

%% Input 4DOF

Input4DOF.Marginals(1).Name='Angle Phi_Remblai';
Input4DOF.Marginals(1).Type='Constant';
Input4DOF.Marginals(1).Parameters=33.1571;

Input4DOF.Marginals(2).Name='Cohesion C_Remblai';
Input4DOF.Marginals(2).Type='Constant';
Input4DOF.Marginals(2).Parameters=0;

Input4DOF.Marginals(3).Name='Module E_Remblai';
Input4DOF.Marginals(3).Type='Constant';
Input4DOF.Marginals(3).Parameters=15000;
 
Input4DOF.Marginals(4).Name='Angle Phi_AL';
Input4DOF.Marginals(4).Type='Constant';
Input4DOF.Marginals(4).Parameters=27.2362;

Input4DOF.Marginals(5).Name='Cohesion C_AL';
Input4DOF.Marginals(5).Type='Constant';
Input4DOF.Marginals(5).Parameters=14.125;

Input4DOF.Marginals(6).Name='Module E_AL';
Input4DOF.Marginals(6).Type='Constant';
Input4DOF.Marginals(6).Parameters=12000;
 
Input4DOF.Marginals(7).Name='Angle Phi_C_Up';
Input4DOF.Marginals(7).Type='Constant';
Input4DOF.Marginals(7).Parameters=37.8938;

Input4DOF.Marginals(8).Name='Cohesion C_C_Up';
Input4DOF.Marginals(8).Type='Constant';
Input4DOF.Marginals(8).Parameters=8.475;

Input4DOF.Marginals(9).Name='Module E_C_Up';
Input4DOF.Marginals(9).Type='Constant';
Input4DOF.Marginals(9).Parameters=50000;
 
Input4DOF.Marginals(10).Name='Angle Phi_C_Mid';
Input4DOF.Marginals(10).Type='Constant';
Input4DOF.Marginals(10).Parameters=44.9989;

Input4DOF.Marginals(11).Name='Cohesion C_C_Mid';
Input4DOF.Marginals(11).Type='Constant';
Input4DOF.Marginals(11).Parameters=84.75;

Input4DOF.Marginals(12).Name='Module E_C_Mid';
Input4DOF.Marginals(12).Type='Constant';
Input4DOF.Marginals(12).Parameters=300000;
 
Input4DOF.Marginals(13).Name='Angle Phi_C_Low';
Input4DOF.Marginals(13).Type='Constant';
Input4DOF.Marginals(13).Parameters=54.4723;

Input4DOF.Marginals(14).Name='Cohesion C_C_Low';
Input4DOF.Marginals(14).Type='Constant';
Input4DOF.Marginals(14).Parameters=141.25;

Input4DOF.Marginals(15).Name='Module E_C_Low';
Input4DOF.Marginals(15).Type='Constant';
Input4DOF.Marginals(15).Parameters=400000;
 
Input4DOF.Marginals(16).Name='Angle Phi_AP_Up';
Input4DOF.Marginals(16).Type='Constant';
Input4DOF.Marginals(16).Parameters=0.1;

Input4DOF.Marginals(17).Name='Cohesion C_AP_Up';
Input4DOF.Marginals(17).Type='Constant';
Input4DOF.Marginals(17).Parameters=141.25;

Input4DOF.Marginals(18).Name='Module E_AP_Up';
Input4DOF.Marginals(18).Type='Lognormal';
Input4DOF.Marginals(18).Moments=[20000.,8000.];
 
Input4DOF.Marginals(19).Name='Angle Phi_AP_Mid';
Input4DOF.Marginals(19).Type='Constant';
Input4DOF.Marginals(19).Parameters=0.1;

Input4DOF.Marginals(20).Name='Cohesion C_AP_Mid';
Input4DOF.Marginals(20).Type='Constant';
Input4DOF.Marginals(20).Parameters=190.687;

Input4DOF.Marginals(21).Name='Module E_AP_Mid';
Input4DOF.Marginals(21).Type='Constant';
Input4DOF.Marginals(21).Parameters=42500;
 
Input4DOF.Marginals(22).Name='Angle Phi_AP_Low';
Input4DOF.Marginals(22).Type='Constant';
Input4DOF.Marginals(22).Parameters=0.1;

Input4DOF.Marginals(23).Name='Cohesion C_AP_Low';
Input4DOF.Marginals(23).Type='Constant';
Input4DOF.Marginals(23).Parameters=240.125;

Input4DOF.Marginals(24).Name='Module E_AP_Low';
Input4DOF.Marginals(24).Type='Lognormal';
Input4DOF.Marginals(24).Moments=[65000.,26000.];
 
Input4DOF.Marginals(25).Name='Angle Phi_C_MM';
Input4DOF.Marginals(25).Type='Constant';
Input4DOF.Marginals(25).Parameters=37.8938;

Input4DOF.Marginals(26).Name='Cohesion C_C_MM';
Input4DOF.Marginals(26).Type='Constant';
Input4DOF.Marginals(26).Parameters=21.1875;

Input4DOF.Marginals(27).Name='Module E_C_MM';
Input4DOF.Marginals(27).Type='Lognormal';
Input4DOF.Marginals(27).Moments=[75000.,30000.];
 
Input4DOF.Marginals(28).Name='Angle Phi_Cr';
Input4DOF.Marginals(28).Type='Constant';
Input4DOF.Marginals(28).Parameters=41.4463;

Input4DOF.Marginals(29).Name='Cohesion C_Cr';
Input4DOF.Marginals(29).Type='Constant';
Input4DOF.Marginals(29).Parameters=56.5;

Input4DOF.Marginals(30).Name='Module E_Cr';
Input4DOF.Marginals(30).Type='Constant';
Input4DOF.Marginals(30).Parameters=500000;
 
Input4DOF.Marginals(31).Name='Lambda';
Input4DOF.Marginals(31).Type='Uniform';
Input4DOF.Marginals(31).Parameters=[0.35,0.7];

Input4DOF.Marginals(32).Name='h_w';
Input4DOF.Marginals(32).Type='Constant';
Input4DOF.Marginals(32).Parameters=29;

Input4DOF.Marginals(33).Name='F_Ed1';
Input4DOF.Marginals(33).Type='Constant';
Input4DOF.Marginals(33).Parameters=29;


myInput4DOF=uq_createInput(Input4DOF);
clear Input4DOF

%% Experimental design
% please add your own path for loading the ED
load(..., 'P2.mat'));
X_ED=uq_ProcessedX;
Y_ED=uq_ProcessedY;
clear uq_ProcessedY uq_ProcessedX uq_AllX Expression1


%% PC-Kriging

PCKOpts.Type = 'Metamodel';
PCKOpts.MetaType = 'PCK';

% Degree et taille du vecteur
PCKOpts.Input=myInput4DOF;
PCKOpts.ExpDesign.X = X_ED;
PCKOpts.ExpDesign.Y = Y_ED(:,21);
PCKOpts.Degree=[1:15];

% Calcul du modele PCE
myPCKModel=uq_createModel(PCKOpts);
clear PCKOpts

LOO=myPCKModel.Error.LOO;

If everything is OK, you should get an LOO of ~6.0e-06, which is the right value.

Now let’s change these two input variables by adding boundaries (adding these boundaries to a Lognormal distribution should not change anything right ?) :

Input4DOF.Marginals(18).Name='Module E_AP_Up';
Input4DOF.Marginals(18).Type='Lognormal';
Input4DOF.Marginals(18).Moments=[20000.,8000.];
Input4DOF.Marginals(18).Bounds=[0,inf];

Input4DOF.Marginals(24).Name='Module E_AP_Low';
Input4DOF.Marginals(24).Type='Lognormal';
Input4DOF.Marginals(24).Moments=[65000.,26000.];
Input4DOF.Marginals(24).Bounds=[0,inf];

Now you should get a LOO of ~0.005, which is much larger than the one calculated earlier =(
I’ve notice cases, where it gets worse.

In the previous version (without modifying the file) you should get the same value twice.

Best regards

ps : P2.zip contains the points cloud for building the PCK

P2.zip (91.1 KB)

Hi @Jocelyn.Minini

I don’t think that these issues are related. In fact, (I think that) PCE in UQLab numerically constructs the polynomial basis functions if bounds are explicitly given by the user - independent of whether they match the theoretical bounds of the marginals or not. The observed decrease in accuracy can probably be attributed to this.