public virtual double TuneDouble(Func function, double[] initial, long msPerTest, StochasticMinimizer.IPropertySetter <double> ps, double lower, double upper, double Tol)
        {
            double[] xtest = new double[initial.Length];
            this.maxTime = msPerTest;
            // check for stochastic derivatives
            if (!(function is AbstractStochasticCachingDiffFunction))
            {
                throw new NotSupportedException();
            }
            AbstractStochasticCachingDiffFunction dfunction = (AbstractStochasticCachingDiffFunction)function;
            IList <Pair <double, double> >        res       = new List <Pair <double, double> >();
            Pair <double, double> best = new Pair <double, double>(lower, double.PositiveInfinity);
            //this is set to lower because the first it will always use the lower first, so it has to be best
            Pair <double, double> low   = new Pair <double, double>(lower, double.PositiveInfinity);
            Pair <double, double> high  = new Pair <double, double>(upper, double.PositiveInfinity);
            Pair <double, double> cur   = new Pair <double, double>();
            Pair <double, double> tmp   = new Pair <double, double>();
            IList <double>        queue = new List <double>();

            queue.Add(lower);
            queue.Add(upper);
            //queue.add(0.5* (lower + upper));
            bool toContinue = true;

            this.numPasses = 10000;
            do
            {
                System.Array.Copy(initial, 0, xtest, 0, initial.Length);
                if (queue.Count != 0)
                {
                    cur.first = queue.Remove(0);
                }
                else
                {
                    cur.first = 0.5 * (low.First() + high.First());
                }
                ps.Set(cur.First());
                log.Info(string.Empty);
                log.Info("About to test with batch size:  " + bSize + "  gain: " + gain + " and  " + ps.ToString() + " set to  " + cur.First());
                xtest = this.Minimize(function, 1e-100, xtest);
                if (double.IsNaN(xtest[0]))
                {
                    cur.second = double.PositiveInfinity;
                }
                else
                {
                    cur.second = dfunction.ValueAt(xtest);
                }
                if (cur.Second() < best.Second())
                {
                    CopyPair(best, tmp);
                    CopyPair(cur, best);
                    if (tmp.First() > best.First())
                    {
                        CopyPair(tmp, high);
                    }
                    else
                    {
                        // The old best is now the upper bound
                        CopyPair(tmp, low);
                    }
                    // The old best is now the lower bound
                    queue.Add(0.5 * (cur.First() + high.First()));
                }
                else
                {
                    // check in the right interval next
                    if (cur.First() < best.First())
                    {
                        CopyPair(cur, low);
                    }
                    else
                    {
                        if (cur.First() > best.First())
                        {
                            CopyPair(cur, high);
                        }
                    }
                }
                if (System.Math.Abs(low.First() - high.First()) < Tol)
                {
                    toContinue = false;
                }
                res.Add(new Pair <double, double>(cur.First(), cur.Second()));
                log.Info(string.Empty);
                log.Info("Final value is: " + nf.Format(cur.Second()));
                log.Info("Optimal so far using " + ps.ToString() + " is: " + best.First());
            }while (toContinue);
            //output the results to screen.
            log.Info("-------------");
            log.Info(" RESULTS          ");
            log.Info(ps.GetType().ToString());
            log.Info("-------------");
            log.Info("  val    ,    function after " + msPerTest + " ms");
            foreach (Pair <double, double> re in res)
            {
                log.Info(re.First() + "    ,    " + re.Second());
            }
            log.Info(string.Empty);
            log.Info(string.Empty);
            return(best.First());
        }
 public virtual double TuneDouble(Func function, double[] initial, long msPerTest, StochasticMinimizer.IPropertySetter <double> ps, double lower, double upper)
 {
     return(this.TuneDouble(function, initial, msPerTest, ps, lower, upper, 1e-3 * System.Math.Abs(upper - lower)));
 }