示例#1
0
        private static double IntegrateSimpsonsRule(FunctionOneVar f, double low, double high, int steps)
        {
            double retval   = 0;
            double stepSize = (high - low) / (double)steps;
            double leftVal  = 0;
            double midVal   = 0;
            double rightVal = 0;

            leftVal = f(low);

            if (steps % 2 == 1)
            {
                steps++;
            }

            for (int i = 2; i <= steps; i += 2)
            {
                double xmid   = low + (i - 1) * stepSize;
                double xright = low + i * stepSize;

                midVal   = f(xmid);
                rightVal = f(xright);

                retval += (leftVal + 4 * midVal + rightVal) * stepSize / 3.0;

                leftVal = rightVal;
            }

            return(retval);
        }
示例#2
0
        public static double Derivative(FunctionOneVar f, double x, double step)
        {
            double val = f(x);

            if (double.IsNaN(val) || double.IsInfinity(val))
                return double.NaN;

            double valRight = f(x + step);
            double valLeft = f(x - step);

            // if they're both NaN, we can't do anything.
            if (double.IsNaN(valRight) && double.IsNaN(valLeft))
                return double.NaN;

            // if only one is NaN, we can still do a first order derivative.
            else if (double.IsNaN(valLeft) || double.IsInfinity(valLeft))
            {
                valLeft = val;

                return (valRight - valLeft) / step;
            }
            else if (double.IsNaN(valRight) || double.IsInfinity(valRight))
            {
                valRight = val;

                return (valRight - valLeft) / step;
            }
            // wel, everything seems good here:
            else
                return (valRight - valLeft) / (2 * step);
        }
示例#3
0
        /// <summary>
        /// Finds the point at which given function is at the given value, using the bisection algorithm.
        /// </summary>
        /// <param name="f">The function whose root we are supposed to find.</param>
        /// <param name="low">The lower end of the range within to look for a root.</param>
        /// <param name="high">The upper end of the range within to look for a root.</param>
        /// <param name="value">The value to look for.</param>
        /// <returns></returns>
        public double ValueByBisection(FunctionOneVar f, double low, double high, double value)
        {
            mFunctionToCall = f;
            mFunctionValue  = value;

            double retval = s_RootByBisection(pValueFunction, low, high, mTolerance, mMaxIterations);

            mFunctionToCall = null;
            mFunctionValue  = 0;

            return(retval);
        }
示例#4
0
        /// <summary>
        /// Finds the root of a passed function.  Returns the value of x for which f(x) = 0.
        /// </summary>
        /// <param name="f">The function whose root we are supposed to find.</param>
        /// <param name="low">The lower end of the range within to look for a root.</param>
        /// <param name="high">The upper end of the range within to look for a root.</param>
        /// <param name="maxIterations">The maximum number of iterations in which to look.</param>
        /// <param name="tolerance">The level of tolerance at which the result should differ from the
        /// correct value.  The actual value used is (tolerance * (f(high) - f(low) / 2)). </param>
        /// <returns></returns>
        public static double s_RootByBisection(FunctionOneVar f, double low, double high, double tolerance, int maxIterations)
        {
            double x     = (low + high) / 2.0;
            double f_val = f(x);
            double f_low = f(low);

            while (double.IsNaN(f_low))
            {
                low += (high - low) / 1000.0;

                f_low = f(low);
            }

            double f_high = f(high);

            while (double.IsNaN(f_high))
            {
                high -= (high - low) / 1000.0;

                f_high = f(high);
            }

            double tol = Math.Abs(tolerance * (f_high - f_low) / 2);

            if (f_low * f_high >= 0)
            {
                throw new Exception("Error: Range given is not guaranteed to bracket a zero.");
            }

            int nIterations = 0;

            do
            {
                f_val = f(x);

                if (f_val * f_low < 0)
                {
                    high   = x;
                    f_high = f_val;
                }
                else if (f_val * f_high < 0)
                {
                    low   = x;
                    f_low = f_val;
                }

                x = (low + high) / 2.0;

                nIterations++;
            } while (nIterations < maxIterations && Math.Abs(f_val) > tol);

            return(x);
        }
示例#5
0
        private static double IntegrateTrapezoidRule(FunctionOneVar f, double low, double high, int steps)
        {
            double retval   = 0;
            double stepSize = (high - low) / (double)steps;
            double leftVal  = 0;
            double rightVal = 0;

            leftVal = f(low);

            for (int i = 1; i <= steps; i++)
            {
                double x = low + i * stepSize;

                rightVal = f(x);

                retval += 0.5 * (rightVal + leftVal) * stepSize;

                leftVal = rightVal;
            }

            return(retval);
        }
示例#6
0
        public static double Derivative(FunctionOneVar f, double x, double step)
        {
            double val = f(x);

            if (double.IsNaN(val) || double.IsInfinity(val))
            {
                return(double.NaN);
            }

            double valRight = f(x + step);
            double valLeft  = f(x - step);

            // if they're both NaN, we can't do anything.
            if (double.IsNaN(valRight) && double.IsNaN(valLeft))
            {
                return(double.NaN);
            }

            // if only one is NaN, we can still do a first order derivative.
            else if (double.IsNaN(valLeft) || double.IsInfinity(valLeft))
            {
                valLeft = val;

                return((valRight - valLeft) / step);
            }
            else if (double.IsNaN(valRight) || double.IsInfinity(valRight))
            {
                valRight = val;

                return((valRight - valLeft) / step);
            }
            // wel, everything seems good here:
            else
            {
                return((valRight - valLeft) / (2 * step));
            }
        }
示例#7
0
 /// <summary>
 /// Finds the root of the given function using the bisection algorithm.
 /// </summary>
 /// <param name="f">The function whose root we are supposed to find.</param>
 /// <param name="low">The lower end of the range within to look for a root.</param>
 /// <param name="high">The upper end of the range within to look for a root.</param>
 /// <returns></returns>
 public double RootByBisection(FunctionOneVar f, double low, double high)
 {
     return(s_RootByBisection(f, low, high, mTolerance, mMaxIterations));
 }
示例#8
0
 public static double Integrate(FunctionOneVar f, double low, double high, int steps)
 {
     return(IntegrateSimpsonsRule(f, low, high, steps));
     //return IntegrateTrapezoidRule(f, low, high, steps);
 }
示例#9
0
        public static double s_MinimumByBisection(FunctionOneVar f, double x_low, double x_high, double tolerance, int maxIterations)
        {
            double x_center = (x_low + x_high) / 2.0;
            double f_center = f(x_center);
            double f_low    = f(x_low);
            double f_high   = f(x_high);
            double tol      = tolerance * (f_high - f_low) / 2;

            int nIterations = 0;

            // check to see if we've failed to bracket a minimum.
            while (nIterations < maxIterations && f_center > f_low)
            {
                x_high = x_center;
                f_high = f_center;

                x_center = (x_low + x_high) / 2.0;
                f_center = f(x_center);

                nIterations++;
            }
            while (nIterations < maxIterations && f_center > f_high)
            {
                x_low = x_center;
                f_low = f_center;

                x_center = (x_low + x_high) / 2.0;
                f_center = f(x_center);

                nIterations++;
            }

            do
            {
                // examine right bracket
                double x     = (x_high + x_center) / 2;
                double f_val = f(x);

                if (f_center < f_val)
                {
                    x_high = x;
                    f_high = f_val;
                }
                else
                {
                    x_low    = x_center;
                    x_center = x;

                    f_low    = f_center;
                    f_center = f_val;
                }

                // examine left bracket
                x     = (x_low + x_center) / 2;
                f_val = f(x);

                if (f_center < f_val)
                {
                    x_low = x;
                    f_low = f_val;
                }
                else
                {
                    x_high   = x_center;
                    x_center = x;

                    f_high   = f_center;
                    f_center = f_val;
                }

                nIterations++;
            } while (nIterations < maxIterations && Math.Abs(f_high - f_low) > tol);

            return(x_center);
        }
示例#10
0
        /// <summary>
        /// Finds the root of a passed function.  Returns the value of x for which f(x) = 0.
        /// </summary>
        /// <param name="f">The function whose root we are supposed to find.</param>
        /// <param name="low">The lower end of the range within to look for a root.</param>
        /// <param name="high">The upper end of the range within to look for a root.</param>
        /// <param name="maxIterations">The maximum number of iterations in which to look.</param>
        /// <param name="tolerance">The level of tolerance at which the result should differ from the 
        /// correct value.  The actual value used is (tolerance * (f(high) - f(low) / 2)). </param>
        /// <returns></returns>
        public static double s_RootByBisection(FunctionOneVar f, double low, double high, double tolerance, int maxIterations)
        {
            double x = (low + high) / 2.0;
            double f_val = f(x);
            double f_low = f(low);

            while (double.IsNaN(f_low))
            {
                low += (high - low) / 1000.0;

                f_low = f(low);
            }

            double f_high = f(high);

            while (double.IsNaN(f_high))
            {
                high -= (high - low) / 1000.0;

                f_high = f(high);
            }

            double tol = Math.Abs(tolerance * (f_high - f_low) / 2);

            if (f_low * f_high >= 0)
                throw new Exception("Error: Range given is not guaranteed to bracket a zero.");

            int nIterations = 0;

            do
            {
                f_val = f(x);

                if (f_val * f_low < 0)
                {
                    high = x;
                    f_high = f_val;
                }
                else if (f_val * f_high < 0)
                {
                    low = x;
                    f_low = f_val;
                }

                x = (low + high) / 2.0;

                nIterations++;

            } while (nIterations < maxIterations && Math.Abs(f_val) > tol) ;

            return x;
        }
示例#11
0
 public static double Integrate(FunctionOneVar f, double low, double high, int steps)
 {
     return IntegrateSimpsonsRule(f, low, high, steps);
     //return IntegrateTrapezoidRule(f, low, high, steps);
 }
示例#12
0
        private static double IntegrateTrapezoidRule(FunctionOneVar f, double low, double high, int steps)
        {
            double retval = 0;
            double stepSize = (high - low) / (double)steps;
            double leftVal = 0;
            double rightVal = 0;

            leftVal = f(low);

            for (int i = 1; i <= steps; i++)
            {
                double x = low + i * stepSize;

                rightVal = f(x);

                retval += 0.5 * (rightVal + leftVal) * stepSize;

                leftVal = rightVal;

            }

            return retval;
        }
示例#13
0
        private static double IntegrateSimpsonsRule(FunctionOneVar f, double low, double high, int steps)
        {
            double retval = 0;
            double stepSize = (high - low) / (double)steps;
            double leftVal = 0;
            double midVal = 0;
            double rightVal = 0;

            leftVal = f(low);

            if (steps % 2 == 1)
                steps++;

            for (int i = 2; i <= steps; i += 2)
            {
                double xmid = low + (i - 1) * stepSize;
                double xright = low + i * stepSize;

                midVal = f(xmid);
                rightVal = f(xright);

                retval += (leftVal + 4 * midVal + rightVal) * stepSize / 3.0;

                leftVal = rightVal;

            }

            return retval;
        }
示例#14
0
        /// <summary>
        /// Finds the point at which given function is at the given value, using the bisection algorithm.
        /// </summary>
        /// <param name="f">The function whose root we are supposed to find.</param>
        /// <param name="low">The lower end of the range within to look for a root.</param>
        /// <param name="high">The upper end of the range within to look for a root.</param>
        /// <param name="value">The value to look for.</param>
        /// <returns></returns>
        public double ValueByBisection(FunctionOneVar f, double low, double high, double value)
        {
            mFunctionToCall = f;
            mFunctionValue = value;

            double retval = s_RootByBisection(pValueFunction, low, high, mTolerance, mMaxIterations);

            mFunctionToCall = null;
            mFunctionValue = 0;

            return retval;
        }
示例#15
0
 /// <summary>
 /// Finds the root of the given function using the bisection algorithm.
 /// </summary>
 /// <param name="f">The function whose root we are supposed to find.</param>
 /// <param name="low">The lower end of the range within to look for a root.</param>
 /// <param name="high">The upper end of the range within to look for a root.</param>
 /// <returns></returns>
 public double RootByBisection(FunctionOneVar f, double low, double high)
 {
     return s_RootByBisection(f, low, high, mTolerance, mMaxIterations);
 }
示例#16
0
 public double MinimumByBisection(FunctionOneVar f, double low, double high)
 {
     return s_MinimumByBisection(f, low, high, Tolerance, MaxIterations);
 }
示例#17
0
 public double MinimumByBisection(FunctionOneVar f, double low, double high)
 {
     return(s_MinimumByBisection(f, low, high, Tolerance, MaxIterations));
 }
示例#18
0
        public static double s_MinimumByBisection(FunctionOneVar f, double x_low, double x_high, double tolerance, int maxIterations)
        {
            double x_center = (x_low + x_high) / 2.0;
            double f_center = f(x_center);
            double f_low = f(x_low);
            double f_high = f(x_high);
            double tol = tolerance * (f_high - f_low) / 2;

            int nIterations = 0;

            // check to see if we've failed to bracket a minimum.
            while (nIterations < maxIterations && f_center > f_low)
            {
                x_high = x_center;
                f_high = f_center;

                x_center = (x_low + x_high) / 2.0;
                f_center = f(x_center);

                nIterations++;
            }
            while (nIterations < maxIterations && f_center > f_high)
            {
                x_low = x_center;
                f_low = f_center;

                x_center = (x_low + x_high) / 2.0;
                f_center = f(x_center);

                nIterations++;
            }

            do
            {
                // examine right bracket
                double x = (x_high + x_center) / 2;
                double f_val = f(x);

                if (f_center < f_val)
                {
                    x_high = x;
                    f_high = f_val;
                }
                else
                {
                    x_low = x_center;
                    x_center = x;

                    f_low = f_center;
                    f_center = f_val;
                }

                // examine left bracket
                x = (x_low + x_center) / 2;
                f_val = f(x);

                if (f_center < f_val)
                {
                    x_low = x;
                    f_low = f_val;
                }
                else
                {
                    x_high = x_center;
                    x_center = x;

                    f_high = f_center;
                    f_center = f_val;
                }

                nIterations++;

            } while (nIterations < maxIterations && Math.Abs(f_high - f_low) > tol);

            return x_center;
        }