public boolean optimize() {
		init();

		int k = 1; // the first step has been explore in init()
		double gNorm, xNorm, fx_old, converge;//get the initial function value and gradient
		
		//initial step for gradient descent
		double fx = m_func.calcFuncGradient(m_g);
		
		do {
			fx_old = fx;
			
			getSearchDirection();
			if (k==1)
				m_linesearch.setInitStep(1.0 / Utils.L2Norm(m_g));
			else
				m_linesearch.setInitStep(1.0);
			
			fx = m_linesearch.linesearch(fx, m_x, m_x_old, m_g, m_sd);
			
			gNorm = Utils.L2Norm(m_g);
			xNorm = Utils.L2Norm(m_x);
			if (fx_old==0)
				converge = 1.0;//no way to compute improvement
			else
				converge = (fx_old-fx)/fx_old;
			
			//System.out.format("%d. f(x)=%.10f |g(x)|=%.10f converge=%.5f\n", k, fx, gNorm, converge);
		} while (++k<m_maxIter && gNorm>xNorm*m_gdelta && Math.abs(converge)>m_fdelta);
		
		return k<m_maxIter;//also need other convergence condition checking
	}