function visualizeBoundary(y, X, model, show_margin, show_sv)
%VISUALIZEBOUNDARY plots a non-linear decision boundary learned by the SVM
%   VISUALIZEBOUNDARYLINEAR(y, X, model) plots a non-linear decision 
%   boundary learned by the SVM and overlays the data on it

if nargin < 4
    show_margin = false;
end

if nargin < 5
    show_sv = show_margin;
end

pos = y==1;
neg = y==0;

sz = 50;
lw = 2;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Plot data
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
scatter(X(pos, 1), X(pos, 2), sz, 'b', '+', 'linewidth', lw);
hold on;
scatter(X(neg, 1), X(neg, 2), sz, 'r', '^', 'linewidth', lw);

if nargin < 3
    return
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Plot support vectors
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if show_sv
    eps = 1e-2;
    [~, ~, vals] = svmpredict(y, X, model);
    SV = (pos & vals <= 1 + eps) | (neg & vals >= -1 - eps);
    scatter(X(SV, 1), X(SV, 2), 150, 'k', 'o', 'linewidth', 1.2);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Plot decision boundary
%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Make classification predictions over a grid of values
x1plot = linspace(min(X(:,1)), max(X(:,1)), 100)';
x2plot = linspace(min(X(:,2)), max(X(:,2)), 100)';
[X1, X2] = meshgrid(x1plot, x2plot);
vals = zeros(size(X1));

X_grid = [X1(:), X2(:)];
y_fake = zeros(size(X_grid,1), 1);

[~, ~, vals] = svmpredict(y_fake, X_grid, model);
vals = reshape(vals, size(X1));

% Plot the SVM boundary
contour(X1, X2, vals, [0 0],  'Color', 'k', 'linewidth', 2);

if show_margin
    contour(X1, X2, vals, [-1 1], 'Color', 'k', 'linewidth', 1);
end




hold off;

end
