function [field] ...
= GP_realization(stage, option_gp)
x_grid_resol = stage.xres;
y_grid_resol = stage.yres;
x_min = stage.xmin;
x_max = stage.xmax;
y_min = stage.ymin;
y_max = stage.ymax;
%%
x = linspace(x_min, x_max, x_grid_resol);
y = linspace(y_min, y_max, y_grid_resol);
[X,Y] = meshgrid(x, y);
mesh = [X(:) Y(:)]; % 2-D mesh
n = size(mesh, 1);
%%
K = GP_kernel(mesh, mesh, option_gp) + sqrt(option_gp.sigma2w)*eye(n, n);
z = chol(K)'*randn(n,1);
Z = reshape(z, y_grid_resol, x_grid_resol);
field = [];
field.xgrid = X;
field.ygrid = Y;
field.zdata = Z - mean(mean(Z));
field.xres = x_grid_resol;
field.yres = y_grid_resol;
field.xmin = x_min;
field.xmax = x_max;
field.ymin = y_min;
field.ymax = y_max;
field.zmin = min(min(field.zdata ));
field.zmax = max(max(field.zdata ));
end
%%
% pred.pos = [reshape(field.xgrid, [], 1), ...
% reshape(flipud(field.ygrid), [], 1)];
function K = GP_kernel(X1, X2, option)
%
% X1: 데이터는 col방향으로 들어있다.
% X2: 데이터는 col방향으로 들어있다.
%
% 여기에는 sigma2w는 포함되어있지 않다!!
%
% <SE kernel 예제 1>
% option_gp.useSE_K = 1;
% option_gp.sigma2f = 1;
% option_gp.sigma2w = 1E-3;
% option_gp.sigma2x = 5E-1;
% option_gp.Grad = 0; <== 미분을 안한다. 할 경우는 일단 scalar
%
% <D kernel 예제 2>
% option_gp.useD_K = 1;
% option_gp.sigma2f = 1;
% option_gp.sigma2w = 1E-3;
% option_gp.r = 0.5;
% option_gp.Grad = 0;
%
%
%
if ~isfield(option, 'Grad')
option.Grad = 0;
end
if ~isfield(option, 'useSE_K')
option.useSE_K = 0;
end
if ~isfield(option, 'useD_K')
option.useD_K = 0;
end
len_X1 = size(X1, 1);
len_X2 = size(X2, 1);
K = zeros(len_X1, len_X2);
for i = 1:len_X1
for j = 1:len_X2
if option.Grad
% X1에서 미분한 gradient를 구한다. (이 때는 앞에서 정의한 K를 사용하지 않을 것이다.)
% 미분을 일반적으로 하나의 X1과 X2를 가정한다. (예: 두 위치, len_X1 = len_X2 = 1)
if option.useSE_K
K = se_kernel(X1(i,:), X2(j,:), option)*-(X1(i,:)-X2(i,:))/option.sigma2x;
elseif option.useD_K
diff = X1(i,:) - X2(j,:);
dist = norm(diff);
sig2f = option.sigma2f;
r = option.r;
if dist == 0
K = zeros(size(diff));
elseif dist > r
K = zeros(size(diff));
else
K = sig2f*pi*(dist/r-1)*sin(pi*dist/r)*diff/dist/r;
end
end
else
% kernel의 값을 구한다.
if option.useSE_K
K_data = se_kernel(X1(i,:), X2(j,:), option);
elseif option.useD_K
K_data = distribute_kernel(X1(i,:), X2(j,:), option);
end
K(i, j) = K_data;
end
end
end
end
%%
function output = se_kernel(x1, x2, option)
output = option.sigma2f*exp(-norm(x1-x2)^2/option.sigma2x/2);
end
%%
function output = distribute_kernel(x1, x2, option)
output = option.sigma2f*Lambda(norm(x1-x2)/option.r);
end
function output_lambda = Lambda(h)
if h <= 1
output_lambda = (1-h)*cos(pi*h) + 1/pi*sin(pi*h);
else
output_lambda = 0;
end
end