function plot3dFun(fun, x_lim, y_lim, size, plot_title, filename)
    % 3D plots a function
    % fun:          The function to plot
    % x_lim:        The range for x axis. ex: [-2, 2]
    % y_lim:        The range for y axis. ex: [0, 2]
    % size:         The number of points for each axis
    % plot_title:   The latex title for the plot
    %

    global image_width, 
    global image_height;

    % Generate a grid for x and y
    x_space = linspace(x_lim(1), x_lim(2), size);
    y_space = linspace(y_lim(1), y_lim(2), size);
    [X, Y] = meshgrid(x_space, y_space);
    
    % Evaluate the function on the grid
    for i = 1:size
        for j = 1:size
            % Pass each [x1; x2] as input to fun
            Z(i, j) = fun([X(i, j); Y(i, j)]);
        end
    end
    
    % 3D plot
    figure('Name', 'f(x,y)', 'NumberTitle', 'off');
    set(gcf, 'Position', [100, 100, image_width, image_height]); % Set the figure size
    surf(X, Y, Z);
    
    % Customize the plot
    xlabel('x1'); % Label for x-axis
    ylabel('x2'); % Label for y-axis
    zlabel('f(x, y)'); % Label for z-axis
    title(plot_title, 'Interpreter', 'latex', 'FontSize', 16); % Title of the plot
    colorbar;

    % save the figure
    if strcmp(filename, '') == 0
        print(gcf, filename, '-dpng', '-r300');
    end
end