private IEnumerable <Configuration> SortedConfigsByError(List <Configuration> configs, List <Feature> model)
        {
            List <Tuple <Configuration, double> > list = new List <Tuple <Configuration, double> >();

            foreach (Configuration c in configs)
            {
                double estimatedValue = FeatureSubsetSelection.estimate(model, c);
                double realValue      = c.GetNFPValue(GlobalState.currentNFP);
                double error          = 0;
                switch (mlSettings.lossFunction)
                {
                case ML_Settings.LossFunction.RELATIVE:
                    error = Math.Abs((estimatedValue - realValue) / realValue);
                    break;

                case ML_Settings.LossFunction.LEASTSQUARES:
                    error = Math.Pow(realValue - estimatedValue, 2);
                    break;

                case ML_Settings.LossFunction.ABSOLUTE:
                    error = Math.Abs(realValue - estimatedValue);
                    break;
                }
                list.Add(new Tuple <Configuration, double>(c, error));
            }
            return(list.OrderByDescending(tuple => tuple.Item2).Select(tuple => tuple.Item1));
        }
        public void learn()
        {
            if (!hasNecessaryData())
                return;
            if (this.mLsettings.bagging)
            {
                //Get number of cores
                int coreCount = 0;
                foreach (var item in new System.Management.ManagementObjectSearcher("Select NumberOfCores from Win32_Processor").Get())
                {
                    coreCount += int.Parse(item["NumberOfCores"].ToString());
                }
                createThreadPool(coreCount);

                this.nbBaggings = this.mLsettings.baggingNumbers;
                iCount = this.nbBaggings;
                Random rand = new Random();
                int nbOfConfigs = (testSet.Count * this.mLsettings.baggingTestDataFraction) / 100;
                for (int i = 0; i < nbBaggings; i++)
                {
                    InfluenceModel infMod = new InfluenceModel(GlobalState.varModel, GlobalState.currentNFP);
                    FeatureSubsetSelection sel = new FeatureSubsetSelection(infMod, this.mLsettings);
                    this.models.Add(sel);
                    List<int> selection = new List<int>();
                    for (int r = 0; r <= nbOfConfigs; r++)
                    {
                        selection.Add(rand.Next(nbOfConfigs));
                    }
                    List<Configuration> newTestSet = new List<Configuration>();
                    List<Configuration> newValidationSet = new List<Configuration>();
                    for (int r = 0; r <= selection.Count; r++)
                    {
                        if (selection.Contains(r))
                            newTestSet.Add(testSet[r]);
                        else
                            newValidationSet.Add(testSet[r]);
                    }
                    sel.setLearningSet(newTestSet);
                    sel.setValidationSet(newValidationSet);
                    Task task = EnqueueTask(() => sel.learn());
                }
                eventX.WaitOne(Timeout.Infinite, true);
                averageModels();
            }
            else
            {
                InfluenceModel infMod = new InfluenceModel(GlobalState.varModel, GlobalState.currentNFP);
                FeatureSubsetSelection sel = new FeatureSubsetSelection(infMod, this.mLsettings);
                this.models.Add(sel);
                sel.setLearningSet(testSet);
                sel.setValidationSet(this.validationSet);
                Stopwatch sw = new Stopwatch();
                sw.Start();
                sel.learn();
                sw.Stop();
                Console.WriteLine("Elapsed={0}", sw.Elapsed);
            }
        }
        /// <summary>
        /// Clears the binary and numeric selections stored in this object. 
        /// </summary>
        public void clearSampling()
        {
            binarySamplings_Learning = "";
            binarySelections_Learning = new List<List<BinaryOption>>();

            binarySamplings_Validation = "";
            binarySelections_Validation = new List<List<BinaryOption>>();

            numericSamplings_Learning = "";
            numericSelection_Learning = new List<Dictionary<NumericOption, double>>();

            numericSamplings_Validation = "";
            numericSelection_Validation = new List<Dictionary<NumericOption, double>>();

            this.learning = new FeatureSubsetSelection();
        }