├── PAK_Bn_code ├── Learning_func.m ├── nB_domain.m ├── Sqrt_ss.m ├── G_function.m ├── Find_CP1.m ├── Preallocation.m ├── DoE_byLHS.m ├── Find_CP2.m ├── Plot_Converg.m ├── Plot_Design.m └── PAK_Bn_main.m ├── README.md └── LICENSE /PAK_Bn_code/Learning_func.m: -------------------------------------------------------------------------------- 1 | % Minimize the learning functon of PAK-Bn 2 | 3 | function [LF_min,i_min] = Learning_func(mu, sigma,penalty_factor) 4 | 5 | % Learning function 6 | U_val = abs(mu)./sigma; 7 | LF_val = U_val.* penalty_factor; 8 | [LF_min, i_min] = min(LF_val); 9 | 10 | end % function end -------------------------------------------------------------------------------- /PAK_Bn_code/nB_domain.m: -------------------------------------------------------------------------------- 1 | % n-ball domain 2 | 3 | function [fx] = nB_domain(u, r) 4 | 5 | % u is m x n matrix (n is dimension) 6 | u_dim = size(u,2); 7 | u_square = zeros(size(u,1),1); 8 | for i=1:u_dim 9 | u_square = u_square + u(:,i).^2; 10 | end 11 | fx = u_square - r.^2; 12 | 13 | end % function end -------------------------------------------------------------------------------- /PAK_Bn_code/Sqrt_ss.m: -------------------------------------------------------------------------------- 1 | % Square Root of Sum of Squares 2 | 3 | function [fx] = Sqrt_ss(x) 4 | 5 | % u function should be m x n matrix (n is dimension) 6 | x_dim = size(x,2); 7 | x_square_sum = zeros(size(x,1),1); 8 | for i=1:x_dim 9 | x_square_sum = x_square_sum + x(:,i).^2; 10 | end 11 | fx = sqrt(x_square_sum); 12 | 13 | end % function end -------------------------------------------------------------------------------- /PAK_Bn_code/G_function.m: -------------------------------------------------------------------------------- 1 | % Limit-state function 2 | 3 | function [gx] = G_function(u1, u2) 4 | 5 | % 4 component function 6 | k = 7; 7 | g1x = 3+(u1-u2).^2/10-(u1+u2)/sqrt(2); 8 | g2x = 3+(u1-u2).^2/10+(u1+u2)/sqrt(2); 9 | g3x = u1-u2+k/sqrt(2); 10 | g4x = u2-u1+k/sqrt(2); 11 | 12 | gx = min(g1x, min(g2x, min(g3x, g4x))); 13 | 14 | end % function end -------------------------------------------------------------------------------- /PAK_Bn_code/Find_CP1.m: -------------------------------------------------------------------------------- 1 | % Find critical point 2 | 3 | function [CP_hat,find_1_id] = Find_CP1(mu,index_neval,Bn_samp) 4 | 5 | I_1 = (mu < 0); 6 | [find_1_id,~] = find(I_1==1); 7 | if ~isempty(find_1_id) 8 | [~,CP_id] = max(index_neval(find_1_id)); 9 | CP_hat(1,:) = Bn_samp(find_1_id(CP_id),:); 10 | end 11 | 12 | end % function end 13 | 14 | 15 | -------------------------------------------------------------------------------- /PAK_Bn_code/Preallocation.m: -------------------------------------------------------------------------------- 1 | % Pre-allocation for data 2 | 3 | N_samp_R_cell = cell(max_round,1); 4 | CP_true = zeros(max_round,n_dim); 5 | iter_cell = cell(max_round,1); 6 | x_cell = cell(max_round,1); 7 | G_cell = cell(max_round,1); 8 | Bn_chg_cell = cell(max_round,1); 9 | CP_eval_cell = cell(max_round,1); 10 | CP_neval_cell = cell(max_round,1); 11 | P_f_cell = cell(max_round,1); 12 | CP_hat_cell = cell(max_round,1); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PAK-Bn v1.0 2 | ======== 3 | 4 | Matlab code for Probability-Adaptive Kriging in n-Ball (PAK-Bn) for reliability analysis, from: 5 | 6 | Kim, J., & Song, J. (2020). Probability-Adaptive Kriging in n-Ball (PAK-Bn) for reliability analysis. Structural Safety, 85, 101924. 7 | https://doi.org/10.1016/j.strusafe.2020.101924. 8 | 9 | Notes: 10 | - The main script is: PAK_Bn_main.m. Run this script after installing GMPL toolbox (Williams, C. K., & Rasmussen, C. E. (2006)). 11 | 12 | -------------------------------------------------------------------------------- /PAK_Bn_code/DoE_byLHS.m: -------------------------------------------------------------------------------- 1 | % Design of Experiments by LHS sampling 2 | 3 | function [x_doe] = DoE_byLHS(n_dim,N_iniDOE,LHS_bound) 4 | 5 | Coded_value = lhsdesign(N_iniDOE,n_dim); 6 | bounds = repmat([-LHS_bound LHS_bound],n_dim,1); 7 | x_doe = zeros(size(Coded_value)); 8 | for i = 1:size(Coded_value,2) % Convert coded values to real-world units 9 | zmax = max(Coded_value(:,i)); 10 | zmin = min(Coded_value(:,i)); 11 | x_doe(:,i) = interp1([zmin zmax],bounds(i,:),Coded_value(:,i)); 12 | end 13 | 14 | end % function end -------------------------------------------------------------------------------- /PAK_Bn_code/Find_CP2.m: -------------------------------------------------------------------------------- 1 | % Find critical point 2 | 3 | function [CP_hat,find_1_id,find_2_id] = Find_CP2(mu,x_doe,G_doe,N_iniDOE,index_neval,index_eval,Bn_samp_chg) 4 | 5 | I_1 = (mu < 0); 6 | I_2 = (G_doe(N_iniDOE+1:end) < 0); 7 | [find_1_id,~] = find(I_1==1); 8 | [find_2_id,~] = find(I_2==1); 9 | if (~isempty(find_1_id) || ~isempty(find_2_id)) 10 | [CP_1,CP_1_id] = max(index_neval(find_1_id)); 11 | [CP_2,CP_2_id] = max(index_eval(find_2_id)); 12 | [~,CP_id] = max([CP_1 CP_2]); 13 | if CP_id==1 14 | CP_hat(1,:) = Bn_samp_chg(find_1_id(CP_1_id),:); 15 | elseif CP_id==2 16 | CP_hat(1,:) = x_doe(N_iniDOE + find_2_id(CP_2_id),:); 17 | end 18 | end 19 | 20 | end % function end 21 | 22 | 23 | -------------------------------------------------------------------------------- /PAK_Bn_code/Plot_Converg.m: -------------------------------------------------------------------------------- 1 | % Plot convergence history 2 | 3 | iter_mat = cell2mat(iter_cell); 4 | iter_sum = [0; cumsum(iter_mat)]; 5 | chg_pt = cumsum(iter_mat)+N_iniDOE; 6 | total_iter = sum(iter_mat); 7 | figure() 8 | for i=1:k 9 | plot(N_iniDOE+iter_sum(i):N_iniDOE+iter_sum(i+1),P_f_cell{i,1}/P_f_MCS,'LineWidth',1.5,'Color','m') 10 | if i==1 11 | hold on 12 | end 13 | if i==1 14 | plot(N_iniDOE:N_iniDOE+total_iter,ones(1,total_iter+1),'LineWidth',1.5,'Color','k') % "Exact" sol (MCS) 15 | end 16 | end 17 | for i=1:k-1 18 | plot([chg_pt(i) chg_pt(i)],[P_f_cell{i,1}(end,1)/P_f_MCS P_f_cell{i+1,1}(1,1)/P_f_MCS],'LineWidth',1.5,'Color','m') 19 | end 20 | xlabel('The number of function calls N_{call}','fontsize',11) 21 | ylabel('Normalized P_{f}','fontsize',11) 22 | ylim([0 4]) 23 | legend('Estimation','"Exact" solution') 24 | hold off -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Jungho Kim 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PAK_Bn_code/Plot_Design.m: -------------------------------------------------------------------------------- 1 | % Plot the final experimental designs 2 | 3 | grid_interv = 0.01; 4 | [xs1, xs2] = meshgrid(-8:grid_interv:8); 5 | G_true = G_function(xs1, xs2); % True function on the grid points 6 | [mu_grid, s2_grid] = gp(hyp, @infGaussLik, meanfunc, covfunc, likfunc, x_doe, G_doe, [xs1(:) xs2(:)]); 7 | mu_grid = reshape(mu_grid, size(G_true)); s2_grid = reshape(s2_grid, size(G_true)); 8 | 9 | radi_dp = 3; 10 | theta_circ = linspace(0,2*pi); 11 | x_circleplot = radi_dp*cos(theta_circ); 12 | y_circleplot = radi_dp*sin(theta_circ); 13 | radi_dp2 = 3.5; 14 | x_circleplot2 = radi_dp2*cos(theta_circ); 15 | y_circleplot2= radi_dp2*sin(theta_circ); 16 | 17 | Finfig = figure(); 18 | Finfig.Color = 'w'; 19 | Finfig.Position = [680 430 760 475]; 20 | contour(xs1, xs2, G_true,'levellist',0,'LineStyle','-', 'LineWidth', 2.0, 'Color',[0.39, 0.47, 0.64]); hold on; % True 21 | contour(xs1, xs2, mu_grid,'levellist',0,'LineStyle','--','LineWidth', 1.5,'Color','k'); % Kriging 22 | plot(x_circleplot,y_circleplot,'LineStyle','-.', 'LineWidth', 1,'Color', [0.40 0.40 0.40],'HandleVisibility','off'); 23 | plot(x_circleplot2,y_circleplot2,'LineStyle','-.', 'LineWidth', 1,'Color', [0.40 0.40 0.40],'HandleVisibility','off'); 24 | scatter(x_doe(1:N_iniDOE,1),x_doe(1:N_iniDOE,2),30,'k','LineWidth',1.1) 25 | scatter(x_doe(N_iniDOE+1:end,1),x_doe(N_iniDOE+1:end,2),50,'r','x','LineWidth',1.5) 26 | xlabel('x_1','fontsize',11) 27 | ylabel('x_2','fontsize',11) 28 | legend('True function','Kriging prediction','Initial DoE','Added DoE','Location','NorthEast') 29 | axis equal; axis([-7 7 -7 7]); hold off; 30 | 31 | 32 | -------------------------------------------------------------------------------- /PAK_Bn_code/PAK_Bn_main.m: -------------------------------------------------------------------------------- 1 | % Jungho Kim, Junho Song 2 | % Probabilisy-Adaptive Kriging in n-ball (PAK-Bn) for Reliability Analysis, 3 | % Structural Safety (2020) 4 | % https://github.com/Jungh0Kim/PAK-Bn 5 | 6 | clear; close all; tic; 7 | 8 | %% Set Initial Parameters 9 | 10 | n_dim = 2; % dimension of random variables 11 | N_sample = 5e4; % number of samples 12 | N_iniDOE = 10; % initial number of DoE 13 | max_iter = 100; 14 | max_round = 10; 15 | 16 | LHS_bound = 6.0; % LHS bound 17 | R1 = 5.0; % initial n-ball radius 18 | del_R = 0.20; 19 | Beta_tol1 = 1e-4; % tolerance1 20 | Beta_tol2 = 1e-5; % tolerance2 21 | P_f_MCS = 2.21e-3; % reference for numerical example 22 | 23 | % Initial DoE 24 | rng(13) % For reproducibility 25 | x_doe = DoE_byLHS(n_dim,N_iniDOE,LHS_bound); 26 | G_doe = G_function(x_doe(:,1), x_doe(:,2)); 27 | 28 | %% Specify the parameters of gp 29 | 30 | meanfunc = []; 31 | covfunc = {@covMaterniso, 5}; hyp.cov = [1/2 1/2]; % Matern covariance function 32 | likfunc = @likGauss; sn = 1e-3; hyp.lik = log(sn); % Gaussian likelihood 33 | % hyp_MLE = minimize(hyp, @gp, -100, @infGaussLik, meanfunc, covfunc, likfunc, x_training, G_training); 34 | 35 | %% Active-Learning 36 | 37 | Preallocation; 38 | R_max = R1+del_R*max_round; 39 | p = haltonset(n_dim,'Skip',1e3,'Leap',1e2); % quasi-random samples 40 | p = scramble(p,'RR2'); 41 | total_sample = -R_max + 2*R_max*p(1:N_sample,:); % total sample (memory) 42 | 43 | k = 1; t_j = 0; 44 | Ad_radi = [0 R1:del_R:R_max]; 45 | while (k <= max_round) 46 | 47 | % n-ball sampling 48 | I_t = (nB_domain(total_sample, Ad_radi(k)) >= 0 & nB_domain(total_sample, Ad_radi(k+1)) < 0); 49 | [sp_pt,~] = find(I_t==1); 50 | Bn_samp = total_sample(sp_pt,:); 51 | Bn_samp_chg = Bn_samp; 52 | N_samp_R = size(Bn_samp,1); 53 | 54 | Vol_m = pi^(n_dim/2)/gamma(n_dim/2+1)*Ad_radi(k+1)^n_dim; % Volume of n-ball 55 | index_s = cumprod(normpdf(Bn_samp_chg,0,1),2); 56 | index = index_s(:,end); 57 | N_samp_R_cell{k,1} = N_samp_R; 58 | if k>1 59 | N_samp_R_cell{k,1} = N_samp_R + N_samp_R_cell{k-1,1}; 60 | end 61 | clear P_f CP_hat 62 | 63 | %% k = 1 64 | if k==1 % 1st iteration 65 | iter = 1; 66 | % divide eval and non-eval points 67 | index_eval = []; index_neval = index(:); 68 | 69 | while (iter <= max_iter) 70 | % Kriging estimation 71 | [mu, s2] = gp(hyp, @infGaussLik, meanfunc, covfunc, likfunc, x_doe, G_doe, Bn_samp_chg); 72 | 73 | if iter==1 74 | [CP_hat_s,find_1_id] = Find_CP1(mu,index_neval,Bn_samp); 75 | CP_hat(iter,:) = CP_hat_s; 76 | P_f(iter,1) = sum(index(find_1_id)) * Vol_m / N_samp_R; 77 | 78 | % Penalty function 79 | if ~isempty(find_1_id) 80 | penalty_factor = abs(Sqrt_ss(Bn_samp_chg) - norm(CP_hat(iter,:),2)) / Ad_radi(k+1); 81 | else 82 | penalty_factor = 1; 83 | end 84 | else % iter > 1 85 | [CP_hat_s,find_1_id,find_2_id] = Find_CP2(mu,x_doe,G_doe,N_iniDOE,index_neval,index_eval,Bn_samp_chg); 86 | CP_hat(iter,:) = CP_hat_s; 87 | P_f(iter,1) = (sum(index_neval(find_1_id)) + sum(index_eval(find_2_id))) * Vol_m / N_samp_R; 88 | 89 | % Penalty function 90 | if (~isempty(find_1_id) || ~isempty(find_2_id)) 91 | penalty_factor = abs(Sqrt_ss(Bn_samp_chg) - norm(CP_hat(iter,:),2)) / Ad_radi(k+1); 92 | if abs( norm(CP_hat(iter,:)-CP_hat(iter-1,:),2) ) < 0.01 93 | penalty_factor = 1; 94 | end 95 | else % not find CP 96 | penalty_factor = 1; 97 | end 98 | 99 | % Convergence condition 100 | Beta_g_1 = -norminv(P_f(iter-1,1)); 101 | Beta_g_2 = -norminv(P_f(iter,1)); 102 | Beta_var = abs(Beta_g_2 - Beta_g_1) / Beta_g_1; 103 | if Beta_var < Beta_tol1 || isnan(Beta_var)==1 104 | break 105 | end 106 | end % if end 107 | 108 | % Minimize the learning function 109 | [LF_min,i_min] = Learning_func(mu, sqrt(s2),penalty_factor); 110 | 111 | % Add the new evaluation point to the DoE 112 | x_doe = vertcat(x_doe, Bn_samp_chg(i_min,:)); 113 | G_doe = vertcat(G_doe, G_function(Bn_samp_chg(i_min,1),Bn_samp_chg(i_min,2))); % +1 G evaluation 114 | index_eval = vertcat(index_eval, index_neval(i_min)); 115 | Bn_samp_chg = [Bn_samp_chg(1:i_min-1,:); Bn_samp_chg(i_min+1:end,:)]; 116 | index_neval = [index_neval(1:i_min-1); index_neval(i_min+1:end)]; 117 | iter = iter + 1; 118 | end % while (iter) end 119 | 120 | x_cell{k,1} = x_doe; 121 | G_cell{k,1} = G_doe; 122 | Bn_chg_cell{k,1} = Bn_samp_chg; 123 | CP_eval_cell{k,1} = index_eval; 124 | CP_neval_cell{k,1} = index_neval; 125 | 126 | % Estimate failure probability of the last model 127 | [mu, ~] = gp(hyp, @infGaussLik, meanfunc, covfunc, likfunc, x_doe, G_doe, Bn_samp_chg); 128 | [CP_hat_s,find_1_id,find_2_id] = Find_CP2(mu,x_doe,G_doe,N_iniDOE,index_neval,index_eval,Bn_samp_chg); 129 | CP_hat(iter,:) = CP_hat_s; 130 | CP_hat_cell{k,1} = CP_hat; 131 | 132 | P_f(iter,1) = (sum(index_neval(find_1_id)) + sum(index_eval(find_2_id))) * Vol_m / N_samp_R; 133 | P_f_cell{k,1} = P_f; 134 | iter = iter - 1; 135 | iter_cell{k,1} = iter; 136 | 137 | %% k > 1 138 | else % from 2nd round to end (k > 1) 139 | iter = 1; 140 | x_doe = x_cell{k-1,1}; 141 | G_doe = G_cell{k-1,1}; 142 | Bn_samp_chg = vertcat(Bn_chg_cell{k-1,1},Bn_samp_chg); 143 | index_eval = CP_eval_cell{k-1,1}; 144 | index_neval = vertcat(CP_neval_cell{k-1,1}, index); 145 | 146 | while (iter <= max_iter) 147 | % Kriging estimation 148 | [mu, s2] = gp(hyp, @infGaussLik, meanfunc, covfunc, likfunc, x_doe, G_doe, Bn_samp_chg); 149 | [CP_hat_s,find_1_id,find_2_id] = Find_CP2(mu,x_doe,G_doe,N_iniDOE,index_neval,index_eval,Bn_samp_chg); 150 | CP_hat(iter,:) = CP_hat_s; 151 | 152 | P_f(iter,1) = (sum(index_neval(find_1_id)) + sum(index_eval(find_2_id))) * Vol_m / N_samp_R_cell{k,1}; 153 | 154 | % Penalty function 155 | if (~isempty(find_1_id) || ~isempty(find_2_id)) 156 | penalty_factor = abs(Sqrt_ss(Bn_samp_chg) - norm(CP_hat(iter,:),2)) / Ad_radi(k+1); 157 | if iter > 1 158 | if abs( norm(CP_hat(iter,:)-CP_hat(iter-1,:),2) ) < 0.01 159 | penalty_factor = 1; 160 | end 161 | end 162 | if iter == 1 && isempty(CP_hat_cell{k-1,1})==0 163 | if abs( norm(CP_hat(iter,:)-CP_hat_cell{k-1,1}(end,:),2) ) < 0.01 164 | penalty_factor = 1; 165 | end 166 | end 167 | else % not find CP 168 | penalty_factor = 1; 169 | end 170 | 171 | Beta_g_j1 = -norminv(P_f_cell{k-1,1}(end)); 172 | Beta_g_j2 = -norminv(P_f(1,1)); 173 | Beta_var_j = abs(Beta_g_j2 - Beta_g_j1) / Beta_g_j1; 174 | if Beta_var_j < Beta_tol2 175 | t_j = 1; 176 | break % break iteration (whole while loop) 177 | end 178 | 179 | if iter > 1 180 | Beta_g_1 = -norminv(P_f(iter-1,1)); 181 | Beta_g_2 = -norminv(P_f(iter,1)); 182 | Beta_var = abs(Beta_g_2 - Beta_g_1) / Beta_g_1; 183 | 184 | if Beta_var < Beta_tol1 || isnan(Beta_var)==1 185 | break % break iteration (while iter loop) 186 | end 187 | end % if end 188 | 189 | % Minimize the learning function 190 | [LF_min,i_min] = Learning_func(mu, sqrt(s2),penalty_factor); 191 | 192 | % Add the new evaluation point to the DoE 193 | x_doe = vertcat(x_doe, Bn_samp_chg(i_min,:)); 194 | G_doe = vertcat(G_doe, G_function(Bn_samp_chg(i_min,1),Bn_samp_chg(i_min,2))); % +1 G evaluation 195 | index_eval = vertcat(index_eval, index_neval(i_min)); 196 | Bn_samp_chg = [Bn_samp_chg(1:i_min-1,:); Bn_samp_chg(i_min+1:end,:)]; 197 | index_neval = [index_neval(1:i_min-1); index_neval(i_min+1:end)]; 198 | iter = iter + 1; 199 | end % while (iter) end 200 | 201 | if t_j==1 202 | break % stop whole process 203 | end 204 | x_cell{k,1} = x_doe; 205 | G_cell{k,1} = G_doe; 206 | Bn_chg_cell{k,1} = Bn_samp_chg; 207 | CP_eval_cell{k,1} = index_eval; 208 | CP_neval_cell{k,1} = index_neval; 209 | 210 | % Estimate failure probability of the last model 211 | [mu, ~] = gp(hyp, @infGaussLik, meanfunc, covfunc, likfunc, x_doe, G_doe, Bn_samp_chg); 212 | [CP_hat_s,find_1_id,find_2_id] = Find_CP2(mu,x_doe,G_doe,N_iniDOE,index_neval,index_eval,Bn_samp_chg); 213 | CP_hat(iter,:) = CP_hat_s; 214 | CP_hat_cell{k,1} = CP_hat; 215 | 216 | P_f(iter,1) = (sum(index_neval(find_1_id)) + sum(index_eval(find_2_id))) * Vol_m / N_samp_R_cell{k,1}; 217 | P_f_cell{k,1} = P_f; 218 | iter = iter - 1; 219 | iter_cell{k,1} = iter; 220 | end % Active-learning end 221 | k = k + 1; % expanding the n-ball 222 | end % k end 223 | k = k - 1; toc; 224 | 225 | %% Results 226 | 227 | Plot_Design; 228 | Plot_Converg; 229 | 230 | % Display the added DoE 231 | fprintf ('added DOE : x =\n'); 232 | disp(x_doe(N_iniDOE+1:end,:)'); 233 | 234 | % Total number of evaluations 235 | fprintf('Number of evaluations: %d + %d = %d.\n', N_iniDOE, sum([iter_cell{:}]), N_iniDOE + sum([iter_cell{:}])); 236 | --------------------------------------------------------------------------------