function v_bar = StochGradDescent(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 = 100;
batch_size2 = size(samples,2);
grad = zeros(2,1);
A_t = 10;
B_t = 10;
G_t = 0.8;
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]);
    for t = 1:num_batch
        mu = v(i+d)./v(i);
        sigma2 = 1./v(i);
        x = nz_samples((batch_size*(t-1)+1):batch_size*t);
        grad_concat = [0.5*x.^2; -x];
        
        if label ~= "SGD w/o Filter"
            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)];       
        end
        
        switch label
            case "SGD w/o Filter"
                z = sampleTrunGauss(mu, sigma2, thres(i), batch_size);
                grad = mean(grad_concat,2) + [-0.5*mean(z.^2);  mean(z)];
            case "SGD with Median"
                grad = median(grad_concat,2) + grad_Z;
            case "SGD with Trimmed Mean"
                grad = trimmean(grad_concat,20,2) + grad_Z;
            case "Oracle SGD"
                z = sampleTrunGauss(mu, sigma2, thres(i), batch_size);
                grad = mean(grad_concat,2) + [-0.5*mean(z.^2);  mean(z)];
        end
        if label == "SGD with Trimmed Mean" 
            v_new = v_old - grad/(lambda*(10*t));
        elseif label == "SGD with Median"
            v_new = v_old - grad/(lambda*(15*t));
        elseif label == "SGD w/o Filter" || label == "Oracle SGD"
            v_new = v_old - grad/(lambda*(t));
        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