예제 #1
0
        qc25c(Func <double, double> f, double a, double b, double c,
              out double result, out double abserr, out bool err_reliable)
        {
            double cc = (2 * c - b - a) / (b - a);

            if (Math.Abs(cc) > 1.1)
            {
                fn_cauchy_params fn_params;
                fn_params.function    = f;
                fn_params.singularity = c;

                Func <double, double> weighted_function = delegate(double t)
                { return(fn_cauchy(t, fn_params)); };

                QK15.Integration(weighted_function, a, b, out result, out abserr,
                                 out var resabs, out var resasc);

                if (abserr == resasc)
                {
                    err_reliable = false; // 0;
                }
                else
                {
                    err_reliable = true; // 1;
                }

                return;
            }
            else
            {
                double[] cheb12 = new double[13];
                double[] cheb24 = new double[25];
                double[] moment = new double[25];
                double   res12 = 0, res24 = 0;
                int      i;
                Qcheb.Approximation(f, a, b, cheb12, cheb24);
                compute_moments(cc, moment);

                for (i = 0; i < 13; i++)
                {
                    res12 += cheb12[i] * moment[i];
                }

                for (i = 0; i < 25; i++)
                {
                    res24 += cheb24[i] * moment[i];
                }

                result       = res24;
                abserr       = Math.Abs(res24 - res12);
                err_reliable = false; // 0;

                return;
            }
        }
예제 #2
0
        qc25s(Func <double, double> f, double a, double b, double a1, double b1,
              gsl_integration_qaws_table t,
              out double result, out double abserr, out bool err_reliable)
        {
            var fn_params = new fn_qaws_params
            {
                function = f,
                a        = a,
                b        = b,
                table    = t
            };

            Func <double, double> weighted_function;

            if (a1 == a && (t.alpha != 0.0 || t.mu != 0))
            {
                double[] cheb12 = new double[13], cheb24 = new double[25];

                double factor = Math.Pow(0.5 * (b1 - a1), t.alpha + 1.0);

                weighted_function = delegate(double tt)
                { return(fn_qaws_R(tt, fn_params)); };

                Qcheb.Approximation(weighted_function, a1, b1, cheb12, cheb24);

                if (t.mu == 0)
                {
                    double u = factor;

                    compute_result(t.ri, cheb12, cheb24, out var res12, out var res24);

                    result = u * res24;
                    abserr = Math.Abs(u * (res24 - res12));
                }
                else
                {
                    double u = factor * Math.Log(b1 - a1);
                    double v = factor;

                    compute_result(t.ri, cheb12, cheb24, out var res12a, out var res24a);
                    compute_result(t.rg, cheb12, cheb24, out var res12b, out var res24b);

                    result = u * res24a + v * res24b;
                    abserr = Math.Abs(u * (res24a - res12a)) + Math.Abs(v * (res24b - res12b));
                }

                err_reliable = false;

                return;
            }
            else if (b1 == b && (t.beta != 0.0 || t.nu != 0))
            {
                double[] cheb12 = new double[13], cheb24 = new double[25];
                double   factor = Math.Pow(0.5 * (b1 - a1), t.beta + 1.0);

                weighted_function = delegate(double tt)
                { return(fn_qaws_L(tt, fn_params)); };

                Qcheb.Approximation(weighted_function, a1, b1, cheb12, cheb24);

                if (t.nu == 0)
                {
                    double u = factor;

                    compute_result(t.rj, cheb12, cheb24, out var res12, out var res24);

                    result = u * res24;
                    abserr = Math.Abs(u * (res24 - res12));
                }
                else
                {
                    double u = factor * Math.Log(b1 - a1);
                    double v = factor;

                    compute_result(t.rj, cheb12, cheb24, out var res12a, out var res24a);
                    compute_result(t.rh, cheb12, cheb24, out var res12b, out var res24b);

                    result = u * res24a + v * res24b;
                    abserr = Math.Abs(u * (res24a - res12a)) + Math.Abs(v * (res24b - res12b));
                }

                err_reliable = false;

                return;
            }
            else
            {
                weighted_function = delegate(double tt)
                { return(fn_qaws(tt, fn_params)); };

                QK15.Integration(weighted_function, a1, b1, out result, out abserr,
                                 out var resabs, out var resasc);

                if (abserr == resasc)
                {
                    err_reliable = false;
                }
                else
                {
                    err_reliable = true;
                }

                return;
            }
        }
예제 #3
0
        qc25f(Func <double, double> f, double a, double b,
              gsl_integration_qawo_table wf, int level,
              out double result, out double abserr, out double resabs, out double resasc)
        {
            double center      = 0.5 * (a + b);
            double half_length = 0.5 * (b - a);
            double omega       = wf.omega;

            double par = omega * half_length;

            if (Math.Abs(par) < 2)
            {
                Func <double, double> weighted_function;
                fn_fourier_params     fn_params;

                fn_params.function = f;
                fn_params.omega    = omega;

                if (wf.sine == gsl_integration_qawo_enum.GSL_INTEG_SINE)
                {
                    weighted_function = delegate(double t)
                    { return(fn_sin(t, fn_params)); };
                }
                else
                {
                    weighted_function = delegate(double t)
                    { return(fn_cos(t, fn_params)); };
                }

                QK15.Integration(weighted_function, a, b, out result, out abserr,
                                 out resabs, out resasc);

                return;
            }
            else
            {
                int      momentix;
                double[] cheb12 = new double[13];
                double[] cheb24 = new double[25];
                double   result_abs, res12_cos, res12_sin, res24_cos, res24_sin;
                double   est_cos, est_sin;
                double   c, s;
                int      i;

                Qcheb.Approximation(f, a, b, cheb12, cheb24);

                if (level >= wf.n)
                {
                    /* table overflow should not happen, check before calling */
                    new GSL_ERROR("table overflow in internal function", GSL_ERR.GSL_ESANITY, true);
                    throw new ArithmeticException("table overflow in internal function"); //
                }

                /* obtain moments from the table */

                momentix = 25 * level;

                res12_cos = cheb12[12] * wf.chebmo[momentix + 12];
                res12_sin = 0;

                for (i = 0; i < 6; i++)
                {
                    int k = 10 - 2 * i;
                    res12_cos += cheb12[k] * wf.chebmo[momentix + k];
                    res12_sin += cheb12[k + 1] * wf.chebmo[momentix + k + 1];
                }

                res24_cos = cheb24[24] * wf.chebmo[momentix + 24];
                res24_sin = 0;

                result_abs = Math.Abs(cheb24[24]);

                for (i = 0; i < 12; i++)
                {
                    int k = 22 - 2 * i;
                    res24_cos  += cheb24[k] * wf.chebmo[momentix + k];
                    res24_sin  += cheb24[k + 1] * wf.chebmo[momentix + k + 1];
                    result_abs += Math.Abs(cheb24[k]) + Math.Abs(cheb24[k + 1]);
                }

                est_cos = Math.Abs(res24_cos - res12_cos);
                est_sin = Math.Abs(res24_sin - res12_sin);

                c = half_length * Math.Cos(center * omega);
                s = half_length * Math.Sin(center * omega);

                if (wf.sine == gsl_integration_qawo_enum.GSL_INTEG_SINE)
                {
                    result = c * res24_sin + s * res24_cos;
                    abserr = Math.Abs(c * est_sin) + Math.Abs(s * est_cos);
                }
                else
                {
                    result = c * res24_cos - s * res24_sin;
                    abserr = Math.Abs(c * est_cos) + Math.Abs(s * est_sin);
                }

                resabs = result_abs * half_length;
                resasc = GSL_CONST.GSL_DBL_MAX;

                return;
            }
        }