private float FindMinObjParallel(float GMax, OrderablePartitioner <Tuple <int, int> > rangePart, int i, float[] Q_i, SortedNVal minIdx) { float GMax2Tmp = -INF; //todo: to many allocation, use range partitioner Parallel.ForEach(rangePart, () => new Pair <float, Pair <int, float> >(-INF, new Pair <int, float>(-1, INF)), (range, loopState, maxMinPair) => { int endRange = range.Item2; for (int j = range.Item1; j < endRange; j++) { if (y[j] == +1) { if (!is_lower_bound(j)) { float grad_diff = GMax + G[j]; if (G[j] >= maxMinPair.First) { maxMinPair.First = G[j]; } if (grad_diff > 0) { float obj_diff; float quad_coef = (float)(Q_i[i] + QD[j] - 2.0 * y[i] * Q_i[j]); if (quad_coef > 0) { obj_diff = -(grad_diff * grad_diff) / quad_coef; } else { obj_diff = (float)(-(grad_diff * grad_diff) / 1e-12); } if (obj_diff < maxMinPair.Second.Second) { maxMinPair.Second.First = j; maxMinPair.Second.Second = obj_diff; } } } } else { if (!is_upper_bound(j)) { float grad_diff = GMax - G[j]; if (-G[j] >= maxMinPair.First) { maxMinPair.First = -G[j]; } if (grad_diff > 0) { float obj_diff; float quad_coef = (float)(Q_i[i] + QD[j] + 2.0 * y[i] * Q_i[j]); if (quad_coef > 0) { obj_diff = -(grad_diff * grad_diff) / quad_coef; } else { obj_diff = (float)(-(grad_diff * grad_diff) / 1e-12); } if (obj_diff < maxMinPair.Second.Second) { maxMinPair.Second.First = j; maxMinPair.Second.Second = obj_diff; } } } } } return(maxMinPair); }, (maxMinPair) => { lock (lockObj) { if (GMax2Tmp < maxMinPair.First) { GMax2Tmp = maxMinPair.First; } //todo: in this solver we use only one value and index, minIdx.Add(maxMinPair.Second.First, maxMinPair.Second.Second); } } ); return(GMax2Tmp); }
//todo: remove it later, not efective private float FindMinObjParallel2(float GMax, int i, float[] Q_i, SortedNVal minIdx) { // object lockObj = new object(); float GMax2Tmp = -INF; // Parallel.For(0, active_size, () => new Pair <float, Pair <int, float> >(-INF, new Pair <int, float>(-1, INF)), (j, loopState, maxMinPair) => { if (y[j] == +1) { if (!is_lower_bound(j)) { float grad_diff = GMax + G[j]; if (G[j] >= maxMinPair.First) { maxMinPair.First = G[j]; } if (grad_diff > 0) { float obj_diff; float quad_coef = (float)(Q_i[i] + QD[j] - 2.0 * y[i] * Q_i[j]); if (quad_coef > 0) { obj_diff = -(grad_diff * grad_diff) / quad_coef; } else { obj_diff = (float)(-(grad_diff * grad_diff) / 1e-12); } if (obj_diff < maxMinPair.Second.Second) { maxMinPair.Second.First = j; maxMinPair.Second.Second = obj_diff; } } } } else { if (!is_upper_bound(j)) { float grad_diff = GMax - G[j]; if (-G[j] >= maxMinPair.First) { maxMinPair.First = -G[j]; } if (grad_diff > 0) { float obj_diff; float quad_coef = (float)(Q_i[i] + QD[j] + 2.0 * y[i] * Q_i[j]); if (quad_coef > 0) { obj_diff = -(grad_diff * grad_diff) / quad_coef; } else { obj_diff = (float)(-(grad_diff * grad_diff) / 1e-12); } if (obj_diff < maxMinPair.Second.Second) { maxMinPair.Second.First = j; maxMinPair.Second.Second = obj_diff; } } } } //if (maxMinPair.Second.First == -1) // return null; return(maxMinPair); }, (maxMinPair) => { if (maxMinPair != null && maxMinPair.Second.First != -1) { lock (lockObj) { if (GMax2Tmp < maxMinPair.First) { GMax2Tmp = maxMinPair.First; } minIdx.Add(maxMinPair.Second.First, maxMinPair.Second.Second); } } } ); return(GMax2Tmp); }
private float FindMinObjSeq(float GMax, float GMax2, int i, float[] Q_i, SortedNVal minIdx) { for (int j = 0; j < active_size; j++) { if (y[j] == +1) { if (!is_lower_bound(j)) { float grad_diff = GMax + G[j]; if (G[j] >= GMax2) { GMax2 = G[j]; } if (grad_diff > 0) { float obj_diff; float quad_coef = (float)(Q_i[i] + QD[j] - 2.0 * y[i] * Q_i[j]); if (quad_coef > 0) { obj_diff = -(grad_diff * grad_diff) / quad_coef; } else { obj_diff = (float)(-(grad_diff * grad_diff) / 1e-12); } minIdx.Add(j, obj_diff); //if (obj_diff < obj_diff_Min) //previous "<=" //{ // GMin_idx = j; // obj_diff_Min = obj_diff; // // minSecIdx.Add(new KeyValuePair<int, float>(j, obj_diff_Min)); //} //else if (obj_diff_Min < obj_diff_NMin) //{ // // minSecIdx.Add(new KeyValuePair<int, float>(j, obj_diff)); //} //else continue; } //else continue; } //else continue; } else { if (!is_upper_bound(j)) { float grad_diff = GMax - G[j]; if (-G[j] >= GMax2) { GMax2 = -G[j]; } if (grad_diff > 0) { float obj_diff; float quad_coef = (float)(Q_i[i] + QD[j] + 2.0 * y[i] * Q_i[j]); if (quad_coef > 0) { obj_diff = -(grad_diff * grad_diff) / quad_coef; } else { obj_diff = (float)(-(grad_diff * grad_diff) / 1e-12); } minIdx.Add(j, obj_diff); //if (obj_diff < obj_diff_Min) //{ // GMin_idx = j; // obj_diff_Min = obj_diff; // //minSecIdx.Add(new KeyValuePair<int, float>(j, obj_diff_Min)); //} //else if (obj_diff < obj_diff_NMin) //{ // minSecIdx.Add(new KeyValuePair<int, float>(j, obj_diff)); //} //else continue; } //else continue; } //else continue; } //if (minSecIdx.Count > pairsCount) //{ // var minPair = minSecIdx.Min; // minSecIdx.Remove(minPair); // obj_diff_NMin = minPair.Value; //} } return(GMax2); }