function [ params ] = gradient_ascent(fs,gs,initial_guess,resolutions)

%% Set up variables
newf = fs;
[rows, cols] = size(gs);
counter = 1;
t = 0.5*resolutions(1); % Introduces an adapative aspect to t
new_params = initial_guess';
newf = push_forward(fs,new_params,resolutions);
df = Derivatives_NGF_v(fs, gs, resolutions);
old_params = initial_guess';
old_cost = 0;


%% Iterate through using Gradient ascent
while(norm(sum(df,2)) > 0.0001)

    d = ngf_D(newf,gs,resolutions);
    d = d(:); 
%     cost = d'*d/(2*rows*cols) %for debugging

    new_params = new_params + t*sum(df,2);
%     new_params = new_params + t*df %for numerical gradient implementation

    newf = push_forward(fs,new_params,resolutions);

    if mod(counter,5)==0 %Display the both images every 5 iterations. 
        C = imfuse(newf,gs,'falsecolor','Scaling','joint','ColorChannels',[1 2 0]);
        imshow(C)
    end
    
    df = Derivatives_NGF_v(newf, gs, resolutions);

    counter = counter  + 1;

    if(mod(counter,1000) == 0)
        if((resolutions(1) == 1) && (counter < 2000))
            %Increase t to speedup convergence
            t = 1;
        else
            break;
        end      
    end

    old_params = new_params;
end

fprintf('Norm of gradient at grid scale %d was %d \n', resolutions(1), norm(sum(df,2)));

params = new_params;

end

