private boolean takeStepNew(int i, int j) {
		if (i == j)
			return false;

		/* init */
		double alpha1 = alpha[i];
		double alpha2 = alpha[j];
		double b_old = b;
		int y1 = model.getY()[i];
		int y2 = model.getY()[j];
		double E1 = d(i) - y1;
		double E2 = d(j) - y2;

		double s = y1 * y2;

		// Compute L and H
		double L = calculateL(i, j);
		double H = calculateH(i, j);
		if (L == H)
			return false;

		double k11 = kernel.calculate(model.getX()[i], model.getX()[i]);
		double k12 = kernel.calculate(model.getX()[i], model.getX()[j]);
		double k22 = kernel.calculate(model.getX()[j], model.getX()[j]);

		double eta = k11 + k22 - 2 * k12; // notice that it is different from
											// calculateEta()
		double a2 = 0;
		if (eta > 0) {
			a2 = alpha2 + y2 * (E1 - E2) / eta;
			if (a2 < L)
				a2 = L;
			else if (a2 > H)
				a2 = H;
		} else {

			double v1 = d(i) - y1 * alpha1 * k11 - y2 * alpha2 * k12;
			double v2 = d(j) - y1 * alpha1 * k12 - y2 * alpha2 * k22;
			double Lobj = obj(L, alpha1, alpha2, y1, y2, k12, k11, k22, v1, v2);
			double Hobj = obj(H, alpha1, alpha2, y1, y2, k12, k11, k22, v1, v2);

			if (Lobj < Hobj - tolerance) {
				a2 = L;
			} else if (Lobj > Hobj + tolerance) {
				a2 = H;
			} else {
				a2 = alpha2;
			}
		}

		if (Math.abs(a2 - alpha2) < tolerance * (a2 + alpha2 + tolerance)) {
			return false;
		}
		double a1 = alpha1 + s * (alpha2 - a2);
		// update b
		computeBias(a1, E1, E2, alpha1, alpha2, a2, y1, y2, k11, k22, k12);
		// store a1 and a2
		alpha[i] = a1;
		alpha[j] = a2;
		// update error cache
		for (int k = 0; k < model.getLength(); k++) {
			double kik = kernel.calculate(model.getX()[i], model.getX()[k]);
			double kjk = kernel.calculate(model.getX()[j], model.getX()[k]);
			E[k] += (a1 - alpha1) * y1 * kik + (a2 - alpha2) * y2 * kjk - b_old
					+ b;
		}

		return true;
	}