double L = Math.max(0, -gamma - C2); double H = Math.min(C1, -gamma);
double L = Math.max(0, -gamma - C1); double H = Math.min(C2, -gamma);
  protected boolean findOptimalPointOnLine(int i1, double alpha1, double alpha1Star, double C1,       int i2, double alpha2, double alpha2Star, double C2,       double gamma, double eta, double deltaPhi) {    if (eta <= 0) {      // this may happen due to numeric instability      // due to Mercer's condition, this should not happen, hence we give up      return false;    }        boolean case1 = false;    boolean case2 = false;    boolean case3 = false;    boolean case4 = false;    boolean finished = false;        //		while !finished     //		% this loop is passed at most three times     //		% case variables needed to avoid attempting small changes twice     while (!finished) {      //			if (case1 == 0) &&       //				(alpha1 > 0 || (alpha1* == 0 && deltaPhi > 0)) &&       //				(alpha2 > 0 || (alpha2* == 0 && deltaPhi < 0))       //				compute L, H (wrt. alpha1, alpha2)       //				if L < H       //					a2 = alpha2 ? - deltaPhi/eta       //					a2 = min(a2, H)       //					a2 = max(L, a2)       //					a1 = alpha1 ? - (a2 ? alpha2)       //					update alpha1, alpha2 if change is larger than some eps       //				else       //					finished = 1       //				endif       //				case1 = 1;             if ((case1 == false) && 	  (alpha1 > 0 || (alpha1Star == 0 && deltaPhi > 0)) && 	  (alpha2 > 0 || (alpha2Star == 0 && deltaPhi < 0))) {	// compute L, H (wrt. alpha1, alpha2) 	double L = Math.max(0, gamma - C2);	double H = Math.min(C1, gamma);	if (L < H) {	  double a2 = alpha2 - deltaPhi / eta;	  a2 = Math.min(a2, H);	  a2 = Math.max(L, a2);	  // To prevent precision problems	  if (a2 > C2 - m_Del * C2) {	    a2 = C2;	  } else if (a2 <= m_Del * C2) {	    a2 = 0;	  }	  double a1 = alpha1 - (a2 - alpha2);	  if (a1 > C1 - m_Del * C1) {	    a1 = C1;	  } else if (a1 <= m_Del * C1) {	    a1 = 0;	  }	  // update alpha1, alpha2 if change is larger than some eps	  if (Math.abs(alpha1 - a1) > m_eps) {	    deltaPhi += eta * (a2 - alpha2);	    alpha1 = a1;	    alpha2 = a2;	  }	} else {	  finished = true;	}	case1 = true;      }            //			elseif (case2 == 0) &&       //				(alpha1 > 0 || (alpha1* == 0 && deltaPhi > 2 epsilon)) &&       //				(alpha2* > 0 || (alpha2 == 0 && deltaPhi > 2 epsilon))       //				compute L, H (wrt. alpha1, alpha2*)       //				if L < H       //					a2 = alpha2* + (deltaPhi ?- 2 epsilon)/eta       //					a2 = min(a2, H)       //					a2 = max(L, a2)       //					a1 = alpha1 + (a2 ? alpha2*)       //					update alpha1, alpha2* if change is larger than some eps       //				else       //					finished = 1       //				endif       //				case2 = 1;             else if (	  (case2 == false)	  && (alpha1 > 0 || (alpha1Star == 0 && deltaPhi > 2 * m_epsilon))	  && (alpha2Star > 0 || (alpha2 == 0 && deltaPhi > 2 * m_epsilon))) {	// compute L, H (wrt. alpha1, alpha2*) 	double L = Math.max(0, -gamma);	double H = Math.min(C1, -gamma + C2);	if (L < H) {	  double a2 = alpha2Star + (deltaPhi - 2 * m_epsilon) / eta;	  a2 = Math.min(a2, H);	  a2 = Math.max(L, a2);	  // To prevent precision problems	  if (a2 > C2 - m_Del * C2) {	    a2 = C2;	  } else if (a2 <= m_Del * C2) {	    a2 = 0;	  }	  double a1 = alpha1 + (a2 - alpha2Star);	  if (a1 > C1 - m_Del * C1) {	    a1 = C1;	  } else if (a1 <= m_Del * C1) {	    a1 = 0;	  }	  // update alpha1, alpha2* if change is larger than some eps 	  if (Math.abs(alpha1 - a1) > m_eps) {	    deltaPhi += eta * (-a2 + alpha2Star);	    alpha1 = a1;	    alpha2Star = a2;	  }	} else {	  finished = true;	}	case2 = true;      }            //			elseif (case3 == 0) &&       //				(alpha1* > 0 || (alpha1 == 0 && deltaPhi < -2 epsilon)) &&       //				(alpha2 > 0 || (alpha2* == 0 && deltaPhi < -2 epsilon))       //				compute L, H (wrt. alpha1*, alpha2)       //				if L < H       //					a2 = alpha2 ?- (deltaPhi ?+ 2 epsilon)/eta       //					a2 = min(a2, H)       //					a2 = max(L, a2)       //					a1 = alpha1* + (a2 ? alpha2)       //					update alpha1*, alpha2 if change is larger than some eps       //				else       //					finished = 1       //				endif       //				case3 = 1;             else if (	  (case3 == false)	  && (alpha1Star > 0 || (alpha1 == 0 && deltaPhi < - 2 * m_epsilon))	  && (alpha2 > 0 || (alpha2Star == 0 && deltaPhi < - 2 * m_epsilon))) {	// compute L, H (wrt. alpha1*, alpha2)	double L = Math.max(0, gamma);	double H = Math.min(C1, C2 + gamma);	if (L < H) {	  // note Smola's psuedocode has a minus, where there should be a plus in the following line, Keerthi's is correct	  double a2 = alpha2 - (deltaPhi + 2 * m_epsilon) / eta;	  a2 = Math.min(a2, H);	  a2 = Math.max(L, a2);	  // To prevent precision problems	  if (a2 > C2 - m_Del * C2) {	    a2 = C2;	  } else if (a2 <= m_Del * C2) {	    a2 = 0;	  }	  double a1 = alpha1Star + (a2 - alpha2);	  if (a1 > C1 - m_Del * C1) {	    a1 = C1;	  } else if (a1 <= m_Del * C1) {	    a1 = 0;	  }	  // update alpha1*, alpha2 if change is larger than some eps 	  if (Math.abs(alpha1Star - a1) > m_eps) {	    deltaPhi += eta * (a2 - alpha2);	    alpha1Star = a1;	    alpha2 = a2;	  }	} else {	  finished = true;	}	case3 = true;      }            //			elseif (case4 == 0) &&       //				(alpha1* > 0 || (alpha1 == 0 && deltaPhi < 0)) &&       //				(alpha2* > 0 || (alpha2 == 0 && deltaPhi > 0))       //				compute L, H (wrt. alpha1*, alpha2*)       //				if L < H       //					a2 = alpha2* + deltaPhi/eta       //					a2 = min(a2, H)       //					a2 = max(L, a2)       //					a1 = alpha1* ? (a2 ? alpha2*)       //					update alpha1*, alpha2* if change is larger than some eps       //				else       //					finished = 1       //				endif       //				case4 = 1;       //			else       //				finished = 1       //			endif             else if ((case4 == false) && 	  (alpha1Star > 0 || (alpha1 == 0 && deltaPhi < 0)) && 	  (alpha2Star > 0 || (alpha2 == 0 && deltaPhi > 0))) {	// compute L, H (wrt. alpha1*, alpha2*) 	double L = Math.max(0, -gamma - C2);	double H = Math.min(C1, -gamma);	if (L < H) {	  double a2 = alpha2Star + deltaPhi / eta;	  a2 = Math.min(a2, H);	  a2 = Math.max(L, a2);	  // To prevent precision problems	  if (a2 > C2 - m_Del * C2) {	    a2 = C2;	  } else if (a2 <= m_Del * C2) {	    a2 = 0;	  }	  double a1 = alpha1Star - (a2 - alpha2Star);	  if (a1 > C1 - m_Del * C1) {	    a1 = C1;	  } else if (a1 <= m_Del * C1) {	    a1 = 0;	  }	  // update alpha1*, alpha2* if change is larger than some eps 	  if (Math.abs(alpha1Star - a1) > m_eps) {	    deltaPhi += eta * (-a2 + alpha2Star);	    	    alpha1Star = a1;	    alpha2Star = a2;	  }	} else {	  finished = true;	}	case4 = true;      } else {	finished = true;      }            //			update deltaPhi      // using 4.36 from Smola's thesis:      // deltaPhi = deltaPhi - eta * ((alpha1New-alpha1StarNew)-(alpha1-alpha1Star));      // the update is done inside the loop, saving us to remember old values of alpha1(*)      //deltaPhi += eta * ((alpha2 - alpha2Star) - dAlpha2Old);      //dAlpha2Old = (alpha2 - alpha2Star);            //		endwhile           }        if (Math.abs(alpha1 - m_alpha[i1]) > m_eps	|| Math.abs(alpha1Star - m_alphaStar[i1]) > m_eps	|| Math.abs(alpha2 - m_alpha[i2]) > m_eps	|| Math.abs(alpha2Star - m_alphaStar[i2]) > m_eps) {            if (alpha1 > C1 - m_Del * C1) {	alpha1 = C1;      } else if (alpha1 <= m_Del * C1) {	alpha1 = 0;      }      if (alpha1Star > C1 - m_Del * C1) {	alpha1Star = C1;      } else if (alpha1Star <= m_Del * C1) {	alpha1Star = 0;      }      if (alpha2 > C2 - m_Del * C2) {	alpha2 = C2;      } else if (alpha2 <= m_Del * C2) {	alpha2 = 0;      }      if (alpha2Star > C2 - m_Del * C2) {	alpha2Star = C2;      } else if (alpha2Star <= m_Del * C2) {	alpha2Star = 0;      }            // store new alpha's      m_alpha[i1] = alpha1;      m_alphaStar[i1] = alpha1Star;      m_alpha[i2] = alpha2;      m_alphaStar[i2] = alpha2Star;            // update supportvector set      if (alpha1 != 0 || alpha1Star != 0){	if (!m_supportVectors.contains(i1)) {	  m_supportVectors.insert(i1);		}      } else {	m_supportVectors.delete(i1);      }      if (alpha2 != 0 || alpha2Star != 0){	if (!m_supportVectors.contains(i2)) {	  m_supportVectors.insert(i2);	}      } else {	m_supportVectors.delete(i2);      }      return true;    }        return false;  }