function [fnew, wnew, Awnew, increase_flag, cg] = restricted_newton(w, U, b, loss, grad, epsilon, newton_iters, verbose, PCG_iter, preconditioned)
	if (nargin < 10)
		PCG_iter = length(b);
	end
	increase_flag = 0;
	base_PCG = PCG_iter;
	current_PCG = base_PCG;
	sigma = 1e-3;
    cg = 0;
% 	if (~exist('newton_iters'))
% 		newton_iters = 1;
% 	end
	wnew = w;
	[fnew, Awnew, g_restricted, D] = loss_fun_and_grad(loss, grad, wnew, U, b, epsilon);
	for i=1:newton_iters
		Amap = @(v) U'*(D.*(U*v));
		
        if preconditioned
            M = D'*((U.^2));
            idx = find(M > 0);
            M(idx) = 1 ./ sqrt(M(idx));
        else 
            M = 1;
        end

		[pNewton, cg_iters] = PCG_newton(Amap, -g_restricted, M, 0.5, current_PCG);
        cg = cg + cg_iters; 
% 		pNewton = PCG_newton(Amap, -g_restricted, 1, 0.5, current_PCG);
		
        [fnew, wnew, Awnew, g_restricted, D, newton_stepsize] = restricted_linesearch(loss, grad, U, b, sigma, wnew, pNewton, g_restricted, fnew, Awnew, U*pNewton, 1, epsilon);
		if (newton_stepsize == 1)
			increase_flag = increase_flag + 1;
			current_PCG = current_PCG * 2;
		else
			increase_flag = 0;
% 			current_PCG = base_PCG;
			break;
		end
% 		if (exist('verbose') && verbose > 0)
% 			fprintf('\t\tNewton iteration %d: stepsize %g\n',i,newton_stepsize);
% 		end
%		if (newton_stepsize == 0)
%			break;
%		end
	end
end
