function [xopt, fopt, gradnorm, iter] = gd(f, gradf, alpha, x0)
% The first two inputs (f and gradf) are function handles:
% they can be used as functions in the code below.
% Note: the code here here is very simple (a bit too simple).
    xopt = x0;
    fopt = f(x0);
    gradnorm = norm(gradf(x0));
    iter = 0;
    while iter < 1000 && gradnorm > 1e-8
        % Careful here: you would normally want to be
        % more prudent in not computing two gradients
        % per iteration: think about how you should
        % modify the code so that gradf(...) is called
        % only once.
        xopt = xopt - alpha * gradf(xopt);
        fopt = f(xopt);
        gradnorm = norm(gradf(xopt));
        iter = iter + 1;
    end
end
