Beispiel #1
0
        public ParallelSmoFanSolver2(Problem <TProblemElement> problem, IKernel <TProblemElement> kernel, float C)
            : base(problem, kernel, C)
        {
            //todo: add checking if kernel is initialized

            //remeber that we have variable kernel in base class
            Q = new CachedKernel <TProblemElement>(problem, kernel);

            //get diagonal cache, kernel should compute that
            QD = Q.GetQD();

            //Shrinking = false;
            //todo: change it, add array to base class with different penalty for labels
            Cp          = C;
            Cn          = C;
            problemSize = problem.ElementsCount;

            numberOfThreads = Environment.ProcessorCount;

            rangeSize   = (int)Math.Ceiling((problemSize + 0.0) / numberOfThreads);
            partition   = Partitioner.Create(0, problemSize, rangeSize);
            resetEvents = new ManualResetEvent[numberOfThreads];
            //max data structures
            maxPairsWaitCallbacks = new WaitCallback[numberOfThreads];
            //data for finding maxPair in svm solver
            maxPairThreadsData = new MaxFindingThreadData[numberOfThreads];
            maxPairs           = new Pair <int, float> [numberOfThreads];

            //min data structures
            minPairsWaitCallbacks = new WaitCallback[numberOfThreads];
            //data for finding minPair in svm solver
            minPairThreadsData = new MinFindingThreadData[numberOfThreads];
            minPairs           = new Pair <int, float> [numberOfThreads];

            //int startRange = 0;
            //int endRange = startRange + rangeSize;

            Tuple <int, int>[] ranges = ListHelper.CreateRanges(problemSize, numberOfThreads);

            for (int i = 0; i < numberOfThreads; i++)
            {
                resetEvents[i] = new ManualResetEvent(false);
                maxPairs[i]    = new Pair <int, float>(-1, float.NegativeInfinity);

                maxPairThreadsData[i] = new MaxFindingThreadData()
                {
                    ResetEvent = resetEvents[i],
                    Pair       = maxPairs[i],
                    //Range = new Tuple<int, int>(startRange, endRange)
                    Range = ranges[i]
                };

                maxPairsWaitCallbacks[i] = new WaitCallback(this.FindMaxPairInThread);

                minPairs[i]           = new Pair <int, float>(-1, float.PositiveInfinity);
                minPairThreadsData[i] = new MinFindingThreadData()
                {
                    ResetEvent = resetEvents[i],
                    Pair       = minPairs[i],
                    //Range = new Tuple<int, int>(startRange, endRange)
                    Range = ranges[i]
                };

                minPairsWaitCallbacks[i] = new WaitCallback(this.FindMinPairInThread);


                //change the range
                //startRange = endRange;
                //int rangeSum = endRange + rangeSize;
                //endRange = rangeSum < problemSize ? rangeSum : problemSize;
            }
        }
Beispiel #2
0
        /// <summary>
        /// finds min 'j' in svm solver, its called in separate thread
        /// and find it in specific range of array
        /// </summary>
        /// <param name="threadData"></param>
        private void FindMinPairInThread(object threadData)
        {
            MinFindingThreadData data        = (MinFindingThreadData)threadData;
            Pair <int, float>    localMaxMin = data.Pair;


            float GMax2 = float.NegativeInfinity;

            int   i         = data.GMaxIdx;
            float obj_diff  = 0;
            float quad_coef = 0;
            float grad_diff = 0;

            for (int j = data.Range.Item1; j < data.Range.Item2; j++)
            {
                if (y[j] == +1)
                {
                    if (!is_lower_bound(j))
                    {
                        grad_diff = data.GMax + G[j];
                        //save max value
                        if (G[j] >= GMax2)
                        {
                            GMax2 = G[j];
                        }



                        if (grad_diff > 0)
                        {
                            quad_coef = (float)(data.Q_i[i] + QD[j] - 2.0 * y[i] * data.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 < localMaxMin.Second)
                            {
                                localMaxMin.First = j;

                                localMaxMin.Second = obj_diff;
                            }
                        }
                    }
                }
                else
                {
                    if (!is_upper_bound(j))
                    {
                        grad_diff = data.GMax - G[j];
                        //save -max
                        if (-G[j] >= GMax2)
                        {
                            GMax2 = -G[j];
                        }

                        if (grad_diff > 0)
                        {
                            quad_coef = (float)(data.Q_i[i] + QD[j] + 2.0 * y[i] * data.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 < localMaxMin.Second)
                            {
                                localMaxMin.First  = j;
                                localMaxMin.Second = obj_diff;
                            }
                        }
                    }
                }
            }

            data.GMax2 = GMax2;

            //signal for thread that computation complete
            data.ResetEvent.Set();
        }