Пример #1
0
 /// <summary>Apply a function to every element of every component of this vector, and replace with the result.</summary>
 /// <param name="fn">the function to apply to every element of every component.</param>
 public virtual void MapInPlace(IDoubleUnaryOperator fn)
 {
     for (int i = 0; i < pointers.Length; i++)
     {
         if (pointers[i] == null)
         {
             continue;
         }
         if (copyOnWrite[i])
         {
             copyOnWrite[i] = false;
             pointers[i]    = pointers[i].MemberwiseClone();
         }
         if (sparse[i])
         {
             pointers[i][1] = fn.ApplyAsDouble(pointers[i][1]);
         }
         else
         {
             for (int j = 0; j < pointers[i].Length; j++)
             {
                 pointers[i][j] = fn.ApplyAsDouble(pointers[i][j]);
             }
         }
     }
 }
Пример #2
0
 public virtual void Map(IDoubleUnaryOperator fn)
 {
     for (int i = 0; i < values.Length; i++)
     {
         for (int j = 0; j < values[i].Length; j++)
         {
             values[i][j] = fn.ApplyAsDouble(values[i][j]);
         }
     }
 }
Пример #3
0
        public virtual void DiscretizeCompute(IDoubleUnaryOperator function, int numPoints, double low, double high)
        {
            double inc = (high - low) / numPoints;

            memory = Generics.NewHashMap();
            for (int i = 0; i < numPoints; i++)
            {
                double x = low + i * inc;
                double y = function.ApplyAsDouble(x);
                memory[x] = y;
                log.Info("for point " + x + '\t' + y);
            }
            DumpMemory();
        }
Пример #4
0
        private double GetRoot(IDoubleUnaryOperator func, double lower, double upper)
        {
            double mid   = 0.5 * (lower + upper);
            double Tol   = 1e-8;
            double skew  = 0.4;
            int    count = 0;

            if (func.ApplyAsDouble(upper) > 0 || func.ApplyAsDouble(lower) < 0)
            {
                Say("LOWER AND UPPER SUPPLIED TO GET ROOT DO NOT BOUND THE ROOT.");
            }
            double fval = func.ApplyAsDouble(mid);

            while (System.Math.Abs(fval) > Tol)
            {
                count += 1;
                if (fval > 0)
                {
                    lower = mid;
                }
                else
                {
                    if (fval < 0)
                    {
                        upper = mid;
                    }
                }
                mid  = skew * lower + (1 - skew) * upper;
                fval = func.ApplyAsDouble(mid);
                if (count > 100)
                {
                    break;
                }
            }
            Say("   " + nf.Format(mid) + "  f" + nf.Format(fval));
            return(mid);
        }
Пример #5
0
        public virtual double Minimize(IDoubleUnaryOperator function)
        {
            double tol  = this.tol;
            double low  = this.low;
            double high = this.high;
            // cdm Oct 2006: The code used to do nothing to find or check
            // the validity of an initial
            // bracketing; it just blindly placed the midpoint at the golden ratio
            // I now try to grid search a little in case the function is very flat
            // (RTE contradictions).
            double flow  = function.ApplyAsDouble(low);
            double fhigh = function.ApplyAsDouble(high);

            if (Verbose)
            {
                log.Info("Finding min between " + low + " (value: " + flow + ") and " + high + " (value: " + fhigh + ')');
            }
            double mid;
            double oldY;
            bool   searchRight;

            if (false)
            {
                // initialize with golden means
                mid  = GoldenMean(low, high);
                oldY = function.ApplyAsDouble(mid);
                if (Verbose)
                {
                    log.Info("Initially probed at " + mid + ", value is " + oldY);
                }
                if (oldY < flow || oldY < fhigh)
                {
                    searchRight = false;
                }
                else
                {
                    // Galen had this true; should be false
                    mid  = GoldenMean(high, low);
                    oldY = function.ApplyAsDouble(mid);
                    if (Verbose)
                    {
                        log.Info("Probed at " + mid + ", value is " + oldY);
                    }
                    searchRight = true;
                    if (!(oldY < flow || oldY < fhigh))
                    {
                        log.Info("Warning: GoldenSectionLineSearch init didn't find slope!!");
                    }
                }
            }
            else
            {
                // grid search a little; this case doesn't do geometric differently...
                if (Verbose)
                {
                    log.Info("20 point gridsearch for good mid point....");
                }
                double bestPoint = low;
                double bestVal   = flow;
                double incr      = (high - low) / 22.0;
                for (mid = low + incr; mid < high; mid += incr)
                {
                    oldY = function.ApplyAsDouble(mid);
                    if (Verbose)
                    {
                        log.Info("Probed at " + mid + ", value is " + oldY);
                    }
                    if (oldY < bestVal)
                    {
                        bestPoint = mid;
                        bestVal   = oldY;
                        if (Verbose)
                        {
                            log.Info(" [best so far!]");
                        }
                    }
                    if (Verbose)
                    {
                        log.Info();
                    }
                }
                mid         = bestPoint;
                oldY        = bestVal;
                searchRight = mid < low + (high - low) / 2.0;
                if (oldY < flow && oldY < fhigh)
                {
                    if (Verbose)
                    {
                        log.Info("Found a good mid point at (" + mid + ", " + oldY + ')');
                    }
                }
                else
                {
                    log.Info("Warning: GoldenSectionLineSearch grid search couldn't find slope!!");
                    // revert to initial positioning and pray
                    mid         = GoldenMean(low, high);
                    oldY        = function.ApplyAsDouble(mid);
                    searchRight = false;
                }
            }
            memory[mid] = oldY;
            while (geometric ? (high / low > 1 + tol) : high - low > tol)
            {
                if (Verbose)
                {
                    log.Info("Current low, mid, high: " + nf.Format(low) + ' ' + nf.Format(mid) + ' ' + nf.Format(high));
                }
                double newX = GoldenMean(searchRight ? high : low, mid);
                double newY = function.ApplyAsDouble(newX);
                memory[newX] = newY;
                if (Verbose)
                {
                    log.Info("Probed " + (searchRight ? "right" : "left") + " at " + newX + ", value is " + newY);
                }
                if (newY < oldY)
                {
                    // keep going in this direction
                    if (searchRight)
                    {
                        low = mid;
                    }
                    else
                    {
                        high = mid;
                    }
                    mid  = newX;
                    oldY = newY;
                }
                else
                {
                    // go the other way
                    if (searchRight)
                    {
                        high = newX;
                    }
                    else
                    {
                        low = newX;
                    }
                    searchRight = !searchRight;
                }
            }
            return(mid);
        }