예제 #1
0
        //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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        // return 1 if already optimal, return 0 otherwise
        int select_working_set(int[] working_set, int pairsCount)
        {
            // return i,j such that
            // i: Maximizes -y_i * grad(f)_i, i in I_up(\alpha)
            // j: mimimizes the decrease of obj value
            //    (if quadratic coefficeint <= 0, replace it with tau)
            //    -y_j*grad(f)_j < -y_i*grad(f)_i, j in I_low(\alpha)

            float GMax = -INF;
            // float GNMax = -INF;

            float GMax2    = -INF;
            int   GMax_idx = -1;
            int   GMin_idx = -1;

            //float obj_diff_Min = INF;
            //float obj_diff_NMin = INF;


            #region find max i

            Pair <int, float> maxPair = new Pair <int, float>(-1, -INF);
            //todo: move it up to class field, in this solver active_size is constant
            var partition = Partitioner.Create(0, active_size);

            #region Find Max pair in parallel

            Parallel.ForEach(partition, () => new Pair <int, float>(-1, -INF),
                             (range, loopState, localMax) =>
            {
                int endRange = range.Item2;
                for (int t = range.Item1; t < endRange; t++)
                {
                    if (y[t] == +1)
                    {
                        if (!is_upper_bound(t))
                        {
                            if (-G[t] > localMax.Second)   //wcześniej było większe lub równe
                            {
                                localMax.First  = t;
                                localMax.Second = -G[t];
                            }
                        }
                    }
                    else
                    {
                        if (!is_lower_bound(t))
                        {
                            if (G[t] > localMax.Second)   //wcześniej było >=
                            {
                                localMax.First  = t;
                                localMax.Second = G[t];
                            }
                        }
                    }
                }
                return(localMax);
            },
                             (localMax) =>
            {
                lock (lockObj)
                {
                    if (localMax.Second > maxPair.Second)
                    {
                        maxPair = localMax;
                    }
                }
            }
                             );

            #endregion

            GMax     = maxPair.Second;
            GMax_idx = maxPair.First;

            #region original sequential find max
            //for (int t = 0; t < active_size; t++)
            //{
            //    if (y[t] == +1)
            //    {
            //        if (!is_upper_bound(t))
            //        {
            //            if (-G[t] > GMax) //wcześniej było większe lub równe
            //            {
            //                GMax = -G[t];
            //                GMax_idx = t;
            //            }
            //        }
            //    }
            //    else
            //    {
            //        if (!is_lower_bound(t))
            //        {
            //            if (G[t] > GMax) //wcześniej było >=
            //            {
            //                GMax = G[t];
            //                GMax_idx = t;
            //            }
            //        }
            //    }
            //}
            #endregion

            #endregion

            int     i   = GMax_idx;
            float[] Q_i = null;
            if (i != -1) // null Q_i not accessed: GMax=-INF if i=-1
            {
                Q_i = Q.GetQ(i, active_size);
            }

            //todo: sorted N values, for this solver we need only one value, not "pairsCount" which is equal number of cores
            //find min
            SortedNVal minIdx = new SortedNVal(pairsCount, SortedNVal.SortMode.Asc);


            GMax2 = FindMinObjParallel(GMax, partition, i, Q_i, minIdx);
            //GMax2 = FindMinObjParallel2(GMax, i, Q_i, minIdx);
            //GMax2 = FindMinObjSeq(GMax, GMax2, i, Q_i, minIdx);

            if (GMax + GMax2 < EPS)
            {
                return(1);
            }

            if (minIdx.Count > 0)
            {
                GMin_idx = minIdx.ToArray()[0].Key;
            }
            else
            {
                GMin_idx = -1;
            }
            working_set[0] = GMax_idx;
            working_set[1] = GMin_idx;
            return(0);
        }