function v_bar = GradDescent(samples,thres,label)
d = size(samples,1);
lambda = 0.1;
v0 = [ones(d,1);zeros(d,1)];
v = v0;
r = 3;
v_avg = zeros(2*d,1);
batch_size = 2;
batch_size2 = 200;
grad = zeros(2,1);
A_t = 20;
B_t = 20;
G_t = 1.5;
thresh2=1e-3;


for i = 1 : d
    nz_samples = samples(i,samples(i,:)>thres(i));
    num_batch = floor(size(nz_samples,2)/batch_size);
    
    v_old = v0([i d+i]);
    num_batch = floor(size(nz_samples,2)/batch_size);
    grad_concat = zeros(2,num_batch);
    for t = 1:num_batch
        x = nz_samples((batch_size*(t-1)+1):batch_size*t);
        grad_concat(:,t) = [0.5*mean(x.^2); -mean(x)];
    end
    for iter=1:floor(size(samples,2)/100)
    mu = v(i+d)./v(i);
    sigma2 = 1./v(i);
            alpha = thres(i)-mu./sqrt(sigma2);
            Z = normpdf(alpha)./(1-normcdf(alpha));
            grad_Z = [sigma2.*(1+alpha.*Z-Z.^2); mu+Z.*sqrt(sigma2)];
            grad_Z = [-0.5*(grad_Z(1)+grad_Z(2)^2); grad_Z(2)];       
        
        switch label
            case "GD w/o Filter"
                grad = mean(grad_concat,2) + grad_Z;
            case "GD with Median"
                grad = median(grad_concat,2) + grad_Z;
            case "GD with Trimmed Mean"
                grad = trimmean(grad_concat,50,2) + grad_Z;
            case "Oracle GD"
                grad = mean(grad_concat,2) + grad_Z;
        end
        if label == "GD with Trimmed Mean" 
            v_new = v_old - grad/(lambda*(iter*10));
        elseif label == "GD with Median"
            v_new = v_old - grad/(lambda*(iter*15));
        elseif label == "GD w/o Filter" || label == "Oracle GD"
            v_new = v_old - grad/(lambda*(iter));
        end    
        v([i d+i]) = v_new;
        v(i) = max(1/r,min(r,v(i)));
        v(d+i) = max(-r,min(r,v(d+i)));
        v_old = v([i d+i]);
    end
    v_bar([i d+i]) = v([i d+i]);
end