示例#1
0
        public double integrate(double a, double b, ConundrumIntegrand integrand)
        {
            double result = .0;

            //double abserr =.0;
            //double alpha = 1.0;

            //double epsabs = precision_;
            //double epsrel = 1.0; // we are interested only in absolute precision
            //size_t neval =0;

            // we use the non adaptive algorithm only for semi infinite interval
            if (a > 0)
            {
                // we estimate the actual boudary by testing integrand values
                double upperBoundary = 2 * a;
                while (integrand.value(upperBoundary) > precision_)
                {
                    upperBoundary *= 2.0;
                }
                // sometimes b < a because of a wrong estimation of b based on stdev
                if (b > a)
                {
                    upperBoundary = Math.Min(upperBoundary, b);
                }

                GaussKronrodNonAdaptive gaussKronrodNonAdaptive = new GaussKronrodNonAdaptive(precision_, 1000000, 1.0);
                // if the integration intervall is wide enough we use the
                // following change variable x -> a + (b-a)*(t/(a-b))^3
                upperBoundary = Math.Max(a, Math.Min(upperBoundary, hardUpperLimit_));
                if (upperBoundary > 2 * a)
                {
                    VariableChange variableChange = new VariableChange(integrand.value, a, upperBoundary, 3);
                    result = gaussKronrodNonAdaptive.value(variableChange.value, .0, 1.0);
                }
                else
                {
                    result = gaussKronrodNonAdaptive.value(integrand.value, a, upperBoundary);
                }

                // if the expected precision has not been reached we use the old algorithm
                if (!gaussKronrodNonAdaptive.integrationSuccess())
                {
                    GaussKronrodAdaptive integrator = new GaussKronrodAdaptive(precision_, 100000);
                    b      = Math.Max(a, Math.Min(b, hardUpperLimit_));
                    result = integrator.value(integrand.value, a, b);
                }
            } // if a < b we use the old algorithm
            else
            {
                b = Math.Max(a, Math.Min(b, hardUpperLimit_));
                GaussKronrodAdaptive integrator = new GaussKronrodAdaptive(precision_, 100000);
                result = integrator.value(integrand.value, a, b);
            }
            return(result);
        }
示例#2
0
        public LinearTsrPricer(Handle <SwaptionVolatilityStructure> swaptionVol,
                               Handle <Quote> meanReversion,
                               Handle <YieldTermStructure> couponDiscountCurve = null,
                               Settings settings     = null,
                               Integrator integrator = null)
            : base(swaptionVol)
        {
            meanReversion_       = meanReversion;
            couponDiscountCurve_ = couponDiscountCurve ?? new Handle <YieldTermStructure>();
            settings_            = settings ?? new Settings();
            volDayCounter_       = swaptionVol.link.dayCounter();
            integrator_          = integrator;

            if (!couponDiscountCurve_.empty())
            {
                couponDiscountCurve_.registerWith(update);
            }

            if (integrator_ == null)
            {
                integrator_ = new  GaussKronrodNonAdaptive(1E-10, 5000, 1E-10);
            }
        }
示例#3
0
        public double integrate(double a, double b, ConundrumIntegrand integrand) {
            double result = .0;
            //double abserr =.0;
            //double alpha = 1.0;

            //double epsabs = precision_;
            //double epsrel = 1.0; // we are interested only in absolute precision
            //size_t neval =0;

            // we use the non adaptive algorithm only for semi infinite interval
            if (a > 0) {
                // we estimate the actual boudary by testing integrand values
                double upperBoundary = 2 * a;
                while (integrand.value(upperBoundary) > precision_)
                    upperBoundary *= 2.0;
                // sometimes b < a because of a wrong estimation of b based on stdev
                if (b > a)
                    upperBoundary = Math.Min(upperBoundary, b);

                GaussKronrodNonAdaptive gaussKronrodNonAdaptive = new GaussKronrodNonAdaptive(precision_, 1000000, 1.0);
                // if the integration intervall is wide enough we use the
                // following change variable x -> a + (b-a)*(t/(a-b))^3
                if (upperBoundary > 2 * a) {
                    VariableChange variableChange = new VariableChange(integrand.value, a, upperBoundary, 3);
                    result = gaussKronrodNonAdaptive.value(variableChange.value, .0, 1.0);
                } else {
                    result = gaussKronrodNonAdaptive.value(integrand.value, a, upperBoundary);
                }

                // if the expected precision has not been reached we use the old algorithm
                if (!gaussKronrodNonAdaptive.integrationSuccess()) {
                    GaussKronrodAdaptive integrator = new GaussKronrodAdaptive(precision_, 1000000);
                    result = integrator.value(integrand.value, a, b);
                }
            } // if a < b we use the old algorithm
            else {
                GaussKronrodAdaptive integrator = new GaussKronrodAdaptive(precision_, 1000000);
                result = integrator.value(integrand.value, a, b);
            }
            return result;
        }