Esempio n. 1
0
brent_iterate(ref brent_state_t state, Func<double, double> f, out double root, ref double x_lower, ref double x_upper)
		{
			double tol, m;

			bool ac_equal = false;

			double a = state.a, b = state.b, c = state.c;
			double fa = state.fa, fb = state.fb, fc = state.fc;
			double d = state.d, e = state.e;

			if ((fb < 0 && fc < 0) || (fb > 0 && fc > 0))
			{
				ac_equal = true;
				c = a;
				fc = fa;
				d = b - a;
				e = b - a;
			}

			if (Math.Abs(fc) < Math.Abs(fb))
			{
				ac_equal = true;
				a = b;
				b = c;
				c = a;
				fa = fb;
				fb = fc;
				fc = fa;
			}

			tol = 0.5 * DoubleConstants.DBL_EPSILON * Math.Abs(b);
			m = 0.5 * (c - b);

			if (fb == 0)
			{
				root = b;
				x_lower = b;
				x_upper = b;

				return null;
			}

			if (Math.Abs(m) <= tol)
			{
				root = b;

				if (b < c)
				{
					x_lower = b;
					x_upper = c;
				}
				else
				{
					x_lower = c;
					x_upper = b;
				}

				return null;
			}

			if (Math.Abs(e) < tol || Math.Abs(fa) <= Math.Abs(fb))
			{
				d = m;            /* use bisection */
				e = m;
			}
			else
			{
				double p, q, r;   /* use inverse cubic interpolation */
				double s = fb / fa;

				if (ac_equal)
				{
					p = 2 * m * s;
					q = 1 - s;
				}
				else
				{
					q = fa / fc;
					r = fb / fc;
					p = s * (2 * m * q * (q - r) - (b - a) * (r - 1));
					q = (q - 1) * (r - 1) * (s - 1);
				}

				if (p > 0)
				{
					q = -q;
				}
				else
				{
					p = -p;
				}

				if (2 * p < Math.Min(3 * m * q - Math.Abs(tol * q), Math.Abs(e * q)))
				{
					e = d;
					d = p / q;
				}
				else
				{
					/* interpolation failed, fall back to bisection */

					d = m;
					e = m;
				}
			}

			a = b;
			fa = fb;

			if (Math.Abs(d) > tol)
			{
				b += d;
			}
			else
			{
				b += (m > 0 ? +tol : -tol);
			}

			fb = f(b);

			state.a = a;
			state.b = b;
			state.c = c;
			state.d = d;
			state.e = e;
			state.fa = fa;
			state.fb = fb;
			state.fc = fc;

			/* Update the best estimate of the root and bounds on each
				 iteration */

			root = b;

			if ((fb < 0 && fc < 0) || (fb > 0 && fc > 0))
			{
				c = a;
			}

			if (b < c)
			{
				x_lower = b;
				x_upper = c;
			}
			else
			{
				x_lower = c;
				x_upper = b;
			}

			return null;
		}
Esempio n. 2
0
        brent_iterate(ref brent_state_t state, Func <double, double> f, out double root, ref double x_lower, ref double x_upper)
        {
            double tol, m;

            bool ac_equal = false;

            double a = state.a, b = state.b, c = state.c;
            double fa = state.fa, fb = state.fb, fc = state.fc;
            double d = state.d, e = state.e;

            if ((fb < 0 && fc < 0) || (fb > 0 && fc > 0))
            {
                ac_equal = true;
                c        = a;
                fc       = fa;
                d        = b - a;
                e        = b - a;
            }

            if (Math.Abs(fc) < Math.Abs(fb))
            {
                ac_equal = true;
                a        = b;
                b        = c;
                c        = a;
                fa       = fb;
                fb       = fc;
                fc       = fa;
            }

            tol = 0.5 * DoubleConstants.DBL_EPSILON * Math.Abs(b);
            m   = 0.5 * (c - b);

            if (fb == 0)
            {
                root    = b;
                x_lower = b;
                x_upper = b;

                return(null);
            }

            if (Math.Abs(m) <= tol)
            {
                root = b;

                if (b < c)
                {
                    x_lower = b;
                    x_upper = c;
                }
                else
                {
                    x_lower = c;
                    x_upper = b;
                }

                return(null);
            }

            if (Math.Abs(e) < tol || Math.Abs(fa) <= Math.Abs(fb))
            {
                d = m;    /* use bisection */
                e = m;
            }
            else
            {
                double p, q, r; /* use inverse cubic interpolation */
                double s = fb / fa;

                if (ac_equal)
                {
                    p = 2 * m * s;
                    q = 1 - s;
                }
                else
                {
                    q = fa / fc;
                    r = fb / fc;
                    p = s * (2 * m * q * (q - r) - (b - a) * (r - 1));
                    q = (q - 1) * (r - 1) * (s - 1);
                }

                if (p > 0)
                {
                    q = -q;
                }
                else
                {
                    p = -p;
                }

                if (2 * p < Math.Min(3 * m * q - Math.Abs(tol * q), Math.Abs(e * q)))
                {
                    e = d;
                    d = p / q;
                }
                else
                {
                    /* interpolation failed, fall back to bisection */

                    d = m;
                    e = m;
                }
            }

            a  = b;
            fa = fb;

            if (Math.Abs(d) > tol)
            {
                b += d;
            }
            else
            {
                b += (m > 0 ? +tol : -tol);
            }

            fb = f(b);

            state.a  = a;
            state.b  = b;
            state.c  = c;
            state.d  = d;
            state.e  = e;
            state.fa = fa;
            state.fb = fb;
            state.fc = fc;

            /* Update the best estimate of the root and bounds on each
             *                         iteration */

            root = b;

            if ((fb < 0 && fc < 0) || (fb > 0 && fc > 0))
            {
                c = a;
            }

            if (b < c)
            {
                x_lower = b;
                x_upper = c;
            }
            else
            {
                x_lower = c;
                x_upper = b;
            }

            return(null);
        }
Esempio n. 3
0
		brent_init(Func<double, double> f, double x_lower, double x_upper, out double root, out brent_state_t state)
		{
			double f_lower, f_upper;

			root = 0.5 * (x_lower + x_upper);

			f_lower = f(x_lower);
			f_upper = f(x_upper);

			state.a = x_lower;
			state.fa = f_lower;

			state.b = x_upper;
			state.fb = f_upper;

			state.c = x_upper;
			state.fc = f_upper;

			state.d = x_upper - x_lower;
			state.e = x_upper - x_lower;

			if ((f_lower < 0.0 && f_upper < 0.0) || (f_lower > 0.0 && f_upper > 0.0))
			{
				return new GSL_ERROR("endpoints do not straddle y=0", GSL_ERR.GSL_EINVAL, false);
			}

			return null;
		}
Esempio n. 4
0
        brent_init(Func <double, double> f, double x_lower, double x_upper, out double root, out brent_state_t state)
        {
            double f_lower, f_upper;

            root = 0.5 * (x_lower + x_upper);

            f_lower = f(x_lower);
            f_upper = f(x_upper);

            state.a  = x_lower;
            state.fa = f_lower;

            state.b  = x_upper;
            state.fb = f_upper;

            state.c  = x_upper;
            state.fc = f_upper;

            state.d = x_upper - x_lower;
            state.e = x_upper - x_lower;

            if ((f_lower < 0.0 && f_upper < 0.0) || (f_lower > 0.0 && f_upper > 0.0))
            {
                return(new GSL_ERROR("endpoints do not straddle y=0", GSL_ERR.GSL_EINVAL, false));
            }

            return(null);
        }