Example #1
0
        gsl_integration_qagil(Func <double, double> f,
                              double b,
                              double epsabs, double epsrel, int limit,
                              gsl_integration_workspace workspace,
                              out double result, out double abserr, gsl_integration_rule q, bool bDebug)
        {
            //int status;

            // gsl_function f_transform;
            var transform_params = new il_params
            {
                b = b,
                f = f
            };

            //  f_transform.function = &il_transform;
            //  f_transform.params = &transform_params;

            Func <double, double> f_transform = delegate(double t)
            { return(il_transform(t, transform_params)); };

            GSL_ERROR status = qags(f_transform, 0.0, 1.0,
                                    epsabs, epsrel, limit,
                                    workspace,
                                    out result, out abserr,
                                    q, bDebug);

            return(status);
        }
Example #2
0
 /// <summary>
 /// Adaptive integration with known singular points.
 /// </summary>
 /// <param name="f">Function to integrate.</param>
 /// <param name="pts">Range of integration including the known singular points, see remarks here: <see cref="QagpIntegration"/></param>
 /// <param name="epsabs">Specifies the expected absolute error of integration. Should be set to zero (0) if you specify a relative error.</param>
 /// <param name="epsrel">Specifies the expected relative error of integration. Should be set to zero (0) if you specify an absolute error.</param>
 /// <param name="limit">Maximum number of subintervals used for integration.</param>
 /// <param name="integrationRule">Integration rule used for integration (only for this function call).</param>
 /// <param name="debug">Setting of the debug flag (only for this function call). If the integration fails or the specified accuracy
 /// is not reached, an exception is thrown if the debug flag is set to true. If set to false, the return value of the integration
 /// function will be set to the appropriate error code (an exception will be thrown then only for serious errors).</param>
 /// <param name="result">On return, contains the integration result.</param>
 /// <param name="abserr">On return, contains the absolute error of integration.</param>
 /// <returns>Null if successfull, otherwise the appropriate error code.</returns>
 public GSL_ERROR Integrate(Func <double, double> f,
                            double[] pts,
                            double epsabs, double epsrel, int limit,
                            gsl_integration_rule integrationRule, bool debug,
                            out double result, out double abserr)
 {
     return(Integrate(f, pts, pts.Length, epsabs, epsrel, limit, integrationRule, debug, out result, out abserr));
 }
Example #3
0
        /// <summary>
        /// Adaptive integration on infinite interval (-Infinity,+Infinity).
        /// </summary>
        /// <param name="f">Function to integrate.</param>
        /// <param name="epsabs">Specifies the expected absolute error of integration. Should be set to zero (0) if you specify a relative error.</param>
        /// <param name="epsrel">Specifies the expected relative error of integration. Should be set to zero (0) if you specify an absolute error.</param>
        /// <param name="limit">Maximum number of subintervals used for integration.</param>
        /// <param name="integrationRule">Integration rule used for integration (only for this function call).</param>
        /// <param name="debug">Setting of the debug flag (only for this function call). If the integration fails or the specified accuracy
        /// is not reached, an exception is thrown if the debug flag is set to true. If set to false, the return value of the integration
        /// function will be set to the appropriate error code (an exception will be thrown then only for serious errors).</param>
        /// <param name="result">On return, contains the integration result.</param>
        /// <param name="abserr">On return, contains the absolute error of integration.</param>
        /// <returns>Null if successfull, otherwise the appropriate error code.</returns>
        public static GSL_ERROR Integration(Func <double, double> f,
                                            double epsabs, double epsrel,
                                            int limit,
                                            gsl_integration_rule integrationRule, bool debug,
                                            out double result, out double abserr
                                            )
        {
            object tempStorage = null;

            return(Integration(f, epsabs, epsrel, limit, integrationRule, debug, out result, out abserr, ref tempStorage));
        }
Example #4
0
        Integration(Func <double, double> f,
                    double b,
                    double epsabs, double epsrel,
                    int limit,
                    gsl_integration_rule q, bool debug,
                    out double result, out double abserr
                    )
        {
            object tempStorage = null;

            return(Integration(f, b, epsabs, epsrel, limit, q, debug, out result, out abserr, ref tempStorage));
        }
Example #5
0
        /// <summary>
        /// Adaptive integration on infinite interval (-Infinity,+Infinity).
        /// </summary>
        /// <param name="f">Function to integrate.</param>
        /// <param name="epsabs">Specifies the expected absolute error of integration. Should be set to zero (0) if you specify a relative error.</param>
        /// <param name="epsrel">Specifies the expected relative error of integration. Should be set to zero (0) if you specify an absolute error.</param>
        /// <param name="limit">Maximum number of subintervals used for integration.</param>
        /// <param name="integrationRule">Integration rule used for integration (only for this function call).</param>
        /// <param name="debug">Setting of the debug flag (only for this function call). If the integration fails or the specified accuracy
        /// is not reached, an exception is thrown if the debug flag is set to true. If set to false, the return value of the integration
        /// function will be set to the appropriate error code (an exception will be thrown then only for serious errors).</param>
        /// <param name="result">On return, contains the integration result.</param>
        /// <param name="abserr">On return, contains the absolute error of integration.</param>
        /// <returns>Null if successfull, otherwise the appropriate error code.</returns>
        public GSL_ERROR Integrate(Func <double, double> f,
                                   double epsabs, double epsrel, int limit,
                                   gsl_integration_rule integrationRule, bool debug,
                                   out double result, out double abserr)
        {
            if (null == _workSpace || limit > _workSpace.limit)
            {
                _workSpace = new gsl_integration_workspace(limit);
            }

            return(gsl_integration_qagi(f, epsabs, epsrel, limit, _workSpace, out result, out abserr, integrationRule, debug));
        }
Example #6
0
        /// <summary>
        /// Adaptive integration on infinite interval (-Infinity,+Infinity).
        /// </summary>
        /// <param name="f">Function to integrate.</param>
        /// <param name="epsabs">Specifies the expected absolute error of integration. Should be set to zero (0) if you specify a relative error.</param>
        /// <param name="epsrel">Specifies the expected relative error of integration. Should be set to zero (0) if you specify an absolute error.</param>
        /// <param name="limit">Maximum number of subintervals used for integration.</param>
        /// <param name="integrationRule">Integration rule used for integration (only for this function call).</param>
        /// <param name="debug">Setting of the debug flag (only for this function call). If the integration fails or the specified accuracy
        /// is not reached, an exception is thrown if the debug flag is set to true. If set to false, the return value of the integration
        /// function will be set to the appropriate error code (an exception will be thrown then only for serious errors).</param>
        /// <param name="result">On return, contains the integration result.</param>
        /// <param name="abserr">On return, contains the absolute error of integration.</param>
        /// <param name="tempStorage">Provides a temporary storage object that you can reuse for repeating function calls.</param>
        /// <returns>Null if successfull, otherwise the appropriate error code.</returns>
        public static GSL_ERROR Integration(Func <double, double> f,
                                            double epsabs, double epsrel,
                                            int limit,
                                            gsl_integration_rule integrationRule, bool debug,
                                            out double result, out double abserr,
                                            ref object tempStorage)
        {
            var algo = tempStorage as QagiIntegration;

            if (null == algo)
            {
                tempStorage = algo = new QagiIntegration(integrationRule, debug);
            }
            return(algo.Integrate(f, epsabs, epsrel, limit, integrationRule, debug, out result, out abserr));
        }
Example #7
0
        qags(Func <double, double> f,
             double a, double b,
             double epsabs, double epsrel,
             int limit,
             gsl_integration_workspace workspace,
             out double result, out double abserr,
             gsl_integration_rule q, bool bDebug)
        {
            double area, errsum;
            double res_ext, err_ext;
            double tolerance;

            double ertest = 0;
            double error_over_large_intervals = 0;
            double reseps = 0, abseps = 0, correc = 0;
            int    ktmin = 0;
            int    roundoff_type1 = 0, roundoff_type2 = 0, roundoff_type3 = 0;
            int    error_type           = 0;
            bool   error_type2          = false;

            int iteration               = 0;

            bool positive_integrand = false;
            bool extrapolate            = false;
            bool disallow_extrapolation = false;

            var table = new extrapolation_table();

            /* Initialize results */

            workspace.initialise(a, b);

            result = double.NaN;
            abserr = double.NaN;

            if (limit > workspace.limit)
            {
                return(new GSL_ERROR("iteration limit exceeds available workspace", GSL_ERR.GSL_EINVAL, bDebug));
            }

            /* Test on accuracy */

            if (epsabs <= 0 && (epsrel < 50 * GSL_CONST.GSL_DBL_EPSILON || epsrel < 0.5e-28))
            {
                return(new GSL_ERROR("tolerance cannot be acheived with given epsabs and epsrel",
                                     GSL_ERR.GSL_EBADTOL, bDebug));
            }

            /* Perform the first integration */

            q(f, a, b, out var result0, out var abserr0, out var resabs0, out var resasc0);

            workspace.set_initial_result(result0, abserr0);

            tolerance = Math.Max(epsabs, epsrel * Math.Abs(result0));

            if (abserr0 <= 100 * GSL_CONST.GSL_DBL_EPSILON * resabs0 && abserr0 > tolerance)
            {
                result = result0;
                abserr = abserr0;

                return(new GSL_ERROR("cannot reach tolerance because of roundoff error on first attempt", GSL_ERR.GSL_EROUND, bDebug));
            }
            else if ((abserr0 <= tolerance && abserr0 != resasc0) || abserr0 == 0.0)
            {
                result = result0;
                abserr = abserr0;

                return(null); // GSL_SUCCESS;
            }
            else if (limit == 1)
            {
                result = result0;
                abserr = abserr0;

                return(new GSL_ERROR("a maximum of one iteration was insufficient", GSL_ERR.GSL_EMAXITER, bDebug));
            }

            /* Initialization */

            table.initialise_table();
            table.append_table(result0);

            area   = result0;
            errsum = abserr0;

            res_ext = result0;
            err_ext = GSL_CONST.GSL_DBL_MAX;

            positive_integrand = test_positivity(result0, resabs0);

            iteration = 1;

            do
            {
                int    current_level;
                double a1, b1, a2, b2;
                double area12  = 0;
                double error12 = 0;
                double last_e_i;

                /* Bisect the subinterval with the largest error estimate */

                workspace.retrieve(out var a_i, out var b_i, out var r_i, out var e_i);

                current_level = workspace.level[workspace.i] + 1;

                a1 = a_i;
                b1 = 0.5 * (a_i + b_i);
                a2 = b1;
                b2 = b_i;

                iteration++;

                q(f, a1, b1, out var area1, out var error1, out var resabs1, out var resasc1);
                q(f, a2, b2, out var area2, out var error2, out var resabs2, out var resasc2);

                area12   = area1 + area2;
                error12  = error1 + error2;
                last_e_i = e_i;

                /* Improve previous approximations to the integral and test for
                 *                               accuracy.
                 *
                 *                               We write these expressions in the same way as the original
                 *                               QUADPACK code so that the rounding errors are the same, which
                 *                               makes testing easier. */

                errsum = errsum + error12 - e_i;
                area   = area + area12 - r_i;

                tolerance = Math.Max(epsabs, epsrel * Math.Abs(area));

                if (resasc1 != error1 && resasc2 != error2)
                {
                    double delta = r_i - area12;

                    if (Math.Abs(delta) <= 1.0e-5 * Math.Abs(area12) && error12 >= 0.99 * e_i)
                    {
                        if (!extrapolate)
                        {
                            roundoff_type1++;
                        }
                        else
                        {
                            roundoff_type2++;
                        }
                    }
                    if (iteration > 10 && error12 > e_i)
                    {
                        roundoff_type3++;
                    }
                }

                /* Test for roundoff and eventually set error flag */

                if (roundoff_type1 + roundoff_type2 >= 10 || roundoff_type3 >= 20)
                {
                    error_type = 2; /* round off error */
                }

                if (roundoff_type2 >= 5)
                {
                    error_type2 = true;
                }

                /* set error flag in the case of bad integrand behaviour at
                 *                               a point of the integration range */

                if (subinterval_too_small(a1, a2, b2))
                {
                    error_type = 4;
                }

                /* append the newly-created intervals to the list */

                workspace.update(a1, b1, area1, error1, a2, b2, area2, error2);

                if (errsum <= tolerance)
                {
                    goto compute_result;
                }

                if (0 != error_type)
                {
                    break;
                }

                if (iteration >= limit - 1)
                {
                    error_type = 1;
                    break;
                }

                if (iteration == 2) /* set up variables on first iteration */
                {
                    error_over_large_intervals = errsum;
                    ertest = tolerance;
                    table.append_table(area);
                    continue;
                }

                if (disallow_extrapolation)
                {
                    continue;
                }

                error_over_large_intervals += -last_e_i;

                if (current_level < workspace.maximum_level)
                {
                    error_over_large_intervals += error12;
                }

                if (!extrapolate)
                {
                    /* test whether the interval to be bisected next is the
                     *                                     smallest interval. */

                    if (workspace.large_interval())
                    {
                        continue;
                    }

                    extrapolate     = true;
                    workspace.nrmax = 1;
                }

                if (!error_type2 && error_over_large_intervals > ertest)
                {
                    if (workspace.increase_nrmax())
                    {
                        continue;
                    }
                }

                /* Perform extrapolation */

                table.append_table(area);

                table.qelg(out reseps, out abseps);

                ktmin++;

                if (ktmin > 5 && err_ext < 0.001 * errsum)
                {
                    error_type = 5;
                }

                if (abseps < err_ext)
                {
                    ktmin   = 0;
                    err_ext = abseps;
                    res_ext = reseps;
                    correc  = error_over_large_intervals;
                    ertest  = Math.Max(epsabs, epsrel * Math.Abs(reseps));
                    if (err_ext <= ertest)
                    {
                        break;
                    }
                }

                /* Prepare bisection of the smallest interval. */

                if (table.n == 1)
                {
                    disallow_extrapolation = true;
                }

                if (error_type == 5)
                {
                    break;
                }

                /* work on interval with largest error */

                workspace.reset_nrmax();
                extrapolate = false;
                error_over_large_intervals = errsum;
            }while (iteration < limit);

            result = res_ext;
            abserr = err_ext;

            if (err_ext == GSL_CONST.GSL_DBL_MAX)
            {
                goto compute_result;
            }

            if (0 != error_type || error_type2)
            {
                if (error_type2)
                {
                    err_ext += correc;
                }

                if (error_type == 0)
                {
                    error_type = 3;
                }

                if (res_ext != 0.0 && area != 0.0)
                {
                    if (err_ext / Math.Abs(res_ext) > errsum / Math.Abs(area))
                    {
                        goto compute_result;
                    }
                }
                else if (err_ext > errsum)
                {
                    goto compute_result;
                }
                else if (area == 0.0)
                {
                    goto return_error;
                }
            }

            /*  Test on divergence. */

            {
                double max_area = Math.Max(Math.Abs(res_ext), Math.Abs(area));

                if (!positive_integrand && max_area < 0.01 * resabs0)
                {
                    goto return_error;
                }
            }

            {
                double ratio = res_ext / area;

                if (ratio < 0.01 || ratio > 100.0 || errsum > Math.Abs(area))
                {
                    error_type = 6;
                }
            }

            goto return_error;

compute_result:

            result = workspace.sum_results();
            abserr = errsum;

return_error:

            if (error_type > 2)
            {
                error_type--;
            }

            if (error_type == 0)
            {
                return(null); // GSL_SUCCESS;
            }
            else if (error_type == 1)
            {
                return(new GSL_ERROR("number of iterations was insufficient", GSL_ERR.GSL_EMAXITER, bDebug));
            }
            else if (error_type == 2)
            {
                return(new GSL_ERROR("cannot reach tolerance because of roundoff error",
                                     GSL_ERR.GSL_EROUND, bDebug));
            }
            else if (error_type == 3)
            {
                return(new GSL_ERROR("bad integrand behavior found in the integration interval",
                                     GSL_ERR.GSL_ESING, bDebug));
            }
            else if (error_type == 4)
            {
                return(new GSL_ERROR("roundoff error detected in the extrapolation table",
                                     GSL_ERR.GSL_EROUND, bDebug));
            }
            else if (error_type == 5)
            {
                return(new GSL_ERROR("integral is divergent, or slowly convergent",
                                     GSL_ERR.GSL_EDIVERGE, bDebug));
            }
            else
            {
                return(new GSL_ERROR("could not integrate function", GSL_ERR.GSL_EFAILED, bDebug));
            }
        }
Example #8
0
		/// <summary>
		/// Creates an instance of this integration class with specified integration rule and specified debug flag setting.
		/// </summary>
		/// <param name="integrationRule">Integration rule used for integration.</param>
		/// <param name="debug">Setting of the debug flag for this instance. If the integration fails or the specified accuracy
		/// is not reached, an exception is thrown if the debug flag is set to true. If set to false, the return value of the integration
		/// function will be set to the appropriate error code (an exception will be thrown then only for serious errors).</param>
		public QagiIntegration(gsl_integration_rule integrationRule, bool debug)
		{
			_integrationRule = integrationRule;
			_debug = debug;
		}
Example #9
0
		gsl_integration_qagi(Func<double, double> f,
													double epsabs, double epsrel, int limit,
													gsl_integration_workspace workspace,
													out double result, out double abserr,
													gsl_integration_rule q, bool bDebug
			)
		{
			//int status;

			//  gsl_function f_transform;
			//  f_transform.function = &i_transform;
			//  f_transform.params = f;

			Func<double, double> f_transform = delegate(double t) { return i_transform(t, f); };

			GSL_ERROR status = qags(f_transform, 0.0, 1.0,
										 epsabs, epsrel, limit,
										 workspace,
										 out result, out abserr,
										 q, bDebug);

			return status;
		}
Example #10
0
		/// <summary>
		/// Adaptive integration on infinite interval (-Infinity,+Infinity).
		/// </summary>
		/// <param name="f">Function to integrate.</param>
		/// <param name="epsabs">Specifies the expected absolute error of integration. Should be set to zero (0) if you specify a relative error.</param>
		/// <param name="epsrel">Specifies the expected relative error of integration. Should be set to zero (0) if you specify an absolute error.</param>
		/// <param name="limit">Maximum number of subintervals used for integration.</param>
		/// <param name="integrationRule">Integration rule used for integration (only for this function call).</param>
		/// <param name="debug">Setting of the debug flag (only for this function call). If the integration fails or the specified accuracy
		/// is not reached, an exception is thrown if the debug flag is set to true. If set to false, the return value of the integration
		/// function will be set to the appropriate error code (an exception will be thrown then only for serious errors).</param>
		/// <param name="result">On return, contains the integration result.</param>
		/// <param name="abserr">On return, contains the absolute error of integration.</param>
		/// <returns>Null if successfull, otherwise the appropriate error code.</returns>
		public static GSL_ERROR Integration(Func<double, double> f,
		 double epsabs, double epsrel,
		 int limit,
			gsl_integration_rule integrationRule, bool debug,
		 out double result, out double abserr
		 )
		{
			object tempStorage = null;
			return Integration(f, epsabs, epsrel, limit, integrationRule, debug, out result, out abserr, ref tempStorage);
		}
Example #11
0
		/// <summary>
		/// Adaptive integration on infinite interval (-Infinity,+Infinity).
		/// </summary>
		/// <param name="f">Function to integrate.</param>
		/// <param name="epsabs">Specifies the expected absolute error of integration. Should be set to zero (0) if you specify a relative error.</param>
		/// <param name="epsrel">Specifies the expected relative error of integration. Should be set to zero (0) if you specify an absolute error.</param>
		/// <param name="limit">Maximum number of subintervals used for integration.</param>
		/// <param name="integrationRule">Integration rule used for integration (only for this function call).</param>
		/// <param name="debug">Setting of the debug flag (only for this function call). If the integration fails or the specified accuracy
		/// is not reached, an exception is thrown if the debug flag is set to true. If set to false, the return value of the integration
		/// function will be set to the appropriate error code (an exception will be thrown then only for serious errors).</param>
		/// <param name="result">On return, contains the integration result.</param>
		/// <param name="abserr">On return, contains the absolute error of integration.</param>
		/// <returns>Null if successfull, otherwise the appropriate error code.</returns>
		public GSL_ERROR Integrate(Func<double, double> f,
				double epsabs, double epsrel, int limit,
			 gsl_integration_rule integrationRule, bool debug,
			 out double result, out double abserr)
		{
			if (null == _workSpace || limit > _workSpace.limit)
				_workSpace = new gsl_integration_workspace(limit);

			return gsl_integration_qagi(f, epsabs, epsrel, limit, _workSpace, out result, out abserr, integrationRule, debug);
		}
Example #12
0
		qag(Func<double, double> f,
				 double a, double b,
				 double epsabs, double epsrel,
				 int limit,
				 gsl_integration_workspace workspace,
				 out double result, out double abserr,
				 gsl_integration_rule q,
				 bool bDebug)
		{
			double area, errsum;
			double result0, abserr0, resabs0, resasc0;
			double tolerance;
			int iteration = 0;
			int roundoff_type1 = 0, roundoff_type2 = 0, error_type = 0;

			double round_off;

			/* Initialize results */

			workspace.initialise(a, b);

			result = 0;
			abserr = 0;

			if (limit > workspace.limit)
			{
				return new GSL_ERROR("iteration limit exceeds available workspace", GSL_ERR.GSL_EINVAL, true);
			}

			if (epsabs <= 0 && (epsrel < 50 * GSL_CONST.GSL_DBL_EPSILON || epsrel < 0.5e-28))
			{
				return new GSL_ERROR("tolerance cannot be acheived with given epsabs and epsrel",
									 GSL_ERR.GSL_EBADTOL, true);
			}

			/* perform the first integration */

			q(f, a, b, out result0, out abserr0, out resabs0, out resasc0);

			workspace.set_initial_result(result0, abserr0);

			/* Test on accuracy */

			tolerance = Math.Max(epsabs, epsrel * Math.Abs(result0));

			/* need IEEE rounding here to match original quadpack behavior */

			round_off = GSL_COERCE_DBL(50 * GSL_CONST.GSL_DBL_EPSILON * resabs0);

			if (abserr0 <= round_off && abserr0 > tolerance)
			{
				result = result0;
				abserr = abserr0;

				return new GSL_ERROR("cannot reach tolerance because of roundoff error on first attempt", GSL_ERR.GSL_EROUND, bDebug);
			}
			else if ((abserr0 <= tolerance && abserr0 != resasc0) || abserr0 == 0.0)
			{
				result = result0;
				abserr = abserr0;

				return null; //GSL_SUCCESS;
			}
			else if (limit == 1)
			{
				result = result0;
				abserr = abserr0;

				return new GSL_ERROR("a maximum of one iteration was insufficient", GSL_ERR.GSL_EMAXITER, bDebug);
			}

			area = result0;
			errsum = abserr0;

			iteration = 1;

			do
			{
				double a1, b1, a2, b2;
				double a_i, b_i, r_i, e_i;
				double area1 = 0, area2 = 0, area12 = 0;
				double error1 = 0, error2 = 0, error12 = 0;
				double resasc1, resasc2;
				double resabs1, resabs2;

				/* Bisect the subinterval with the largest error estimate */

				workspace.retrieve(out a_i, out b_i, out r_i, out e_i);

				a1 = a_i;
				b1 = 0.5 * (a_i + b_i);
				a2 = b1;
				b2 = b_i;

				q(f, a1, b1, out area1, out error1, out resabs1, out resasc1);
				q(f, a2, b2, out area2, out error2, out resabs2, out resasc2);

				area12 = area1 + area2;
				error12 = error1 + error2;

				errsum += (error12 - e_i);
				area += area12 - r_i;

				if (resasc1 != error1 && resasc2 != error2)
				{
					double delta = r_i - area12;

					if (Math.Abs(delta) <= 1.0e-5 * Math.Abs(area12) && error12 >= 0.99 * e_i)
					{
						roundoff_type1++;
					}
					if (iteration >= 10 && error12 > e_i)
					{
						roundoff_type2++;
					}
				}

				tolerance = Math.Max(epsabs, epsrel * Math.Abs(area));

				if (errsum > tolerance)
				{
					if (roundoff_type1 >= 6 || roundoff_type2 >= 20)
					{
						error_type = 2;   /* round off error */
					}

					/* set error flag in the case of bad integrand behaviour at
						 a point of the integration range */

					if (subinterval_too_small(a1, a2, b2))
					{
						error_type = 3;
					}
				}

				workspace.update(a1, b1, area1, error1, a2, b2, area2, error2);

				workspace.retrieve(out a_i, out b_i, out r_i, out e_i);

				iteration++;
			}
			while (iteration < limit && 0 == error_type && errsum > tolerance);

			result = workspace.sum_results();
			abserr = errsum;

			if (errsum <= tolerance)
			{
				return null; //GSL_SUCCESS;
			}
			else if (error_type == 2)
			{
				return new GSL_ERROR("roundoff error prevents tolerance from being achieved",
									 GSL_ERR.GSL_EROUND, bDebug);
			}
			else if (error_type == 3)
			{
				return new GSL_ERROR("bad integrand behavior found in the integration interval",
									 GSL_ERR.GSL_ESING, bDebug);
			}
			else if (iteration == limit)
			{
				return new GSL_ERROR("maximum number of subdivisions reached", GSL_ERR.GSL_EMAXITER, bDebug);
			}
			else
			{
				return new GSL_ERROR("could not integrate function", GSL_ERR.GSL_EFAILED, bDebug);
			}
		}
Example #13
0
		/// <summary>
		/// Adaptive integration with known singular points.
		/// </summary>
		/// <param name="f">Function to integrate.</param>
		/// <param name="pts">Range of integration including the known singular points, see remarks here: <see cref="QagpIntegration"/></param>
		/// <param name="epsabs">Specifies the expected absolute error of integration. Should be set to zero (0) if you specify a relative error.</param>
		/// <param name="epsrel">Specifies the expected relative error of integration. Should be set to zero (0) if you specify an absolute error.</param>
		/// <param name="limit">Maximum number of subintervals used for integration.</param>
		/// <param name="integrationRule">Integration rule used for integration (only for this function call).</param>
		/// <param name="debug">Setting of the debug flag (only for this function call). If the integration fails or the specified accuracy
		/// is not reached, an exception is thrown if the debug flag is set to true. If set to false, the return value of the integration
		/// function will be set to the appropriate error code (an exception will be thrown then only for serious errors).</param>
		/// <param name="result">On return, contains the integration result.</param>
		/// <param name="abserr">On return, contains the absolute error of integration.</param>
		/// <returns>Null if successfull, otherwise the appropriate error code.</returns>
		public GSL_ERROR Integrate(Func<double, double> f,
			double[] pts,
			double epsabs, double epsrel, int limit,
			gsl_integration_rule integrationRule, bool debug,
			out double result, out double abserr)
		{
			return Integrate(f, pts, pts.Length, epsabs, epsrel, limit, integrationRule, debug, out result, out abserr);
		}
Example #14
0
 /// <summary>
 /// Creates an instance of this integration class with specified integration rule and specified debug flag setting.
 /// </summary>
 /// <param name="integrationRule">Integration rule used for integration.</param>
 /// <param name="debug">Setting of the debug flag for this instance. If the integration fails or the specified accuracy
 /// is not reached, an exception is thrown if the debug flag is set to true. If set to false, the return value of the integration
 /// function will be set to the appropriate error code (an exception will be thrown then only for serious errors).</param>
 public QagilIntegration(gsl_integration_rule integrationRule, bool debug)
 {
     _integrationRule = integrationRule;
     _debug           = debug;
 }
Example #15
0
		/// <summary>
		/// Adaptive integration on infinite interval (-Infinity,+Infinity).
		/// </summary>
		/// <param name="f">Function to integrate.</param>
		/// <param name="epsabs">Specifies the expected absolute error of integration. Should be set to zero (0) if you specify a relative error.</param>
		/// <param name="epsrel">Specifies the expected relative error of integration. Should be set to zero (0) if you specify an absolute error.</param>
		/// <param name="limit">Maximum number of subintervals used for integration.</param>
		/// <param name="integrationRule">Integration rule used for integration (only for this function call).</param>
		/// <param name="debug">Setting of the debug flag (only for this function call). If the integration fails or the specified accuracy
		/// is not reached, an exception is thrown if the debug flag is set to true. If set to false, the return value of the integration
		/// function will be set to the appropriate error code (an exception will be thrown then only for serious errors).</param>
		/// <param name="result">On return, contains the integration result.</param>
		/// <param name="abserr">On return, contains the absolute error of integration.</param>
		/// <param name="tempStorage">Provides a temporary storage object that you can reuse for repeating function calls.</param>
		/// <returns>Null if successfull, otherwise the appropriate error code.</returns>
		public static GSL_ERROR Integration(Func<double, double> f,
					double epsabs, double epsrel,
					int limit,
					gsl_integration_rule integrationRule, bool debug,
					out double result, out double abserr,
					ref object tempStorage)
		{
			QagiIntegration algo = tempStorage as QagiIntegration;
			if (null == algo)
				tempStorage = algo = new QagiIntegration(integrationRule, debug);
			return algo.Integrate(f, epsabs, epsrel, limit, integrationRule, debug, out result, out abserr);
		}
Example #16
0
		qags(Func<double, double> f,
					double a, double b,
					double epsabs, double epsrel,
					int limit,
					gsl_integration_workspace workspace,
					out double result, out double abserr,
					gsl_integration_rule q, bool bDebug)
		{
			double area, errsum;
			double res_ext, err_ext;
			double result0, abserr0, resabs0, resasc0;
			double tolerance;

			double ertest = 0;
			double error_over_large_intervals = 0;
			double reseps = 0, abseps = 0, correc = 0;
			int ktmin = 0;
			int roundoff_type1 = 0, roundoff_type2 = 0, roundoff_type3 = 0;
			int error_type = 0;
			bool error_type2 = false;

			int iteration = 0;

			bool positive_integrand = false;
			bool extrapolate = false;
			bool disallow_extrapolation = false;

			extrapolation_table table = new extrapolation_table();

			/* Initialize results */

			workspace.initialise(a, b);

			result = double.NaN;
			abserr = double.NaN;

			if (limit > workspace.limit)
			{
				return new GSL_ERROR("iteration limit exceeds available workspace", GSL_ERR.GSL_EINVAL, bDebug);
			}

			/* Test on accuracy */

			if (epsabs <= 0 && (epsrel < 50 * GSL_CONST.GSL_DBL_EPSILON || epsrel < 0.5e-28))
			{
				return new GSL_ERROR("tolerance cannot be acheived with given epsabs and epsrel",
									 GSL_ERR.GSL_EBADTOL, bDebug);
			}

			/* Perform the first integration */

			q(f, a, b, out result0, out abserr0, out resabs0, out resasc0);

			workspace.set_initial_result(result0, abserr0);

			tolerance = Math.Max(epsabs, epsrel * Math.Abs(result0));

			if (abserr0 <= 100 * GSL_CONST.GSL_DBL_EPSILON * resabs0 && abserr0 > tolerance)
			{
				result = result0;
				abserr = abserr0;

				return new GSL_ERROR("cannot reach tolerance because of roundoff error on first attempt", GSL_ERR.GSL_EROUND, bDebug);
			}
			else if ((abserr0 <= tolerance && abserr0 != resasc0) || abserr0 == 0.0)
			{
				result = result0;
				abserr = abserr0;

				return null; // GSL_SUCCESS;
			}
			else if (limit == 1)
			{
				result = result0;
				abserr = abserr0;

				return new GSL_ERROR("a maximum of one iteration was insufficient", GSL_ERR.GSL_EMAXITER, bDebug);
			}

			/* Initialization */

			table.initialise_table();
			table.append_table(result0);

			area = result0;
			errsum = abserr0;

			res_ext = result0;
			err_ext = GSL_CONST.GSL_DBL_MAX;

			positive_integrand = test_positivity(result0, resabs0);

			iteration = 1;

			do
			{
				int current_level;
				double a1, b1, a2, b2;
				double a_i, b_i, r_i, e_i;
				double area1 = 0, area2 = 0, area12 = 0;
				double error1 = 0, error2 = 0, error12 = 0;
				double resasc1, resasc2;
				double resabs1, resabs2;
				double last_e_i;

				/* Bisect the subinterval with the largest error estimate */

				workspace.retrieve(out a_i, out b_i, out r_i, out e_i);

				current_level = workspace.level[workspace.i] + 1;

				a1 = a_i;
				b1 = 0.5 * (a_i + b_i);
				a2 = b1;
				b2 = b_i;

				iteration++;

				q(f, a1, b1, out area1, out error1, out resabs1, out resasc1);
				q(f, a2, b2, out area2, out error2, out resabs2, out resasc2);

				area12 = area1 + area2;
				error12 = error1 + error2;
				last_e_i = e_i;

				/* Improve previous approximations to the integral and test for
					 accuracy.

					 We write these expressions in the same way as the original
					 QUADPACK code so that the rounding errors are the same, which
					 makes testing easier. */

				errsum = errsum + error12 - e_i;
				area = area + area12 - r_i;

				tolerance = Math.Max(epsabs, epsrel * Math.Abs(area));

				if (resasc1 != error1 && resasc2 != error2)
				{
					double delta = r_i - area12;

					if (Math.Abs(delta) <= 1.0e-5 * Math.Abs(area12) && error12 >= 0.99 * e_i)
					{
						if (!extrapolate)
						{
							roundoff_type1++;
						}
						else
						{
							roundoff_type2++;
						}
					}
					if (iteration > 10 && error12 > e_i)
					{
						roundoff_type3++;
					}
				}

				/* Test for roundoff and eventually set error flag */

				if (roundoff_type1 + roundoff_type2 >= 10 || roundoff_type3 >= 20)
				{
					error_type = 2;       /* round off error */
				}

				if (roundoff_type2 >= 5)
				{
					error_type2 = true;
				}

				/* set error flag in the case of bad integrand behaviour at
					 a point of the integration range */

				if (subinterval_too_small(a1, a2, b2))
				{
					error_type = 4;
				}

				/* append the newly-created intervals to the list */

				workspace.update(a1, b1, area1, error1, a2, b2, area2, error2);

				if (errsum <= tolerance)
				{
					goto compute_result;
				}

				if (0 != error_type)
				{
					break;
				}

				if (iteration >= limit - 1)
				{
					error_type = 1;
					break;
				}

				if (iteration == 2)       /* set up variables on first iteration */
				{
					error_over_large_intervals = errsum;
					ertest = tolerance;
					table.append_table(area);
					continue;
				}

				if (disallow_extrapolation)
				{
					continue;
				}

				error_over_large_intervals += -last_e_i;

				if (current_level < workspace.maximum_level)
				{
					error_over_large_intervals += error12;
				}

				if (!extrapolate)
				{
					/* test whether the interval to be bisected next is the
						 smallest interval. */

					if (workspace.large_interval())
						continue;

					extrapolate = true;
					workspace.nrmax = 1;
				}

				if (!error_type2 && error_over_large_intervals > ertest)
				{
					if (workspace.increase_nrmax())
						continue;
				}

				/* Perform extrapolation */

				table.append_table(area);

				table.qelg(out reseps, out abseps);

				ktmin++;

				if (ktmin > 5 && err_ext < 0.001 * errsum)
				{
					error_type = 5;
				}

				if (abseps < err_ext)
				{
					ktmin = 0;
					err_ext = abseps;
					res_ext = reseps;
					correc = error_over_large_intervals;
					ertest = Math.Max(epsabs, epsrel * Math.Abs(reseps));
					if (err_ext <= ertest)
						break;
				}

				/* Prepare bisection of the smallest interval. */

				if (table.n == 1)
				{
					disallow_extrapolation = true;
				}

				if (error_type == 5)
				{
					break;
				}

				/* work on interval with largest error */

				workspace.reset_nrmax();
				extrapolate = false;
				error_over_large_intervals = errsum;
			}
			while (iteration < limit);

			result = res_ext;
			abserr = err_ext;

			if (err_ext == GSL_CONST.GSL_DBL_MAX)
				goto compute_result;

			if (0 != error_type || error_type2)
			{
				if (error_type2)
				{
					err_ext += correc;
				}

				if (error_type == 0)
					error_type = 3;

				if (res_ext != 0.0 && area != 0.0)
				{
					if (err_ext / Math.Abs(res_ext) > errsum / Math.Abs(area))
						goto compute_result;
				}
				else if (err_ext > errsum)
				{
					goto compute_result;
				}
				else if (area == 0.0)
				{
					goto return_error;
				}
			}

			/*  Test on divergence. */

			{
				double max_area = Math.Max(Math.Abs(res_ext), Math.Abs(area));

				if (!positive_integrand && max_area < 0.01 * resabs0)
					goto return_error;
			}

			{
				double ratio = res_ext / area;

				if (ratio < 0.01 || ratio > 100.0 || errsum > Math.Abs(area))
					error_type = 6;
			}

			goto return_error;

		compute_result:

			result = workspace.sum_results();
			abserr = errsum;

		return_error:

			if (error_type > 2)
				error_type--;

			if (error_type == 0)
			{
				return null; // GSL_SUCCESS;
			}
			else if (error_type == 1)
			{
				return new GSL_ERROR("number of iterations was insufficient", GSL_ERR.GSL_EMAXITER, bDebug);
			}
			else if (error_type == 2)
			{
				return new GSL_ERROR("cannot reach tolerance because of roundoff error",
									 GSL_ERR.GSL_EROUND, bDebug);
			}
			else if (error_type == 3)
			{
				return new GSL_ERROR("bad integrand behavior found in the integration interval",
									 GSL_ERR.GSL_ESING, bDebug);
			}
			else if (error_type == 4)
			{
				return new GSL_ERROR("roundoff error detected in the extrapolation table",
									 GSL_ERR.GSL_EROUND, bDebug);
			}
			else if (error_type == 5)
			{
				return new GSL_ERROR("integral is divergent, or slowly convergent",
									 GSL_ERR.GSL_EDIVERGE, bDebug);
			}
			else
			{
				return new GSL_ERROR("could not integrate function", GSL_ERR.GSL_EFAILED, bDebug);
			}
		}
Example #17
0
        qag(Func <double, double> f,
            double a, double b,
            double epsabs, double epsrel,
            int limit,
            gsl_integration_workspace workspace,
            out double result, out double abserr,
            gsl_integration_rule q,
            bool bDebug)
        {
            double area, errsum;
            double tolerance;
            int    iteration = 0;
            int    roundoff_type1 = 0, roundoff_type2 = 0, error_type = 0;

            double round_off;

            /* Initialize results */

            workspace.initialise(a, b);

            result = 0;
            abserr = 0;

            if (limit > workspace.limit)
            {
                return(new GSL_ERROR("iteration limit exceeds available workspace", GSL_ERR.GSL_EINVAL, true));
            }

            if (epsabs <= 0 && (epsrel < 50 * GSL_CONST.GSL_DBL_EPSILON || epsrel < 0.5e-28))
            {
                return(new GSL_ERROR("tolerance cannot be acheived with given epsabs and epsrel",
                                     GSL_ERR.GSL_EBADTOL, true));
            }

            /* perform the first integration */

            q(f, a, b, out var result0, out var abserr0, out var resabs0, out var resasc0);

            workspace.set_initial_result(result0, abserr0);

            /* Test on accuracy */

            tolerance = Math.Max(epsabs, epsrel * Math.Abs(result0));

            /* need IEEE rounding here to match original quadpack behavior */

            round_off = GSL_COERCE_DBL(50 * GSL_CONST.GSL_DBL_EPSILON * resabs0);

            if (abserr0 <= round_off && abserr0 > tolerance)
            {
                result = result0;
                abserr = abserr0;

                return(new GSL_ERROR("cannot reach tolerance because of roundoff error on first attempt", GSL_ERR.GSL_EROUND, bDebug));
            }
            else if ((abserr0 <= tolerance && abserr0 != resasc0) || abserr0 == 0.0)
            {
                result = result0;
                abserr = abserr0;

                return(null); //GSL_SUCCESS;
            }
            else if (limit == 1)
            {
                result = result0;
                abserr = abserr0;

                return(new GSL_ERROR("a maximum of one iteration was insufficient", GSL_ERR.GSL_EMAXITER, bDebug));
            }

            area   = result0;
            errsum = abserr0;

            iteration = 1;

            do
            {
                double a1, b1, a2, b2;
                double area12  = 0;
                double error12 = 0;

                /* Bisect the subinterval with the largest error estimate */

                workspace.retrieve(out var a_i, out var b_i, out var r_i, out var e_i);

                a1 = a_i;
                b1 = 0.5 * (a_i + b_i);
                a2 = b1;
                b2 = b_i;

                q(f, a1, b1, out var area1, out var error1, out var resabs1, out var resasc1);
                q(f, a2, b2, out var area2, out var error2, out var resabs2, out var resasc2);

                area12  = area1 + area2;
                error12 = error1 + error2;

                errsum += (error12 - e_i);
                area   += area12 - r_i;

                if (resasc1 != error1 && resasc2 != error2)
                {
                    double delta = r_i - area12;

                    if (Math.Abs(delta) <= 1.0e-5 * Math.Abs(area12) && error12 >= 0.99 * e_i)
                    {
                        roundoff_type1++;
                    }
                    if (iteration >= 10 && error12 > e_i)
                    {
                        roundoff_type2++;
                    }
                }

                tolerance = Math.Max(epsabs, epsrel * Math.Abs(area));

                if (errsum > tolerance)
                {
                    if (roundoff_type1 >= 6 || roundoff_type2 >= 20)
                    {
                        error_type = 2; /* round off error */
                    }

                    /* set error flag in the case of bad integrand behaviour at
                     *                                     a point of the integration range */

                    if (subinterval_too_small(a1, a2, b2))
                    {
                        error_type = 3;
                    }
                }

                workspace.update(a1, b1, area1, error1, a2, b2, area2, error2);

                workspace.retrieve(out a_i, out b_i, out r_i, out e_i);

                iteration++;
            }while (iteration < limit && 0 == error_type && errsum > tolerance);

            result = workspace.sum_results();
            abserr = errsum;

            if (errsum <= tolerance)
            {
                return(null); //GSL_SUCCESS;
            }
            else if (error_type == 2)
            {
                return(new GSL_ERROR("roundoff error prevents tolerance from being achieved",
                                     GSL_ERR.GSL_EROUND, bDebug));
            }
            else if (error_type == 3)
            {
                return(new GSL_ERROR("bad integrand behavior found in the integration interval",
                                     GSL_ERR.GSL_ESING, bDebug));
            }
            else if (iteration == limit)
            {
                return(new GSL_ERROR("maximum number of subdivisions reached", GSL_ERR.GSL_EMAXITER, bDebug));
            }
            else
            {
                return(new GSL_ERROR("could not integrate function", GSL_ERR.GSL_EFAILED, bDebug));
            }
        }