Lobj = alph1 + L - 0.5 * k11 * alph1 * alph1 - 0.5 * k22 * L * L - s * k12 * alph1 * L - y1 * alph1 * v1 - y2 * L * v2; Hobj = alph1 + H - 0.5 * k11 * alph1 * alph1 - 0.5 * k22 * H * H - s * k12 * alph1 * H - y1 * alph1 * v1 - y2 * H * v2;
double gamma = alph1 + s * alph2; Lobj = (gamma - s * L) + L - 0.5 * k11 * (gamma - s * L) * (gamma - s * L) - 0.5 * k22 * L * L - s * k12 * (gamma - s * L) * L - y1 * (gamma - s * L) * v1 - y2 * L * v2; Hobj = (gamma - s * H) + H - 0.5 * k11 * (gamma - s * H) * (gamma - s * H) - 0.5 * k22 * H * H - s * k12 * (gamma - s * H) * H - y1 * (gamma - s * H) * v1 - y2 * H * v2;
  private boolean takeStep(int i1, int i2, double E2) throws Exception {    Instance inst1, inst2;    double alph1, alph2, y1, y2, E1, s, L, H, k11, k12, k22, eta,      a1, a2, f1, f2, v1, v2, Lobj, Hobj, b1, b2, bOld;        // Don't do anything if the two instances are the same    if (i1 == i2) {      return false;    }    // Initialize variables    inst1 = m_data.instance(i1); inst2 = m_data.instance(i2);    alph1 = m_alpha[i1]; alph2 = m_alpha[i2];    y1 = m_class[i1]; y2 = m_class[i2];    if ((alph1 > 0) && (alph1 < m_C)) {      E1 = m_errors[i1];    } else {      E1 = SVMOutput(inst1) - y1;    }    s = y1 * y2;    // Find the constraints on a2    if (y1 != y2) {      L = Math.max(0, alph2 - alph1);       H = Math.min(m_C, m_C + alph2 - alph1);    } else {      L = Math.max(0, alph1 + alph2 - m_C);      H = Math.min(m_C, alph1 + alph2);    }    if (L == H) {      return false;    }    // Compute second derivative of objective function    k11 = kernel(inst1, inst1);    k12 = kernel(inst1, inst2);    k22 = kernel(inst2, inst2);    eta = 2 * k12 - k11 - k22;    // Check if second derivative is negative    if (eta < 0) {      // Compute unconstrained maximum      a2 = alph2 - y2 * (E1 - E2) / eta;      // Compute constrained maximum      if (a2 < L) {	a2 = L;      } else if (a2 > H) {	a2 = H;      }    } else {      // Look at endpoints of diagonal      f1 = SVMOutput(inst1);      f2 = SVMOutput(inst2);      v1 = f1 + m_b - y1 * alph1 * k11 - y2 * alph2 * k12;       v2 = f2 + m_b - y1 * alph1 * k12 - y2 * alph2 * k22;       Lobj = alph1 + L - 0.5 * k11 * alph1 * alph1 - 	0.5 * k22 * L * L - s * k12 * alph1 * L - 	y1 * alph1 * v1 - y2 * L * v2;      Hobj = alph1 + H - 0.5 * k11 * alph1 * alph1 - 	0.5 * k22 * H * H - s * k12 * alph1 * H - 	y1 * alph1 * v1 - y2 * H * v2;      if (Lobj > Hobj + m_eps) {	a2 = L;      } else if (Lobj < Hobj - m_eps) {	a2 = H;      } else {	a2 = alph2;      }    }    if (Math.abs(a2 - alph2) < m_eps * (a2 + alph2 + m_eps)) {      return false;    }    // Compute new value of a1    a1 = alph1 + s * (alph2 - a2);    // Update threshold to reflect change in Lagrange multipliers    bOld = m_b;    b1 = E1 + y1 * (a1 - alph1) * k11 + y2 * (a2 - alph2) * k12 + m_b;    b2 = E2 + y1 * (a1 - alph1) * k12 + y2 * (a2 - alph2) * k22 + m_b;    if ((a1 > 0) && (a1 < m_C)) {      m_b = b1;    } else if ((a2 > 0) && (a2 < m_C)) {      m_b = b2;    } else if (L != H) {      m_b = (b1 + b2) / 2;    } else {      throw new Exception("This should never happen!");    }        // Update weight vector to reflect change a1 and a2, if linear SVM    // (not implemented)    // Update array with Lagrange multipliers    if ((a1 > 0) && (m_alpha[i1] == 0)) {      for (int i = i1; 	   (i >= 0) && (m_nextUnbound[i] == m_nextUnbound[i1 + 1]); i--) {	m_nextUnbound[i] = i1;      }      m_numSupportVectors++;    }    if ((a1 == 0) && (m_alpha[i1] > 0)) {      for (int i = i1; (i >= 0) && (m_nextUnbound[i] == i1); i--) {	m_nextUnbound[i] = m_nextUnbound[i1 + 1];      }      m_numSupportVectors--;    }    m_alpha[i1] = a1;    if ((a2 > 0) && (m_alpha[i2] == 0)) {      for (int i = i2; 	   (i >= 0) && (m_nextUnbound[i] == m_nextUnbound[i2 + 1]); i--) {	m_nextUnbound[i] = i2;      }      m_numSupportVectors++;    }    if ((a2 == 0) && (m_alpha[i2] > 0)) {      for (int i = i2; (i >= 0) && (m_nextUnbound[i] == i2); i--) {	m_nextUnbound[i] = m_nextUnbound[i2 + 1];      }      m_numSupportVectors--;    }    m_alpha[i2] = a2;    // Update error cache using new Lagrange multipliers    for (int j = m_nextUnbound[0]; j != -1; j = m_nextUnbound[j + 1]) {      if (m_alpha[j] < m_C) {	if ((j == i1) || (j == i2)) {	  m_errors[j] = 0;	} else {	  m_errors[j] += 	    y1 * (a1 - alph1) * kernel(inst1, m_data.instance(j)) +	    y2 * (a2 - alph2) * kernel(inst2, m_data.instance(j)) + bOld - m_b;	}      }    }    // Made some progress.    return true;  }