public OptimizationParameterList Clone()
        {
            List <OptimizationParameter> parameterCollection = new List <OptimizationParameter>();

            foreach (OptimizationParameter parameter in _asParameterList)
            {
                parameterCollection.Add(parameter.Clone());
            }
            OptimizationParameterList result = GetInstance2(parameterCollection);

            if (_enumerationOrder != null)
            {
                result.SetEnumerationOrder(_enumerationOrder);
            }
            return(result);
        }
        public bool IsClose(OptimizationParameterList other, double eps)
        {
            if (other == null)
            {
                return(false);
            }

            SpecialFunctions.CheckCondition(other.Count == Count);

            for (int iParam = 0; iParam < Count; ++iParam)
            {
                if (!IsClose(_asParameterList[iParam], other._asParameterList[iParam], eps))
                {
                    return(false);
                }
            }
            return(true);
        }
        public static OptimizationParameterList GetInstance2(IEnumerable <OptimizationParameter> parameterCollection)
        {
            OptimizationParameterList aParamsList = new OptimizationParameterList();

            foreach (OptimizationParameter parameter in parameterCollection)
            {
                aParamsList._asDictionary.Add(parameter.Name, parameter);
                aParamsList._asParameterList.Add(parameter);
            }

            // no longer requires sort.
            ////Must do this after because the parameters may get re-ordered.
            //aQmrrParams._asParameterArray = new OptimizationParameter[aQmrrParams._asSortedDictionary.Count];
            //int iParam = -1;
            //foreach (OptimizationParameter parameter in aQmrrParams._asSortedDictionary.Values)
            //{
            //    ++iParam;
            //    aQmrrParams._asParameterArray[iParam] = parameter;
            //}

            return(aParamsList);
        }
        public double Optimize(Converter <OptimizationParameterList, double> functionToOptimize,
                               //ref List<double> pointList, List<double> lowList, List<double> highList,
                               /*ref*/ OptimizationParameterList paramList, int numberOfIterationsOverParameters, int gridLineCount)
        {
            double eps = 1e-9;

            List <double> pointList = paramList.ExtractParameterValueListForSearch();
            List <double> lowList   = paramList.ExtractParameterLowListForSearch();
            List <double> highList  = paramList.ExtractParameterHighListForSearch();

            double oldScore     = double.NaN;
            double tempOldScore = functionToOptimize(paramList);
            //Console.WriteLine(tempOldScore);
            Dictionary <int, double> paramNumberToInitValue = new Dictionary <int, double>();

            for (int iterationOverParameters = 0; iterationOverParameters < numberOfIterationsOverParameters; ++iterationOverParameters)
            {
                double newScore = double.NaN;
                int    doSearchParameterCount = 0;
                foreach (OptimizationParameter paramToOptimize in paramList)
                {
                    //if (paramList.DoSearch(iParameter))
                    if (paramToOptimize.DoSearch)
                    {
                        ++doSearchParameterCount;

                        //double initValue = SpecialFunctions.GetValueOrDefault(paramNumberToInitValue, doSearchParameterCount, paramToOptimize.Value);
                        Debug.WriteLine("Search Param " + doSearchParameterCount.ToString());

                        double bestInput;
                        newScore = OneDOptimization.Run(
                            delegate(OptimizationParameter param)
                        {
                            if (!double.IsNaN(param.Value) && paramList.SatisfiesConditions())
                            {
                                return(functionToOptimize(paramList));
                            }
                            else
                            {
                                return(double.NaN);
                            }
                        },
                            /*ref*/ paramToOptimize, gridLineCount, out bestInput);

                        Debug.WriteLine("bestInput " + bestInput.ToString());
                        if (newScore > 0)
                        {
                            Debug.Write("stop.");
                        }
                        paramToOptimize.ValueForSearch = bestInput;

                        //Debug.WriteLine("END ITER:" + SpecialFunctions.CreateTabString2(point) + SpecialFunctions.CreateTabString("", newScore));
                    }
                }
                if ((!double.IsNaN(oldScore) && Math.Abs(oldScore - newScore) < eps) ||
                    doSearchParameterCount < 2)    //If only 0 or 1 searchable params, then one pass is enough
                {
                    oldScore = newScore;
                    break;
                }
                oldScore = newScore;
            }


            return(oldScore);
        }