├── DYNIA ├── dynia_histograms.m ├── dynia_plot.m └── tv_objfun.m ├── EET ├── EET_convergence.m ├── EET_indices.m └── EET_plot.m ├── FAST ├── FAST_indices.m ├── FAST_sampling.m ├── FAST_sampling_unif.m └── generate_FAST_frequency.m ├── GLUE └── GLUE.m ├── LICENCE ├── PAWN ├── SWAT_sample_description.txt ├── SWAT_samples.mat ├── conditional_sampling.m ├── pawn_cdfs.m ├── pawn_convergence.m ├── pawn_exclude_NaN.m ├── pawn_indices.m ├── pawn_indices_givendata.m ├── pawn_ks.m ├── pawn_ks_givendata.m ├── pawn_ks_test.m ├── pawn_model_execution.m ├── pawn_plot_cdf.m ├── pawn_plot_kstest.m ├── pawn_sampling.m └── pawn_split_sample.m ├── RSA ├── RSA_convergence_thres.m ├── RSA_indices_groups.m ├── RSA_indices_thres.m ├── RSA_plot_groups.m └── RSA_plot_thres.m ├── VBSA ├── vbsa_convergence.m ├── vbsa_indices.m └── vbsa_resampling.m ├── example ├── external │ ├── Input_samples.txt │ └── Output_samples.txt ├── hbv │ ├── 01055500.txt │ ├── HBV_structure.pdf │ ├── Snow_routine_structure.pdf │ ├── hbv_sim.m │ ├── hbv_snow_objfun.m │ └── snow_routine.m ├── hymod │ ├── Hymod_structure.pdf │ ├── LeafCatch.txt │ ├── hymod_MulObj.m │ ├── hymod_max.m │ ├── hymod_nse.m │ └── hymod_sim.m ├── ishigami_homma │ └── ishigami_homma_function.m └── sobol_g_function │ └── sobol_g_function.m ├── sampling ├── AAT_sampling.m ├── AAT_sampling_extend.m ├── Morris_sampling.m ├── OAT_sampling.m ├── OAT_sampling_extend.m ├── ipdm.m ├── lhcube.m ├── lhcube_extend.m ├── lhcube_shrink.m └── model_execution.m ├── util ├── NSE.m ├── RMSE.m ├── aggregate_boot_draft.m └── empiricalcdf.m ├── visualization ├── Andres_plots.m ├── boxplot1.m ├── boxplot2.m ├── parcoor.m ├── plot_cdf.m ├── plot_convergence.m ├── plot_pdf.m ├── scatter_plots.m ├── scatter_plots_col.m ├── scatter_plots_interaction.m └── stackedbar.m ├── workflow_dynia_hymod.m ├── workflow_eet_hbv.m ├── workflow_eet_hymod.m ├── workflow_external_model.m ├── workflow_fast_gsobol.m ├── workflow_fast_hymod.m ├── workflow_glue_hymod.m ├── workflow_pawn_givendata_IshigamiHomma.m ├── workflow_pawn_givendata_swat.m ├── workflow_pawn_hymod.m ├── workflow_rsa_hymod.m ├── workflow_tvsa_hymod.m ├── workflow_vbsa_groups_hbv.m ├── workflow_vbsa_hymod.m ├── workflow_vbsa_ishigami_homma.m └── workflow_visual_ishigami_homma.m /DYNIA/dynia_histograms.m: -------------------------------------------------------------------------------- 1 | function [ xi, fi ] = dynia_histograms(X,Y,perc,varargin) 2 | % 3 | % Estimate probability distribution of the subset of samples in X 4 | % corresponding to the top 'perc' values in Y (probability 5 | % distribution is approximated by histogram). 6 | % The deviation of this 'posterior' distribution 7 | % from the 'prior' distribution of the entire sample X, 8 | % provides an indication of the strength of the relationship 9 | % between X and Y (or, the sensitivity of Y to X) (Wagener et al, 2003). 10 | % 11 | % Usage: 12 | % [ xi, fi ] = dynia_histograms(X,Y,perc) 13 | % [ xi, fi ] = dynia_histograms(X,Y,perc,nbins) 14 | % 15 | % Input: 16 | % X = set of input samples - vector (N,1) 17 | % Y = set of output samples - matrix (N,T) 18 | % perc = percentage of samples that will - scalar 19 | % be retained to estimate the a posteriori distribution (*) 20 | % nbins = number of bins used to approximate the a posteriori - scalar 21 | % distribution by histogram (default: 10) 22 | % 23 | % Output: 24 | % xi = bins centers - vector (nbin,1) 25 | % fi = frequency associated to each bin at each time step - matrix (nbin,T) 26 | % 27 | % (*) The function retains the 'perc' samples with lower-valued output. 28 | % 29 | % References: 30 | % 31 | % Wagener, T., McIntyre, N., Lees, M., Wheater, H., Gupta, H., 2003. 32 | % Towards reduced uncertainty in conceptual rainfall-runoff modelling: 33 | % dynamic identifiability analysis. Hydrol. Process. 17, 455?476. 34 | 35 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 36 | % and T. Wagener at Bristol University (2015). 37 | % SAFE is provided without any warranty and for non-commercial use only. 38 | % For more details, see the Licence file included in the root directory 39 | % of this distribution. 40 | % For any comment and feedback, or to discuss a Licence agreement for 41 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 42 | % For details on how to cite SAFE in your publication, please see: 43 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 44 | 45 | %%%%%%%%%%%%%% 46 | % Check inputs 47 | %%%%%%%%%%%%%% 48 | 49 | if ~isnumeric(X) ; error('input ''X'' must be a vector of size (N,1)'); end 50 | if ~isnumeric(Y) ; error('input ''Y'' must be a matrix of size (N,T)'); end 51 | [N,M]=size(X) ; 52 | if M>1 ; error('input ''X'' must be a vector of size (N,1)'); end 53 | [n,T]=size(Y) ; 54 | if N~=n; error('input ''X'' and ''Y'' must have the same number of rows'); end 55 | if T<=1; error('input ''Y'' must have at least 2 columns'); end 56 | 57 | if ~isnumeric(perc) ; error('input ''perc'' must be a scalar number'); end 58 | if ~isscalar(perc); error('''perc'' must be scalar'); end 59 | if perc <=0 ; error('''perc'' must be higher than 0'); end 60 | if perc >=100 ; error('''perc'' must be lower than 100'); end 61 | 62 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 63 | % Recover and check optional inputs 64 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 65 | 66 | % Set optional arguments to their default values: 67 | nbins = 10 ; 68 | 69 | % Recover and update optional arguments: 70 | if nargin > 3 71 | if ~isempty(varargin{1}) 72 | nbins = varargin{1} ; 73 | if ~isnumeric(nbins) ; error('input ''perc'' must be a scalar number'); end 74 | if ~isscalar(nbins); error('''nbins'' must be scalar'); end 75 | if nbins<1; error('''nbins'' must be larger than 1' ); end 76 | if abs(nbins-round(nbins)); error('''nbins'' must be an integer'); end 77 | end 78 | end 79 | 80 | %%%%%%% 81 | % DYNIA 82 | %%%%%%% 83 | 84 | % Find top-perc samples: 85 | 86 | [Y_sorted,idx] = sort(Y) ; 87 | n = floor(N*perc/100) ; 88 | 89 | % Sort samples according to associated performances: 90 | X_sorted = X(idx) ; % (N,T) 91 | % Take the first 'n' parameter sets at each time t=1,...,T 92 | X_best = X_sorted(1:n,:) ; % (n,T) 93 | 94 | % Because we want function 'hist' to define the bins in the same way 95 | % at all time steps, i.e. covering the a priori variability range of 96 | % the input, we add two fake rows filled in with the minimum and 97 | % maximum possible values of that input: 98 | xmin = min(X) ; 99 | xmax = max(X) ; 100 | X_best_mod = [ ones(1,T)*xmin ; X_best ; ones(1,T)*xmax ] ; 101 | 102 | % Estimate and frequency distribution of the input samples that 103 | % generated the 'perc' top performances: 104 | [ni,xi] = hist(X_best_mod,nbins) ; 105 | 106 | % Then, remove the two 'fake' counts from the first and last bin: 107 | ni(1,:) = ni(1,:)-1 ; 108 | ni(end,:) = ni(end,:)-1 ; 109 | 110 | % Finally, we compute the frequency: 111 | fi = ni / n ; 112 | 113 | -------------------------------------------------------------------------------- /DYNIA/dynia_plot.m: -------------------------------------------------------------------------------- 1 | function hfig = dynia_plot(xi,fi,varargin) 2 | % 3 | % Plot time pattern of posterior distribution of a model input 4 | % (posterior distribution is approximated by histogram) 5 | % 6 | % Usage: 7 | % dynia_plot(xi,fi) 8 | % dynia_plot(xi,fi,X_Label) 9 | % dynia_plot(xi,fi,X_Label,y) 10 | % 11 | % Input: 12 | % xi = bins centers - vector (nbin,1) 13 | % fi = frequency associated to each bin at each time step - matrix (nbin,T) 14 | % X_Label = label for horizontal axis - string 15 | % default: 'input range' 16 | % y = time series of model output - vector (T,1) 17 | % (to be plotted on the top of the input posterior probability) 18 | % 19 | % See also dynia_histograms for further information and interpretation. 20 | 21 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 22 | % and T. Wagener at Bristol University (2015). 23 | % SAFE is provided without any warranty and for non-commercial use only. 24 | % For more details, see the Licence file included in the root directory 25 | % of this distribution. 26 | % For any comment and feedback, or to discuss a Licence agreement for 27 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 28 | % For details on how to cite SAFE in your publication, please see: 29 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 30 | 31 | % Options for the graphic: 32 | fn = 'Helvetica' ; % font type of axes, labels, etc. 33 | %fn = 'Courier' ; 34 | fs = 24 ; % font size of axes, labels, etc. 35 | nb_fig=2; %number of digits after decimal points for vertical axis 36 | 37 | %%%%%%%%%%%%%% 38 | % Check inputs 39 | %%%%%%%%%%%%%% 40 | 41 | if ~isnumeric(xi) ; error('input ''xi'' must be a vector of real numbers'); end 42 | if ~isnumeric(fi) ; error('input ''fi'' must be a matrix of real numbers'); end 43 | [N,M]=size(xi) ; 44 | [n,T]=size(fi) ; 45 | if M~=1; error('input ''xi'' must be a column vector'); end 46 | if N~=n; error('input ''xi'' and ''fi'' must have the same number of rows'); end 47 | if T<=1; error('input ''fi'' must be a matrix with more than one column'); end 48 | 49 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 50 | % Recover and check optional inputs 51 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 52 | 53 | % Set optional arguments to their default values: 54 | 55 | X_Label = 'input range' ; 56 | y = [] ; 57 | 58 | % Recover and update optional arguments: 59 | 60 | if nargin > 2 61 | if ~isempty(varargin{1}) 62 | X_Label = varargin{1}; 63 | if ~ischar(X_Label); error('''X_Label'' must be a string'); end 64 | end 65 | end 66 | if nargin > 3 67 | if ~isempty(varargin{2}) 68 | y = varargin{2}; 69 | y = y(:) ; 70 | if length(y)~=T; error('''y'' must be a vector with the same number of components as the rows in ''fi'''); end 71 | end 72 | end 73 | 74 | %%%%%%%%%%%%%%%% 75 | % Generate plots 76 | %%%%%%%%%%%%%%%% 77 | 78 | nbins = length(xi) ; 79 | 80 | % Pre-processing: invert the order of the rows in 'xi' and 'fi' so that 81 | % data relevant to higher parameter values be on the first rows (and 82 | % thus will be displaced at the top of the vertical axis by the 83 | % function 'imagesc' used later) 84 | [xi_plot,idx] = sort(xi,'descend') ; 85 | fi_plot = fi(idx,:) ; 86 | %xi_plot = xi(end:-1:1) ; 87 | %fi_plot = fi(end:-1:1,:) ; 88 | 89 | % add two fake columns filled in with ones and zeros so that 'imagesc' 90 | % will rescale to the range [0,1] (0 and 1 having now become the 91 | % minimum and maximum of 'fi_plot'): 92 | fi_plot = [ fi_plot ones(nbins,1) zeros(nbins,1) ] ; 93 | 94 | % Plot results: 95 | hfig = figure; 96 | %clrs = gray ; 97 | clrs = autumn ; 98 | % invert ordering of row sin 'clrs' so that black colour is associated 99 | % to value of 1 and white to the value of 0: 100 | clrs = clrs(end:-1:1,:); 101 | colormap(clrs) 102 | % plot the frequencies: 103 | imagesc( fi_plot ) 104 | % set axes, labels, etc.: 105 | axis([1 T 0.5 nbins+0.5]) 106 | xlabel('time','FontName',fn,'FontSize',fs) 107 | ylabel(X_Label,'FontName',fn,'FontSize',fs) 108 | str=cell(1,nbins); 109 | %for j=1:nbins; str{j}=num2str(xi_plot(j)); end 110 | for j=1:nbins; str{j}=num2str(round(10^nb_fig*xi_plot(j))/(10^nb_fig)); end 111 | 112 | set(gca,'YTick',1:nbins,'YTickLabel',str) 113 | c = colorbar; 114 | set(get(c,'title'),'String','freq','FontName',fn,'FontSize',fs) 115 | 116 | % Plot (rescaled) output values (y) on the top: 117 | hold on 118 | y_norm = y/max(y) ; % now 'y' varies between zero and one 119 | plot(nbins+0.5-y_norm*(nbins-1),'k','LineWidth',2) 120 | 121 | set(gca,'FontName',fn,'FontSize',fs) 122 | -------------------------------------------------------------------------------- /DYNIA/tv_objfun.m: -------------------------------------------------------------------------------- 1 | function Y = tv_objfun(TSsim,TSobs,obj_fun,W) 2 | % 3 | % This function returns a time-varying metric of model performance: 4 | % 5 | % Y(t) = PERF[ sim(t-w, ..., t, ..., t+w) , 6 | % obs(t-w, ..., t, ..., t+w) ] for t=1,...,T 7 | % 8 | % Usage: 9 | % Y = tv_objfun(TSsim,TSobs,obj_fun,W) 10 | % 11 | % Input: 12 | % TSsim = set of N time series of simulated output - matrix (N,T) 13 | % TSobs = set of N time series of observed output - matrix (N,T) 14 | % (or 1 time series if all rows in TSsim or vector (1,T) 15 | % should be evaluated against the same 16 | % time series of observations) 17 | % obj_fun = performance metric to be computed - string 18 | % options: 'MAE','RMSE','BIAS' (*) 19 | % W = semi-length of the window for averaging performances - scalar 20 | % 21 | % Output: 22 | % Y = set of N time series of time-varying objective - matrix (N,T) 23 | % function 24 | % 25 | % (*) Comment: 26 | % Performance metrics are defined as: 27 | % MAE(t) = mean( | sim(t-w,...,t+w) - obs(t-w,..., t+w) | ) 28 | % RMSE(t) = mean( ( sim(t-w,...,t+w) - obs(t-w,..., t+w) )^2 ) 29 | % BIAS(t) = | mean(sim(t-w,...,t+w)) - mean(obs(t-w,..., t+w)) | 30 | 31 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 32 | % and T. Wagener at Bristol University (2015). 33 | % SAFE is provided without any warranty and for non-commercial use only. 34 | % For more details, see the Licence file included in the root directory 35 | % of this distribution. 36 | % For any comment and feedback, or to discuss a Licence agreement for 37 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 38 | % For details on how to cite SAFE in your publication, please see: 39 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 40 | 41 | if ~isnumeric(TSsim) ; error('input ''TSsim'' must be a matrix of real numbers'); end 42 | if ~isnumeric(TSobs) ; error('input ''TSobs'' must be a matrix of real numbers'); end 43 | [N,T] = size(TSsim) ; 44 | [n,t] = size(TSobs) ; 45 | if t~=T 46 | error('inputs ''TSsim'' and ''TSobs'' should have the same number of columns'); 47 | end 48 | if n~=N 49 | if n==1 50 | TSobs = repmat(TSobs,N,1); 51 | else 52 | error('inputs ''TSsim'' and ''TSobs'' should have the same number of rows'); 53 | end 54 | end 55 | 56 | if ~ischar(obj_fun) ; error('input ''obj_fun'' must be a string'); end 57 | 58 | if ~isnumeric(W) ; error('input ''W'' must be a scalar number'); end 59 | if ~isscalar(W); error('''W'' must be scalar'); end 60 | if W<1; error('''W'' must be >= 1' ); end 61 | if abs(W-round(W)); error('''W'' must be an integer'); end 62 | 63 | Err = TSsim - TSobs ; % (N,T) 64 | Y = nan(N,T) ; 65 | 66 | for t=1:T 67 | if strcmp(obj_fun,'MAE') 68 | 69 | err = Err(:,max(1,t-W):min(T,t+W)) ; % (N,W+1) 70 | Y(:,t) = mean(abs(err),2) ; % (N,1) 71 | 72 | elseif strcmp(obj_fun,'RMSE') 73 | 74 | err = Err(:,max(1,t-W):min(T,t+W)) ; % (N,W+1) 75 | Y(:,t) = sqrt(mean(err.^2,2)) ; % (N,1) 76 | 77 | elseif strcmp(obj_fun,'BIAS') 78 | 79 | qobs = TSobs(:,max(1,t-W):min(T,t+W)) ; % (N,W+1) 80 | qsim = TSsim(:,max(1,t-W):min(T,t+W)) ; % (N,W+1) 81 | Y(:,t) = abs( mean(qsim,2) - mean(qobs,2) ) ; % (N,1) 82 | 83 | else 84 | fprintf('\n ERROR! obj_fun %s not available\n',obj_fun) 85 | end 86 | 87 | end 88 | -------------------------------------------------------------------------------- /FAST/FAST_indices.m: -------------------------------------------------------------------------------- 1 | function [Si,V,A,B,Vi] = FAST_indices(Y,M,varargin) 2 | % 3 | % Computes main effect (first-order) sensitivity index 4 | % according to the Fourier Amplitude Sensitivity Test (FAST) 5 | % (Cukier et al., 1978; Saltelli et al., 1999) 6 | % 7 | % Usage: 8 | % [Si,V,A,B,Vi] = FAST_indices(Y,M) 9 | % [Si,V,A,B,Vi] = FAST_indices(Y,M,Nharm) 10 | % [Si,V,A,B,Vi] = FAST_indices(Y,M,Nharm,omega) 11 | % 12 | % Input: 13 | % Y = set of model output samples - vector (N,1) 14 | % M = number of inputs - scalar 15 | % Nharm = interference factor, i.e.the number of higher - scalar 16 | % harmonics to be considered (default is 4) 17 | % omega = angular frequencies associated to inputs - vector (1,M) 18 | % (default values computed by function 'generate_FAST_frequency.m') 19 | % 20 | % Output: 21 | % Si = main effect (first-order) sensitivity indices - vector (1,M) 22 | % V = total output variance - scalar 23 | % A = Fourier coefficients - vector (1,N) 24 | % B = Fourier coefficients - vector (1,N) 25 | % Vi = output variances from each input - vector (1,M) 26 | % 27 | % References: 28 | % 29 | % Cukier, R.I., Levine, H.B., and Shuler, K.E. (1978), Nonlinear 30 | % Sensitivity Analyis of Multiparameter Model SYstems, Journal of 31 | % Computational Physics, 16, 1-42. 32 | % 33 | % Saltelli, A., Tarantola, S. and Chan, K.P.S. (1999), A Quantitative 34 | % Model-Independent Method ofr Global Sensitivty Analysis of Model Output, 35 | % Technometrics, 41(1), 39-56. 36 | 37 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 38 | % and T. Wagener at Bristol University (2015). 39 | % SAFE is provided without any warranty and for non-commercial use only. 40 | % For more details, see the Licence file included in the root directory 41 | % of this distribution. 42 | % For any comment and feedback, or to discuss a Licence agreement for 43 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 44 | % For details on how to cite SAFE in your publication, please see: 45 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 46 | 47 | %%%%%%%%%%%%%% 48 | % Check inputs 49 | %%%%%%%%%%%%%% 50 | 51 | if ~isnumeric(Y) ; error('input ''Y'' must be a vector of size (N,1)'); end 52 | [N,tmp] = size(Y) ; 53 | if tmp>1 ; error('input ''Y'' must be a vector of size (N,1)'); end 54 | if N<1 ; error('input ''Y'' must be a vector of size (N,1)'); end 55 | 56 | if ~isscalar(M); error('''M'' must be a scalar'); end 57 | if (M - round(M))~=0 ; error('''M'' must be an integer'); end 58 | if M<=0 ; error('''M'' must be a positive integer'); end 59 | 60 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 61 | % Recover and check optional inputs 62 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 63 | 64 | % Set optional arguments to their default values: 65 | Nharm = 4; % taken from Saltelli et al. (1999; page 42) 66 | omega = generate_FAST_frequency(M); 67 | 68 | % Recover and update optional arguments: 69 | if nargin > 2 70 | if ~isempty(varargin{1}) 71 | Nharm = varargin{1}; 72 | if ~isscalar(Nharm); error('''Nharm'' must be a scalar'); end 73 | if (Nharm - round(Nharm))~=0 ; error('''Nharm'' must be an integer'); end 74 | if Nharm<=0 ; error('''Nharm'' must be a positive integer'); end 75 | end 76 | end 77 | if nargin > 3 78 | if ~isempty(varargin{2}) 79 | omega = varargin{2}; 80 | if ~isnumeric(omega) ; error('input ''omega'' must be a vector of size (1,M)'); end 81 | [tmp,M2] = size(omega); 82 | if tmp>1 ; error('input ''omega'' must be a vector of size (1,M)'); end 83 | if M2~=M ; error('input ''omega'' must be a vector of size (1,M)'); end 84 | if any(omega<0); error('all components of ''omega'' should be positive'); end 85 | if any(omega-round(omega)~=0); error('all components of ''omega'' should be integer'); end 86 | end 87 | end 88 | 89 | if N < 2*Nharm*max(omega)+1 % and finally check that is is consistent with omega 90 | error('Sample size (i.e. the length of vector Y) is %d, which is lower than the minimum sample size (i.e. 2*Nharm*max(omega)+1=2*%d*%d+1=%d',N,Nharm,max(omega),2*Nharm*max(omega)+1); 91 | end 92 | 93 | 94 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 95 | % Compute Fourier coefficients (vectors A and B) from Y 96 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 97 | 98 | % The code below implements the equations given in Appendix C 99 | % of Saltelli et al. (1999). 100 | 101 | A = zeros(1,N) ; 102 | B = zeros(1,N) ; 103 | baseplus = sum( reshape(Y(2:end),2,(N-1)/2) )' ; % ((N-1)/2,1) 104 | baseminus = -diff( reshape(Y(2:end),2,(N-1)/2) )' ; % ((N-1)/2,1) 105 | for j=1:N 106 | if mod(j,2)==0 % j is even 107 | sp = Y(1) ; 108 | for k=1:(N-1)/2 109 | sp = sp + baseplus(k)*cos(j*k*pi/N) ; 110 | end 111 | A(j) = sp/N ; 112 | else % j is odd 113 | sp = 0 ; 114 | for k=1:(N-1)/2 115 | sp = sp + baseminus(k)*sin(j*k*pi/N) ; 116 | end 117 | B(j) = sp/N ; 118 | end 119 | end 120 | 121 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 122 | % Compute main effect from A and B 123 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 124 | 125 | % The code below implements the equations given in Appendix B 126 | % of Saltelli et al. (1999) (here we use 'V' and 'Vi' for the output 127 | % variances while in that paper they are called 'D' and 'Di') 128 | 129 | V = 2*sum(A.^2+B.^2); % total output variance 130 | Vi = nan(1,M) ; % output variances from the i-th input 131 | for i=1:M 132 | idx = [1:Nharm]*omega(i) ; 133 | Vi(i) = 2*sum(A(idx).^2+B(idx).^2) ; 134 | end 135 | Si = Vi / V ; 136 | 137 | fprintf('\n \t main \n'); 138 | fprintf(' X%d:\t %1.4f\t \n',[ 1:M; Si ]); 139 | fprintf('\n sum:\t %1.4f\t \n\n',sum(Si)); 140 | 141 | -------------------------------------------------------------------------------- /FAST/FAST_sampling_unif.m: -------------------------------------------------------------------------------- 1 | function [X,s] = FAST_sampling_unif(M,varargin) 2 | % 3 | % Implements sampling for the Fourier Amplitude Sensitivity Test (FAST; 4 | % Cukier et al., 1978) and returns a matrix 'X' of N input samples. 5 | % Inputs are assumed to be uniformly distributed in the unit hypercube 6 | % [0,1]^M. 7 | % Samples are taken along the search curve defined by transformations 8 | % 9 | % x_i(s) = G_i( sin( omega_i*s ) ) i=1,...,M (*) 10 | % 11 | % where 's' is a scalar variable that varies in (-pi/2,pi/2) 12 | % 13 | % Usage: 14 | % [X,s] = FAST_sampling_unif(M) 15 | % [X,s] = FAST_sampling_unif(M,N) 16 | % [X,s] = FAST_sampling_unif(M,N,Nharm) 17 | % [X,s] = FAST_sampling_unif(M,N,Nharm,omega) 18 | % 19 | % Input: 20 | % M = number of inputs - scalar 21 | % N = number of samples (default is 2*Nharm*max(omega)+1 - scalar 22 | % which is the minimum sampling size according to (odd) 23 | % Cukier et al. (1978)) 24 | % Nharm = interference factor, i.e.the number of higher - scalar 25 | % harmonics to be considered (default is 4) 26 | % omega = angular frequencies associated to inputs - vector (1,M) 27 | % (default values computed by function 'generate_FAST_frequency.m') 28 | % 29 | % Output: 30 | % X = matrix of input samples - matrix (N,M) 31 | % s = vector of sampled points over the search curve - vector (N,1) 32 | % 33 | % Notes: 34 | % (*) Here we use the curve proposed by Saltelli et al. (1999): 35 | % x_i = 1/2 + 1/pi * arcsin( sin( omega_i*s ) ) 36 | % 37 | % References: 38 | % 39 | % Cukier, R.I., Levine, H.B., and Shuler, K.E. (1978), Nonlinear 40 | % Sensitivity Analyis of Multiparameter Model SYstems, Journal of 41 | % Computational Physics, 16, 1-42. 42 | % 43 | % Saltelli, A., Tarantola, S. and Chan, K.P.S. (1999), A Quantitative 44 | % Model-Independent Method ofr Global Sensitivty Analysis of Model Output, 45 | % Technometrics, 41(1), 39-56. 46 | 47 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 48 | % and T. Wagener at Bristol University (2015). 49 | % SAFE is provided without any warranty and for non-commercial use only. 50 | % For more details, see the Licence file included in the root directory 51 | % of this distribution. 52 | % For any comment and feedback, or to discuss a Licence agreement for 53 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 54 | % For details on how to cite SAFE in your publication, please see: 55 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 56 | 57 | %%%%%%%%%%%%%% 58 | % Check inputs 59 | %%%%%%%%%%%%%% 60 | 61 | if ~isscalar(M); error('''M'' must be a scalar'); end 62 | if (M - round(M))~=0 ; error('''M'' must be an integer'); end 63 | if M<=0 ; error('''M'' must be a positive integer'); end 64 | 65 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 66 | % Recover and check optional inputs 67 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 68 | 69 | % Set optional arguments to their default values: 70 | Nharm = 4; % taken from Saltelli et al. (1999; page 42) 71 | omega = generate_FAST_frequency(M); 72 | N = [] ; % minimum sample size 73 | 74 | % Recover and update optional arguments: 75 | if nargin > 1 76 | if ~isempty(varargin{1}) 77 | N = varargin{1}; 78 | if ~isscalar(N); error('''N'' must be scalar'); end 79 | if (N - round(N))~=0 ; error('''N'' must be integer'); end 80 | if N<=0 ; error('''N'' must be positive'); end 81 | if mod(N,2)==0 ; error('''N'' must be odd'); end 82 | end 83 | end 84 | if nargin > 2 85 | if ~isempty(varargin{2}) 86 | Nharm = varargin{2}; 87 | if ~isscalar(Nharm); error('''Nharm'' must be a scalar'); end 88 | if (Nharm - round(Nharm))~=0 ; error('''Nharm'' must be an integer'); end 89 | if Nharm<=0 ; error('''Nharm'' must be a positive integer'); end 90 | end 91 | end 92 | if nargin > 3 93 | if ~isempty(varargin{3}) 94 | omega = varargin{3}; 95 | if ~isnumeric(omega) ; error('input ''omega'' must be a vector of size (1,M)'); end 96 | [tmp,M2] = size(omega); 97 | if tmp>1 ; error('input ''omega'' must be a vector of size (1,M)'); end 98 | if M2~=M ; error('input ''omega'' must be a vector of size (1,M)'); end 99 | if any(omega<0); error('all components of ''omega'' should be positive'); end 100 | if any(omega-round(omega)~=0); error('all components of ''omega'' should be integer'); end 101 | end 102 | end 103 | 104 | if isempty(N) ; % If user did not specify the sample size 105 | N = 2*Nharm*max(omega)+1 ; % ... set it to the minimum sample size 106 | end 107 | if N < 2*Nharm*max(omega)+1 % and finally check that is is consistent with omega 108 | Nuser = N ; % (in case omega was specified by user) 109 | N = 2*Nharm*max(omega)+1 ; 110 | warning('Sample size specified by user (%d) is smaller than minimum sample size. Using the latter (%d) instead',Nuser,N); 111 | end 112 | 113 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 114 | % Perform sampling over the search curve 115 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 116 | 117 | s = pi/2*(2*[1:N]'-N-1)/N ; 118 | % s = [ pi/2*(-N+1)/N 119 | % pi/2*(-N+3)/N 120 | % ... 121 | % pi/2*( -1 )/N 122 | % pi/2*( +1 )/N 123 | % ... 124 | % pi/2*(+N-3)/N 125 | % pi/2*(+N-1)/N ] 126 | 127 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 128 | % Map back sampled points in the input space 129 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 130 | 131 | X = nan(N,M) ; 132 | for n=1:N 133 | % X(n,:) = feval(searchcurve,s(n),omega) ; 134 | X(n,:) = 1/2+1/pi*asin( sin(omega*s(n)) ) ; 135 | end 136 | 137 | 138 | %function x = Saltelli1999_searchcurve(s,omega) 139 | % 140 | %x = 1/2+1/pi*arcsin( sin(omega*s) ) ; 141 | 142 | 143 | -------------------------------------------------------------------------------- /FAST/generate_FAST_frequency.m: -------------------------------------------------------------------------------- 1 | function omega = generate_FAST_frequency(M) 2 | % 3 | % Generates a sequence of M frequency values (omega) for sampling 4 | % according to the FAST method 5 | % (See also FAST_sampling_unif.m for details and references about FAST 6 | % sampling strategy) 7 | % 8 | % omega = generate_FAST_frequency(M) 9 | % 10 | % M = number of inputs (integer scalar between 4 and 50) 11 | % omega = frequency set free of interferences through (at least) 4th order 12 | % (vector (1,M)) 13 | % 14 | % For M>4, frequencies are computed based on the recursive algorithm by: 15 | % 16 | % Cukier et al. (1975) Study of the sensitivity of coupled reaction systems 17 | % to uncertainties in rate coefficients. III. Analysis of the 18 | % approximations, J. Chem. Phys. 63, 1140 19 | % 20 | % which is free of interferences through the 4th order. 21 | % For M<=4, we use values from the literature that guarantee higher order 22 | % interferences free (see comments in the code for specific references) 23 | 24 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 25 | % and T. Wagener at Bristol University (2015). 26 | % SAFE is provided without any warranty and for non-commercial use only. 27 | % For more details, see the Licence file included in the root directory 28 | % of this distribution. 29 | % For any comment and feedback, or to discuss a Licence agreement for 30 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 31 | % For details on how to cite SAFE in your publication, please see: 32 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 33 | 34 | if ~isscalar(M); error('''M'' must be a scalar'); end 35 | if (M - round(M))~=0 ; error('''M'' must be an integer'); end 36 | if M<2 ; error('''M'' must be >4'); end 37 | if M>50; error('''M'' must be <25'); end 38 | 39 | if M==2 % Use values from Sec. 3.1 in: 40 | % Xu, C. and G. Gertner (2007), Extending a global sensitivity analysis 41 | % technique to models with correlated parameters, Computational Statistics 42 | % and Data Analysis, 51, 5579-5590. 43 | omega = [ 5 23 ] ; 44 | % (free of interference through 10th order) 45 | elseif M==4 % Use values from Table III in Cukier et al. (1975) 46 | % (free of interferences through 6th order) 47 | omega = [13 31 37 41 ]; 48 | else % Use recursive algorithm in the same paper 49 | Omega = [ 0 0 1 5 11 1 17 23 19 25 41 31 23 87 67 73 85 143 149 99 119 ... 50 | 237 267 283 151 385 157 215 449 163 337 253 375 441 673 773 875 873 ... 51 | 587 849 623 637 891 943 1171 1225 1335 1725 1663 2019 ] ; 52 | d = [ 4 8 6 10 20 22 32 40 38 26 56 62 46 76 96 60 86 126 134 112 ... 53 | 92 128 154 196 34 416 106 208 328 198 382 88 348 186 140 170 284 ... 54 | 568 302 438 410 248 448 388 596 216 100 488 166 ] ; 55 | % above values taken from Table VI 56 | omega = nan(1,M) ; 57 | omega(1) = Omega(M) ; 58 | for i=2:M 59 | omega(i)=omega(i-1)+d(M+1-i); 60 | % equation (5.1) 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /GLUE/GLUE.m: -------------------------------------------------------------------------------- 1 | function [ idx, Llim, Ulim ] = GLUE(GLF,threshold,Y_sim,varargin) 2 | % 3 | % This function implements the Generalized Likelihood Uncertainty 4 | % Estimation (GLUE) method, as first proposed by Beven and Binley (1992) 5 | % and Beven and Freer (2001)). 6 | % It retains as 'behavioural' the simulations associated to values 7 | % of the Generalized Likelihood Function(s) (GLFs) below a given 8 | % threshold ('below' because we assume that GLFs measure the distance 9 | % between observations and predictions) i.e.: 10 | % 11 | % GLF(i,j)1 for multiple GLFs are considered simoultaneously) 28 | % threshold = threshold for the GFLs - vector (1,P) 29 | % (if not specified: threshold=median(Y) ) 30 | % alfa = significance level for the predictions - scalar 31 | % limits (default: 0.05) 32 | % 33 | % Output: 34 | % 35 | % idxb = indices of samples statisfying the condition - vector (N,1) 36 | % (logical vector: 1 if behavioural, 0 otherwise) 37 | % Llim = time series of lower prediction limit - vector (T,1) 38 | % Ulim = time series of upper prediction limit - vector (T,1) 39 | % 40 | % REFERENCES 41 | % 42 | % Beven, K. and Binley, A. (1992), The future of distributed models: 43 | % Model calibration and uncertainty prediction. Hydrol. Process.,6,279-298 44 | % 45 | % Beven, K.GLF and Freer, J.E. (2001), Equifinality, data assimilation, and 46 | % uncertainty estimation in mechanistic modelling of complex environmental 47 | % systems using the GLUE methodology. Journal of Hydrology, 249(1-4),11-29 48 | 49 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 50 | % and T. Wagener at Bristol University (2015). 51 | % SAFE is provided without any warranty and for non-commercial use only. 52 | % For more details, see the Licence file included in the root directory 53 | % of this distribution. 54 | % For any comment and feedback, or to discuss a Licence agreement for 55 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 56 | % For details on how to cite SAFE in your publication, please see: 57 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 58 | 59 | %%%%%%%%%%%%%% 60 | % Check inputs 61 | %%%%%%%%%%%%%% 62 | 63 | if ~isnumeric(GLF) ; error('GLF must be numeric'); end 64 | if ~isnumeric(threshold) ; error('''threshold'' must be numeric'); end 65 | if ~isnumeric(Y_sim) ; error('Y_sim must be numeric'); end 66 | [N,T] = size(Y_sim) ; 67 | [N2,P] = size(GLF) ; 68 | [f,P2] = size(threshold) ; 69 | if N2~=N 70 | error('GLF and Y_sim must have the same number of rows') 71 | end 72 | if P2~=P 73 | error('GLF and threshold must have the same number of columns') 74 | end 75 | if f>1 76 | error('threshold must be a row vector') 77 | end 78 | 79 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 80 | % Recover and check optional inputs 81 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 82 | 83 | % Set optional arguments to their default values: 84 | alfa=0.05; 85 | 86 | % Recover and update optional arguments: 87 | 88 | if nargin > 3 89 | if ~isempty(varargin{1}) 90 | alfa=varargin{1}; 91 | if ~isscalar(alfa); error('''alfa'' must be scalar'); end 92 | if any([alfa<0,alfa>1]); error('''alfa'' must be in [0,1]' ); end 93 | end 94 | end 95 | 96 | %%%%%%%%%%%%% 97 | % GLUE 98 | %%%%%%%%%%%% 99 | 100 | idx = sum(GLF<+repmat(threshold,N,1),2)==P ;% indices of behavioural samples 101 | % idx = GLF >= threshold ; % old (scalar case) 102 | 103 | if isempty(idx) 104 | 105 | warning('No samples satisfying the condition GLF>=%g',threshold); 106 | Llim = []; Ulim= []; 107 | 108 | else 109 | 110 | % Define "likelihood" measure: 111 | Jb = GLF ; % take the objective function 'GLF' as likelihood function 112 | Jb(~idx) = 0 ; % set to 0 the likelihood of non-behavioural samples 113 | Jb = Jb/(sum(Jb)); % rescale 114 | 115 | % Find "CDFs" (and prediction limits) at all time steps: 116 | Jbt = Jb(idx) ; % (Nb,1) 117 | Llim = nan(T,1); 118 | Ulim = nan(T,1); 119 | for t=1:T 120 | [y_sorted,idx_sort] = sort(Y_sim(idx,t)); 121 | CDF_t = cumsum(Jbt(idx_sort)); 122 | % Find lower limit: 123 | Llim_ = y_sorted(CDF_t1-alfa); 131 | if ~isempty(Ulim_); 132 | Ulim(t) = Ulim_(1); 133 | else 134 | Ulim(t) = y_sorted(end); 135 | end 136 | end 137 | 138 | end 139 | 140 | -------------------------------------------------------------------------------- /PAWN/SWAT_sample_description.txt: -------------------------------------------------------------------------------- 1 | %% Description of SWAT_samples.mat %% 2 | 3 | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 4 | 5 | %% Simulation time horizon: %% 6 | 7 | 01/01/2001 - 31/12/2005 8 | 9 | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 10 | %% Variable description: %% 11 | 12 | 13 | Xrsa_ext: parameter sample 14 | Yrsa_ext: output sample 15 | Yrsa_ext(:,1): absolute mean error for streamflow 16 | Yrsa_ext(:,2): NSE for streamflow (used in convergence paper) 17 | Yrsa_ext(:,3): BIAS for streamflow 18 | Yrsa_ext(:,4): RMSE for streamflow 19 | 20 | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 21 | %% Parameter description %% 22 | 23 | 24 | X_Labels_swat={ 'ALPHA-BF A','ALPHA-BF U','ALPHA-BF F','ALPHA-BF P','ALPHA-BF R','BIOMIX','BLAI','CANMAX','CH-K2','CH-N2','CN2 A','CN2 U','CN2 F','CN2 P','CN2 R',... 25 | 'EPCO','ESCO','GW-DELAY','GW-REVAP','GWQMN A','GWQMN U','GWQMN F','GWQMN P','GWQMN R','RCHRG-DP A','RCHRG-DP U','RCHRG-DP F','RCHRG-DP P','RCHRG-DP R',... 26 | 'REVAPMN','SFTMP','SLOPE A','SLOPE U','SLOPE F','SLOPE P','SLOPE R','SLSUBBSN','SMFMN','SMFMX','SMTMP','SOL-ALB','SOL-AWC','SOL-K A','SOL-K U','SOL-K F','SOL-K P','SOL-K R','SURLAG','TLAPS','TIMP'} ; % input names 27 | 28 | xmin=[0 0 0 0 0 0 0.5 0 0.5 0 -50 -50 -50 -50 -50 0.1 0 1 0.02 10 10 10 10 10 0 0 0 0 0 1 -5 0 0 0 0 0 10 0 0 -5 0 -25 0 0 0 0 0 0.5 -10 0]; 29 | xmax=[1 1 1 1 1 1 10 10 150 0.3 25 25 25 25 25 1 1 60 0.2 500 500 500 500 500 1 1 1 1 1 500 5 1 1 1 1 1 150 10 10 5 0.25 60 2000 2000 2000 2000 2000 10 10 1]; 30 | 31 | 32 | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 33 | %% Sampling strategy %% 34 | 35 | The sample was created using: 36 | - a LH sample of size 20,000 (first 20,000 rows of the Qs_ext,Xrsa_ext and Yrsa_ext) 37 | - an additional sample of size 10,000 using the function AAT_sampling_extend of SAFE (last 10,000 rows of the Qs_ext,Xrsa_ext and Yrsa_ext) -------------------------------------------------------------------------------- /PAWN/SWAT_samples.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAFEtoolbox/SAFE-matlab/0a24bb6c708351cef8719d0ea497b38ff380f492/PAWN/SWAT_samples.mat -------------------------------------------------------------------------------- /PAWN/conditional_sampling.m: -------------------------------------------------------------------------------- 1 | function [ XX, xc ] = conditional_sampling(samp_strat,M,distr_fun,distr_par,n,NC,ifixed) 2 | % 3 | % [ XX, xc ] = conditional_sampling(samp_strat,M,distr_fun,distr_par,n,NC,ifixed) 4 | % 5 | % Input: 6 | % samp_strat = sampling strategy - string 7 | % Options: 'rsu': random uniform 8 | % 'lhs': latin hypercube 9 | % M = number of inputs - scalar 10 | % distr_fun = probability distribution function of each input 11 | % - string (eg: 'unif') if all inputs have the same pdf 12 | % - cell array of M strings (eg:{'unif','norm'}) otherwise 13 | % distr_par = parameters of the probability distribution function 14 | % - row vector if all input pdfs have the same parameters 15 | % - cell array of M vectors otherwise 16 | % n = number of conditioning points - scalar 17 | % NC = number of samples to be generated - scalar 18 | % at each conditioning point 19 | % ifixed = boolean vector that specifies the inputs to be 20 | % fixed at conditioning points while varying all 21 | % others (1: fixed, 0: varying) - vector (1,M) 22 | % 23 | % Output: 24 | % XX = cell array of size (M,n). The element X{i,k} is the subsamples 25 | % of input datapoints to compute the sensitivity of factor i in 26 | % subsample k, and it is a matrix of size (NC,M) 27 | % xc = cell array of size (M,1). The element xc{i} is the list of 28 | % subsample centers used to compute the sensitivity of factor i 29 | % and it is a matrix of size (n,K), where 'K' is the number of inputs 30 | % to fixed at conditioning value (i.e. K varies between 1 and M, 31 | % and it is linked to 'ifixed' by the relation: K=sum(ifixed) ). 32 | 33 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 34 | % and T. Wagener at Bristol University (2015). 35 | % SAFE is provided without any warranty and for non-commercial use only. 36 | % For more details, see the Licence file included in the root directory 37 | % of this distribution. 38 | % For any comment and feedback, or to discuss a Licence agreement for 39 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 40 | % For details on how to cite SAFE in your publication, please see: 41 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 42 | 43 | 44 | if ~iscell(distr_fun); tmp=cell(1,M);for i=1:M; tmp{i}=distr_fun; end; distr_fun = tmp; end 45 | if ~iscell(distr_par); tmp=cell(1,M);for i=1:M; tmp{i}=distr_par; end; distr_par = tmp; end 46 | 47 | if ~isscalar(M); error('''M'' must be a scalar'); end 48 | if M<=0; error('''M'' must be positive' ); end 49 | if abs(M-round(M)); error('''M'' must be integer'); end 50 | 51 | if ~isscalar(n); error('''n'' must be a scalar'); end 52 | if n<=0; error('''n'' must be positive' ); end 53 | if abs(n-round(n)); error('''n'' must be integer'); end 54 | 55 | if ~isscalar(NC); error('''NC'' must be a scalar'); end 56 | if NC<=0; error('''NC'' must be positive' ); end 57 | if abs(NC-round(NC)); error('''NC'' must be integer'); end 58 | 59 | [n1,M1] = size(ifixed) ; 60 | if n1~=1; error('''ifixed'' must be a row vector' ); end 61 | if M1~=M; error('''ifixed'' must be a row vector with M components' ); end 62 | 63 | ivarying = true(1,M) ; % indices of inputs to be let vary 64 | ivarying(ifixed) = false ; 65 | 66 | % Randomly sample 'n' fixed points: 67 | xc = AAT_sampling('lhs',sum(ifixed>0),distr_fun(ifixed),distr_par(ifixed),n); 68 | % For each fixed point, randomly sample 'NC' points in the remaining input 69 | % space: 70 | XX = cell(1,n); 71 | for k=1:n 72 | X_new = AAT_sampling(samp_strat,sum(ivarying>0),distr_fun(ivarying),distr_par(ivarying),NC); 73 | X_sub = nan(NC,M) ; 74 | X_sub(:,ifixed) = repmat(xc(k,:),NC,1) ; 75 | X_sub(:,ivarying ) = X_new ; 76 | XX{1,k} = X_sub ; 77 | end 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /PAWN/pawn_cdfs.m: -------------------------------------------------------------------------------- 1 | function [ YF, FU, FC ] = pawn_cdfs(Y,YY,varargin) 2 | % 3 | % Estimate the unconditional output CDF (i.e. when all inputs vary) 4 | % and the conditional CDFs (when one or more inputs are fixed). 5 | % 6 | % Usage: 7 | % [ YF, FU, FC ] = pawn_cdfs(Y,YY) 8 | % [ YF, FU, FC ] = pawn_cdfs(Y,YY,idx) 9 | % 10 | % Input: 11 | % Y = output sample for estimating the unconditional CDF - matrix (N,P) 12 | % YY = output samples for the conditional CDFs - cell array (M,n) 13 | % The element Y{i,k} is the k-th subsample 14 | % of output evaluations obtained by fixing the i-th input 15 | % (or group of inputs) to its k-th conditioning value, 16 | % and it is a matrix of size (NC,P). 17 | % idx = when dealing with multiple output (P>1), - scalar 18 | % this function will actually estimate the conditional and 19 | % unconditional CDFs of one output only. 'idx' thus is the 20 | % index of the output to be analyzed (i.e. the column of 21 | % matrix Y and YY{i,k}) (default value: 1) 22 | % 23 | % Output: 24 | % YF = values of y at which the CDFs are given - vector (P,1) 25 | % FU = values of the empirical unconditional CDF - vector (P,1) 26 | % estimated from Y 27 | % FC = cell array whose element (i,k) is a - cell array (M,n) 28 | % vector (P,1) of values of the empirical 29 | % conditional CDF estimated from subsample YY{i,k} 30 | % 31 | % Example: 32 | % 33 | % NU = 150 ; 34 | % NC = 100 ; 35 | % n = 10 ; 36 | % M = 3 ; 37 | % XU = AAT_sampling('lhs',M,'unif',[-pi,pi],NU); 38 | % YU = model_evaluation('ishigami_homma_function',XU) ; 39 | % XX = pawn_sampling('lhs',M,'unif',[-pi,pi],n,NC); 40 | % YY = pawn_model_evaluation('ishigami_homma_function',XX) ; 41 | % [ YF, FU, FC ] = pawn_cdfs(YU,YY) ; 42 | % 43 | % IMPORTANT NOTE: 44 | % If the column 'idx' of input Y or of any YY{i,k} includes any 45 | % NaN values, the function will identify them and exclude them from further 46 | % computation. A Warning message about the number of discarded NaN elements 47 | % (and hence the actual number of samples used for estimating the CDFs) 48 | % will be displayed. If all elements are NaNs in YY{i,k} the 49 | % corresponding estimated CDF FC{i,k} will be empty. 50 | 51 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 52 | % and T. Wagener at Bristol University (2015). 53 | % SAFE is provided without any warranty and for non-commercial use only. 54 | % For more details, see the Licence file included in the root directory 55 | % of this distribution. 56 | % For any comment and feedback, or to discuss a Licence agreement for 57 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 58 | % For details on how to cite SAFE in your publication, please see: 59 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 60 | 61 | %%%%%%%%%%%%%% 62 | % Check inputs 63 | %%%%%%%%%%%%%% 64 | 65 | [~,P] = size(Y) ; 66 | [M,n] = size(YY) ; 67 | [~,P2]=size(YY{1}); 68 | if P2~=P; error('''Y'' and ''YY{1}''must have the same number of colums'); end 69 | 70 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 71 | % Recover and check optional inputs 72 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 73 | 74 | % Set optional arguments to their default values: 75 | idx=1; 76 | 77 | % Recover and update optional arguments: 78 | if nargin > 2 79 | if ~isempty(varargin{1}) 80 | idx = varargin{1} ; 81 | if ~isscalar(idx) ; error('input ''idx'' must be scalar'); end 82 | if abs(idx-round(idx)); error('''idx'' must be integer'); end 83 | if idx<1 ; error('input ''idx'' must be a positive integer'); end 84 | if idx>P2 ; error('''idx'' exceeds the number of columns in Y'); end 85 | end 86 | end 87 | 88 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 89 | % Remove Nan values and select output 'idx' 90 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 91 | 92 | [Y,YY]=pawn_exclude_NaN(Y,YY,idx); 93 | % Y is a vector of size (NU,1) without NaN values 94 | % YY is a cell matrix of size (M,n) where each element YY{i,k} is vector of 95 | % size (NC,1) without NaN values. 96 | 97 | %%%%%%%%%%%%%%% 98 | % Estimate CDFS 99 | %%%%%%%%%%%%%%% 100 | 101 | FC = cell(M,n) ; 102 | Ymin = min(Y) ; % Ymin is the minimum value of the output 103 | Ymax = max(Y) ; % Ymax is the maximum value of the output 104 | for i=1:M 105 | for k=1:n ; 106 | if ~isempty(YY{i,k}) % skip output YY{i,k) if it is empty 107 | Ymin = min( Ymin, min(YY{i,k}) ) ; Ymax = max( Ymax, max(YY{i,k}) ) ; 108 | end 109 | end 110 | end 111 | 112 | 113 | deltaY = (Ymax-Ymin)/4000 ; 114 | YF = [ (Ymin-std(Y)/10) : deltaY : (Ymax+std(Y)/10) ]' ; 115 | 116 | % unconditional CDF: 117 | FU = empiricalcdf(Y,YF); 118 | 119 | for i=1:M % for each input factor 120 | 121 | for k=1:n 122 | if ~isempty(YY{i,k}) % if YY{i,k} is empty, FC{i,k} is empty 123 | % Approximate conditional CDF: 124 | FCik = empiricalcdf(YY{i,k},YF) ; 125 | % Recover results: 126 | FC{i,k}=FCik; 127 | end 128 | end 129 | 130 | end 131 | -------------------------------------------------------------------------------- /PAWN/pawn_exclude_NaN.m: -------------------------------------------------------------------------------- 1 | function [Y_noNaN,YY_noNaN]=pawn_exclude_NaN(Y,YY,varargin) 2 | 3 | % Exclude NaN values in output samples generated to estimate unconditional 4 | % and conditional CDFs. 5 | % 6 | % Usage: 7 | % [Y_noNaN,YY_noNaN]=pawn_exclude_nan(Y,YY) 8 | % [Y_noNaN,YY_noNaN]=pawn_exclude_nan(Y,YY,idx) 9 | % 10 | % Input: 11 | % Y = output sample for estimating the unconditional CDF - matrix (NU,P) 12 | % YY = output samples for the conditional CDFs - cell array (M,n) 13 | % The element Y{i,k} is the k-th subsample 14 | % of output evaluations obtained by fixing the i-th input 15 | % (or group of inputs) to its k-th conditioning value, 16 | % and it is a matrix of size (NC,P). 17 | % idx = when dealing with multiple output (P>1), - scalar 18 | % this function will actually estimate the conditional and 19 | % unconditional CDFs of one output only. 'idx' thus is the 20 | % index of the output to be analyzed (i.e. the column of 21 | % matrix Y and YY{i,k}) (default: 1) 22 | % 23 | % Output 24 | % Y_noNaN = output sample for estimating the - matrix (NU_new,P) 25 | % unconditional CDF where NaN values 26 | % were removed 27 | % YY = output samples for the conditional CDFs - cell array (M,n) 28 | % all NaN values were removed for each 29 | % element Y{i,k} 30 | % 31 | % NOTE: This function is called in pawn_indices and pawn_cdfs so that NaNs 32 | % are excluded from the calculation of the indices and CDFs. 33 | % 34 | % REFERENCES 35 | % 36 | % Pianosi, F. and Wagener, T. (2015), A simple and efficient method 37 | % for global sensitivity analysis based on cumulative distribution 38 | % functions, Env. Mod. & Soft., 67, 1-11. 39 | 40 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 41 | % and T. Wagener at Bristol University (2015). 42 | % SAFE is provided without any warranty and for non-commercial use only. 43 | % For more details, see the Licence file included in the root directory 44 | % of this distribution. 45 | % For any comment and feedback, or to discuss a Licence agreement for 46 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 47 | % For details on how to cite SAFE in your publication, please see: 48 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 49 | 50 | %%%%%%%%%%%%%% 51 | % Check inputs 52 | %%%%%%%%%%%%%% 53 | 54 | if ~isnumeric(Y); error('''Y'' must be a matrix'); end 55 | [ ~, P ] = size(Y) ; 56 | if ~iscell(YY); error('''YY'' must be a cell array'); end 57 | [ M, n ] = size(YY) ; 58 | 59 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 60 | % Recover and check optional inputs 61 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 62 | 63 | % Set optional arguments to their default values: 64 | idx=1; 65 | 66 | % Recover and update optional arguments: 67 | if nargin > 2 68 | if ~isempty(varargin{1}) 69 | idx = varargin{1} ; 70 | if ~isscalar(idx) ; error('input ''idx'' must be scalar'); end 71 | if abs(idx-round(idx)); error('''idx'' must be integer'); end 72 | if idx<1 ; error('input ''idx'' must be a positive integer'); end 73 | if idx>P ; error('''idx'' exceeds the number of columns in Y'); end 74 | end 75 | end 76 | 77 | %%%%%%%%%%%%%%%%%%%%%%%%% 78 | % Exclude NaN value in Y 79 | %%%%%%%%%%%%%%%%%%%%%%%%% 80 | if all(isnan(Y(:,idx))); error('all data in ''Y'' are NaN'); end 81 | nan_Y=isnan(Y(:,idx)); % find any NaN in Y 82 | idx_Y=sum(nan_Y); % total number of NaN in Y 83 | Y_noNaN=Y(~nan_Y,idx); 84 | 85 | % Print warning message if NaN values are found 86 | if idx_Y 87 | fprintf('\n WARNING: %d NaN were found in Y',idx_Y) 88 | fprintf('\n') 89 | end 90 | %%%%%%%%%%%%%%%%%%%%%%%%% 91 | % Exclude NaN value in YY 92 | %%%%%%%%%%%%%%%%%%%%%%%%% 93 | % Preallocate variable 94 | YY_noNaN=cell(size(YY)); 95 | 96 | for i=1:M % for each input factor 97 | for k=1:n %for each conditioning value 98 | 99 | nan_YYik=isnan(YY{i,k}(:,idx)); % find any NaN in YY{i,k} 100 | idx_YYik=sum(nan_YYik); % total number of NaN in YY{i,k} 101 | YY_noNaN{i,k}=YY{i,k}(~nan_YYik,idx); 102 | 103 | % Print warning message if NaN values are found 104 | if idx_YYik 105 | fprintf('\n WARNING: %d NaN were found in YY{%d,%d}',idx_YYik,i,k) 106 | fprintf('\n') 107 | 108 | end 109 | end 110 | end 111 | 112 | -------------------------------------------------------------------------------- /PAWN/pawn_indices_givendata.m: -------------------------------------------------------------------------------- 1 | function [KS_median,KS_mean,KS_max,KS_dummy,YY,xc,NC,XX] = pawn_indices_givendata(X,Y,n,nboot) 2 | % 3 | % Compute PAWN sensitivity indices as a statistic of the KS 4 | % between the unconditional and conditional output distributions, 5 | % according to the approximation strategy by Pianosi and Wagener (2018). 6 | % 7 | % Usage: 8 | % [KS_median,KS_mean,KS_max,KS_dummy,YY,xc,NC,XX] = pawn_indices_givendata(X,Y,n,nboot) 9 | % 10 | % Input: 11 | % X = set of inputs samples - matrix (N,M) 12 | % Y = set of output samples - matrix (N,1) 13 | % n = number of conditional intervals - scalar 14 | % nboot = number of bootstrap resamples to derive - scalar 15 | % confidence intervals 16 | % 17 | % Output: 18 | % KS_median = median KS across n conditioning points - size (nboot,M) 19 | % (one value for each input and each bootstrap resample) 20 | % KS_mean = mean KS across n conditioning points - size (nboot,M) 21 | % KS_max = max KS across n conditioning points - size (nboot,M) 22 | % KS_dummy = KS of dummy parameter - size (nboot,1) 23 | % (one value for each bootstrap resample) 24 | % YY = output samples for the conditional distributions - cell array (M,n) 25 | % The element Y{i,k} is the k-th subsample 26 | % of output evaluations obtained by fixing the i-th input 27 | % (or group of inputs) to its k-th conditioning interval, 28 | % and it is a matrix of size (NC(i,k),1). 29 | % xc = mean value of conditioning intervals - cell array (M,1) 30 | % The element xc{i} is the list of 31 | % subsample centers (mean points of the conditioning intervals) 32 | % used to ccondition input i, and it is a matrix of size (n,1). 33 | % NC = number of conditional output samples - matrix (M,n) 34 | % for each input and each conditional interval 35 | % XX = input samples to derive the conditional samples - cell array (M,n) 36 | % The element X{i,k} is the k-th subsample 37 | % of input values where the i-th input is fixed to 38 | % the k-th conditioning interval (while other inputs vary freely), 39 | % and it is a matrix of size (NC(i,k),M) 40 | % 41 | % REFERENCES 42 | % 43 | % Pianosi, F. and Wagener, T. (2018), Distribution-based sensitivity 44 | % analysis from a generic input-output sample, Env. Mod. & Soft. 45 | 46 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 47 | % and T. Wagener at Bristol University (2015). 48 | % SAFE is provided without any warranty and for non-commercial use only. 49 | % For more details, see the Licence file included in the root directory 50 | % of this distribution. 51 | % For any comment and feedback, or to discuss a Licence agreement for 52 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 53 | % For details on how to cite SAFE in your publication, please see: 54 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 55 | 56 | % Check inputs 57 | if ~isnumeric(X) ; error('input ''X'' must be numeric'); end 58 | if ~isnumeric(Y) ; error('input ''Y'' must be numeric'); end 59 | [N,M]=size(X) ; 60 | [N2,m]=size(Y) ; 61 | if N~=N2; error('input ''X'' and ''Y'' must have the same number of rows'); end 62 | if m~=1; error('input ''Y'' must be a column vector'); end 63 | if ~isscalar(n) ; error('input ''n'' must be scalar'); end 64 | if abs(n-round(n)); error('''n'' must be integer'); end 65 | if n<1 ; error('input ''n'' must be a positive integer'); end 66 | if ~isscalar(nboot) ; error('input ''nboot'' must be scalar'); end 67 | if abs(nboot-round(nboot)); error('''nboot'' must be integer'); end 68 | if nboot<1 ; error('input ''nboot'' must be a positive integer'); end 69 | 70 | % 71 | [YY,xc,NC,XX] = pawn_split_sample(X,Y,n); 72 | bootsize = round(mean(mean(NC))); 73 | KS_median = nan(nboot,M) ; 74 | KS_mean = nan(nboot,M) ; 75 | KS_max = nan(nboot,M) ; 76 | KS_dummy = nan(nboot,1) ; 77 | 78 | for k=1:nboot 79 | 80 | % Bootrstrap from unconditional sample: 81 | idx_bootstrap = randperm(N,bootsize) ; 82 | YU = Y(idx_bootstrap) ; % (bootsize,1) 83 | % Compute empirical CDFs of unconditional and conditional samples: 84 | [ YF, Fu, Fc ] = pawn_cdfs(YU,YY) ; 85 | % Compute KS among CDFs: 86 | KS = pawn_ks(YF,Fu,Fc) ; % (n,M) 87 | 88 | % Take a statistic of KS across x_i values: 89 | KS_median(k,:) = median(KS) ; % (1,M) 90 | KS_mean(k,:) = mean(KS) ; % (1,M) 91 | KS_max(k,:) = max(KS) ; % (1,M) 92 | 93 | % Compute KS statistic for dummy parameter: 94 | % Bootrstrap again from unconditional sample: 95 | YU2 = Y(randperm(N,bootsize)) ; % (bootsize,1) 96 | % Compute empirical CDFs of the two unconditional samples: 97 | [ YF, Fu, Fc ] = pawn_cdfs(YU,{YU2}) ; 98 | % Compute KS among CDFs: 99 | KS_dummy(k) = pawn_ks(YF,Fu,Fc) ; 100 | 101 | % figure(100); hold on; plot(YF,Fu,'.-b',YF,Fc{1},'.-m') 102 | 103 | end 104 | -------------------------------------------------------------------------------- /PAWN/pawn_ks.m: -------------------------------------------------------------------------------- 1 | function KS = pawn_ks(YF,FU,FC,varargin) 2 | % 3 | % Compute the Kolmogorov-Smirnov (KS) statistic between the empirical 4 | % unconditional CDF and the conditional CDFs at different conditioning 5 | % values: 6 | % 7 | % KS(k,i) = max | F(y) - F(y|x(i)=x_ik) | 8 | % y 9 | % 10 | % i=1,...,M (number of inputs) 11 | % k=1,...,n (number of conditioning values for each input) 12 | % 13 | % Usage: 14 | % KS = pawn_ks(YF,FU,FC) 15 | % 16 | % Input: 17 | % YF = values of y at which the CDFs are given - vector (P,1) 18 | % FU = values of the empirical unconditional CDF F(y) - vector (P,1) 19 | % FC = cell array whose element (i,k) is a - cell array (M,n) 20 | % vector (P,1) of values of the empirical 21 | % conditional CDF F(y|x(i)=x_ik) 22 | % 23 | % Output: 24 | % KS = matrix (n,M) of KS statistic 25 | % 26 | % Example: 27 | % 28 | % NU = 150 ; 29 | % NC = 100 ; 30 | % n = 10 ; 31 | % M = 3 ; 32 | % XU = AAT_sampling('lhs',M,'unif',[-pi,pi],NU); 33 | % YU = model_evaluation('ishigami_homma_function',XU) ; 34 | % XX = pawn_sampling('lhs',M,'unif',[-pi,pi],n,NC); 35 | % YY = pawn_model_evaluation('ishigami_homma_function',XX) ; 36 | % [ YF, FU, FC ] = pawn_cdfs(YU,YY) ; 37 | % KS = pawn_ks(YF,FU,FC); 38 | % 39 | % ------------------------------------------------------------------------- 40 | % ADVANCED USAGE 41 | % for Regional-Response Global Sensitivity Analysis: 42 | % ------------------------------------------------------------------------- 43 | % 44 | % KS = pawn_ks(YF,FU,FC,'above',Ythreshold) 45 | % 46 | % Compute KS considering only output values satisfying the condition: 47 | % Y >= Ythreshold 48 | % Use 'below' instead of 'above' for the condition Y<=Ythreshold. 49 | % For more sophisticate conditions, the user can define its own 50 | % function and use it as follows: 51 | % 52 | % KS = pawn_ks(YF,FU,FC,'output_condition',param) 53 | % 54 | % Where 'output_condition' is a function with the following structure: 55 | % 56 | % idx = output_condition(Y,param) 57 | % 58 | % where Y = vector (N,1) of output samples 59 | % param = vector (any size) of parameters to check the condition 60 | % idx = vector (N,1) of logical values (1 if condition is satisfied, 61 | % 0 otherwise) 62 | % 63 | % NOTE: The function discard empty conditional outputs (the function 64 | % pawn_cdfs returns an empty FC{i,k} when all values are NaNs in the 65 | % corresponding sample YY{i,k}. 66 | 67 | % REFERENCES: 68 | % 69 | % Pianosi, F. and Wagener, T. (2015), A simple and efficient method 70 | % for global sensitivity analysis based on cumulative distribution 71 | % functions, Env. Mod. & Soft., 67, 1-11. 72 | 73 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 74 | % and T. Wagener at Bristol University (2015). 75 | % SAFE is provided without any warranty and for non-commercial use only. 76 | % For more details, see the Licence file included in the root directory 77 | % of this distribution. 78 | % For any comment and feedback, or to discuss a Licence agreement for 79 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 80 | % For details on how to cite SAFE in your publication, please see: 81 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 82 | 83 | %%%%%%%%%%%%%% 84 | % Check inputs 85 | %%%%%%%%%%%%%% 86 | 87 | if ~isnumeric(YF); error('input ''YF'' must be numeric'); end 88 | [P,m]=size(YF) ; 89 | if m~=1; error('input ''YF'' must be a column vector'); end 90 | 91 | if ~isnumeric(FU); error('input ''FU'' must be numeric'); end 92 | [PU,m]=size(FU) ; 93 | if m~=1; error('input ''FU'' must be a column vector'); end 94 | if P~=PU; error('input ''UF'' and ''FU'' must have the same number of rows'); end 95 | 96 | if ~iscell(FC); error('input ''FC'' must be a cell array'); end 97 | [M,n] = size(FC) ; 98 | for i=1:M; 99 | for k=1:n; 100 | if ~isempty(FC{i,k}) 101 | if ~isnumeric(FC{i,k}); error('element (%d,%d) of ''FC'' is not numeric',i,k); end 102 | [PC,m]=size(FC{i,k}) ; 103 | if m~=1; error('element (%d,%d) of ''FC'' must be a column vector',i,k); end 104 | if P~=PC; error('element (%d,%d) of ''FC'' must have the same number of rows as ''YF''',i,k); end 105 | end 106 | end 107 | end 108 | 109 | 110 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 111 | % Recover and check optional inputs 112 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 113 | 114 | % Set optional arguments to their default values: 115 | output_condition = 'allrange' ; 116 | par = NaN ; 117 | % Recover and update optional arguments: 118 | if nargin > 3 119 | if ~isempty(varargin{1}) 120 | output_condition = varargin{1} ; 121 | if ~ischar(output_condition); error('''output_condition'' must be a string'); end 122 | end 123 | if isempty(varargin{2}) 124 | error('please specify the parameters for the output condition') 125 | else 126 | par = varargin{2} ; 127 | end 128 | end 129 | 130 | KS = NaN(n,M) ; 131 | 132 | % Find subset of output values specifying a given condition 133 | idx = feval(output_condition,YF,par); 134 | 135 | for i=1:M % for each input: 136 | 137 | for k=1:n % for each conditioning value: 138 | if ~isempty(FC{i,k} ) 139 | FCik = FC{i,k} ; 140 | % Compute KS: 141 | KS(k,i)=max(abs(FU(idx)-FCik(idx))) ; 142 | end 143 | end 144 | 145 | end 146 | 147 | % % Print results to screen: 148 | % str='X%d:'; for k=1:n; str = [ str ' \t %2.3f' ]; end; str = [ str ' \n']; 149 | % fprintf(str,[ 1:M; KS ]); 150 | 151 | % Built-in functions: 152 | 153 | function idx = above(y,par) 154 | 155 | idx = y >= par ; 156 | 157 | function idx = below(y,par) 158 | 159 | idx = y <= par ; 160 | 161 | function idx = allrange(y,par) 162 | 163 | idx = true(size(y)) ; -------------------------------------------------------------------------------- /PAWN/pawn_ks_givendata.m: -------------------------------------------------------------------------------- 1 | function [KS,KS_dummy,YF,Fu,Fc,YY,xc,NC,XX,YU,idx_bootstrap,YUd] = pawn_ks_givendata(X,Y,n) 2 | % 3 | % Compute KS statistic between the unconditional and conditional output 4 | % distributions - to be used to approximate the PAWN sensitivity indices 5 | % according to the approximation strategy by Pianosi and Wagener (2018). 6 | % The KS statistic for the i-th input (i=1,...,M) at the k-th conditioning 7 | % interval (k=1,...,n) is defined as: 8 | % 9 | % KS(k,i) = max | F(y) - F(y| x(i) belongs to I(i,k)) | 10 | % y 11 | % 12 | % where F(y) is the unconditional output distribution, and F(y|...) is 13 | % the conditional output distribution when input x(i) varies within the 14 | % interval I(i,k). 15 | % 16 | % Usage: 17 | % [KS,KS_dummy,YF,Fu,Fc,YY,xc,NC,XX] = pawn_ks_givendata(X,Y,n) 18 | % 19 | % Input: 20 | % X = set of inputs samples - matrix (N,M) 21 | % Y = set of output samples - matrix (N,1) 22 | % n = number of conditional intervals - scalar 23 | % 24 | % Output: 25 | % KS = KS statistic between unconditional and conditional - matrix (n,M) 26 | % output distributions for each input factor at different 27 | % conditioning intervals. 28 | % KS_dummy = KS statistic of the dummy parameter - scalar 29 | % YF = values of y at which the CDFs are given - vector (P,1) 30 | % Fu = values of the empirical unconditional distribution F(y) - vector (P,1) 31 | % Fc = cell array whose element (i,k) is a - cell array (M,n) 32 | % vector (P,1) of values of the empirical 33 | % conditional distribution F(y|...) 34 | % YY = output samples for the conditional distributions - cell array (M,n) 35 | % The element Y{i,k} is the k-th subsample 36 | % of output evaluations obtained by fixing the i-th input 37 | % (or group of inputs) to its k-th conditioning interval, 38 | % and it is a matrix of size (NC(i,k),1). 39 | % xc = mean value of conditioning intervals - cell array (M,1) 40 | % The element xc{i} is the list of 41 | % subsample centers (mean points of the conditioning intervals) 42 | % used to ccondition input i, and it is a matrix of size (n,1). 43 | % NC = number of conditional output samples - matrix (M,n) 44 | % for each input and each conditional interval 45 | % XX = input samples to derive the conditional samples - cell array (M,n) 46 | % The element X{i,k} is the k-th subsample 47 | % of input values where the i-th input is fixed to 48 | % the k-th conditioning interval (while other inputs vary freely), 49 | % and it is a matrix of size (NC(i,k),M) 50 | % 51 | % REFERENCES 52 | % 53 | % Pianosi, F. and Wagener, T. (2018), Distribution-based sensitivity 54 | % analysis from a generic input-output sample, Env. Mod. & Soft. 55 | 56 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 57 | % and T. Wagener at Bristol University (2015). 58 | % SAFE is provided without any warranty and for non-commercial use only. 59 | % For more details, see the Licence file included in the root directory 60 | % of this distribution. 61 | % For any comment and feedback, or to discuss a Licence agreement for 62 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 63 | % For details on how to cite SAFE in your publication, please see: 64 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 65 | 66 | % Check inputs 67 | if ~isnumeric(X) ; error('input ''X'' must be numeric'); end 68 | if ~isnumeric(Y) ; error('input ''Y'' must be numeric'); end 69 | [N,M]=size(X) ; 70 | [N2,m]=size(Y) ; 71 | if N~=N2; error('input ''X'' and ''Y'' must have the same number of rows'); end 72 | if m~=1; error('input ''Y'' must be a column vector'); end 73 | if ~isscalar(n) ; error('input ''n'' must be scalar'); end 74 | if abs(n-round(n)); error('''n'' must be integer'); end 75 | if n<1 ; error('input ''n'' must be a positive integer'); end 76 | 77 | % Split sample 78 | [YY,xc,NC,XX] = pawn_split_sample(X,Y,n); 79 | bootsize = round(mean(mean(NC))); 80 | 81 | % Bootrstrap from unconditional sample: 82 | idx_bootstrap = randperm(N,bootsize) ; 83 | YU = Y(idx_bootstrap) ; % (bootsize,1) 84 | % Compute empirical CDFs of unconditional and conditional samples: 85 | [ YF, Fu, Fc ] = pawn_cdfs(YU,YY) ; 86 | % Compute KS among CDFs: 87 | KS = pawn_ks(YF,Fu,Fc) ; % (n,M) 88 | 89 | % Compute KS statistic for dummy parameter: 90 | % Bootrstrap again from unconditional sample: 91 | YUd = Y(randperm(N,bootsize)) ; % (bootsize,1) 92 | % Compute empirical CDFs of the two unconditional samples: 93 | [ YFd, Fud, Fcd ] = pawn_cdfs(YU,{YUd}) ; 94 | % Compute KS among CDFs: 95 | KS_dummy = pawn_ks(YFd,Fud,Fcd) ; 96 | 97 | 98 | -------------------------------------------------------------------------------- /PAWN/pawn_ks_test.m: -------------------------------------------------------------------------------- 1 | function [rej, ks_crit] = pawn_ks_test(ks,NC,NU,alfa) 2 | % 3 | % Apply the two-sample Kolmogorov-Smirnov test for inputs screening, 4 | % according to the PAWN approach (Pianosi adn Wagener, 2015). 5 | % 6 | % [rej, ks_crit] = pawn_ks_test(ks,NC,NU,alfa,xc,dimplot) 7 | % 8 | % Input: 9 | % KS = Kolmogorov-Smirnov statistic - matrix (n,M) 10 | % between empirical unconditional CDF of the output 11 | % and conditional CDF when fixing the i-th input (i=1,...,M) 12 | % at its k-th (k=1,...,n) conditioning value 13 | % NC = number of output samples used to compute the - scalar 14 | % conditional CDFs 15 | % NU = number of output samples used to compute the - scalar 16 | % unconditional CDF 17 | % alfa = confidence level of the KS test - scalar 18 | % must be one among {0.1,0.05,0.025,0.01,0.005,0.001} 19 | % 20 | % Output: 21 | % rej = frequency (over n conditioning values) - vector (M,1) 22 | % of rejecting the null hypothesis that the 23 | % unconditional and conditional CDFs be equal, 24 | % i.e. that the i-th input be non-influential. 25 | % In other words, rej(i)=0 means that the 26 | % i-th input was always found non-influential 27 | % while rej(i)=1 means that it was never 28 | % found non-influential 29 | % ks_crit = critical value of the KS statistic used to - scalar 30 | % reject the hypothesis 31 | % (computed according to Table AIX in Wall (1996)) 32 | % 33 | % REFERENCES 34 | % 35 | % Pianosi, F. and Wagener, T. (2015), A simple and efficient method 36 | % for global sensitivity analysis based on cumulative distribution 37 | % functions, Env. Mod. & Soft., 67, 1-11. 38 | % 39 | % Wall, J. (1996). Practical statistics for astronomers - ii. correlation, 40 | % data-modelling and sample comparison. Quarterly Journal of the 41 | % Royal Astronomical Society 37, 519?563. 42 | 43 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 44 | % and T. Wagener at Bristol University (2015). 45 | % SAFE is provided without any warranty and for non-commercial use only. 46 | % For more details, see the Licence file included in the root directory 47 | % of this distribution. 48 | % For any comment and feedback, or to discuss a Licence agreement for 49 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 50 | % For details on how to cite SAFE in your publication, please see: 51 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 52 | 53 | %%%%%%%%%%%%%% 54 | % Check inputs 55 | %%%%%%%%%%%%%% 56 | 57 | if ~isnumeric(ks); error('''ks'' must be a matrix'); end 58 | [n,M] = size(ks) ; 59 | ks = ks' ; 60 | 61 | if ~isscalar(NC); error('''NC'' must be a scalar'); end 62 | if NC<=0; error('''NC'' must be positive' ); end 63 | if abs(NC-round(NC)); error('''NC'' must be integer'); end 64 | 65 | if ~isscalar(NU); error('''NU'' must be a scalar'); end 66 | if NU<=0; error('''NU'' must be positive' ); end 67 | if abs(NU-round(NU)); error('''NU'' must be integer'); end 68 | 69 | if alfa==0.10 ; c=1.22; 70 | elseif alfa==0.05 ; c=1.36; 71 | elseif alfa==0.025; c=1.48; 72 | elseif alfa==0.01 ; c=1.63; 73 | elseif alfa==0.005; c=1.73; 74 | elseif alfa==0.001; c=1.95; 75 | else 76 | error('''alfa'' must take a value in {0.1,0.05,0.025,0.01,0.005,0.001}'); 77 | end 78 | % c = [ 1.22 1.36 1.48 1.63 1.73 1.95 ] ; 79 | % alfa = 0.10 0.05 0.025 0.01 0.005 0.001 80 | 81 | 82 | %%%%%%%%%%%%%%% 83 | % Apply KS-test 84 | %%%%%%%%%%%%%%% 85 | 86 | ks_crit = c*sqrt((NC+NU)/(NC*NU)) ; 87 | reject = ks > ks_crit ; 88 | rej = sum(reject,2)/n ; 89 | % frequency (across fixed points) of passing the KS test at confidence level alfa, 90 | % i.e. the empirical unconditional and conditional CDFs are different 91 | % or, the factor is influential. 92 | 93 | % Print results to screen: 94 | str='X%d:'; for k=1:n; str = [ str ' \t %2.3f' ]; end; str = [ str ' \n']; 95 | fprintf('X%d: \t %2.3f\n',[ 1:M; rej' ]); 96 | -------------------------------------------------------------------------------- /PAWN/pawn_model_execution.m: -------------------------------------------------------------------------------- 1 | function [YY, comp_time] = pawn_model_execution(fun_test,XX,varargin) 2 | % 3 | % This function evaluate a given model against the random samples generated 4 | % by the PAWN_SAMPLING function. 5 | % 6 | % Usage: 7 | % YY = pawn_model_execution(fun_test,XX) 8 | % [YY ,compt_time] = pawn_model_execution(fun_test,XX) 9 | % 10 | % Input: 11 | % XX = cell array of size (M,n). The element X{i,k} is the subsamples 12 | % of input datapoints to compute the sensitivity of factor i in 13 | % subsample k, and it is a matrix of size (NC,M). 14 | % XX can be generated using the PAWN_SAMPLING function 15 | % (see help pawn_sampling to learn more). 16 | % fun_test = name of the function implementing the model (string) 17 | 18 | % 19 | % Output: 20 | % YY = cell array of size (M,n). The element X{i,k} is the subsamples 21 | % of output values to compute the sensitivity of factor i in 22 | % subsample k, and it is a vector of size (NC,P) 23 | % comp_time = total computing time for model evaluation (sec) 24 | % 25 | % NOTE: If the 'fun_test' function requires other arguments besides 'XX', 26 | % they can be passed as optional arguments after 'X' (see function 27 | % model_evaluation). 28 | 29 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 30 | % and T. Wagener at Bristol University (2015). 31 | % SAFE is provided without any warranty and for non-commercial use only. 32 | % For more details, see the Licence file included in the root directory 33 | % of this distribution. 34 | % For any comment and feedback, or to discuss a Licence agreement for 35 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 36 | % For details on how to cite SAFE in your publication, please see: 37 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 38 | 39 | %%%%%%%%%%%%%% 40 | % Check inputs 41 | %%%%%%%%%%%%%% 42 | 43 | if ~ischar(fun_test); error('''fun_test'' must be a string'); end 44 | if exist(fun_test,'file')~=2; error('function ''%s'' does not exist',fun_test); end 45 | 46 | %%%%%%%%%%%%%%%%%% 47 | % Model evaluation 48 | %%%%%%%%%%%%%%%%%% 49 | 50 | if nargin > 2 51 | NumExtraArg = length(varargin); 52 | end 53 | 54 | [M,n] = size(XX) ; 55 | YY = cell(M,n); 56 | tic 57 | for i=1:M 58 | for k=1:n 59 | YY{i,k} = model_evaluation(fun_test,XX{i,k},varargin{1:NumExtraArg}); 60 | end 61 | end 62 | comp_time=toc; -------------------------------------------------------------------------------- /PAWN/pawn_sampling.m: -------------------------------------------------------------------------------- 1 | function [ XX, xc ] = pawn_sampling(samp_strat,M,distr_fun,distr_par,n,NC) 2 | % 3 | % This function performs random sampling to implement the PAWN method 4 | % (Pianosi and Wagener, 2015). 5 | % 6 | % Usage: 7 | % [ XX, xc ] = pawn_sampling(samp_strat,M,distr_fun,distr_par,n,NC) 8 | % 9 | % Input: 10 | % samp_strat = sampling strategy - string 11 | % Options: 'rsu': random uniform 12 | % 'lhs': latin hypercube 13 | % M = number of inputs - scalar 14 | % distr_fun = probability distribution function of each input 15 | % - string (eg: 'unif') if all inputs have the same pdf 16 | % - cell array of M strings (eg:{'unif','norm'}) otherwise 17 | % distr_par = parameters of the probability distribution function 18 | % - row vector if all input pdfs have the same parameters 19 | % - cell array of M vectors otherwise 20 | % n = number of conditioning points - scalar 21 | % NC = number of samples to be generated - scalar 22 | % at each conditioning point 23 | % 24 | % Output: 25 | % XX = cell array of size (M,n). The element X{i,k} is the subsamples 26 | % of input datapoints to compute the sensitivity of factor i in 27 | % subsample k, and it is a matrix of size (NC,M) 28 | % xc = cell array of size (M,1). The element xc{i} is the list of 29 | % subsample centers used to compute the sensitivity of factor i 30 | % and it is a matrix of size (n,1). 31 | % 32 | % REFERENCES 33 | % 34 | % Pianosi, F. and Wagener, T. (2015), A simple and efficient method 35 | % for global sensitivity analysis based on cumulative distribution 36 | % functions, Env. Mod. & Soft., 67, 1-11. 37 | 38 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 39 | % and T. Wagener at Bristol University (2015). 40 | % SAFE is provided without any warranty and for non-commercial use only. 41 | % For more details, see the Licence file included in the root directory 42 | % of this distribution. 43 | % For any comment and feedback, or to discuss a Licence agreement for 44 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 45 | % For details on how to cite SAFE in your publication, please see: 46 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 47 | 48 | if ~iscell(distr_fun); tmp=cell(1,M);for i=1:M; tmp{i}=distr_fun; end; distr_fun = tmp; end 49 | if ~iscell(distr_par); tmp=cell(1,M);for i=1:M; tmp{i}=distr_par; end; distr_par = tmp; end 50 | 51 | if ~isscalar(M); error('''M'' must be a scalar'); end 52 | if M<=0; error('''M'' must be positive' ); end 53 | if abs(M-round(M)); error('''M'' must be integer'); end 54 | 55 | if ~isscalar(n); error('''n'' must be a scalar'); end 56 | if n<=0; error('''n'' must be positive' ); end 57 | if abs(n-round(n)); error('''n'' must be integer'); end 58 | 59 | if ~isscalar(NC); error('''NC'' must be a scalar'); end 60 | if NC<=0; error('''NC'' must be positive' ); end 61 | if abs(NC-round(NC)); error('''NC'' must be integer'); end 62 | 63 | XX = cell(M,n); 64 | xc = cell(M,1); 65 | 66 | for i=1:M 67 | 68 | ifixed = false(1,M); 69 | ifixed(i) = true ; 70 | [ XXi, xci ] = conditional_sampling(samp_strat,M,distr_fun,distr_par,n,NC,ifixed) ; 71 | xc{i} = xci ; 72 | for k=1:n; XX{i,k}=XXi{k}; end 73 | 74 | end -------------------------------------------------------------------------------- /PAWN/pawn_split_sample.m: -------------------------------------------------------------------------------- 1 | function [YY,xc,NC,XX] = pawn_split_sample(X,Y,varargin) 2 | % 3 | % Split a generic input-output dataset in order to create 4 | % unconditional and conditional samples for the approximation 5 | % of PAWN sensitivity indices (Pianosi and Wagener, 2018) 6 | % 7 | % [YY,xc,NC,XX] = pawn_split_sample(X,Y) 8 | % [YY,xc,NC,XX] = pawn_split_sample(X,Y,n) 9 | % 10 | % Input: 11 | % X = set of inputs samples - matrix (N,M) 12 | % Y = set of output samples - matrix (N,1) 13 | % n = number of conditional intervals (default: 10) - scalar 14 | % 15 | % Output: 16 | % YY = output samples for the conditional CDFs - cell array (M,n) 17 | % The element Y{i,k} is the k-th subsample 18 | % of output evaluations obtained by fixing the i-th input 19 | % (or group of inputs) to its k-th conditioning interval, 20 | % and it is a matrix of size (NC,1). 21 | % xc = cell array of size (M,1). The element xc{i} is the list of 22 | % subsample centers (mean points of the conditioning intervals) 23 | % used to compute the sensitivity of factor i 24 | % and it is a matrix of size (n,1). 25 | % XX = input samples to derive the conditional samples - cell array (M,n) 26 | % The element X{i,k} is the k-th subsample 27 | % of input values where the i-th input is fixed to 28 | % the k-th conditioning interval (while other inputs vary freely), 29 | % and it is a matrix of size (NC,M) 30 | % 31 | % REFERENCES 32 | % 33 | % Pianosi, F. and Wagener, T. (2018), Distribution-based sensitivity 34 | % analysis from a generic input-output sample, Env. Mod. & Soft. 35 | 36 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 37 | % and T. Wagener at Bristol University (2015). 38 | % SAFE is provided without any warranty and for non-commercial use only. 39 | % For more details, see the Licence file included in the root directory 40 | % of this distribution. 41 | % For any comment and feedback, or to discuss a Licence agreement for 42 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 43 | % For details on how to cite SAFE in your publication, please see: 44 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 45 | 46 | %%%%%%%%%%%%%% 47 | % Check inputs 48 | %%%%%%%%%%%%%% 49 | 50 | if ~isnumeric(X) ; error('input ''X'' must be numeric'); end 51 | if ~isnumeric(Y) ; error('input ''Y'' must be numeric'); end 52 | [N,M]=size(X) ; 53 | [n,m]=size(Y) ; 54 | if N~=n; error('input ''X'' and ''Y'' must have the same number of rows'); end 55 | if m~=1; error('input ''Y'' must be a column vector'); end 56 | 57 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 58 | % Recover and check optional inputs 59 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 60 | 61 | % Set optional arguments to their default values: 62 | n = 10 ; 63 | 64 | % Recover and update optional arguments: 65 | if nargin > 2 66 | if ~isempty(varargin{1}) 67 | n = varargin{1} ; 68 | if ~isscalar(n) ; error('input ''n'' must be scalar'); end 69 | if abs(n-round(n)); error('''n'' must be integer'); end 70 | if n<1 ; error('input ''n'' must be a positive integer'); end 71 | end 72 | end 73 | 74 | %%%%%%%%%%%%% 75 | % Create sub-samples: 76 | %%%%%%%%%%%% 77 | 78 | YY = cell(M,n); 79 | XX = cell(M,n); 80 | xc = cell(1,M); 81 | NC = nan(M,n) ; 82 | for i=1:M 83 | edges = min(X(:,i)):(max(X(:,i))-min(X(:,i)))/n:max(X(:,i)) ; 84 | centers = nan(n,1) ; 85 | for k=1:n 86 | centers(k) = mean([edges(k),edges(k+1)]); 87 | if k=edges(k) & X(:,i) < edges(:,k+1); 89 | else 90 | indices = X(:,i)>=edges(k) & X(:,i) <= edges(:,k+1); 91 | end 92 | YY{i,k} = Y(indices) ; 93 | NC(i,k) = sum(indices); 94 | XX{i,k} = X(indices,:) ; 95 | 96 | end 97 | xc{i}=centers; 98 | end -------------------------------------------------------------------------------- /RSA/RSA_plot_groups.m: -------------------------------------------------------------------------------- 1 | function []= RSA_plot_groups(X,idx,Yk,varargin) 2 | % 3 | % Plotting function for Regional Sensitivity Analysis with grouping. 4 | % Plot 'Ng' CDFs of the samples in X with different colours. 5 | % (see help of RSA_indices_groups for details about RSA and references) 6 | % 7 | % Usage: 8 | % RSA_plot_groups(X,idx,Yk) 9 | % RSA_plot_groups(X,idx,Yk,n_col) 10 | % RSA_plot_groups(X,idx,Yk,n_col,X_Labels,legend_title) 11 | % 12 | % Input: 13 | % X = set of input samples - matrix (N,M) 14 | % idx = index of group to which input samples belong - vector (N,1) 15 | % Yk = range of Y in each group - vector (Ng+1,1) 16 | % n_col = number of panels per row (default: min(5,M)) - scalar 17 | % X_Labels = labels of horizontal axis - cell array (1,M) 18 | % (default: {'X1','X2',...}) 19 | % legend_title = label for legend (default: 'Y') - string 20 | 21 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 22 | % and T. Wagener at Bristol University (2015). 23 | % SAFE is provided without any warranty and for non-commercial use only. 24 | % For more details, see the Licence file included in the root directory 25 | % of this distribution. 26 | % For any comment and feedback, or to discuss a Licence agreement for 27 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 28 | % For details on how to cite SAFE in your publication, please see: 29 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 30 | 31 | fn = 'Helvetica' ; % font type of axes, labels, etc. 32 | fs = 20 ; % font size of axes, labels, etc. 33 | lw = 2 ; % line width 34 | colorscale = 'jet' ; % use this for coloured plot 35 | %colorscale = 'gray' ; % use this for black and white plot 36 | 37 | %%%%%%%%%%%%%% 38 | % Check inputs 39 | %%%%%%%%%%%%%% 40 | 41 | if ~isnumeric(X) ; error('input ''X'' must be a matrix of size (N,M)'); end 42 | if ~isnumeric(Yk) ; error('input ''Yk'' must be a vector of size (1,nb_groups+1)'); end 43 | if ~isnumeric(idx) ; error('input ''idx'' must be a vector of size (L,nb_groups)'); end 44 | [N,M]=size(X) ; 45 | [n,m]=size(Yk) ; 46 | [N2,L]=size(idx) ; 47 | if L~=1; error('input ''idx'' must be a vector of size (1,N)'); end 48 | if N~=N2; error('input ''X'' and ''idx'' must have a consistent number of rows'); end 49 | if m~=1; error('input ''Yk'' must be a column vector'); end 50 | Ng=n-1; 51 | 52 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 53 | % Recover and check optional inputs 54 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 55 | 56 | % Set optional arguments to their default values: 57 | 58 | n_col = 5 ; 59 | X_Labels = cell(1,M); for i=1:M; X_Labels{i}=['X' num2str(i)]; end 60 | legend_title = 'Y'; 61 | 62 | % Recover and update optional arguments: 63 | if nargin > 3 64 | if ~isempty(varargin{1}) 65 | n_col = varargin{1}; 66 | if ~isscalar(n_col); error('''n_col'' must be a scalar'); end 67 | end 68 | end 69 | if nargin > 4 70 | if ~isempty(varargin{2}) 71 | X_Labels = varargin{2}; 72 | if ~iscell(X_Labels); error('''X_Labels'' must be a cell array'); end 73 | if length(X_Labels)~=M; error('''X_Labels'' must have M=%d components',M); end 74 | for i=1:M; if ~ischar(X_Labels{i}); error('all components of ''X_Labels'' must be string'); end; end 75 | end 76 | end 77 | 78 | if nargin > 5 79 | if ~isempty(varargin{2}) 80 | legend_title = varargin{3}; 81 | if ~ischar(legend_title); error('''legend_title'' must be string'); end; 82 | end 83 | end 84 | 85 | 86 | %%%%%% 87 | % RSA 88 | %%%%%% 89 | 90 | % set number of columns and rows in the plot: 91 | n_col = min(floor(n_col),M) ; 92 | n_row = ceil(M/n_col) ; 93 | 94 | figure 95 | 96 | % set colour scale: 97 | clrs = feval(colorscale,Ng); 98 | 99 | for i=1:M % for each input 100 | 101 | xx = unique(sort(X(:,i))) ; 102 | 103 | for j=1:Ng % for each group 104 | 105 | % Compute empirical CDF: 106 | CDFj = empiricalcdf(X(idx==j,i),xx) ; 107 | 108 | % Plot the CFD: 109 | subplot(n_row,n_col,i); hold on 110 | plot(xx,CDFj,'color',clrs(j,:),'LineWidth',lw) 111 | end 112 | box on 113 | 114 | % Costumize axes: 115 | axis([min(X(1:N,i)),max(X(1:N,i)),0,1]) 116 | set(gca,'FontName',fn,'FontSize',fs) 117 | 118 | % x-axis label: 119 | xlabel(X_Labels{i},'FontName',fn,'FontSize',fs) 120 | 121 | % y-axis label: 122 | if mod(i,n_col) == 1 % first column 123 | ylabel('cdf','FontName',fn,'FontSize',fs) 124 | %set(gca,'YTick',[0 1]) 125 | else 126 | set(gca,'YTick',[]) 127 | end 128 | 129 | 130 | end 131 | 132 | % Add colorbar: 133 | axes('Position', [0.10 0.05 0.9 0.9], 'Visible', 'off'); 134 | for i=1:Ng+1; ctick{i}=sprintf('%1.2g',Yk(i)); end 135 | colormap(feval(colorscale,Ng)) 136 | c=colorbar('YTickLabel',ctick,'FontName',fn,'Fontsize',fs); 137 | ylabel(c,legend_title,'FontName',fn,'Fontsize',fs) 138 | 139 | -------------------------------------------------------------------------------- /RSA/RSA_plot_thres.m: -------------------------------------------------------------------------------- 1 | function [] = RSA_plot_thres(X,idxb,varargin) 2 | % 3 | % Plotting function for Regional Sensitivity Analysis. 4 | % Plot the CDF of the samples in dataset X that satisfy a given condition 5 | % ('behavioural'), and the CDF of the samples that do not satisfy 6 | % the condition ('non-bahvioural'). 7 | % (see help of RSA_indices_thres for details about RSA and references) 8 | % 9 | % Usage: 10 | % RSA_plot_thres(X,idxb) 11 | % RSA_plot_thres(X,idxb,n_col) 12 | % RSA_plot_thres(X,idxb,n_col,labels) 13 | % RSA_plot_thres(X,idxb,n_col,labels,str_legend) 14 | % 15 | % Input: 16 | % X = set of input samples - matrix (N,M) 17 | % idxb = indices of samples statisfying the condition - vector (N,1) 18 | % n_col = number of panels per row in the plot - scalar 19 | % (default: min(5,M)) 20 | % labels = labels for the horizontal axis - cell array (1,M) 21 | % (default: {' X1','X2',...}) 22 | % str_legend = text for legend - cell array (1,2) 23 | 24 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 25 | % and T. Wagener at Bristol University (2015). 26 | % SAFE is provided without any warranty and for non-commercial use only. 27 | % For more details, see the Licence file included in the root directory 28 | % of this distribution. 29 | % For any comment and feedback, or to discuss a Licence agreement for 30 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 31 | % For details on how to cite SAFE in your publication, please see: 32 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 33 | 34 | % Options for the graphic: 35 | fn = 'Helvetica' ; % font type of axes, labels, etc. 36 | %fn = 'Courier' ; 37 | fs = 20 ; % font size of axes, labels, etc. 38 | 39 | lwn = 2 ; % line width for non-behavioural records 40 | lwb = 2 ; % line width for behavioural records 41 | 42 | % Options for the colours: 43 | % You can produce a coloured plot or a black and white one 44 | % (printer-friendly). 45 | % Option 1 - coloured plot: uncomment the following 2 lines: 46 | lcn = 'b' ; % line colour for non-behavioural 47 | lcb = 'r' ; % line colour for behavioural 48 | % Option 2 - B&W plot: uncomment the following 2 lines: 49 | %lcn = [150 150 150]/256 ; % line colour 50 | %lcb = 'k' ; % line colour for behavioural 51 | 52 | 53 | %%%%%%%%%%%%%% 54 | % Check inputs 55 | %%%%%%%%%%%%%% 56 | 57 | if ~isnumeric(X) ; error('input ''X'' must be a matrix of size (N,M)'); end 58 | if ~islogical(idxb) ; error('input ''idxb'' must be a vector of N logical'); end 59 | [N,M]=size(X) ; 60 | [n,m]=size(idxb) ; 61 | if N~=n; error('input ''X'' and ''idxb'' must have the same number of rows'); end 62 | if m~=1; error('input ''idxb'' must be a column vector'); end 63 | 64 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 65 | % Recover and check optional inputs 66 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 67 | 68 | % Set optional arguments to their default values: 69 | n_col = 5 ; 70 | X_Labels = cell(1,M); for i=1:M; X_Labels{i}=['X' num2str(i)]; end 71 | str_legend={'behavioural','non-behavioural'}; 72 | 73 | % Recover and update optional arguments: 74 | if nargin > 2 75 | if ~isempty(varargin{1}) 76 | n_col = varargin{1}; 77 | if ~isscalar(n_col); error('''n_col'' must be a scalar'); end 78 | end 79 | end 80 | if nargin > 3 81 | if ~isempty(varargin{2}) 82 | X_Labels = varargin{2}; 83 | if ~iscell(X_Labels); error('''X_Labels'' must be a cell array'); end 84 | if length(X_Labels)~=M; error('''X_Labels'' must have M=%d components',M); end 85 | for i=1:M; if ~ischar(X_Labels{i}); error('all components of ''X_Labels'' must be string'); end; end 86 | end 87 | end 88 | if nargin > 4 89 | if ~isempty(varargin{3}) 90 | str_legend = varargin{3}; 91 | if ~iscell(str_legend); error('''str_legend'' must be a cell array'); end 92 | if length(str_legend)~=2; error('''str_legend'' must have 2 components'); end 93 | for i=1:2; if ~ischar(str_legend{i}); error('all components of ''str_legend'' must be string'); end; end 94 | end 95 | end 96 | 97 | 98 | %%%%%%%% 99 | % Plot 100 | %%%%%%%% 101 | 102 | n_col = min(floor(n_col),M) ; 103 | n_row = ceil(M/n_col) ; 104 | 105 | Xb = X(idxb,:) ; 106 | Xnb = X(~idxb,:) ; 107 | 108 | figure 109 | for i=1:M 110 | % Approximate behavioural and non-behavioural CDFs: 111 | xx = unique(sort(X(:,i))) ; 112 | CDFb = empiricalcdf(Xb(:,i),xx) ; 113 | CDFnb = empiricalcdf(Xnb(:,i),xx) ; 114 | % Plot CDFs: 115 | subplot(n_row,n_col,i); hold on 116 | plot(xx,CDFb,'Color',lcb,'LineWidth',lwb) 117 | plot(xx,CDFnb,'Color',lcn,'LineWidth',lwn) 118 | hold on 119 | xlabel(X_Labels{i},'FontName',fn,'FontSize',fs) 120 | set(gca,'FontName',fn,'FontSize',fs) 121 | if mod(i,n_col) == 1 % first column 122 | ylabel('cdf','FontName',fn,'FontSize',fs) 123 | end 124 | axis([min(X(1:N,i)),max(X(1:N,i)),0,1]) 125 | if i==1; 126 | if ~isempty(str_legend); legend(str_legend); end 127 | end 128 | box on 129 | 130 | % [ks,imax]=max(abs(CDFb-CDFnb)) ; 131 | % hold on 132 | % plot([xx(imax) xx(imax)],[CDFb(imax) CDFnb(imax)],'k') 133 | 134 | end 135 | -------------------------------------------------------------------------------- /VBSA/vbsa_resampling.m: -------------------------------------------------------------------------------- 1 | function [ XA, XB, XC ] = vbsa_resampling(X) 2 | % 3 | % This function implements the resampling strategy needed to build the 4 | % approximators of the first-order (main effects) and total order 5 | % sensitivity indices (e.g. Saltelli et al. 2008; 2010). 6 | % 7 | % Usage: 8 | % [ XA, XB, XC ] = vbsa_resampling(X) 9 | % 10 | % Input: 11 | % X = matrix of NX input samples - matrix (NX,M) 12 | % 13 | % Output: 14 | % XA = first N=NX/2 rows of X - matrix (N,M) 15 | % XB = last N=NX/2 rows of X - matrix (N,M) 16 | % XC = Block matrix of M 'recombinations of XA and XB - matrix (N*M,M) 17 | % XC = [ XC1 ; 18 | % XC2 ; 19 | % ... 20 | % XCM ] 21 | % Each block XCi is a (N,M) matrix whose columns are all taken from XB 22 | % exception made for i-th, which is taken from XA. 23 | % 24 | % This function is meant to be used in combination with 'vbsa_indices'. 25 | % See help of that function for more details and examples. 26 | % 27 | % REFERENCES: 28 | % 29 | % Saltelli et al. (2008), Global Sensitivity Analysis, The Primer, Wiley. 30 | % 31 | % Saltelli et al. (2010), Variance based sensitivity analysis of model 32 | % output. Design and estimator for the total sensitivity index, Computer 33 | % Physics Communications, 181, 259-270. 34 | 35 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 36 | % and T. Wagener at Bristol University (2015). 37 | % SAFE is provided without any warranty and for non-commercial use only. 38 | % For more details, see the Licence file included in the root directory 39 | % of this distribution. 40 | % For any comment and feedback, or to discuss a Licence agreement for 41 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 42 | % For details on how to cite SAFE in your publication, please see: 43 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 44 | 45 | [NX,M]=size(X); 46 | if mod(NX,2)>0; NX=NX-1; fprintf('\n WARNING: input matrix X has an odd number of rows, using the first %d rows only.\n',NX); end 47 | 48 | N = NX/2 ; 49 | XA = X( 1:N ,:) ; 50 | XB = X(N+1:2*N,:) ; 51 | XC = nan(N*M,M) ; 52 | for i=1:M 53 | Ci = XB ; Ci(:,i)=XA(:,i) ; 54 | XC((i-1)*N+1:(i-1)*N+N,:) = Ci ; 55 | end 56 | 57 | -------------------------------------------------------------------------------- /example/external/Output_samples.txt: -------------------------------------------------------------------------------- 1 | 1.1631205e-01 2 | 1.3051489e-01 3 | 8.0218387e-02 4 | 2.4144633e-01 5 | -2.7126821e-02 6 | 2.9571674e-01 7 | 2.7984643e-01 8 | 2.6551215e-01 9 | -1.0431723e-02 10 | 3.9312254e-01 11 | 2.7903872e-01 12 | 3.1379369e-01 13 | 4.5364615e-01 14 | 4.4838783e-01 15 | 4.5966400e-01 16 | -2.9193440e-01 17 | 4.9321343e-01 18 | 5.8325320e-02 19 | 1.4023161e-01 20 | 2.5977772e-01 21 | 1.7320260e-01 22 | 3.6290805e-01 23 | 1.3791312e-01 24 | -1.9802731e-02 25 | 2.1625708e-01 26 | 1.1780721e-01 27 | 2.3442844e-01 28 | -1.0597999e-01 29 | 5.5192197e-01 30 | 2.8338424e-01 31 | -9.6080385e-01 32 | -9.6340493e-01 33 | -6.9662969e-01 34 | -2.0645203e+00 35 | -9.7592733e-01 36 | 1.4443675e-01 37 | 2.0769294e-01 38 | 1.9921338e-01 39 | 2.1702408e-01 40 | 3.1152917e-01 41 | 5.7996640e-01 42 | 1.9774421e-01 43 | 3.1592147e-01 44 | 3.0678642e-01 45 | 2.9860455e-01 46 | 4.8871938e-01 47 | 2.7005647e-01 48 | 3.3264198e-01 49 | -1.3895944e-01 50 | -8.0540883e-01 51 | -3.8076452e-01 52 | -9.4708189e-02 53 | -1.3723362e-01 54 | 1.9639734e-01 55 | 4.2368577e-01 56 | 3.9414884e-01 57 | 4.2366481e-01 58 | 1.3085996e-01 59 | 2.9861643e-01 60 | 4.5166157e-01 61 | 3.7700425e-01 62 | 3.8548950e-01 63 | 3.8318786e-01 64 | 2.0305667e-01 65 | 3.2890786e-01 66 | 3.7880235e-01 67 | 4.9439053e-01 68 | 5.5928792e-01 69 | 4.9901512e-01 70 | 2.7358881e-01 71 | 4.7356567e-01 72 | 5.6651461e-01 73 | -6.8100930e-02 74 | -6.4818702e-02 75 | -1.1125241e-01 76 | 2.1273823e-01 77 | -5.9123261e-02 78 | 1.6463171e-01 79 | -2.5151724e-02 80 | 1.9376050e-01 81 | -1.9318079e-02 82 | 3.0400237e-01 83 | -1.1500091e-02 84 | 2.9548692e-02 85 | 3.7495337e-01 86 | 3.8743015e-01 87 | 3.4904562e-01 88 | 3.8378795e-01 89 | 3.7841749e-01 90 | 1.3795228e-01 91 | 3.6849755e-01 92 | 4.0111350e-01 93 | 2.5403531e-01 94 | 4.1103881e-01 95 | 3.1172113e-01 96 | 5.1723999e-01 97 | 2.5847069e-01 98 | 2.2519913e-01 99 | 1.3519336e-01 100 | 4.4227618e-01 101 | 2.6078864e-01 102 | 7.1144414e-02 103 | 4.6296096e-02 104 | 4.6874661e-02 105 | 7.2951450e-02 106 | 4.1367427e-02 107 | 9.9829748e-02 108 | 1.9898194e-01 109 | 5.8736183e-01 110 | 6.3818068e-01 111 | 5.8608063e-01 112 | 3.6913727e-01 113 | 5.7874311e-01 114 | 4.9377036e-01 115 | 1.5920560e-01 116 | 2.2379774e-01 117 | 1.5535523e-01 118 | 1.0844881e-01 119 | 4.0077821e-01 120 | 4.3604277e-01 121 | -4.4250062e-01 122 | -8.2212055e-02 123 | -4.6588974e-01 124 | 5.8762581e-01 125 | -4.5928587e-01 126 | 1.3109791e-01 127 | -6.8103486e-01 128 | -3.7641606e-01 129 | -6.4144555e-01 130 | 2.6047673e-01 131 | -6.8295681e-01 132 | 4.9035724e-01 133 | 3.6962249e-01 134 | 4.1948299e-01 135 | 2.7082536e-01 136 | 2.9465622e-01 137 | 2.1347337e-01 138 | 5.0262588e-01 139 | 1.7964711e-01 140 | 1.9962132e-01 141 | 1.6747421e-01 142 | 4.6211622e-01 143 | 1.0142275e-01 144 | 3.0581607e-01 145 | 4.7173033e-01 146 | 3.9314546e-01 147 | 4.6779934e-01 148 | 4.4489032e-01 149 | 4.9337934e-01 150 | 2.5334422e-01 151 | 3.4315225e-01 152 | 3.5009863e-01 153 | 3.5765054e-01 154 | 1.7697302e-01 155 | 3.4305672e-01 156 | -9.9648638e-02 157 | 2.7193779e-01 158 | 2.2915581e-01 159 | 2.6897923e-01 160 | 1.3956928e-01 161 | 9.1781065e-02 162 | 4.1949686e-01 163 | 3.9012932e-01 164 | 3.6328466e-01 165 | 3.1362255e-01 166 | 3.6190080e-01 167 | 4.7614132e-01 168 | 3.4362805e-01 169 | 5.5519357e-01 170 | 5.5182397e-01 171 | 5.4769365e-01 172 | 5.3789856e-01 173 | 4.6620328e-01 174 | 5.8509868e-01 175 | 3.3106001e-01 176 | 3.3074513e-01 177 | 3.7878454e-01 178 | 3.8717041e-01 179 | 3.9240615e-01 180 | 4.4358307e-01 181 | -------------------------------------------------------------------------------- /example/hbv/HBV_structure.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAFEtoolbox/SAFE-matlab/0a24bb6c708351cef8719d0ea497b38ff380f492/example/hbv/HBV_structure.pdf -------------------------------------------------------------------------------- /example/hbv/Snow_routine_structure.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAFEtoolbox/SAFE-matlab/0a24bb6c708351cef8719d0ea497b38ff380f492/example/hbv/Snow_routine_structure.pdf -------------------------------------------------------------------------------- /example/hbv/hbv_snow_objfun.m: -------------------------------------------------------------------------------- 1 | function [f,Q_sim,STATES,FLUXES] = hbv_snow_objfun(param,prec,temp,ept,flow,warmup,Case) 2 | % 3 | % This function simulates the snow accumulation/melting process 4 | % (via the function ''snow_routine'') and the rainfall-runoff process 5 | % (via the HBV model by Seibert (1997)) and returns 6 objective functions 6 | % (see Kollat et al, 2012). 7 | % 8 | % [f,Q_sim,STATES,FLUXES] = hbv_snow_objfun(param,prec,temp,ept,flow,warmup,Case) 9 | % 10 | % Input: 11 | % param = vector of model parameters - vector (1,13) 12 | % Snow routine parameters: 13 | % 1. Ts = threshold temperature [C] 14 | % 2. CFMAX = degree day factor [mm/C] 15 | % 3. CFR = refreezing factor [-] 16 | % 4. CWH = Water holding capacity of snow [-] 17 | % HBV parameters: 18 | % 5. BETA = Exponential parameter in soil routine [-] 19 | % 6. LP = evapotranspiration limit [-] 20 | % 7. FC = field capacity [mm] 21 | % 8. PERC = maximum flux from Upper to Lower Zone [mm/Dt] 22 | % 9. K0 = Near surface flow coefficient (ratio) [1/Dt] 23 | % 10. K1 = Upper Zone outflow coefficient (ratio) [1/Dt] 24 | % 11. K2 = Lower Zone outflow coefficient (ratio) [1/Dt] 25 | % 12. UZL = Near surface flow threshold [mm] 26 | % 13. MAXBAS= Flow routing coefficient [Dt] 27 | % prec = time series of precipitation - vector (T,1) 28 | % temp = time series of temperature - vector (T,1) 29 | % ept = time series of evapotranspiration - vector (T,1) 30 | % flow = time series of observed flow - vector (T,1) 31 | % warmup = number of time steps for model warm-up - scalar 32 | % Case = flag [see hbv_sim.m for more details] - scalar 33 | % 34 | % Output: 35 | % f = vector of objective functions - vector (1,6) 36 | % 1:AME, 2:NSE, 3:BIAS, 4:TRMSE, 5:SFDCE, 6:RMSE 37 | % Q_sim = time series of simulated flow - vector (T,1) 38 | % STATES = time series of simulated storages (all in mm) - matrix (T,5) 39 | % 1: water content of snowpack (snow component) 40 | % 2: water content of snowpack (liquid component) 41 | % 3: water content of soil (soil moisture) 42 | % 4. water content of upper reservoir of flow routing routine 43 | % 5. water content of lower reservoir of flow routing routine 44 | % FLUXES = time series of simulated fluxes (all in mm/Dt) - matrix (T,8) 45 | % 1: refreezing 46 | % 2: snowmelt 47 | % 3: actual evapotranspiration 48 | % 4: recharge (water flux from soil moisture accounting module 49 | % to flow routing module) 50 | % 5: percolation (water flux from upper to lower reservoir of the 51 | % flow routing module) 52 | % 6: runoff from upper reservoir 53 | % 7: runoff from lower reservoir 54 | % 55 | % References: 56 | % 57 | % Seibert,J.(1997)."Estimation of Parameter Uncertainty in the HBV Model". 58 | % Nordic Hydrology.28(4/5).247-262. 59 | % 60 | % Kollat,J.B.,Reed,P.M.,Wagener,T.(2012)."When are multiobjective 61 | % calibration trade-offs in hydrologic models meaningful?". Water resources 62 | % research,VOL.48,W03520,doi:10.1029/2011WR011534. 63 | 64 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 65 | % and T. Wagener at Bristol University (2015). 66 | % SAFE is provided without any warranty and for non-commercial use only. 67 | % For more details, see the Licence file included in the root directory 68 | % of this distribution. 69 | % For any comment and feedback, or to discuss a Licence agreement for 70 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 71 | % For details on how to cite SAFE in your publication, please see: 72 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 73 | 74 | % Comments: 75 | % * Model components: snow routine (optional)- soil moisture, upper zone 76 | % and lower routine - flow routing routine 77 | 78 | N = length(prec); 79 | STATES=nan(N+1,5); 80 | FLUXES=nan(N,7); 81 | 82 | [P,STATES(:,1:2),FLUXES(:,1:2)] = snow_routine(temp,prec,param(1:4)) ; 83 | [Q_sim,STATES(:,3:5),FLUXES(:,3:7)] = hbv_sim(P,ept,param(5:13),Case); 84 | 85 | f=zeros(1,6); 86 | 87 | Qs=Q_sim(warmup+1:end); 88 | Qo=flow(warmup+1:end); 89 | 90 | N=length(Qs); 91 | 92 | N_67=floor(N*0.67); 93 | N_33=floor(N*0.33); 94 | Qs_sort=sort(Qs); 95 | Qo_sort=sort(Qo); 96 | 97 | 98 | lambda=0.3; 99 | Zs=((1+Qs).^lambda-1)/lambda; 100 | Zo=((1+Qo).^lambda-1)/lambda; 101 | 102 | f(1)= mean(abs(Qs-Qo)); %AME 103 | f(2)= 1 - sum((Qs - Qo).^2)/sum((mean(Qo) - Qo).^2); %NSE 104 | f(3) = abs(mean(Qs - Qo)) ; %BIAS 105 | f(4)=sqrt(mean((Zs - Zo).^2)); % TRMSE 106 | f(5) = abs((Qs_sort(N_33)-Qs_sort(N_67))/(Qo_sort(N_33)-Qo_sort(N_67))-1)*100; %SFDCE 107 | f(6) = sqrt(mean((Qs - Qo).^2));%RMSE 108 | -------------------------------------------------------------------------------- /example/hbv/snow_routine.m: -------------------------------------------------------------------------------- 1 | function [P,STATES,FLUXES] = snow_routine(temp,prec,param) 2 | % 3 | % This function simulates a simple, conceptual snow accumulation/melting 4 | % model based on a degree day approach. 5 | % 6 | % Usage: 7 | % 8 | % [P,STATES,FLUXES] = snow_routine(temp,prec,param) 9 | % 10 | % Input: 11 | % temp = time series of temperature - vector (T,1) 12 | % prec = time series of precipitation - vector (T,1) 13 | % param = model parameters - vector (1,4) 14 | % 1. Ts = threshold temperature [C] 15 | % 2. CFMAX = degree day factor [mm/C] 16 | % 3. CFR = refreezing factor [-] 17 | % 4. CWH = Water holding capacity of snow [-] 18 | % 19 | % Output: 20 | % P = time series of simulated flow exiting from the - vector (T,1) 21 | % snowpack (as a result of melt-refreezing) [mm/Dt] 22 | % STATES = time series of simulated storages (all in mm) - matrix (T,2) 23 | % 1st column: water content of snowpack (snow component) 24 | % 2nd column: water content of snowpack (liquid component) 25 | % FLUXES = time series of simulated fluxes (all in mm/Dt) - matrix (T,2) 26 | % 1st column: refreezing 27 | % 2nd column: snowmelt 28 | 29 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 30 | % and T. Wagener at Bristol University (2015). 31 | % SAFE is provided without any warranty and for non-commercial use only. 32 | % For more details, see the Licence file included in the root directory 33 | % of this distribution. 34 | % For any comment and feedback, or to discuss a Licence agreement for 35 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 36 | % For details on how to cite SAFE in your publication, please see: 37 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 38 | 39 | 40 | 41 | % -------------------------- 42 | % Recover model parameters: 43 | % -------------------------- 44 | 45 | Ts = param(1); % threshold temperature [C] 46 | CFMAX = param(2); % degree day factor [mm/C] 47 | CFR = param(3); % refreezing factor [-] 48 | CWH = param(4); % Water holding capacity of snow [-] 49 | 50 | 51 | N = length(prec);% number of time samples 52 | 53 | % ---------------- 54 | % SNOWPACK ROUTINE 55 | % ---------------- 56 | 57 | P = zeros(N,1); % snowmelt leaving the snowpack/recharge to the soil [mm/Dt] 58 | 59 | rain = prec; rain(temp=Ts) = 0 ; % [mm/Dt] 61 | Ta = temp-Ts; Ta(temp=Ts) = 0 ; % Active Temperature for refreezing 63 | m = zeros(N,1); % snowmelt [mm/Dt] 64 | rfz= zeros(N,1); % refreezing [mm/Dt] 65 | v = zeros(N+1,1); % snowpack depth [mm]: solid component 66 | vl = zeros(N+1,1); % snowpack depth [mm]: liquid component 67 | 68 | for t=1:N 69 | 70 | m(t) = min(CFMAX*Ta(t),v(t)) ; 71 | rfz(t)= min(CFR*CFMAX*Tn(t) ,vl(t)) ; 72 | % snowpack dynamics: solid component 73 | v(t+1) = v(t)- m(t)+snow(t)+rfz(t); 74 | % snowpack dynamics: liquid component 75 | vl(t+1) = vl(t)+m(t)+rain(t)-rfz(t); 76 | if vl(t+1)>CWH*v(t+1) % if the liquid component exceed the snow pack 77 | % holding capacity 78 | P(t) = vl(t+1)-CWH*v(t+1) ; 79 | vl(t+1) = CWH*v(t+1) ; 80 | else 81 | P(t)=0; 82 | end 83 | end 84 | STATES=[v,vl]; 85 | FLUXES=[rfz,m]; -------------------------------------------------------------------------------- /example/hymod/Hymod_structure.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SAFEtoolbox/SAFE-matlab/0a24bb6c708351cef8719d0ea497b38ff380f492/example/hymod/Hymod_structure.pdf -------------------------------------------------------------------------------- /example/hymod/hymod_MulObj.m: -------------------------------------------------------------------------------- 1 | function [f,Q_sim,STATES,FLUXES]=hymod_MulObj(x,rain,evap,flow,warmup) 2 | % 3 | % This function runs the rainfall-runoff Hymod model 4 | % and returns 2 metrics of model performance: RMSE and BIAS 5 | % 6 | % [f,Q_sim,STATES,FLUXES] = hymod_MulObj(param,rain,evap,flow,warmup) 7 | % 8 | % Input: 9 | % param = vector of model parameters (Smax,beta,alfa,Rs,Rf) - vector (1,5) 10 | % rain = time series of rainfall - vector (T,1) 11 | % evap = time series of potential evaporation - vector (T,1) 12 | % flow = time series of observed flow - vector (T,1) 13 | % warmup = number of time steps for model warm-up - scalar 14 | % 15 | % Output: 16 | % f = vector of objective functions (RMSE,BIAS) - vector (1,2) 17 | % Q_sim = time series of simulated flow - vector (T,1) 18 | % STATES = time series of simulated storages (all in mm) - matrix (T,5) 19 | % FLUXES = time series of simulated fluxes (all in mm/Dt) - matrix (T,4) 20 | % 21 | % See also hymod_sim about the model parameters, simulated variables, 22 | % and references. 23 | 24 | 25 | M = 5 ; % number of model parameters 26 | x = x(:); 27 | if ~isnumeric(x); error('input argument ''param'' must be numeric'); end 28 | if length(x)~=M; error('input argument ''param'' must have %d components',M); end 29 | 30 | [Q_sim,STATES,FLUXES] = hymod_sim(x,rain,evap) ; 31 | 32 | Qs = Q_sim(warmup+1:end); 33 | Qo = flow(warmup+1:end); 34 | 35 | f(1) = sqrt(mean((Qs - Qo).^2)) ; % RMSE 36 | f(2) = abs(mean(Qs - Qo)) ; % BIAS 37 | 38 | 39 | -------------------------------------------------------------------------------- /example/hymod/hymod_max.m: -------------------------------------------------------------------------------- 1 | function [y,Q_sim,STATES,FLUXES] = hymod_max(x,rain,evap,warmup) 2 | % 3 | % This function runs the rainfall-runoff Hymod model 4 | % and returns the maximum flow in the simulated time series 5 | % 6 | % [y,Q_sim,STATES,FLUXES] = hymod_max(param,rain,evap,warmup) 7 | % 8 | % Input: 9 | % param = vector of model parameters (Smax,beta,alfa,Rs,Rf) - vector (1,5) 10 | % rain = time series of rainfall - vector (T,1) 11 | % evap = time series of potential evaporation - vector (T,1) 12 | % warmup = number of time steps for model warm-up - scalar 13 | % 14 | % Output: 15 | % y = maximum flow over the simulation horizon - scalar 16 | % Q_sim = time series of simulated flow - vector (T,1) 17 | % STATES = time series of simulated storages (all in mm) - matrix (T,5) 18 | % FLUXES = time series of simulated fluxes (all in mm/Dt) - matrix (T,4) 19 | % 20 | % See also hymod_sim about the model parameters, simulated variables, 21 | % and references. 22 | 23 | % y = hymod_max( x ) 24 | % 25 | % x = model parameters 26 | % y = maximum flow over the simulation horizon 27 | 28 | M = 5 ; % number of model parameters 29 | x = x(:); 30 | if ~isnumeric(x); error('input argument ''param'' must be numeric'); end 31 | if length(x)~=M; error('input argument ''param'' must have %d components',M); end 32 | 33 | [Q_sim,STATES,FLUXES] = hymod_sim(x,rain,evap) ; 34 | 35 | y = max(Q_sim(warmup+1:end)) ; 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /example/hymod/hymod_nse.m: -------------------------------------------------------------------------------- 1 | function [y,Q_sim,STATES,FLUXES] = hymod_nse(x,rain,evap,flow,warmup) 2 | % 3 | % This function runs the rainfall-runoff Hymod model 4 | % and returns the associated Nash-Sutcliffe Efficiency 5 | % 6 | % [y,Q_sim,STATES,FLUXES] = hymod_nse(param,rain,evap,flow,warmup) 7 | % 8 | % Input: 9 | % param = vector of model parameters (Smax,beta,alfa,Rs,Rf) - vector (1,5) 10 | % rain = time series of rainfall - vector (T,1) 11 | % evap = time series of potential evaporation - vector (T,1) 12 | % flow = time series of observed flow - vector (T,1) 13 | % warmup = number of time steps for model warm-up - scalar 14 | % 15 | % Output: 16 | % y = Nash-Sutcliffe Efficiency - scalar 17 | % Q_sim = time series of simulated flow - vector (T,1) 18 | % STATES = time series of simulated storages (all in mm) - matrix (T,5) 19 | % FLUXES = time series of simulated fluxes (all in mm/Dt) - matrix (T,8) 20 | % 21 | % See also hymod_sim about the model parameters, simulated variables, 22 | % and references. 23 | 24 | 25 | M = 5 ; % number of model parameters 26 | x = x(:); 27 | if ~isnumeric(x); error('input argument ''param'' must be numeric'); end 28 | if length(x)~=M; error('input argument ''param'' must have %d components',M); end 29 | 30 | [Q_sim,STATES,FLUXES] = hymod_sim(x,rain,evap) ; 31 | 32 | Qs = Q_sim(warmup+1:end); 33 | Qo = flow(warmup+1:end); 34 | 35 | y = NSE(Qs', Qo'); 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /example/hymod/hymod_sim.m: -------------------------------------------------------------------------------- 1 | function [Q_sim,STATES,FLUXES] = hymod_sim(param,prec,evap) 2 | % 3 | % This function simulates the Hymod rainfall-runoff model 4 | % (Boyle, 2001; Wagener et al., 2001). 5 | % 6 | % Usage: 7 | % 8 | % [Q_sim,STATES,FLUXES] = hymod_sim(param,prec,evap) 9 | % 10 | % param = 5 elements vector of model parameters: - vector (1,5) 11 | % 1. Sm = maximum soil moisture [mm] 12 | % 2. beta = exponent in the soil moisture 13 | % routine [-] 14 | % 3. alfa = partition coefficient [-] 15 | % 4. Rs = slow reservoir coefficient [1/Dt] 16 | % 5. Rf = fast reservoir coefficient [1/Dt] 17 | % prec = time series of rainfall - vector (T,1) 18 | % evap = time series of potential evaporation - vector (T,1) 19 | % 20 | % Q_sim = time series of simulated flow - vector (T,1) 21 | % STATES = time series of simulated states - matrix (T,5) 22 | % FLUXES = time series of simulated fluxes - matrix (T,4) 23 | % (see comments in the code for the definition of state and flux 24 | % variables) 25 | % 26 | % Recommended parameter values: Smax should fall in [0,400] (mm) 27 | % beta should fall in [0,2] (-) 28 | % alfa should fall in [0,1] (-) 29 | % Rs should fall in [0,k] (-) 30 | % Rf should fall in [k,1] (-) with 02 66 | if ~isempty(varargin{1}) 67 | nrep = varargin{1} ; 68 | if ~isscalar(nrep); error('''nrep'' must be a scalar'); end 69 | if nrep<=0; error('''nrep'' must be positive' ); end 70 | if abs(nrep-round(nrep)); error('''nrep'' must be integer'); end 71 | end 72 | end 73 | 74 | d = 0 ; 75 | 76 | % Generate nrep hypercube sample X and keep the one that maximises the 77 | % minimum inter-point Euclidean distance between any two sampled points: 78 | for k=1:nrep 79 | 80 | % Generate a latin-hypercube: 81 | ran = rand(N,M) ; 82 | Xk = zeros(N,M); 83 | for i=1:M 84 | idx=randperm(N); 85 | Xk(:,i)=(idx'-ran(:,i))/N; 86 | end 87 | 88 | % Compute the minimum distance between points in X: 89 | dk = min(pdist(Xk)) ; % Requires Statistical Toolbox 90 | % Alternative option: 91 | %dk=(ipdm(Xk,'metric',2)); dk=min(dk(dk>0)); 92 | 93 | % If the current latin hypercube has minimum distance higher than 94 | % the best so far, it will be retained as the best. 95 | if (dk > d) 96 | X = Xk ; 97 | d = dk ; 98 | end 99 | 100 | end 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /sampling/lhcube_extend.m: -------------------------------------------------------------------------------- 1 | function X_new = lhcube_extend(X,N_new,varargin) 2 | % 3 | % This function add rows to a latin hypercube using the maximin criterion. 4 | % 5 | % Usage: 6 | % X_new = lhcube_extend(X,N_new) 7 | % X_new = lhcube_extend(X,N_new,nrep) 8 | % 9 | % Input: 10 | % X = initial latin hypercube - matrix(N,M) 11 | % N_new = new dimension for the latin hypercube - scalar 12 | % nrep = number of replicate to select the best hypercube - scalar 13 | % (default value: 10) 14 | % 15 | % Output: 16 | % X_new = best latin hypercube - matrix(N_new,M) 17 | % idx_new = indices of the rows selected from X - vector(N_new,1) 18 | % [ i.e. Xnew = X(idx_new,:) ] 19 | % 20 | % Example: 21 | % 22 | % N = 30 ; 23 | % M = 2 ; 24 | % X = lhcube(N,M); % create LHS 25 | % figure(1) 26 | % plot(X(:,1),X(:,2),'x') 27 | % set(gca,'XTick',[0:1/N:1],'XTickLabel',{},'YTick',[0:1/N:1],'YTickLabel',{}) 28 | % grid on 29 | % 30 | % N_new = 40 ; 31 | % X_new = lhcube_extend(X,N_new); 32 | % figure(1); hold on 33 | % plot(X_new(:,1),X_new(:,2),'or') 34 | % 35 | % References: 36 | % 37 | % this is the matlab/octave version of the code in: 38 | % J.C. Rougier, calibrate package 39 | % http://www.maths.bris.ac.uk/~mazjcr/#software 40 | 41 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 42 | % and T. Wagener at Bristol University (2015). 43 | % SAFE is provided without any warranty and for non-commercial use only. 44 | % For more details, see the Licence file included in the root directory 45 | % of this distribution. 46 | % For any comment and feedback, or to discuss a Licence agreement for 47 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 48 | % For details on how to cite SAFE in your publication, please see: 49 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 50 | 51 | %%%%%%%%%%%%%% 52 | % Check inputs 53 | %%%%%%%%%%%%%% 54 | 55 | if ~isnumeric(X) ; error('input ''X'' must be a matrix of size (N,M)'); end 56 | [N,M]=size(X) ; 57 | if ~isscalar(N_new); error('''N_new'' must be a scalar'); end 58 | if (N_new - round(N_new))~=0 ; error('''N_new'' must be an integer'); end 59 | if N_new<=0 ; error('''N_new'' must be a positive integer'); end 60 | if N_new < N ; error('''N_new'' must be larger than ''N''');end 61 | 62 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 63 | % Recover and check optional inputs 64 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 65 | 66 | % Set optional arguments to their default values: 67 | nrep=10; 68 | 69 | % Recover and update optional arguments: 70 | if nargin > 2 71 | if ~isempty(varargin{1}) 72 | nrep = varargin{1}; 73 | if ~isscalar(nrep); error('''nrep'' must be a scalar'); end 74 | end 75 | end 76 | 77 | %%%%%%%%%%%%%% 78 | % Extend rows 79 | %%%%%%%%%%%%%% 80 | 81 | X_new=nan; 82 | ddbest=0; 83 | 84 | for i=1:nrep 85 | % Xext=lhsdesign(N_new-N,M); % requires Matlab Statistical Toolbox 86 | Xext=lhcube(N_new-N,M); 87 | Xi=[X;Xext]; 88 | dd=min(pdist(Xi)); % requires Matlab Statistical Toolbox 89 | %dd=(ipdm(Xi,'metric',2)); dd=min(dd(dd>0)); 90 | if dd>ddbest 91 | X_new=Xi; 92 | ddbest=dd; 93 | end 94 | end 95 | -------------------------------------------------------------------------------- /sampling/lhcube_shrink.m: -------------------------------------------------------------------------------- 1 | function [X_new,idx_new]=lhcube_shrink(X,N_new,varargin) 2 | % 3 | % This function drop rows from a latin hypercube using the maximin 4 | % criterion. 5 | % 6 | % Usage: 7 | % [X_new,idx_new]=lhcube_shrink(X,N_new) 8 | % [X_new,idx_new]=lhcube_shrink(X,N_new,nrep) 9 | % 10 | % 11 | % Input: 12 | % X = initial latin hypercube - matrix(N,M) 13 | % N_new = new dimension for the latin hypercube - scalar 14 | % nrep = number of replicate to select the best hypercube - scalar 15 | % (default value: 10) 16 | % 17 | % Output: 18 | % X_new = new latin hypercube - matrix(N_new,M) 19 | % idx_new = indices of the rows selected from X - vector(N_new,1) 20 | % [ i.e. Xnew = X(idx_new,:) ] 21 | % 22 | % Example: 23 | % 24 | % N = 30 ; 25 | % M = 2 ; 26 | % X = lhcube(N,M); % create LHS 27 | % figure(1) 28 | % plot(X(:,1),X(:,2),'x') 29 | % set(gca,'XTick',[0:1/N:1],'XTickLabel',{},'YTick',[0:1/N:1],'YTickLabel',{}) 30 | % grid on 31 | % 32 | % N_new = 20 ; 33 | % X_new = lhcube_shrink(X,N_new); 34 | % figure(1); hold on 35 | % plot(X_new(:,1),X_new(:,2),'or') 36 | % 37 | % References: 38 | % 39 | % this is the matlab/octave version of the code in: 40 | % J.C. Rougier, calibrate package 41 | % http://www.maths.bris.ac.uk/~mazjcr/#software 42 | % 43 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 44 | % and T. Wagener at Bristol University (2015). 45 | % SAFE is provided without any warranty and for non-commercial use only. 46 | % For more details, see the Licence file included in the root directory 47 | % of this distribution. 48 | % For any comment and feedback, or to discuss a Licence agreement for 49 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 50 | % For details on how to cite SAFE in your publication, please see: 51 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 52 | 53 | 54 | %%%%%%%%%%%%%% 55 | % Check inputs 56 | %%%%%%%%%%%%%% 57 | 58 | if ~isnumeric(X) ; error('input ''X'' must be a matrix of size (N,M)'); end 59 | [N,M]=size(X) ; 60 | if ~isscalar(N_new); error('''N_new'' must be a scalar'); end 61 | if (N_new - round(N_new))~=0 ; error('''N_new'' must be an integer'); end 62 | if N_new<=0 ; error('''N_new'' must be a positive integer'); end 63 | if N_new>N ; error('''N_new'' must be smaller than ''N''');end 64 | 65 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 66 | % Recover and check optional inputs 67 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 68 | 69 | % Set optional arguments to their default values: 70 | nrep=10; 71 | 72 | % Recover and update optional arguments: 73 | if nargin > 2 74 | if ~isempty(varargin{1}) 75 | nrep = varargin{1}; 76 | if ~isscalar(nrep); error('''nrep'' must be a scalar'); end 77 | end 78 | end 79 | 80 | %%%%%%%%%%%% 81 | % Drop rows 82 | %%%%%%%%%%%% 83 | 84 | X_new = nan ; 85 | ddbest = 0 ; 86 | idx_new = nan ; 87 | 88 | % Generate nrep subsamples of the initial latin hypercube sample X and keep 89 | % the one that maximises the minimum inter-point Euclidean distance between 90 | % any two sampled points: 91 | for i=1:nrep 92 | idx=randperm(N,N_new); 93 | Xi=X(idx,:); 94 | dd=min(pdist(Xi)); % use this if you have the Matlab Statistical Toolbox 95 | % dd=(ipdm(Xi,'metric',2)); dd=min(dd(dd>0)); 96 | if dd>ddbest 97 | X_new=Xi; 98 | idx_new=idx; 99 | ddbest=dd; 100 | end 101 | end 102 | -------------------------------------------------------------------------------- /sampling/model_execution.m: -------------------------------------------------------------------------------- 1 | function [ Y, varargout ] = model_execution(fun_test,X,varargin) 2 | % 3 | % Evaluates the model coded in the matlab function 'fun_test' against 4 | % each sample input vector in matrix X, and returns the associated output 5 | % vectors (in matrix Y). 6 | % 7 | % Usage: 8 | % 9 | % Y = model_execution(fun_test,X) 10 | % 11 | % fun_test = name of the function implementing the model (string) 12 | % X = matrix (NxM) of N input samples 13 | % (each input sample has M components) 14 | % 15 | % Y = vector (NxP) of associated output samples 16 | % (P being the number of model outputs associated to 17 | % each sampled input combination) 18 | % 19 | % NOTE: If the 'fun_test' function requires other arguments besides 'X', 20 | % or produce other output besides 'Y', they can be passed as optional 21 | % arguments after 'X' and recovered as optional output after 'Y'. 22 | % Example: 23 | % 24 | % fun_test = 'sobol_g_function' ; 25 | % X = rand(3,4) ; 26 | % a = ones(1,4) ; 27 | % Y = model_execution(fun_test,X,a) ; % Or: 28 | % [Y,V] = model_execution(fun_test,X,a) ; 29 | 30 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 31 | % and T. Wagener at Bristol University (2015). 32 | % SAFE is provided without any warranty and for non-commercial use only. 33 | % For more details, see the Licence file included in the root directory 34 | % of this distribution. 35 | % For any comment and feedback, or to discuss a Licence agreement for 36 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 37 | % For details on how to cite SAFE in your publication, please see: 38 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 39 | 40 | %%%%%%%%%%%%%% 41 | % Check inputs 42 | %%%%%%%%%%%%%% 43 | 44 | if ~ischar(fun_test); error('''fun_test'' must be a string'); end 45 | if exist(fun_test,'file')~=2; error('function ''%s'' does not exist',fun_test); end 46 | 47 | %%%%%%%%%%%%%%%%%% 48 | % Model evaluation 49 | %%%%%%%%%%%%%%%%%% 50 | 51 | NumExtraArgOut = max(nargout,1) - 1; 52 | NumExtraArgIn = length(varargin) ; 53 | 54 | if nargin > 2 55 | tmp = feval(fun_test,X(1,:),varargin{1:NumExtraArgIn}) ; 56 | else 57 | tmp = feval(fun_test,X(1,:)) ; 58 | end 59 | P = length(tmp) ; % number of model output 60 | 61 | N = size(X,1); 62 | Y = nan(N,P) ; 63 | 64 | if (NumExtraArgIn>0)&&(NumExtraArgOut>0) 65 | for j=1:N 66 | [Y(j,:),varargout{1:NumExtraArgOut}] = feval(fun_test,X(j,:),varargin{1:NumExtraArgIn}) ; 67 | end 68 | elseif (NumExtraArgIn>0)&&(NumExtraArgOut<=0) 69 | for j=1:N 70 | Y(j,:) = feval(fun_test,X(j,:),varargin{1:NumExtraArgIn}) ; 71 | end 72 | elseif (NumExtraArgIn<=0)&&(NumExtraArgOut>0) 73 | for j=1:N 74 | [Y(j,:),varargout{1:NumExtraArgOut}] = feval(fun_test,X(j,:)) ; 75 | end 76 | else 77 | for j=1:N 78 | Y(j,:) = feval(fun_test,X(j,:)) ; 79 | end 80 | end 81 | 82 | 83 | -------------------------------------------------------------------------------- /util/NSE.m: -------------------------------------------------------------------------------- 1 | function nse = NSE(y_sim,y_obs) 2 | % 3 | % Computes the Nash-Sutcliffe Efficiency (NSE) coefficient 4 | % 5 | % nse = NSE(Y_sim,y_obs) 6 | % 7 | % Y_sim = time series of modelled variable - matrix (N,T) 8 | % (N>1 different time series can be evaluated at once) 9 | % y_obs = time series of observed variable - vector (1,T) 10 | % 11 | % nse = vector of NSE coefficients - vector (N,1) 12 | % 13 | % References: 14 | % 15 | % Nash, J. E. and J. V. Sutcliffe (1970), 16 | % River flow forecasting through conceptual models part I 17 | % A discussion of principles, Journal of Hydrology, 10 (3), 282-290. 18 | 19 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 20 | % and T. Wagener at Bristol University (2015). 21 | % SAFE is provided without any warranty and for non-commercial use only. 22 | % For more details, see the Licence file included in the root directory 23 | % of this distribution. 24 | % For any comment and feedback, or to discuss a Licence agreement for 25 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 26 | % For details on how to cite SAFE in your publication, please see: 27 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 28 | 29 | [N,T] = size(y_sim) ; 30 | [M,D] = size(y_obs) ; 31 | 32 | if T~=D 33 | error('input y_sim and y_obs must have the same number of columns') 34 | end 35 | if M>1 36 | error('input y_obs must be a row vector') 37 | end 38 | 39 | Err = y_sim - repmat(y_obs,N,1) ; 40 | Err0 = y_obs - mean(y_obs) ; 41 | nse = 1 - sum(Err.^2,2) / sum(Err0.^2) ; -------------------------------------------------------------------------------- /util/RMSE.m: -------------------------------------------------------------------------------- 1 | function rmse = RMSE(y_sim,y_obs) 2 | % 3 | % Computes the Root Mean Squared Error 4 | % 5 | % rmse = RMSE(Y_sim,y_obs) 6 | % 7 | % Y_sim = time series of modelled variable - matrix (N,T) 8 | % (N>1 different time series can be evaluated at once) 9 | % y_obs = time series of observed variable - vector (1,T) 10 | % 11 | % rmse = vector of RMSE coefficients - vector (N,1) 12 | 13 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 14 | % and T. Wagener at Bristol University (2015). 15 | % SAFE is provided without any warranty and for non-commercial use only. 16 | % For more details, see the Licence file included in the root directory 17 | % of this distribution. 18 | % For any comment and feedback, or to discuss a Licence agreement for 19 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 20 | % For details on how to cite SAFE in your publication, please see: 21 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 22 | 23 | [N,T] = size(y_sim) ; 24 | [M,D] = size(y_obs) ; 25 | 26 | if T~=D 27 | error('input y_sim and y_obs must have the same number of columns') 28 | end 29 | if M>1 30 | error('input y_obs must be a row vector') 31 | end 32 | 33 | Err = y_sim - repmat(y_obs,N,1) ; 34 | rmse = sqrt(mean(Err.^2,2)) ; -------------------------------------------------------------------------------- /util/aggregate_boot_draft.m: -------------------------------------------------------------------------------- 1 | function [S_m, S_lb, S_ub] = aggregate_boot(S, varargin) 2 | % 3 | % This function computes the mean and confidence intervals of the 4 | % sensitivity indices across bootstrap resamples. 5 | % 6 | % Usage: 7 | % S_m, S_lb, S_ub = aggregate_bootstrap(S) 8 | % S_m, S_lb, S_ub = aggregate_bootstrap(S, alfa) 9 | % 10 | % Input: 11 | % S = array of sensitivity indices estimated for each - matrix(Nboot,M) 12 | % bootstrap resample 13 | % or cell array of sensitivity indices or - cell(1,R) 14 | % estimated for each bootstrap resample (array 15 | % of R matrix(Nboot, M) where S{j} are the 16 | % estimates of the sensitivity indices at the 17 | % jth sample size) 18 | % 19 | % Optional input: 20 | % alfa = significance level for the confidence - scalar 21 | % intervals estimated by bootstrapping 22 | % (default: 0.05) 23 | % 24 | % Output: 25 | % S_m = mean sensitivity indices across bootstrap - matrix(R,M) 26 | % resamples at the different sample sizes 27 | % S_lb = lower bound of sensitivity indices across - matrix(R,M) 28 | % bootstrap resamples at the different 29 | % sample sizes 30 | % S_lb = upper bound of sensitivity indices across - matrix(R,M) 31 | % bootstrap resamples at the different 32 | % sample sizes 33 | % 34 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 35 | % and T. Wagener at Bristol University (2015). 36 | % SAFE is provided without any warranty and for non-commercial use only. 37 | % For more details, see the Licence file included in the root directory 38 | % of this distribution. 39 | % For any comment and feedback, or to discuss a Licence agreement for 40 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 41 | % For details on how to cite SAFE in your publication, please see: 42 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 43 | 44 | %%%%%%%%%%%%%% 45 | % Check inputs 46 | %%%%%%%%%%%%%% 47 | if isnumeric(S) 48 | [Nboot,M] = size(S); 49 | R = 1; % number of sample sizes 50 | tmp = cell(1,1); tmp{1}=S; S=tmp ; % create cell array to simplify computations 51 | elseif iscell(S) 52 | R = length(S); 53 | [Nboot,M] = size(S{1}); 54 | else 55 | error('Wrong data type for input ''S''') 56 | end 57 | 58 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 59 | % Recover and check optional inputs 60 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 61 | if nargin > 1 62 | if ~isempty(varargin{4}) 63 | alfa=varargin{4}; 64 | if ~isscalar(alfa); error('''alfa'' must be scalar'); end 65 | if any([alfa<0,alfa>1]); error('''alfa'' must be in [0,1]' ); end 66 | end 67 | end 68 | 69 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 70 | % Compute statistics across bootstrap resamples 71 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 72 | 73 | % Initialise variables 74 | S_m = ones(R,M); 75 | S_lb = ones(R,M); 76 | S_ub = ones(R,M); 77 | 78 | for j=1:R % loop over sample sizes 79 | 80 | if Nboot>1 81 | S_m(j,:) = nanmean(S{j}) ; % bootstrap mean 82 | idx = ~isnan(S{j}(:,1)) ; 83 | if sum(idx)M; error('Input argument ''idx'' exceeds the number of columns in X'); end 60 | 61 | X_1 = X ; X_1(:,idx) = X_ref(idx) ; 62 | X_2 = repmat(X_ref,N,1) ; X_2(:,idx) = X(:,idx) ; 63 | Y_1 = nan(N,1) ; 64 | Y_2 = nan(N,1) ; 65 | for k=1:N 66 | Y_1(k) = feval(fun_test,X_1(k,:)) ; 67 | Y_2(k) = feval(fun_test,X_2(k,:)) ; 68 | end 69 | figure 70 | mY = min(min(Y),min(Y_1)) ; 71 | MY = max(max(Y),max(Y_1)) ; 72 | % 73 | subplot(121) 74 | plot(Y,Y,'r',Y,Y_1,'.k') 75 | axis([mY,MY,mY,MY]) 76 | xlabel('Y (all varying)','FontSize',fs,'FontName',fn) 77 | ylabel(['Y1 (all varying but #' int2str(idx) ')'],'FontSize',fs,'FontName',fn) 78 | set(gca,'FontSize',fs,'FontName',fn) 79 | axis square 80 | % 81 | subplot(122) 82 | plot(Y,Y,'r',Y,Y_2,'.k') 83 | axis([mY,MY,mY,MY]) 84 | xlabel('Y (all varying)','FontSize',fs,'FontName',fn) 85 | ylabel(['Y2 (only #' int2str(idx) ' varying)'],'FontSize',fs,'FontName',fn) 86 | set(gca,'FontSize',fs,'FontName',fn) 87 | axis square 88 | -------------------------------------------------------------------------------- /visualization/plot_cdf.m: -------------------------------------------------------------------------------- 1 | function [] = plot_cdf(y,varargin) 2 | % 3 | % This function plot the empirical Cumulative Distribution Function (CDF) 4 | % of a given sample (y). 5 | % 6 | % plot_cdf(y) 7 | % plot_cdf(y,Y_Label) 8 | % 9 | % y = sample variable values - matrix/vector 10 | % Y_label = label for horizontal axis - string 11 | % 12 | % NOTE: If Y includes any NaN values, the function will identify them from 13 | % the CDF. 14 | 15 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 16 | % and T. Wagener at Bristol University (2015). 17 | % SAFE is provided without any warranty and for non-commercial use only. 18 | % For more details, see the Licence file included in the root directory 19 | % of this distribution. 20 | % For any comment and feedback, or to discuss a Licence agreement for 21 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 22 | % For details on how to cite SAFE in your publication, please see: 23 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 24 | 25 | % Options for the graphic: 26 | fn = 'Helvetica' ; % font type of axes, labels, etc. 27 | %fn = 'Courier' ; 28 | fs = 20 ; % font size of axes, labels, etc. 29 | 30 | %%%%%%%%%%%%%% 31 | % Check inputs 32 | %%%%%%%%%%%%%% 33 | 34 | if ~isnumeric(y); error('''y'' must be a matrix or a vector'); end 35 | 36 | if all(isnan(y)); error('all data in ''y'' are NaN'); end 37 | if all(isinf(y)); error('all data in ''y'' are Inf'); end 38 | 39 | if any(any(isnan(y))); disp('Warning: some data in ''y'' are NaN'); end 40 | if any(any(isinf(y))); disp('Warning: some data in ''y'' are Inf'); end 41 | 42 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 43 | % Recover and check optional inputs 44 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 45 | 46 | % Set optional arguments to their default values: 47 | Y_Label = 'y' ; 48 | 49 | % Recover and update optional arguments: 50 | if nargin > 1 51 | if ~isempty(varargin{1}) 52 | Y_Label = varargin{1} ; 53 | if ~ischar(Y_Label); error('''Y_Label'' must be a string'); end; 54 | end 55 | end 56 | 57 | %%%%%%%%%%%%%%%%%%% 58 | % Produce plot 59 | %%%%%%%%%%%%%%%%%%% 60 | 61 | y = y(:) ; 62 | y = y(~isnan(y));% remove NaNs 63 | 64 | %n = length(y) ; 65 | %F = [1:n]/n ; 66 | %ys = sort(y) ; 67 | %plot(ys,F,'.-','LineWidth',2) 68 | 69 | Nmax = 5000 ; 70 | if length(y)>Nmax 71 | yi = sort(y) ; 72 | F = empiricalcdf(y,yi); 73 | plot(yi,F,'.') 74 | else 75 | yi=min(y):(max(y)-min(y))/Nmax:max(y); 76 | F = empiricalcdf(y,yi); 77 | plot(yi,F) 78 | end 79 | 80 | % Customize plot: 81 | set(gca,'FontName',fn,'FontSize',fs) 82 | xlabel(Y_Label,'FontName',fn,'FontSize',fs) 83 | ylabel('CDF','FontName',fn,'FontSize',fs) 84 | box on 85 | 86 | % Limit for horizontal axis: 87 | ym = min(y); 88 | yM = max(y); 89 | if ym==yM % (i.e., if all data have the same value) 90 | ym = ym - ym/10 ; 91 | yM = yM + yM/10 ; 92 | end 93 | axis([ym,yM,0,1]) 94 | 95 | 96 | -------------------------------------------------------------------------------- /visualization/plot_pdf.m: -------------------------------------------------------------------------------- 1 | function [fi,yi] = plot_pdf(y,varargin) 2 | % 3 | % This function plot the empirical Probability Distribution Function (PDF) 4 | % of a given sample (y). The empirical PDF is approximated by the histogram 5 | % 6 | % plot_pdf(y) 7 | % plot_pdf(y,Y_Label) 8 | % 9 | % Input: 10 | % y = sample variable values - matrix/vector % 11 | % Y_label = label for horizontal axis - string % 12 | % nbin = number of bins for histogram - scalar % 13 | % (default: min(100,length(y)/10)) % 14 | % Output: 15 | % fi = frequency of each bin - vector (1,nbin) % 16 | % yi = center of each bin - vector (1,nbin) % 17 | % 18 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 19 | % and T. Wagener at Bristol University (2015). 20 | % SAFE is provided without any warranty and for non-commercial use only. 21 | % For more details, see the Licence file included in the root directory 22 | % of this distribution. 23 | % For any comment and feedback, or to discuss a Licence agreement for 24 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 25 | % For details on how to cite SAFE in your publication, please see: 26 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 27 | 28 | % Options for the graphic: 29 | fn = 'Helvetica' ; % font type of axes, labels, etc. 30 | %fn = 'Courier' ; 31 | fs = 20 ; % font size of axes, labels, etc. 32 | 33 | %%%%%%%%%%%%%% 34 | % Check inputs 35 | %%%%%%%%%%%%%% 36 | 37 | if ~isnumeric(y); error('''y'' must be a matrix or a vector'); end 38 | 39 | if all(isnan(y)); error('all data in ''y'' are NaN'); end 40 | if all(isinf(y)); error('all data in ''y'' are Inf'); end 41 | 42 | if any(any(isnan(y))); disp('Warning: some data in ''y'' are NaN'); end 43 | if any(any(isinf(y))); disp('Warning: some data in ''y'' are Inf'); end 44 | 45 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 46 | % Recover and check optional inputs 47 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 48 | 49 | % Set optional arguments to their default values: 50 | Y_Label = 'y' ; 51 | y = y(:) ; 52 | n = length(y); 53 | nbin = max(5,min(100,n/10)); 54 | 55 | % Recover and update optional arguments: 56 | if nargin > 1 57 | if ~isempty(varargin{1}) 58 | Y_Label = varargin{1} ; 59 | if ~ischar(Y_Label); error('''Y_Label'' must be a string'); end; 60 | end 61 | end 62 | if nargin > 2 63 | if ~isempty(varargin{2}) 64 | nbin = varargin{2} ; 65 | if ~isscalar(nbin); error('''nbin'' must be scalar'); end 66 | if nbin<+1; error('''nbin'' must be >1' ); end 67 | if abs(nbin-round(nbin)); error('''nbin'' must be an integer'); end 68 | end 69 | end 70 | 71 | %%%%%%%%%%%%%%%%%%% 72 | % Produce plot 73 | %%%%%%%%%%%%%%%%%%% 74 | 75 | [ni,yi] = hist(y,nbin); 76 | fi = ni/(n*(max(y)-min(y))/nbin) ; 77 | 78 | % Limit for horizontal axis: 79 | ym = min(y); 80 | yM = max(y); 81 | if ym==yM % (i.e., if all data have the same value) 82 | ym = ym - ym/10 ; 83 | yM = yM + yM/10 ; 84 | end 85 | % 86 | % Limit for vertical axis: 87 | fm = 0 ; 88 | fM = max(fi); 89 | % if mean(fi)/std(fi)>2; % if frequency is rather constant (''flat''), 90 | % % expand the vertical axis so to highlight this: 91 | % fM = min(1,max(fi)+10*mean(fi)) ; 92 | % else 93 | % fM = min(1,max(fi)+std(fi)) ; 94 | % end 95 | 96 | % Plot: 97 | plot(yi,fi,'.-','LineWidth',2) 98 | set(gca,'FontName',fn,'FontSize',fs) 99 | axis([ym,yM,fm,fM]) 100 | xlabel(Y_Label,'FontName',fn,'FontSize',fs) 101 | ylabel('PDF','FontName',fn,'FontSize',fs) 102 | box on 103 | 104 | 105 | -------------------------------------------------------------------------------- /visualization/scatter_plots.m: -------------------------------------------------------------------------------- 1 | function scatter_plots(X,Y,varargin) 2 | % 3 | % This function produces M scatter plots, each one plotting the output 4 | % sample (Y) against one component of the input vector sample 5 | % (i.e. one column of X). 6 | % 7 | % Usage: 8 | % scatter_plots(X,Y) 9 | % scatter_plots(X,Y,n_col) 10 | % scatter_plots(X,Y,n_col,Y_Label) 11 | % scatter_plots(X,Y,n_col,Y_Label,X_Labels) 12 | % scatter_plots(X,Y,n_col,Y_Label,X_Labels,idx) 13 | % 14 | % Input: 15 | % X = set of model inputs samples - matrix (N,M) 16 | % Y = set of model output samples - vector (N,1) 17 | % n_col = number of panels per row - scalar 18 | % (default: min(5,M)) 19 | % Y_Label = label of vertical axis - string 20 | % (default: 'Y') 21 | % X_Labels = cell array of model inputs names - cell array (1,M) 22 | % (default: {'X1','X2',...,'XM'}) 23 | % idx = indices of datapoints to be highlighted - vector (N,1) 24 | % 25 | % Example: 26 | % 27 | % X = rand(100,3) ; 28 | % Y = sin(X(:,1)) + 2 * sin(X(:,2)).^2 + X(:,3).^4.*sin(X(:,1)); 29 | % scatter_plots(X,Y) 30 | % scatter_plots(X,Y,2) 31 | % scatter_plots(X,Y,[],'y') 32 | % scatter_plots(X,Y,[],'y',{'x1','x2','x3'}) 33 | % scatter_plots(X,Y,[],'y',{'x1','x2','x3'},Y>2) 34 | 35 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 36 | % and T. Wagener at Bristol University (2015). 37 | % SAFE is provided without any warranty and for non-commercial use only. 38 | % For more details, see the Licence file included in the root directory 39 | % of this distribution. 40 | % For any comment and feedback, or to discuss a Licence agreement for 41 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 42 | % For details on how to cite SAFE in your publication, please see: 43 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 44 | 45 | % Options for the graphic: 46 | fn = 'Helvetica' ; % font type of axes, labels, etc. 47 | %fn = 'Courier' ; 48 | fs = 20 ; % font size of axes, labels, etc. 49 | mt = 'o' ; % marker type 50 | mth = 'o' ; % marker type for highlighted datapoints 51 | 52 | % Options for the colours: 53 | % You can produce a coloured plot or a black and white one 54 | % (printer-friendly). 55 | % Option 1 - coloured plot: uncomment the following 4 lines: 56 | me = 'b' ; % marker edge colour 57 | meh = 'r' ; % marker edge colour for highlighted datapoints 58 | mc = 'b' ; % marker face colour 59 | mch = 'r' ; % marker face colour for highlighted datapoints 60 | % Option 2 - B&W plot: uncomment the following 4 lines: 61 | % me = [100 100 100]/256 ; % marker edge colour 62 | % meh = 'k' ; % marker edge colour for highlighted datapoints 63 | % mc = 'w' ; % marker face colour 64 | % mch = 'k' ; % marker face colour for highlighted datapoints 65 | 66 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 67 | % Check input arguments 68 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 69 | 70 | if ~isnumeric(X); error('''X'' must be a matrix of size (N,M)'); end 71 | if ~isnumeric(Y); error('''Y'' must be a vector of size (N,1)'); end 72 | [N,M]=size(X) ; 73 | [n,m]=size(Y) ; 74 | if N~=n; error('input ''X'' and ''Y'' must have the same number of rows'); end 75 | if m~=1; error('input ''Y'' must be a column vector'); end 76 | 77 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 78 | % Recover and check optional inputs 79 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 80 | 81 | % Set optional arguments to their default values: 82 | n_col = 5 ; 83 | Y_Label = 'Y' ; 84 | X_Labels = cell(1,M); for i=1:M; X_Labels{i}=['X' num2str(i)]; end 85 | idx = []; 86 | 87 | % Recover and update optional arguments: 88 | if nargin > 2 89 | if ~isempty(varargin{1}) 90 | n_col = varargin{1}; % max number of panels per row 91 | if ~isscalar(n_col); error('''n_col'' must be a scalar'); end 92 | if n_col<=0; error('''n_col'' must be positive' ); end 93 | if abs(n_col-round(n_col)); error('''n_col'' must be integer'); end 94 | end 95 | end 96 | 97 | if nargin > 3 98 | if ~isempty(varargin{2}) 99 | Y_Label = varargin{2}; 100 | if ~ischar(Y_Label); error('''Y_Label'' must be a string'); end 101 | end 102 | end 103 | 104 | if nargin > 4 105 | if ~isempty(varargin{3}) 106 | X_Labels = varargin{3}; 107 | if ~iscell(X_Labels); error('''X_Labels'' must be a cell array'); end 108 | if length(X_Labels)~=M; error('''X_Labels'' must have M=%d components',M); end 109 | for i=1:M; if ~ischar(X_Labels{i}); error('all components of ''X_Labels'' must be string'); end; end 110 | end 111 | end 112 | 113 | if nargin > 5 114 | if ~isempty(varargin{4}) 115 | idx = varargin{4}; 116 | [n,m]=size(idx) ; 117 | if N~=n; error('input ''idx'' must have the same number of rows as ''X'' and ''Y'' '); end 118 | if m~=1; error('input ''idx'' must be a column vector'); end 119 | end 120 | end 121 | 122 | 123 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 124 | % Create plot 125 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 126 | 127 | n_col = min(n_col,M) ; 128 | n_row = ceil(M/n_col) ; 129 | %figure 130 | for i=1:M 131 | 132 | subplot(n_row,n_col,i) 133 | plot( X(:,i), Y, mt , 'MarkerFaceColor', mc, 'MarkerEdgeColor', me ) 134 | xlabel(X_Labels{i},'FontSize',fs,'FontName',fn) 135 | 136 | % add axis, labels, etc. 137 | if mod(i,n_col)==1; ylabel(Y_Label,'FontSize',fs,'FontName',fn); end 138 | axis([min(X(:,i)),max(X(:,i)),min(Y)-std(Y),max(Y)+std(Y)]) 139 | set(gca,'FontSize',fs,'FontName',fn) 140 | 141 | if ~isempty(idx); 142 | hold on; plot( X(idx,i), Y(idx), mth, 'MarkerFaceColor', mch, 'MarkerEdgeColor', meh ) 143 | end 144 | 145 | end 146 | 147 | -------------------------------------------------------------------------------- /visualization/scatter_plots_col.m: -------------------------------------------------------------------------------- 1 | function scatter_plots_col(X,Y,i1,i2,varargin) 2 | % 3 | % This function produces scatter plots of X(i1) against X(i2). 4 | % The marker colour is proportional to the value of Y. 5 | % 6 | % Usage: 7 | % scatter_plots_col(X,Y,i1,i2) 8 | % scatter_plots_col(X,Y,i1,i2,marker_size) 9 | % scatter_plots_col(X,Y,i1,i2,marker_size,X_Labels) 10 | % 11 | % Input: 12 | % X = set of input samples - matrix (N,M) 13 | % Y = set of output samples - vector (N,1) 14 | % i1 = index of input on the horizontal axis - scalar 15 | % i2 = index of input on the vertical axis - scalar 16 | % marker_size = size of marker (default: 7) - scalar 17 | % X_Labels = cell array of model inputs names - cell array (1,M) 18 | % (default: {'#1','#2',...,'#M'}) 19 | % 20 | % Example: 21 | % 22 | % X = rand(100,3) ; 23 | % Y = sin(X(:,1)) + 2 * sin(X(:,2)).^2 + X(:,3).^4.*sin(X(:,1)); 24 | % scatter_plots_col(X,Y,1,2) 25 | % scatter_plots_col(X,Y,1,2,16) 26 | % scatter_plots_col(X,Y,1,2,[],{'x1','x2','x3'}) 27 | 28 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 29 | % and T. Wagener at Bristol University (2015). 30 | % SAFE is provided without any warranty and for non-commercial use only. 31 | % For more details, see the Licence file included in the root directory 32 | % of this distribution. 33 | % For any comment and feedback, or to discuss a Licence agreement for 34 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 35 | % For details on how to cite SAFE in your publication, please see: 36 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 37 | 38 | % Options for the graphic: 39 | fn = 'Helvetica' ; % font type of axes, labels, etc. 40 | %fn = 'Courier' ; 41 | fs = 20 ; % font size of axes, labels, etc. 42 | 43 | 44 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 45 | % Check input arguments 46 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 47 | 48 | if ~isnumeric(X); error('''X'' must be a matrix of size (N,M)'); end 49 | if ~isnumeric(Y); error('''Y'' must be a vector of size (N,1)'); end 50 | [N,M]=size(X) ; 51 | [n,m]=size(Y) ; 52 | if N~=n; error('input ''X'' and ''Y'' must have the same number of rows'); end 53 | if m~=1; error('input ''Y'' must be a column vector'); end 54 | 55 | if ~isscalar(i1); error('''i1'' must be a scalar'); end 56 | if i1<=0; error('''i1'' must be positive' ); end 57 | if abs(i1-round(i1)); error('''i1'' must be integer'); end 58 | if i1>M; error('input indes %d exceeds the number of columns in X',i1); end 59 | 60 | if ~isscalar(i2); error('''i2'' must be a scalar'); end 61 | if i2<=0; error('''i2'' must be positive' ); end 62 | if abs(i2-round(i2)); error('''i2'' must be integer'); end 63 | if i2>M; error('input indes %d exceeds the number of columns in X',i2); end 64 | 65 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 66 | % Recover and check optional inputs 67 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 68 | 69 | % Set optional arguments to their default values: 70 | marker_size=7; 71 | X_Labels = cell(1,M); for i=1:M; X_Labels{i}=['#' num2str(i)]; end 72 | 73 | % Recover and update optional arguments: 74 | if nargin > 4 75 | if ~isempty(varargin{1}) 76 | marker_size = varargin{1}; 77 | if ~isscalar(marker_size); error('''marker_size'' must be a scalar'); end 78 | if marker_size<=0; error('''marker_size'' must be positive' ); end 79 | if abs(marker_size-round(marker_size)); error('''marker_size'' must be integer'); end 80 | end 81 | end 82 | 83 | if nargin > 5 84 | if ~isempty(varargin{2}) 85 | X_Labels = varargin{2}; 86 | if ~iscell(X_Labels); error('''X_Labels'' must be a cell array'); end 87 | if length(X_Labels)~=M; error('''X_Labels'' must have M=%d components',M); end 88 | for i=1:M; if ~ischar(X_Labels{i}); error('all components of ''X_Labels'' must be string'); end; end 89 | end 90 | end 91 | 92 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 93 | % Create plot 94 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 95 | 96 | 97 | %figure 98 | scatter(X(:,i1),X(:,i2),marker_size,Y,'fill'); box on 99 | xlabel(X_Labels{i1},'FontSize',fs,'FontName',fn) 100 | ylabel(X_Labels{i2},'FontSize',fs,'FontName',fn) 101 | colorbar 102 | axis([min(X(:,i1)),max(X(:,i1)),min(X(:,i2)),max(X(:,i2))]) 103 | set(gca,'FontSize',fs,'FontName',fn) 104 | 105 | -------------------------------------------------------------------------------- /visualization/scatter_plots_interaction.m: -------------------------------------------------------------------------------- 1 | function [] = scatter_plots_interaction(X,Y,varargin) 2 | % 3 | % This function produces scatter plots of X(i) against X(j), 4 | % for all possible combinations of (i,j). In each plot, 5 | % the marker colour is proportional to the value of Y. 6 | % 7 | % Usage: 8 | % scatter_plots_interaction(X,Y) 9 | % scatter_plots_interaction(X,Y,ms) 10 | % scatter_plots_interaction(X,Y,ms,X_Labels) 11 | % 12 | % Input: 13 | % X = set of input samples - matrix (N,M) 14 | % Y = set of output samples - vector (N,1) 15 | % ms = marker size (default: 10) - scalar 16 | % X_Labels = cell array of model inputs names - cell array (1,M) 17 | % (default: {'#1','#2',...,'#M'}) 18 | % 19 | % Example: 20 | % 21 | % X = rand(100,3) ; 22 | % Y = sin(X(:,1)) + 2 * sin(X(:,2)).^2 + X(:,3).^4.*sin(X(:,1)); 23 | % scatter_plots_interaction(X,Y) 24 | % scatter_plots_interaction(X,Y,16) 25 | % scatter_plots_interaction(X,Y,[],{'x1','x2','x3'}) 26 | 27 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 28 | % and T. Wagener at Bristol University (2015). 29 | % SAFE is provided without any warranty and for non-commercial use only. 30 | % For more details, see the Licence file included in the root directory 31 | % of this distribution. 32 | % For any comment and feedback, or to discuss a Licence agreement for 33 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 34 | % For details on how to cite SAFE in your publication, please see: 35 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 36 | 37 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 38 | % Check input arguments 39 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 40 | 41 | if ~isnumeric(X); error('''X'' must be a matrix of size (N,M)'); end 42 | if ~isnumeric(Y); error('''Y'' must be a vector of size (N,1)'); end 43 | [N,M]=size(X) ; 44 | [n,m]=size(Y) ; 45 | if N~=n; error('input ''X'' and ''Y'' must have the same number of rows'); end 46 | if m~=1; error('input ''Y'' must be a column vector'); end 47 | 48 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 49 | % Recover and check optional inputs 50 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 51 | 52 | % Set optional arguments to their default values: 53 | ms = 10; 54 | X_Labels = cell(1,M); for i=1:M; X_Labels{i}=['#' num2str(i)]; end 55 | 56 | % Recover and update optional arguments: 57 | if nargin > 2 58 | if ~isempty(varargin{1}) 59 | ms = varargin{1}; % marker size 60 | if ~isscalar(ms); error('''ms'' must be a scalar'); end 61 | if ms<=0; error('''ms'' must be positive' ); end 62 | if abs(ms-round(ms)); error('''ms'' must be integer'); end 63 | end 64 | end 65 | if nargin > 3 66 | if ~isempty(varargin{2}) 67 | X_Labels = varargin{2}; 68 | if ~iscell(X_Labels); error('''X_Labels'' must be a cell array'); end 69 | if length(X_Labels)~=M; error('''X_Labels'' must have M=%d components',M); end 70 | for i=1:M; if ~ischar(X_Labels{i}); error('all components of ''X_Labels'' must be string'); end; end 71 | end 72 | end 73 | 74 | figure 75 | k=1; 76 | for i=1:M-1 77 | for j=i+1:M 78 | subplot(M-1,M-1,k) 79 | scatter(X(:,i),X(:,j),ms,Y,'fill'); set(gca,'XTick',[],'YTick',[]) 80 | axis([min(X(:,i)),max(X(:,i)),min(X(:,j)),max(X(:,j))]) 81 | title(['( ' X_Labels{i} ' vs ' X_Labels{j} ' )']) 82 | k=k+1; 83 | end 84 | k=k+i; 85 | end 86 | 87 | -------------------------------------------------------------------------------- /visualization/stackedbar.m: -------------------------------------------------------------------------------- 1 | function [] = stackedbar(S,varargin) 2 | % 3 | % Plot and compare N different set of indices using stacked bar plot. 4 | % 5 | % stackedbar(S) 6 | % stackedbar(S,labelinput,Y_Label) 7 | % stackedbar(S,labelinput,Y_Label,horiz_tick) 8 | % stackedbar(S,labelinput,Y_Label,horiz_tick,horiz_tick_label) 9 | % 10 | % S = set of indices (N sets, each composed of M indices) - matrix (N,M) 11 | % labelinput = names of inputs to appear in the legend - cell array (1,M) 12 | % (default: no legend) 13 | % Y_Label = label for vertical axis (default: 'Sensitivity') - string 14 | % horiz_tick = ticks for horizontal axis - vector (1,N) 15 | % (default: [1,2,...,N] ) 16 | % horiz_tick = labels for ticks of horizontal axis - cell array (1,N) 17 | % (default: {'1','2',...,'N'} ) 18 | % 19 | % Example: 20 | % S = rand(5,4); 21 | % figure; stackedbar(S) 22 | % figure; stackedbar(S,{'a','b','c','d'}) 23 | % figure; stackedbar(S,{'a','b','c','d'},'total') 24 | % figure; stackedbar(S,[],'total',[1,2,9,11,12]) 25 | % figure; stackedbar(S,[],'total',[1,2,9,11,12],{'d1','d2','d3','d4','d5'}) 26 | 27 | % This function is part of the SAFE Toolbox by F. Pianosi, F. Sarrazin 28 | % and T. Wagener at Bristol University (2015). 29 | % SAFE is provided without any warranty and for non-commercial use only. 30 | % For more details, see the Licence file included in the root directory 31 | % of this distribution. 32 | % For any comment and feedback, or to discuss a Licence agreement for 33 | % commercial use, please contact: francesca.pianosi@bristol.ac.uk 34 | % For details on how to cite SAFE in your publication, please see: 35 | % bristol.ac.uk/cabot/resources/safe-toolbox/ 36 | 37 | % Options for the graphic: 38 | fn = 'Helvetica' ; % font type of axes, labels, etc. 39 | %fn = 'Courier' ; 40 | fs = 20 ; % font size of axes, labels, etc. 41 | 42 | %%%%%%%%%%%%%% 43 | % Check inputs 44 | %%%%%%%%%%%%%% 45 | 46 | if ~isnumeric(S); error('''S'' must be a vector of size (1,M)'); end 47 | [N,M] = size(S) ; 48 | %if N~=1; error('''S'' must be a row vector'); end 49 | if M<1 ; error('''S'' must have at least one component'); end 50 | 51 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 52 | % Recover and check optional inputs 53 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 54 | 55 | % Set optional arguments to their default values: 56 | labelinput = []; 57 | Y_Label = 'Sensitivity'; 58 | horiz_tick = 1:N ; 59 | horiz_tick_label=[]; 60 | 61 | % Recover and update optional arguments: 62 | if nargin > 1 63 | if ~isempty(varargin{1}) 64 | labelinput = varargin{1}; 65 | if ~iscell(labelinput); error('''labelinput'' must be a cell array'); end 66 | if length(labelinput)~=M; error('''labelinput'' must have M=%d components',M); end 67 | for i=1:M; if ~ischar(labelinput{i}); error('all components of ''labelinput'' must be string'); end; end 68 | end 69 | end 70 | if nargin > 2 71 | if ~isempty(varargin{2}) 72 | Y_Label = varargin{2}; 73 | if ~ischar(Y_Label); error('''Y_Label'' must be a string'); end 74 | end 75 | end 76 | if nargin > 3 77 | if ~isempty(varargin{3}) 78 | horiz_tick = varargin{3}; 79 | if ~isnumeric(horiz_tick); error('''horiz_tick'' must be a vector of length N=%d',N); end 80 | if length(horiz_tick(:))~=N ; error('''horiz_tick'' must be a vector of length N=%d',N); end 81 | end 82 | end 83 | 84 | if nargin > 4 85 | if ~isempty(varargin{4}) 86 | horiz_tick_label = varargin{4}; 87 | if ~iscell(horiz_tick_label); error('''horiz_tick_label'' must be a cell array'); end 88 | if length(horiz_tick_label)~=N; error('''horiz_tick_label'' must have N=%d components',N); end 89 | for i=1:N; if ~ischar(horiz_tick_label{i}); error('all components of ''horiz_tick_label'' must be string'); end; end 90 | end 91 | end 92 | 93 | %%%%%%%%%%%%%%%%%%% 94 | % Produce plot 95 | %%%%%%%%%%%%%%%%%%% 96 | 97 | % figure 98 | bar(horiz_tick,S,'stacked') 99 | set(gca,'FontSize',fs,'XTick',horiz_tick,'XGrid','On','FontName',fn) 100 | if ~isempty(horiz_tick_label); set(gca,'XTickLabel',horiz_tick_label); end 101 | if ~isempty(labelinput); legend(labelinput); end 102 | ylabel(Y_Label,'FontSize',fs,'FontName',fn) 103 | box on 104 | 105 | -------------------------------------------------------------------------------- /workflow_dynia_hymod.m: -------------------------------------------------------------------------------- 1 | % This script provides an application example of the 2 | % dynamic identifiability analysis (DYNIA) by Wagener et at. (2003). 3 | % 4 | % MODEL AND STUDY AREA 5 | % 6 | % The model under study is the rainfall-runoff model Hymod 7 | % (see help of function hymod_sim.m for more details) 8 | % applied to the Leaf catchment in Mississipi, USA 9 | % (see header of file LeafCatch.txt for more details). 10 | % The inputs subject to SA are the 5 model parameters, 11 | % and the time-varying model output is a metric of model performance 12 | % computed over a moving window around each time step of the simulation. 13 | % 14 | % REFERENCES 15 | % 16 | % Wagener, T., McIntyre, N., Lees, M., Wheater, H., Gupta, H., 2003. 17 | % Towards reduced uncertainty in conceptual rainfall-runoff modelling: 18 | % dynamic identifiability analysis. Hydrol. Process. 17, 455-476. 19 | 20 | % This script prepared by Francesca Pianosi 21 | % University of Bristol, 2015 22 | % mail to: francesca.pianosi@bristol.ac.uk 23 | 24 | 25 | %% Step 1: Set current directory to 'my_dir' and add path to sub-folders: 26 | my_dir = pwd ; % use the 'pwd' command if you have already setup the Matlab 27 | % current directory to the SAFE directory. Otherwise, you may define 28 | % 'my_dir' manually by giving the path to the SAFE directory, e.g.: 29 | % my_dir = '/Users/francescapianosi/Documents/safe_R1.0'; 30 | 31 | cd(my_dir) 32 | addpath(genpath(my_dir)) 33 | 34 | %% Step 2 (setup the Hymod model) 35 | 36 | % Load data: 37 | load -ascii LeafCatch.txt 38 | T = 2*365 ; % length of simulation horizon 39 | rain = LeafCatch(1:T,1) ; 40 | evap = LeafCatch(1:T,2) ; 41 | flow = LeafCatch(1:T,3) ; 42 | 43 | % Define inputs: 44 | DistrFun = 'unif' ; % Parameter distribution 45 | DistrPar = { [ 0 400 ]; [ 0 2 ]; [ 0 1 ]; [ 0 0.1 ] ; [ 0.1 1 ] } ; % Parameter ranges (from literature) 46 | x_labels = {'Sm','beta','alfa','Rs','Rf'} ; 47 | M = length(DistrPar) ; % number of SA inputs (parameters) 48 | 49 | %% Step 3 (Define the model output and GSA method) 50 | 51 | % Choose the function for model simulation: 52 | simfun = 'hymod_sim' ; 53 | warmup = 30 ; % lenght of model warmup period (days) 54 | % (sensitivity indices will not be computed for the warmup period) 55 | 56 | % Choose the objective function among the 3 available options: 57 | %obj_fun = 'MAE' ; % mean( | obs-sim | ) 58 | obj_fun = 'RMSE'; % mean( (obs-sim).^2 ) 59 | %obj_fun ='BIAS'; % | mean(obs) - mean(sim) | 60 | 61 | % Define semi-length of the window for averaging performances (days): 62 | W = 10 ; 63 | % (in other words, the objective function will be computed using 2W+1 days) 64 | 65 | % Define percentage of samples that will be retained 66 | % to estimate the a posteriori frequency distribution of the parameters: 67 | perc = 10 ; % % of the input/output sample size 68 | 69 | % Define number of bins to compute the a posteriori frequency distribution: 70 | nbins = 10 ; 71 | 72 | 73 | %% Step 3 Sample inputs space and evaluate the model 74 | 75 | % Choose number of samples: 76 | N = 1000 ; 77 | 78 | % Choose sampling strategy: 79 | SampStrategy = 'lhs'; 80 | 81 | % Perform sampling: 82 | X = AAT_sampling(SampStrategy,M,DistrFun,DistrPar,N); % matrix (N,M) 83 | 84 | % Evaluate model output: 85 | Q_sim = model_execution(simfun,X,rain,evap,warmup); % matrix (N,T) holding the 86 | % time series of simulated flows 87 | Y = tv_objfun(Q_sim,flow',obj_fun,W) ; % matrix (N,T) holding the time 88 | % series of time-varying objective functions 89 | 90 | % Plot temporal pattern of objective function: 91 | figure 92 | clrs = autumn ; 93 | clrs = clrs(end:-1:1,:); 94 | colormap(clrs) 95 | imagesc(Y) 96 | xlabel('time') 97 | ylabel('model run') 98 | colorbar 99 | title(['Obj.Fun.:' obj_fun ]) 100 | % add flow: 101 | hold on 102 | Nplot = size(Y,1); % scaling factor 103 | plot(Nplot+0.5-flow/max(flow)*Nplot,'k','LineWidth',2) 104 | 105 | %% Step 4 DYNIA 106 | 107 | 108 | for i=1:M 109 | 110 | % Compute posterior probability: 111 | [ xi, fi ] = dynia_histograms(X(:,i),Y,perc,nbins) ; 112 | 113 | % Plot results: 114 | dynia_plot(xi,fi,x_labels{i},flow) ; 115 | title(['Sensitivity indices - Obj.Fun: ' obj_fun ]) 116 | 117 | end 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /workflow_eet_hbv.m: -------------------------------------------------------------------------------- 1 | % This script provides an application example of the 2 | % Elementary Effects Test to the HBV rainfall-runoff model. 3 | % Useful to learn about how to use the EET when one of the parameter takes 4 | % discrete values. 5 | % 6 | % METHOD 7 | % 8 | % see description in 'workflow_eet_hymod.m' 9 | % 10 | % MODEL AND STUDY AREA 11 | % 12 | % The model under study is the HBV rainfall-runoff model, 13 | % the inputs subject to SA are the 13 model parameters, 14 | % and the outputs for SA are a set of performance metrics. 15 | % See help of function 'hbv_snow_objfun.m' for more details 16 | % and references about the HBV model and the objective functions. 17 | % 18 | % The case study area is is the Nezinscot River at Turner center, Maine, 19 | % USA (USGS 01055500, see http://waterdata.usgs.gov/nwis/nwismap) 20 | 21 | % This script prepared by Francesca Pianosi and Fanny Sarrazin 22 | % University of Bristol, 2014 23 | % mail to: francesca.pianosi@bristol.ac.uk 24 | 25 | 26 | %% Step 1 (add paths) 27 | my_dir = pwd ; % use the 'pwd' command if you have already setup the Matlab 28 | % current directory to the SAFE directory. Otherwise, you may define 29 | % 'my_dir' manually by giving the path to the SAFE directory, e.g.: 30 | % my_dir = '/Users/francescapianosi/Documents/safe_R1.0'; 31 | 32 | % Set current directory to 'my_dir' and add path to sub-folders: 33 | cd(my_dir) 34 | addpath(genpath(my_dir)) 35 | 36 | %% Step 2 (setup the HBV model) 37 | 38 | % Load data: 39 | load 01055500.txt 40 | 41 | 42 | Case = 1; % Case=1: interflow is dominant / Case = 2: percolation is dominant 43 | warmup=365; % Model warmup period (days) 44 | 45 | date=[1948 10 1; 1953 09 30]; % 5-years simulation 46 | t_start=find(ismember(X01055500(:,1:3),date(1,:),'rows')>0); 47 | t_end =find(ismember(X01055500(:,1:3),date(2,:),'rows')>0); 48 | time =t_start:t_end; 49 | prec = X01055500(time,4); 50 | ept = X01055500(time,5); 51 | flow = X01055500(time,6); 52 | temp = mean(X01055500(time,7:8),2); 53 | 54 | X_labels = {'TS','CFMAX','CFR','CWH','BETA','LP','FC','PERC','K0','K1','K2','UZL','MAXBAS'} ; % uncertain parameters 55 | M = length(X_labels) ;% number of uncertain parameters 56 | 57 | % Parameter ranges (from Kollat et al.(2012)) 58 | xmin =[-3 0 0 0 0 0.3 1 0 0.05 0.01 0.05 0 1]; 59 | xmax =[3 20 1 0.8 7 1 2000 100 2 1 0.1 100 6]; 60 | DistrPar = cell(M,1); 61 | for i=1:M-1; DistrPar{i} = [ xmin(i) xmax(i) ] ; end 62 | DistrPar{end} = xmax(end) ; % parameter MAXBAS is an integer 63 | % Parameter distributions 64 | DistrFun = cell(1,M) ; 65 | for i=1:M-1; DistrFun{i}='unif'; end; % uniform 66 | DistrFun{end}='unid'; % discrete uniform 67 | 68 | % Define output: 69 | myfun = 'hbv_snow_objfun'; 70 | 71 | %% Step 3 (sample inputs space) 72 | 73 | r = 100 ; % Number of samples 74 | 75 | % % Option 1: use the sampling method originally proposed by Morris (1991). 76 | % % 77 | % % This requires specifying the number of levels in the uniform grid (L). 78 | % % In this specific case, because one of the parameters (MAXBAS) is 79 | % % discrete-valued, the value of 'L' must coincide with the number of 80 | % % feasible values for the discrete parameter 81 | % % (6 in this case, ranging from 1 to 6). 82 | % L = 6 ; 83 | % design_type = 'trajectory'; % (note used here but required later) 84 | % X = Morris_sampling(r,xmin,xmax,L); % (r*(M+1),M) 85 | 86 | % Option 2: Latin Hypercube sampling strategy. 87 | % 88 | % In this case, we do not need to make any specific choice for the tuning 89 | % parameters of the sampling strategy, however it may happen that during 90 | % the sampling we will get several 'warning' messages due to the fact that 91 | % the 'OAT_sampling' function checks that each consecutive sampled input 92 | % vectors differ at least by one component, and if they don't, randomly 93 | % change one of the two. 94 | SampStrategy = 'lhs' ; % Latin Hypercube 95 | design_type='radial'; % other option is 'trajectory' 96 | X = OAT_sampling(r,M,DistrFun,DistrPar,SampStrategy,design_type); 97 | 98 | %% From now on just the same as in 'workflow_eet_hymod.m'... 99 | 100 | % Step 4 (run the model) 101 | Y = model_execution(myfun,X,prec,temp,ept,flow,warmup,Case) ; 102 | 103 | % Step 5 (Computation of the Elementary effects) 104 | 105 | % Choose one among multiple outputs for subsequent analysis: 106 | Yi = Y(:,2); 107 | 108 | % Compute indices: 109 | [ mi, sigma ] = EET_indices(r,xmin,xmax,X,Yi,design_type); 110 | % Plot: 111 | EET_plot(mi, sigma,X_labels ) 112 | 113 | % Use bootstrapping to derive confidence bounds: 114 | Nboot=100; 115 | [mi, sigma, EE, mi_sd, sigma_sd, mi_lb, sigma_lb, mi_ub, sigma_ub, mi_all, sigma_all] = EET_indices(r,xmin,xmax,X,Yi,design_type,Nboot); 116 | % Plot results in the plane: 117 | EET_plot(mi,sigma,X_labels,mi_lb,mi_ub,sigma_lb,sigma_ub) 118 | 119 | % Convergence analysis: 120 | rr = [ r/10:r/10:r ] ; 121 | [m_r,s_r,m_lb_r,m_ub_r,s_lb_r,s_ub_r,m_sd_r,s_sd_r]=EET_convergence(EE,rr); 122 | % Plot: 123 | figure 124 | plot_convergence(m_r,rr*(M+1),[],[],[],'no of model evaluations','mean of EEs',X_labels) 125 | 126 | % Convergence analysis with bootstrapping: 127 | Nboot = 100; 128 | rr = [ r/5:r/5:r ] ; 129 | [m_r,s_r,m_lb_r,m_ub_r,s_lb_r,s_ub_r,m_sd_r,s_sd_r]=EET_convergence(EE,rr,Nboot); 130 | % Plot: 131 | figure 132 | plot_convergence(m_r,rr*(M+1),m_lb_r,m_ub_r,[],'no of model evaluations','mean of EEs',X_labels) 133 | -------------------------------------------------------------------------------- /workflow_external_model.m: -------------------------------------------------------------------------------- 1 | % This script provides an examples of how to use the SAFE Toolbox in 2 | % combination with a model that does not run under matlab. 3 | % 4 | % STEPS 5 | % 6 | % 1) In Matlab: use SAFE sampling functions to sample the input space. 7 | % Then save the input samples in a text file that will be passed on to the 8 | % external model. 9 | % 10 | % 2) Outside Matlab [not shown in this workflow]: run the model against 11 | % each input sample and save the corresponding output into a text file. 12 | % 13 | % 3) In Matlab: load the text file and use SAFE post-processing functions 14 | % to compute sensitivity indices. 15 | 16 | % This script prepared by Francesca Pianosi and Fanny Sarrazin 17 | % University of Bristol, 2014 18 | % mail to: francesca.pianosi@bristol.ac.uk 19 | 20 | my_dir = pwd ; % use the 'pwd' command if you have already setup the Matlab 21 | % current directory to the SAFE directory. Otherwise, you may define 22 | % 'my_dir' manually by giving the path to the SAFE directory, e.g.: 23 | % my_dir = '/Users/francescapianosi/Documents/safe_R1.0'; 24 | 25 | % Add path to sub-folders: 26 | cd(my_dir) 27 | addpath(genpath(my_dir)) 28 | 29 | %% Step 1 30 | 31 | % a) Define the input feasible space 32 | 33 | M = 5 ; % Number of inputs 34 | DistrFun = 'unif' ; % Distribution (same for all inputs) 35 | DistrPar = { [ 0 400 ]; ... 36 | [ 0 2 ]; ... 37 | [ 0 1 ]; ... 38 | [ 0 0.1 ]; ... 39 | [ 0.1 1 ] } ; % Ranges 40 | 41 | % b) Perform sampling 42 | 43 | % For instance, One-At-the-Time sampling (see workflow about EET to learn 44 | % more about available options for OAT): 45 | r = 30 ; % number of sampling points 46 | SampStrategy = 'lhs' ; % Latin Hypercube 47 | design_type = 'radial'; % Type of design 48 | X = OAT_sampling(r,M,DistrFun,DistrPar,SampStrategy,design_type); 49 | 50 | % Or, All-At-the-Time sampling (again, see workflow about RSA for more 51 | % options): 52 | SampStrategy = 'lhs' ; 53 | N = 3000 ; % Number of samples 54 | X = AAT_sampling(SampStrategy,M,DistrFun,DistrPar,N); 55 | 56 | % c) Save to file: 57 | 58 | % Choose name for the input file: 59 | file_name = 'Input_samples.txt' ; 60 | 61 | % Set current directory to the directory where the input file will be saved: 62 | cd([ my_dir '/example/external']) 63 | 64 | % Write to file: 65 | save(file_name,'X','-ascii') ; % With this command, data will be saved in 66 | % exponential notation with 8 digits. 67 | 68 | % If you don't like that format, you can use the fprintf command, e.g.: 69 | formattype = '%3.0f \t %1.2f \t %1.2f \t %1.3f \t %1.3f \n' ; 70 | fid = fopen(file_name,'w') ; 71 | fprintf(fid,formattype,X'); 72 | fclose(fid); 73 | % Or, let the function choose the 'more compact' format (but in this case 74 | % double-check that numbers in the file have the required precision): 75 | formattype = '' ; for i=1:M-1; formattype = [ formattype '%g\t' ]; end; formattype = [ formattype '%g\n' ]; 76 | fid = fopen(file_name,'w') ; 77 | fprintf(fid,formattype,X'); 78 | fclose(fid); 79 | 80 | % 'fprintf' is also useful to add an header to the file: 81 | header = 'This file created by XXX' ; 82 | formattype = '%3.0f \t %1.2f \t %1.2f \t %1.3f \t %1.3f \n' ; 83 | fid = fopen(file_name,'w') ; 84 | fprintf(fid,'%s\n',header); 85 | fprintf(fid,formattype,X'); 86 | fclose(fid); 87 | 88 | %% Step 2 89 | 90 | % Run the model outside matlab and generate the output file 91 | 92 | 93 | %% Step 3 94 | 95 | % Set current directory to the directory where the output file was saved: 96 | cd([ my_dir '/example/external']) 97 | 98 | % Output file name: 99 | output_file = 'Output_samples.txt' ; 100 | 101 | % Load data from file: 102 | Y = load(output_file,'-ascii') ; 103 | 104 | % From now on, just use all the functions in RSA, EET, VBSA, etc. 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /workflow_fast_gsobol.m: -------------------------------------------------------------------------------- 1 | % This script provides an application example of the 2 | % Fourier Amplitude Sensitivity Test (FAST). 3 | % FAST uses the Fourier decomposition of the model output 4 | % to approximates the variance-based first-order sensitivity indices. 5 | % See help of 'FAST_indices.m' for more details and references. 6 | % 7 | % In this workflow, FAST is applied to the Sobol g-function 8 | % with varying number of inputs and different parameterizations for the 9 | % function parameters not subject to SA 10 | % [see help of 'sobol_g_function.m']. 11 | % 12 | % FAST estimates are compared to those obtained by the 'conventional' 13 | % resampling approach used in Variance-Based SA 14 | % [see help of 'vbsa_indices.m']. 15 | % 16 | % This script can be used to reproduce Figure 2 in: 17 | % Saltelli and Bolado (1998), An alternative way to compute Fourier 18 | % amplitude sensitivity test (FAST), Computational Statistics & Data 19 | % Analysis, 26, 445-460. 20 | 21 | % This script prepared by Francesca Pianosi and Fanny Sarrazin 22 | % University of Bristol, 2014 23 | % mail to: francesca.pianosi@bristol.ac.uk 24 | 25 | %% Step 1: set paths 26 | 27 | my_dir = pwd ; % use the 'pwd' command if you have already setup the Matlab 28 | % current directory to the SAFE directory. Otherwise, you may define 29 | % 'my_dir' manually by giving the path to the SAFE directory, e.g.: 30 | % my_dir = '/Users/francescapianosi/Documents/safe_R1.0'; 31 | 32 | % Set current directory to 'my_dir' and add path to sub-folders: 33 | cd(my_dir) 34 | addpath(genpath(my_dir)) 35 | 36 | % Define output function: 37 | myfun = 'sobol_g_function' ; 38 | % Define input distribution and ranges: 39 | DistrFun = 'unif' ; 40 | DistrPar = [ 0 1 ]; 41 | 42 | aa = [0 1 9 99] ; % options for the (fixed) parameters 43 | MM = 5:11 ; % options for the number of inputs 44 | 45 | ms = 16; 46 | figure; hold on 47 | 48 | for param = 1:4 49 | 50 | SM = nan(length(MM),3) ; 51 | Nfast = nan(1,length(MM)) ; 52 | Nvbsa = nan(1,length(MM)) ; 53 | for m=1:length(MM) 54 | 55 | M = MM(m); 56 | a = ones(1,M)*aa(param) ; 57 | % Analytic: 58 | [ tmp, V_ex, Si_ex ] = sobol_g_function(rand(1,M),a) ; 59 | % FAST: 60 | [X,s] = FAST_sampling(DistrFun,DistrPar,M); 61 | % Run the model and compute selected model output at sampled parameter 62 | % sets: 63 | Y = model_execution(myfun,X,a) ; % size (Ns,1) 64 | [Si_fast,V_fast,A,B] = FAST_indices(Y,M) ; 65 | % VBSA: 66 | SampStrategy = 'lhs' ; 67 | Nfast(m) = length(Y) ; 68 | % Option 1: set the base sample size for VBSA in such a way that 69 | % the total number of model evaluations be the same as FAST: 70 | Nvbsa(m) = ceil(Nfast(m)/(M+2)) ; 71 | % Option 2: set the base sample size to 4096 independently by the 72 | % sample size used for FAST (as done in Saltelli and Bolado, 1998) 73 | % [THIS OPTION MAY BE TIME-CONSUMING!] 74 | % Nvbsa(m) = 4096 ; 75 | X = AAT_sampling(SampStrategy,M,DistrFun,DistrPar,2*Nvbsa(m)); 76 | [ XA, XB, XC ] = vbsa_resampling(X) ; 77 | YA = model_execution(myfun,XA,a) ; % size (N,1) 78 | YB = model_execution(myfun,XB,a) ; % size (N,1) 79 | YC = model_execution(myfun,XC,a) ; % size (N*M,1) 80 | Si_vbsa = vbsa_indices(YA,YB,YC); 81 | SM(m,:) = [ mean(Si_ex) mean(Si_vbsa) mean(Si_fast) ] ; 82 | 83 | end 84 | 85 | subplot(2,2,param); hold on 86 | % next three lines just for the legend: 87 | plot(MM(1),SM(1,1),'sk','MarkerSize',ms,'MarkerFaceColor',[126 126 126]/256); hold on 88 | plot(MM(1),SM(1,2),'^k','MarkerSize',ms,'LineWidth',2) 89 | plot(MM(1),SM(1,3),'ok','MarkerSize',ms,'LineWidth',2) 90 | % next three for plotting: 91 | plot(MM,SM(:,1),'sk','MarkerSize',ms,'MarkerFaceColor',[126 126 126]/256) 92 | plot(MM,SM(:,2),'^k','MarkerSize',ms,'LineWidth',2) 93 | plot(MM,SM(:,3),'ok','MarkerSize',ms,'LineWidth',2) 94 | % customize picture: 95 | set(gca,'XTick',MM,'XLim',[MM(1)-1,MM(end)+1],'FontSize',20) 96 | set(gca,'YLim',[-0.1,1.1]) 97 | box on 98 | xlabel('Number of inputs M','FontSize',20) 99 | ylabel('1st-order sensitivity','FontSize',20) 100 | legend('Analytic','VBSA','FAST') 101 | title(['a(i)=' num2str(aa(param)) ]) 102 | 103 | end 104 | 105 | % Plot number of model evaluations against number of inputs: 106 | figure; hold on 107 | plot(MM,Nvbsa.*(MM+2),'^k','MarkerSize',ms,'LineWidth',2) 108 | plot(MM,Nfast,'ok','MarkerSize',ms,'LineWidth',2) 109 | set(gca,'XTick',MM,'FontSize',20) 110 | xlabel('Number of inputs M','FontSize',20) 111 | ylabel('Number of model evaluations N','FontSize',20) 112 | legend('VBSA','FAST') 113 | box on 114 | grid on 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /workflow_fast_hymod.m: -------------------------------------------------------------------------------- 1 | % This script provides an application example of the 2 | % Fourier Amplitude Sensitivity Test (FAST). 3 | % FAST uses the Fourier decomposition of the model output 4 | % to approximate the variance-based first-order sensitivity indices. 5 | % See help of 'FAST_indices.m' for more details and references. 6 | % 7 | % In this workflow, FAST is applied to the rainfall-runoff Hymod model 8 | % (see help of 'hymod_sim.m' for more details) 9 | % applied to the Leaf catchment in Mississipi, USA 10 | % (see header of file LeafCatch.txt for more details). 11 | % The inputs subject to SA are the 5 model parameters, and the scalar 12 | % output for SA is a performance metric. 13 | % 14 | % FAST estimates are compared to those obtained by the 'conventional' 15 | % resampling approach used in Variance-Based SA 16 | % [see help of 'vbsa_indices.m']. 17 | 18 | % This script prepared by Francesca Pianosi and Fanny Sarrazin 19 | % University of Bristol, 2014 20 | % mail to: francesca.pianosi@bristol.ac.uk 21 | 22 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 23 | % Step 1: set paths 24 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 25 | 26 | my_dir = pwd ; % use the 'pwd' command if you have already setup the Matlab 27 | % current directory to the SAFE directory. Otherwise, you may define 28 | % 'my_dir' manually by giving the path to the SAFE directory, e.g.: 29 | % my_dir = '/Users/francescapianosi/Documents/safe_R1.0'; 30 | 31 | % Set current directory to 'my_dir' and add path to sub-folders: 32 | cd(my_dir) 33 | addpath(genpath(my_dir)) 34 | 35 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 36 | % Step 2: setup the model and define input ranges 37 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 38 | 39 | % Load data: 40 | addpath([ my_dir '/example/hymod']) 41 | load -ascii LeafCatch.txt 42 | rain = LeafCatch(1:365,1) ; 43 | evap = LeafCatch(1:365,2) ; 44 | flow = LeafCatch(1:365,3) ; 45 | 46 | % Number of uncertain parameters subject to SA: 47 | M = 5 ; 48 | % Parameter ranges (from literature): 49 | xmin = [ 0 0 0 0 0.1 ]; 50 | xmax = [400 2 1 0.1 1 ]; 51 | % Parameter distributions: 52 | DistrFun = 'unif' ; 53 | DistrPar = cell(M,1); 54 | for i=1:M; DistrPar{i} = [ xmin(i) xmax(i) ] ; end 55 | % Name of parameters (will be used to costumize plots): 56 | X_labels = {'Sm','beta','alfa','Rs','Rf'} ; 57 | % Define output: 58 | myfun = 'hymod_nse' ; 59 | warmup = 30 ; % lenght of model warmup period (days) 60 | % (sensitivity indices will not be computed for the warmup period) 61 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 62 | % Step 3: approximate first-order sensitivity indices by FAST 63 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 64 | 65 | % FAST sampling: 66 | [X,s] = FAST_sampling(DistrFun,DistrPar,M); 67 | 68 | % Run the model and compute model output at sampled parameter sets: 69 | Y = model_execution(myfun,X,rain,evap,flow,warmup) ; 70 | 71 | % Estimate indices: 72 | Si_fast = FAST_indices(Y,M) ; 73 | 74 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 75 | % Step 4: Convergence analysis 76 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 77 | 78 | % The 'FAST_sampling' function used above automatically set the sample size 79 | % to the minimum possible given the number M of inputs (see help of 80 | % FAST_sampling to learn about this). In our case this is: 81 | N_fast = length(Y) ; 82 | 83 | % We can now assess whether FAST estimates would change if using a larger 84 | % number of samples: 85 | NNfast = [N_fast:1000:N_fast+5000] ; 86 | Si_fast_conv = nan(length(NNfast),M) ; 87 | Si_fast_conv(1,:) = Si_fast ; 88 | for n=2:length(NNfast) 89 | [Xn,sn] = FAST_sampling(DistrFun,DistrPar,M,NNfast(n)); 90 | Yn = model_execution(myfun,Xn,rain,evap,flow,warmup) ; 91 | Si_fast_conv(n,:) = FAST_indices(Yn,M) ; 92 | end 93 | % Plot results: 94 | figure 95 | plot_convergence(Si_fast_conv,NNfast,[],[],[],'model evals','1st-order sensitivity',X_labels) 96 | 97 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 98 | % Step 5: Comparison with VBSA 99 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 100 | 101 | % Here we compare FAST estimates with those obtained by the 'conventional' 102 | % resampling approach used in Variance-Based SA 103 | % [see help of 'vbsa_indices.m']. 104 | 105 | addpath([ my_dir '/vbsa']) 106 | 107 | % Set the base sample size for VBSA in such a way that 108 | % the total number of model evaluations be the same as FAST: 109 | Nvbsa = ceil(max(NNfast)/(M+2)) ; 110 | % VBSA sampling: 111 | SampStrategy = 'lhs' ; 112 | X = AAT_sampling(SampStrategy,M,DistrFun,DistrPar,2*Nvbsa); 113 | [ XA, XB, XC ] = vbsa_resampling(X) ; 114 | % Run the model and compute model output at sampled parameter sets: 115 | YA = model_execution(myfun,XA,rain,evap,flow,warmup) ; 116 | YB = model_execution(myfun,XB,rain,evap,flow,warmup) ; 117 | YC = model_execution(myfun,XC,rain,evap,flow,warmup) ; 118 | % Use output samples to estimate the indices at different sub-sample sizes: 119 | NNvbsa = floor(NNfast/(M+2)) ; 120 | Si_vbsa_conv = vbsa_convergence([YA;YB;YC],M,NNvbsa); 121 | 122 | % Compare 123 | xm = min(NNfast(1),NNvbsa(1)*(M+2)); 124 | xM = max(NNfast(end),NNvbsa(end)*(M+2)) ; 125 | ym = -0.1 ; 126 | yM = 1.1 ; 127 | figure 128 | subplot(211); plot_convergence(Si_fast_conv,NNfast ,[],[],[],'model evals','FAST',X_labels) 129 | axis([xm,xM,ym,yM]) 130 | subplot(212); plot_convergence(Si_vbsa_conv,NNvbsa*(M+2),[],[],[],'model evals','VBSA',X_labels); 131 | axis([xm,xM,ym,yM]) 132 | 133 | -------------------------------------------------------------------------------- /workflow_glue_hymod.m: -------------------------------------------------------------------------------- 1 | % This script provides an application example of the Generalized Likelihood 2 | % Uncertainty Estimation (GLUE) method (see help GLUE.m for more details 3 | % about this Uncertainty Analysis method and references). 4 | % 5 | % MODEL AND STUDY AREA 6 | % 7 | % The model under study is the rainfall-runoff model Hymod 8 | % (see help of function hymod_sim.m for more details) 9 | % applied to the Leaf catchment in Mississipi, USA 10 | % (see header of file LeafCatch.txt for more details). 11 | % The inputs subject to SA are the 5 model parameters, and the scalar 12 | % output for SA is (one or multiple) performance metric. 13 | 14 | % This script prepared by Francesca Pianosi and Fanny Sarrazin 15 | % University of Bristol, 2014 16 | % mail to: francesca.pianosi@bristol.ac.uk 17 | 18 | my_dir = pwd ; % use the 'pwd' command if you have already setup the Matlab 19 | % current directory to the SAFE directory. Otherwise, you may define 20 | % 'my_dir' manually by giving the path to the SAFE directory, e.g.: 21 | % my_dir = '/Users/francescapianosi/Documents/safe_R1.0'; 22 | 23 | % Set current directory to 'my_dir' and add path to sub-folders: 24 | cd(my_dir) 25 | addpath(genpath(my_dir)) 26 | 27 | % Load data: 28 | load -ascii LeafCatch.txt 29 | rain = LeafCatch(1:365,1) ; 30 | evap = LeafCatch(1:365,2) ; 31 | flow = LeafCatch(1:365,3) ; 32 | 33 | % Plot data: 34 | figure 35 | subplot(311) 36 | plot(rain) 37 | subplot(312) 38 | plot(evap) 39 | subplot(313) 40 | plot(flow) 41 | xlabel('time (days)') 42 | 43 | %%%% EXPERIMENT SETUP 44 | 45 | M = 5 ; % number of uncertain parameters [ Sm beta alfa Rs Rf ] 46 | DistrFun = 'unif' ; % Parameter distribution 47 | % Parameter ranges: 48 | xmin = [ 0 0 0 0 0.1 ] ; % minimum values 49 | xmax = [ 400 2 1 0.1 1 ] ; % maximum values 50 | 51 | %%%% SAMPLING INPUT SPACE 52 | 53 | % Sample the input space using the 'AAT_sampling' function 54 | % (see help AAT_sampling.m for more details) 55 | 56 | addpath('sampling') 57 | 58 | SampStrategy = 'lhs' ; % sampling strategy (other options is 'rsu') 59 | N = 3000 ; % sample size 60 | % Create data structure for parameter ranges 61 | % as required by AAT_sampling 62 | for i=1:M; DistrPar{i} = [xmin(i) xmax(i) ] ; end % this is to resort to 63 | % the format required by AAT_sampling function. 64 | % Perform sampling: 65 | X = AAT_sampling(SampStrategy,M,DistrFun,DistrPar,N); 66 | % Plot results (for instance samples of param.1 vs param. 2): 67 | figure; plot(X(:,1),X(:,2),'ob') 68 | 69 | %%%% MODEL EVALUATION 70 | 71 | % Define output function: 72 | myfun = 'hymod_sim' ; 73 | % (in the first place we just want to simulate the model and look at the 74 | % time series of simulated flows) 75 | warmup = 30 ; % lenght of model warmup period (days) 76 | % (sensitivity indices will not be computed for the warmup period) 77 | 78 | % Run the model and compute selected model output at sampled parameter 79 | % sets: 80 | Qsim = model_execution(myfun,X,rain,evap,warmup) ; 81 | % Check size of 'Qsim': 82 | size(Qsim) 83 | 84 | % Plot simulated time series: 85 | figure 86 | plot(Qsim','b') 87 | hold on; plot(flow,'ok') % add flow observations as black circles 88 | xlabel('time (days)'); ylabel('flow (m3/s)') 89 | 90 | %%%% GLUE 91 | 92 | % Find 'behavioural' parameterizations and associated prediction limits 93 | % by the 'GLUE' function 94 | % (see help GLUE.m for more details) 95 | 96 | addpath('GLUE') 97 | 98 | % Compute Root Mean Squared Error for each time series: 99 | Y = RMSE(Qsim,flow') ; 100 | % Check size of 'Y': 101 | size(Y) 102 | 103 | % Plot the distribution of the output samples: 104 | figure 105 | plot_cdf(Y,'RMSE (m3/s)') 106 | 107 | % Apply GLUE 108 | threshold = 2.5 ; % threshold value 109 | % (tip: make sure the sign of 'Y' and 'threshold' is consistent 110 | % with the inequality assumption (above/below threshold) 111 | % of the GLUE function) 112 | [ idx, Llim, Ulim ] = GLUE(Y,threshold,Qsim) ; 113 | 114 | % Plot 'behavioural' time series: 115 | figure 116 | plot(Qsim','b') 117 | hold on 118 | plot(Qsim(idx,:)','r') 119 | plot(flow,'ok') 120 | xlabel('time (days)'); ylabel('flow (m3/s)') 121 | 122 | % Plot prediction limits by GLUE: 123 | figure 124 | plot([Llim Ulim],'m','LineWidth',2) 125 | hold on 126 | plot(flow,'ok') 127 | xlabel('time (days)'); ylabel('flow (m3/s)') 128 | 129 | %%%% VISUALIZATION TOOLS 130 | 131 | % Use some visualization functions to gain further insights 132 | % (see help scatter_plots.m 133 | % and help parcoor.m) 134 | 135 | % Scatter plots: 136 | figure 137 | scatter_plots(X,Y) 138 | % customize the plot: 139 | X_Labels = {'Sm','beta','alfa','Rs','Rf'} ; 140 | figure 141 | scatter_plots(X,Y,[],'RMSE',X_Labels) 142 | % Highlight 'behavioural parameterizations' in different colour: 143 | figure 144 | scatter_plots(X,Y,[],'RMSE',X_Labels,idx) 145 | 146 | % Parallel coordinate plots: 147 | parcoor(X,X_Labels,[],idx); 148 | 149 | 150 | -------------------------------------------------------------------------------- /workflow_pawn_hymod.m: -------------------------------------------------------------------------------- 1 | % This script provides an application example 2 | % of the PAWN sensitivity analysis approach (Pianosi and Wagener, 2015) 3 | % 4 | % MODEL AND STUDY AREA 5 | % 6 | % The model under study is the rainfall-runoff model Hymod 7 | % (see help of function hymod_sim.m for more details) 8 | % applied to the Leaf catchment in Mississipi, USA 9 | % (see header of file LeafCatch.txt for more details). 10 | % The inputs subject to SA are the 5 model parameters, and the scalar 11 | % output for SA is a statistic of the simulated time series 12 | % (e.g. the maximum flow over the simulation horizon) 13 | % 14 | % REFERENCES 15 | % 16 | % Pianosi, F. and Wagener, T. (2015), A simple and efficient method 17 | % for global sensitivity analysis based on cumulative distribution 18 | % functions, Env. Mod. & Soft., 67, 1-11. 19 | 20 | % This script prepared by Francesca Pianosi and Fanny Sarrazin 21 | % University of Bristol, 2015 22 | % mail to: francesca.pianosi@bristol.ac.uk 23 | 24 | %% Step 1: Add paths 25 | 26 | my_dir = pwd ; % use the 'pwd' command if you have already setup the Matlab 27 | % current directory to the SAFE directory. Otherwise, you may define 28 | % 'my_dir' manually by giving the path to the SAFE directory, e.g.: 29 | % my_dir = '/Users/francescapianosi/Documents/safe_R1.0'; 30 | 31 | % Set current directory to 'my_dir' and add path to sub-folders: 32 | cd(my_dir) 33 | addpath(genpath(my_dir)) 34 | 35 | %% Step 2: setup the Hymod model 36 | load -ascii LeafCatch.txt 37 | rain = LeafCatch(1:730,1) ; 38 | evap = LeafCatch(1:730,2) ; 39 | flow = LeafCatch(1:730,3) ; 40 | warmup = 30; % model warmup period days 41 | 42 | % Define uncertain inputs (parameters): 43 | M = 5 ; % number of inputs 44 | labelparams={ 'SM','beta','alfa','Rs','Rf' } ; % input names 45 | % parameter ranges: 46 | xmin = [ 0 0 0 0 0.1 ]; 47 | xmax = [400 2 1 0.1 1 ]; 48 | distrpar=cell(M,1); for i=1:M; distrpar{i}=[xmin(i) xmax(i)]; end 49 | 50 | % Define model output: 51 | fun_test = 'hymod_max'; 52 | 53 | %% Step 3: Apply PAWN 54 | 55 | NU = 150 ; % number of samples to estimate unconditional CDF 56 | NC = 100 ; % number of samples to estimate conditional CDFs 57 | n = 10 ; % number of conditioning points 58 | 59 | % Create input/output samples to estimate the unconditional output CDF: 60 | Xu = AAT_sampling('lhs',M,'unif',distrpar,NU); % matrix (NU,M) 61 | Yu = model_execution(fun_test,Xu,rain,evap,warmup) ; % vector (1,M) 62 | 63 | % Create input/output samples to estimate the conditional output CDFs: 64 | [ XX, xc ] = pawn_sampling('lhs',M,'unif',distrpar,n,NC); 65 | YY = pawn_model_execution(fun_test,XX,rain,evap,warmup) ; 66 | 67 | % Estimate unconditional and conditional CDFs: 68 | [ YF, Fu, Fc ] = pawn_cdfs(Yu,YY) ; 69 | 70 | % Plot CDFs: 71 | figure 72 | for i=1:M 73 | subplot(1,M,i) 74 | pawn_plot_cdf(YF, Fu, Fc(i,:),[],'y (max flow)') 75 | end 76 | 77 | % Further analyze CDF of one input: 78 | i = 3 ; 79 | figure; 80 | pawn_plot_cdf(YF, Fu, Fc(i,:),xc{i},'y (max flow)',labelparams{i}) % same 81 | % function as before but exploiting more optional input arguments 82 | 83 | % Compute KS statistics: 84 | KS = pawn_ks(YF,Fu,Fc) ; 85 | 86 | % Plot KS statistics: 87 | figure 88 | for i=1:M 89 | subplot(1,M,i) 90 | pawn_plot_kstest(KS(:,i),NC,NU,0.05,xc{i},labelparams{i}) 91 | end 92 | 93 | % Compute PAWN index by taking a statistic of KSs (e.g. max): 94 | Pi = max(KS); 95 | 96 | % Plot: 97 | figure 98 | boxplot1(Pi,labelparams) 99 | 100 | % Use bootstrapping to assess robustness of PAWN indices: 101 | stat = 'max' ; % statistic to be applied to KSs 102 | Nboot = 100 ; % number of boostrap resamples 103 | [ T_m, T_lb, T_ub ] = pawn_indices(Yu,YY,stat,[],Nboot); 104 | 105 | % Plot: 106 | figure; boxplot1(T_m,labelparams,[],T_lb,T_ub) 107 | 108 | % Convergence analysis: 109 | stat = 'max' ; % statistic to be applied to KSs 110 | NCb = [ NC/10 NC/2 NC ] ; 111 | NUb = [ NU/10 NU/2 NU ] ; 112 | 113 | [ T_m_n, T_lb_n, T_ub_n ] = pawn_convergence( Yu, YY, stat, NUb, NCb,[],Nboot ); 114 | NN = NUb+n*NCb ; 115 | figure; plot_convergence(T_m_n,NN,T_lb_n,T_ub_n,[],'no of evals',[],labelparams) 116 | 117 | %% Step 4: Apply PAWN to sub-region of the output range 118 | 119 | % Compute the PAWN index over a sub-range of the output distribution, for 120 | % instance only output values above a given threshold 121 | thres = 50 ; 122 | [ T_m2, T_lb2, T_ub2 ]= pawn_indices( Yu, YY, stat,[], Nboot,[],'above',thres ) ; 123 | 124 | % Plot: 125 | figure; boxplot1(T_m2,labelparams,[],T_lb2,T_ub2) 126 | 127 | 128 | -------------------------------------------------------------------------------- /workflow_rsa_hymod.m: -------------------------------------------------------------------------------- 1 | % This script provides an application example of Regional Sensitivity 2 | % Analysis (RSA) 3 | % 4 | % METHODS 5 | % 6 | % This script provides an example of application of Regional Sensitivity 7 | % Analysis (RSA). RSA is applied in two different ways: 8 | % 9 | % - according to the original formulation 10 | % where the input samples are split into two datasets depending on whether 11 | % the corresponding output satisfies a threshold condition 12 | % >> matlab functions: RSA_indices_thres, RSA_plot_thres, RSA_convergence_thres 13 | % (see help of 'RSA_indices_thres' for more details and references) 14 | % 15 | % - splitting the input samples into 'ngroup' datasets corresponding to 16 | % equally spaced ranges of the output 17 | % >> matlab functions: RSA_indices_groups, RSA_plot_groups, RSA_convergence_groups 18 | % (see help of 'RSA_indices_groups' for more details and references) 19 | % 20 | % MODEL AND STUDY AREA 21 | % 22 | % The model under study is the rainfall-runoff model Hymod 23 | % (see help of function hymod_sim.m for more details) 24 | % applied to the Leaf catchment in Mississipi, USA 25 | % (see header of file LeafCatch.txt for more details). 26 | % The inputs subject to SA are the 5 model parameters, and the scalar 27 | % output for SA is (one or multiple) performance metric. 28 | % 29 | % INDEX 30 | % 31 | % Steps: 32 | % 1. Add paths to required directories 33 | % 2. Load data and set-up the Hymod model 34 | % 3. Sample inputs space 35 | % 4. Run the model against input samples 36 | % 5a. Perform RSA with thresholds 37 | % or 38 | % 5b. Perform RSA with groups 39 | 40 | % This script prepared by Francesca Pianosi and Fanny Sarrazin 41 | % University of Bristol, 2014 42 | % mail to: francesca.pianosi@bristol.ac.uk 43 | 44 | %% Step 1 (add paths) 45 | my_dir = pwd ; % use the 'pwd' command if you have already setup the Matlab 46 | % current directory to the SAFE directory. Otherwise, you may define 47 | % 'my_dir' manually by giving the path to the SAFE directory, e.g.: 48 | % my_dir = '/Users/francescapianosi/Documents/safe_R1.0'; 49 | 50 | % Set current directory to 'my_dir' and add path to sub-folders: 51 | cd(my_dir) 52 | addpath(genpath(my_dir)) 53 | 54 | %% Step 2 (setup the Hymod model) 55 | 56 | % Load data: 57 | load -ascii LeafCatch.txt 58 | rain = LeafCatch(1:365,1) ; 59 | evap = LeafCatch(1:365,2) ; 60 | flow = LeafCatch(1:365,3) ; 61 | 62 | % Define inputs: 63 | DistrFun = 'unif' ; % Parameter distribution 64 | DistrPar = { [ 0 400 ]; [ 0 2 ]; [ 0 1 ]; [ 0 0.1 ] ; [ 0.1 1 ] } ; % Parameter ranges (from literature) 65 | x_labels = {'Sm','beta','alfa','Rs','Rf'} ; 66 | 67 | % Define output: 68 | myfun = 'hymod_MulObj' ; 69 | warmup = 30 ; % lenght of model warmup period (days) 70 | % (sensitivity indices will not be computed for the warmup period) 71 | %% Step 3 (sample inputs space) 72 | SampStrategy = 'lhs' ; % Latin Hypercube 73 | N = 3000 ; % Number of samples 74 | M = length(DistrPar) ; % Number of inputs 75 | X = AAT_sampling(SampStrategy,M,DistrFun,DistrPar,N); 76 | 77 | %% Step 4 (run the model) 78 | Y = model_execution(myfun,X,rain,evap,flow) ; 79 | 80 | %% Step 5a (Regional Sensitivity Analysis with threshold) 81 | 82 | % Visualize input/output samples (this may help finding a reasonable value 83 | % for the output threshold): 84 | figure; scatter_plots(X,Y(:,1),[],'rmse',x_labels) ; 85 | figure; scatter_plots(X,Y(:,2),[],'bias',x_labels) ; 86 | 87 | % Set output threshold: 88 | rmse_thres = 3 ; % threshold for the first obj. fun. 89 | bias_thres = 0.5 ; % behavioural threshold for the second obj. fun. 90 | 91 | % RSA (find behavioural parameterizations): 92 | threshold = [ rmse_thres bias_thres ] ; 93 | [mvd,idxb] = RSA_indices_thres(X,Y,threshold) ; 94 | 95 | % Highlight the behavioural parameterizations in the scatter plots: 96 | figure; scatter_plots(X,Y(:,1),[],'rmse',x_labels,idxb) ; 97 | figure; scatter_plots(X,Y(:,2),[],'bias',x_labels,idxb) ; 98 | 99 | % Plot parameter CDFs: 100 | RSA_plot_thres(X,idxb,[],x_labels,{'behav','non-behav'}); % add legend 101 | 102 | % Check the ranges of behavioural parameterizations by 103 | % Parallel coordinate plot: 104 | parcoor(X,x_labels,[],idxb) 105 | 106 | % Plot the sensitivity indices (maximum vertical distance between 107 | % parameters CDFs): 108 | figure; boxplot1(mvd,x_labels,'mvd') 109 | 110 | % Assess robustness by bootstrapping: 111 | Nboot = 100; 112 | [mvd,idxb,mvd_lb,mvd_ub] = RSA_indices_thres(X,Y,threshold,[],Nboot); 113 | % Plot results: 114 | boxplot1(mvd,x_labels,'mvd',mvd_lb,mvd_ub) 115 | 116 | % Repeat computations using an increasing number of samples so to assess 117 | % convergence: 118 | NN = [ N/5:N/5:N ] ; 119 | mvd = RSA_convergence_thres(X,Y,NN,threshold) ; 120 | % Plot the sensitivity measures (maximum vertical distance between 121 | % parameters CDFs) as a function of the number of samples: 122 | figure; plot_convergence(mvd,NN,[],[],[],'no of samples','mvd',x_labels) 123 | 124 | % Repeat convergence analysis using bootstrapping to derive confidence 125 | % bounds: 126 | Nboot = 100; 127 | [mvd_mean,mvd_lb,mvd_ub] = RSA_convergence_thres(X,Y,NN,threshold,[],Nboot) ; 128 | figure 129 | plot_convergence(mvd_mean,NN,mvd_lb,mvd_ub,[],'no of samples','mvd',x_labels) 130 | 131 | %% Step 5b (Regional Sensitivity Analysis with groups) 132 | 133 | % RSA (find behavioural parameterizations): 134 | [stat,idx,Yk] = RSA_indices_groups(X,Y(:,1)) ; 135 | 136 | % Plot parameter CDFs: 137 | RSA_plot_groups(X,idx,Yk) ; 138 | % Customize labels and legend: 139 | RSA_plot_groups(X,idx,Yk,[],x_labels,'rmse'); % add legend 140 | 141 | -------------------------------------------------------------------------------- /workflow_tvsa_hymod.m: -------------------------------------------------------------------------------- 1 | % This script provides an application example of time-varying 2 | % sensitivity analysis. 3 | % The user can choose one of three GSA methods (FAST, VBSA or EET) 4 | % and this script will guide through the application of that method 5 | % to a time-varying model output. 6 | % In this example, the time-varying model output is the model prediction 7 | % (estimated flow) at each time step of the simulation. 8 | % 9 | % MODEL AND STUDY AREA 10 | % 11 | % The model under study is the rainfall-runoff model Hymod 12 | % (see help of function hymod_sim.m for more details) 13 | % applied to the Leaf catchment in Mississipi, USA 14 | % (see header of file LeafCatch.txt for more details). 15 | % The inputs subject to SA are the 5 model parameters, 16 | % and the time-varying model output is the model prediction 17 | % (estimated flow) at each time step of the simulation. 18 | % For an example of how to use this type of analysis, 19 | % see for instance Reusser and Zehe (2011) 20 | % 21 | % REFERENCES 22 | % 23 | % Reusser, D. E., Zehe, E., 2011. Inferring model structural deficits 24 | % by analyzing temporal dynamics of model performance and parameter 25 | % sensitivity. Water Resources Research 47 (7). 26 | 27 | % This script prepared by Francesca Pianosi 28 | % University of Bristol, 2015 29 | % mail to: francesca.pianosi@bristol.ac.uk 30 | 31 | %% Step 1: Set current directory to 'my_dir' and add path to sub-folders: 32 | my_dir = pwd ; % use the 'pwd' command if you have already setup the Matlab 33 | % current directory to the SAFE directory. Otherwise, you may define 34 | % 'my_dir' manually by giving the path to the SAFE directory, e.g.: 35 | % my_dir = '/Users/francescapianosi/Documents/safe_R1.0'; 36 | 37 | % Set current directory to 'my_dir' and add path to sub-folders: 38 | cd(my_dir) 39 | addpath(genpath(my_dir)) 40 | 41 | %% Step 2 Setup the Hymod model and define input variability space 42 | 43 | % Load data: 44 | load -ascii LeafCatch.txt 45 | rain = LeafCatch(1:730,1) ; 46 | evap = LeafCatch(1:730,2) ; 47 | flow = LeafCatch(1:730,3) ; 48 | 49 | % Define inputs: 50 | DistrFun = 'unif' ; % Parameter distribution 51 | % Parameter ranges (from literature): 52 | xmin = [ 0 0 0 0 0.1 ] ; 53 | xmax = [ 400 2 1 0.1 1 ] ; 54 | % Parameter names (needed for plots): 55 | x_labels = {'Sm','beta','alfa','Rs','Rf'} ; 56 | 57 | %% Step 3 Define the model output and GSA method 58 | 59 | myfun = 'hymod_sim' ; 60 | warmup = 30 ; % lenght of model warmup period (days) 61 | % (sensitivity indices will not be computed for the warmup period) 62 | 63 | GSA_met = 'FAST' ; 64 | %GSA_met = 'EET' ; 65 | %GSA_met = 'VBSA' ; 66 | 67 | %% Step 3 Define choices for sampling 68 | 69 | r = 20 ; % number of EEs (needed for EET only) 70 | 71 | N = 3001 ; % sample size (needed for all other methods) 72 | % Notes: 73 | % Case VBSA: N is the size of the base sample: the total number of model 74 | % evaluations will be N*(M+2) [more on this: see help vbsa_resampling] 75 | % Case FAST: N must be odd [more on this: see help FAST_sampling] 76 | % Case EET: N is not used, total number of model evaluations depend on 'r' 77 | % and precisely it will be r*(M+1) [more on this: see help OAT_sampling] 78 | 79 | SampStrategy = 'lhs' ; % Sampling strategy (needed for EET and VBSA) 80 | 81 | %% Step 4 Sample inputs space and evaluate the model 82 | 83 | 84 | M = length(xmin) ; % Number of inputs 85 | DistrPar = cell(M,1) ; for i=1:M; DistrPar{i} = [ xmin(i) xmax(i) ] ; end 86 | 87 | 88 | if strcmp(GSA_met,'FAST') 89 | 90 | X = FAST_sampling(DistrFun,DistrPar,M,N) ; 91 | Y = model_execution(myfun,X,rain,evap,warmup); % (N,T) 92 | 93 | 94 | elseif strcmp(GSA_met,'VBSA') 95 | 96 | X = AAT_sampling(SampStrategy,M,DistrFun,DistrPar,2*N); 97 | [ XA, XB, XC ] = vbsa_resampling(X) ; 98 | YA = model_execution(myfun,XA,rain,evap,warmup) ; % size (N,T) 99 | YB = model_execution(myfun,XB,rain,evap,warmup) ; % size (N,T) 100 | YC = model_execution(myfun,XC,rain,evap,warmup) ; % size (N*M,T) 101 | Y = [ YA; YB; YC ] ; % (N*(2+M),T) ... only needed for the next plot! 102 | 103 | elseif strcmp(GSA_met,'EET') 104 | 105 | design_type = 'radial'; 106 | X = OAT_sampling(r,M,DistrFun,DistrPar,SampStrategy,design_type); 107 | % More options are actually available for EET sampling, 108 | % see workflow_eet_hymod 109 | Y = model_execution(myfun,X,rain,evap,warmup); % (r*(M+1),T) 110 | 111 | else 112 | error('No method called %s',GSA_met) 113 | 114 | end 115 | 116 | % Plot results: 117 | figure 118 | plot(Y','b') 119 | xlabel('time') 120 | ylabel('flow') 121 | axis([1,size(Y,2),0,max(max(Y))]) 122 | 123 | %% Step 5 Compute time-varying Sensitivity Indices 124 | 125 | T = size(Y,2) ; 126 | 127 | if strcmp(GSA_met,'FAST') 128 | 129 | Si = nan(T,M) ; 130 | for t=warmup:T 131 | Si(t,:) = FAST_indices(Y(:,t),M) ; 132 | end 133 | S_plot = Si' ; 134 | 135 | elseif strcmp(GSA_met,'VBSA') 136 | 137 | Si = nan(T,M) ; 138 | STi = nan(T,M) ; 139 | for t=warmup:T 140 | [ Si(t,:), STi(t,:) ] = vbsa_indices(YA(:,t),YB(:,t),YC(:,t)); 141 | end 142 | % select sensitivity index to be plotted in the next figure: 143 | S_plot = Si' ; 144 | %S_plot = STi' ; 145 | 146 | elseif strcmp(GSA_met,'EET') 147 | 148 | mi = nan(T,M) ; 149 | sigma = nan(T,M) ; 150 | for t=warmup:T 151 | [ mi(t,:), sigma(t,:) ] = EET_indices(r,xmin,xmax,X,Y(:,t),design_type) ; 152 | end 153 | % select sensitivity index to be plotted in the next figure: 154 | S_plot = mi' ; 155 | %S_plot = sigma' ; 156 | 157 | end 158 | 159 | % Plot results: 160 | 161 | figure 162 | clrs = autumn ; 163 | clrs = clrs(end:-1:1,:); 164 | colormap(clrs) 165 | imagesc(S_plot) 166 | xlabel('time') 167 | ylabel('inputs') 168 | set(gca,'YTick',1:M,'YTickLabel',x_labels) 169 | colorbar 170 | title(['Sensitivity indices - GSA meth: ' GSA_met ]) 171 | hold on 172 | plot(M+0.5-flow/max(flow)*M,'k','LineWidth',2) 173 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /workflow_vbsa_ishigami_homma.m: -------------------------------------------------------------------------------- 1 | % This script applies Variance-Based Sensitivity Analysis to the 2 | % Ishigami-Homma function. 3 | % This function is commonly used to test approximation procedures 4 | % of variance-based indices because its output variance, first-order and 5 | % total-order indices (or 'main' and 'total' effects) can be analytically 6 | % computed. Therefore this script mainly aims at analyzing the accuracy 7 | % and convergence of the function 'vbsa_indices'. 8 | 9 | % This script prepared by Francesca Pianosi and Fanny Sarrazin 10 | % University of Bristol, 2014 11 | % mail to: francesca.pianosi@bristol.ac.uk 12 | 13 | my_dir = pwd ; % use the 'pwd' command if you have already setup the Matlab 14 | % current directory to the SAFE directory. Otherwise, you may define 15 | % 'my_dir' manually by giving the path to the SAFE directory, e.g.: 16 | % my_dir = '/Users/francescapianosi/Documents/safe_R1.0'; 17 | 18 | % Set current directory to 'my_dir' and add path to sub-folders: 19 | cd(my_dir) 20 | addpath(genpath(my_dir)) 21 | 22 | % Setup the model and define input ranges 23 | 24 | fun_test = 'ishigami_homma_function' ; 25 | M = 3 ; 26 | distr_fun = 'unif' ; 27 | distrpar = [ -pi pi ]; 28 | 29 | % Compute the exact values of the output variance (V) and of 30 | % the first-order (Si_ex) and total-order (STi_ex) 31 | % variance-based sensitivity indices (this is possible in this 32 | % very specific case because V, Si_ex and STi_ex can be computed 33 | % analytically) 34 | [ tmp, V, Si_ex, STi_ex ] = ishigami_homma_function(rand(1,M)) ; 35 | 36 | % Sample parameter space: 37 | SampStrategy = 'lhs' ; 38 | N = 3000 ; 39 | X = AAT_sampling(SampStrategy,M,distr_fun,distrpar,2*N); 40 | % Apply resampling strategy for the efficient approximation of the indices: 41 | [ XA, XB, XC ] = vbsa_resampling(X) ; 42 | 43 | % Run the model and compute selected model output at sampled parameter 44 | % sets: 45 | YA = model_execution(fun_test,XA) ; % size (N,1) 46 | YB = model_execution(fun_test,XB) ; % size (N,1) 47 | YC = model_execution(fun_test,XC) ; % size (N*M,1) 48 | 49 | % Compute main (first-order) and total effects: 50 | [ Si, STi ] = vbsa_indices(YA,YB,YC); 51 | 52 | % Plot main and total effects and compare the values estimated 53 | % by the function 'vbsa_indices' with the exact values 54 | figure 55 | subplot(121); boxplot2([ Si; Si_ex]) 56 | subplot(122); boxplot2([STi; STi_ex]) 57 | legend('estimated','exact')% add legend 58 | 59 | % Analyze convergence of sensitivity indices: 60 | NN = [N/5:N/5:N] ; 61 | [ Si, STi ] = vbsa_convergence([YA;YB;YC],M,NN); 62 | figure 63 | subplot(121); plot_convergence(Si,NN*(M+2),[],[],Si_ex,'model evals','main effect') 64 | subplot(122); plot_convergence(STi,NN*(M+2),[],[],STi_ex,'model evals','total effect') 65 | 66 | -------------------------------------------------------------------------------- /workflow_visual_ishigami_homma.m: -------------------------------------------------------------------------------- 1 | % This script provides an application example of how to use several 2 | % visualization tools (scatter plots, coloured scatter plots, parallel 3 | % coordinate plots, Andres' plot) to learn about sensitivity. 4 | % The application example is the Hishigami-Homma function, which is a 5 | % standard benchmark function in the Sensitivity Analysis literature. 6 | % (see help of function 'ishigami_homma_function.m' for more details and 7 | % references). 8 | 9 | % This script prepared by Francesca Pianosi and Fanny Sarrazin 10 | % University of Bristol, 2014 11 | % mail to: francesca.pianosi@bristol.ac.uk 12 | 13 | %% Step 1 (set directories) 14 | 15 | my_dir = pwd ; % use the 'pwd' command if you have already setup the Matlab 16 | % current directory to the SAFE directory. Otherwise, you may define 17 | % 'my_dir' manually by giving the path to the SAFE directory, e.g.: 18 | % my_dir = '/Users/francescapianosi/Documents/safe_R1.0'; 19 | 20 | % Set current directory to 'my_dir' and add path to sub-folders: 21 | cd(my_dir) 22 | addpath(genpath(my_dir)) 23 | 24 | %% Step 2 (setup the model) 25 | fun_test = 'ishigami_homma_function' ; 26 | M = 3 ; 27 | distr_fun = 'unif' ; 28 | distrpar = [ -pi pi ]; 29 | 30 | %% Step 3 (sampling and model evaluation) 31 | 32 | N = 3000; 33 | X = AAT_sampling('lhs',M,'unif',distrpar,N); 34 | Y = model_execution(fun_test,X) ; 35 | 36 | %% Step 4 (Scatter plots) 37 | 38 | % Use scatter plots of inputs againts output to visually assess 39 | % direct effects: 40 | scatter_plots(X,Y) 41 | 42 | % Use coloured scatter plots of one input against another on to assess 43 | % interactions: 44 | i1 = 1 ; 45 | i2 = 2 ; 46 | figure; scatter_plots_col(X,Y,i1,i2) % plot x(i1) against x(i2) 47 | % Change i2: 48 | i2 = 3 ; 49 | scatter_plots_col(X,Y,i1,i2) 50 | % Put all possible combinations of i1,i2 into one figure: 51 | scatter_plots_interaction(X,Y) 52 | % Customize titles: 53 | scatter_plots_interaction(X,Y,[],{'x(1)','x(2)','x(3)'}) 54 | 55 | %% Step 5 (Parallel Coordinate Plot) 56 | 57 | % Use Parallel Coordinate Plot to find patterns of input combinations 58 | % mapping into specific output condition 59 | idx = Y>30 ; % output condition to be highlighted 60 | parcoor(X,{'x(1)','x(2)','x(3)'},[],idx) 61 | 62 | %% Step 6 (Andres' visualization test) 63 | 64 | Xref= [ 2 2 2 ] ; 65 | idx = 2 ; 66 | Andres_plots(X,Y,Xref,idx,fun_test) 67 | 68 | 69 | --------------------------------------------------------------------------------