Пример #1
0
            protected internal override double doFirstDerivative(double xValue)
            {
                int lowerIndex  = lowerBoundIndex(xValue, xValues);
                int higherIndex = lowerIndex + 1;

                RealPolynomialFunction1D[] quadFirstDerivative = quadraticsFirstDerivative_Renamed.get();
                // at start of curve, or only one interval
                if (lowerIndex == 0 || intervalCount == 1)
                {
                    RealPolynomialFunction1D quadraticFirstDerivative = quadFirstDerivative[0];
                    double x = xValue - xValues[1];
                    return(quadraticFirstDerivative.applyAsDouble(x));
                }
                // at end of curve
                if (higherIndex >= intervalCount)
                {
                    RealPolynomialFunction1D quadraticFirstDerivative = quadFirstDerivative[intervalCount - 2];
                    double x = xValue - xValues[intervalCount - 1];
                    return(quadraticFirstDerivative.applyAsDouble(x));
                }
                RealPolynomialFunction1D quadratic1 = quadratics_Renamed[lowerIndex - 1];
                RealPolynomialFunction1D quadratic2 = quadratics_Renamed[higherIndex - 1];
                RealPolynomialFunction1D quadratic1FirstDerivative = quadFirstDerivative[lowerIndex - 1];
                RealPolynomialFunction1D quadratic2FirstDerivative = quadFirstDerivative[higherIndex - 1];
                double w = WEIGHT_FUNCTION.getWeight((xValues[higherIndex] - xValue) / (xValues[higherIndex] - xValues[lowerIndex]));

                return(w * quadratic1FirstDerivative.applyAsDouble(xValue - xValues[lowerIndex]) + (1 - w) * quadratic2FirstDerivative.applyAsDouble(xValue - xValues[higherIndex]) + (quadratic2.applyAsDouble(xValue - xValues[higherIndex]) - quadratic1.applyAsDouble(xValue - xValues[lowerIndex])) / (xValues[higherIndex] - xValues[lowerIndex]));
            }
 /// <summary>
 /// {@inheritDoc} </summary>
 /// <exception cref="MathException"> If there are no real roots; if the Commons method could not evaluate the function; if the Commons method could not converge. </exception>
 public virtual double?[] getRoots(RealPolynomialFunction1D function)
 {
     ArgChecker.notNull(function, "function");
     try
     {
         Complex[]      roots     = ROOT_FINDER.solveAllComplex(function.Coefficients, 0);
         IList <double> realRoots = new List <double>();
         foreach (Complex c in roots)
         {
             if (DoubleMath.fuzzyEquals(c.Imaginary, 0d, EPS))
             {
                 realRoots.Add(c.Real);
             }
         }
         if (realRoots.Count == 0)
         {
             throw new MathException("Could not find any real roots");
         }
         return(realRoots.ToArray());
     }
     catch (TooManyEvaluationsException e)
     {
         throw new MathException(e);
     }
 }
Пример #3
0
            //-------------------------------------------------------------------------
            protected internal override double doInterpolate(double xValue)
            {
                // x-value is less than the x-value of the last node (lowerIndex < intervalCount)
                int lowerIndex  = lowerBoundIndex(xValue, xValues);
                int higherIndex = lowerIndex + 1;

                // at start of curve
                if (lowerIndex == 0)
                {
                    RealPolynomialFunction1D quadratic = quadratics_Renamed[0];
                    double x = xValue - xValues[1];
                    return(quadratic.applyAsDouble(x));
                }
                // at end of curve
                if (higherIndex == intervalCount)
                {
                    RealPolynomialFunction1D quadratic = quadratics_Renamed[intervalCount - 2];
                    double x = xValue - xValues[intervalCount - 1];
                    return(quadratic.applyAsDouble(x));
                }
                // normal case
                RealPolynomialFunction1D quadratic1 = quadratics_Renamed[lowerIndex - 1];
                RealPolynomialFunction1D quadratic2 = quadratics_Renamed[higherIndex - 1];
                double w = WEIGHT_FUNCTION.getWeight((xValues[higherIndex] - xValue) / (xValues[higherIndex] - xValues[lowerIndex]));

                return(w * quadratic1.applyAsDouble(xValue - xValues[lowerIndex]) + (1 - w) * quadratic2.applyAsDouble(xValue - xValues[higherIndex]));
            }
Пример #4
0
 //-------------------------------------------------------------------------
 internal static RealPolynomialFunction1D[] quadratics(double[] x, double[] y, int intervalCount)
 {
     if (intervalCount == 1)
     {
         double a = y[1];
         double b = (y[1] - y[0]) / (x[1] - x[0]);
         return(new RealPolynomialFunction1D[] { new RealPolynomialFunction1D(a, b) });
     }
     RealPolynomialFunction1D[] quadratic = new RealPolynomialFunction1D[intervalCount - 1];
     for (int i = 1; i < intervalCount; i++)
     {
         quadratic[i - 1] = Bound.quadratic(x, y, i);
     }
     return(quadratic);
 }
Пример #5
0
 internal static RealPolynomialFunction1D[] quadraticsFirstDerivative(double[] x, double[] y, int intervalCount)
 {
     if (intervalCount == 1)
     {
         double b = (y[1] - y[0]) / (x[1] - x[0]);
         return(new RealPolynomialFunction1D[] { new RealPolynomialFunction1D(b) });
     }
     else
     {
         RealPolynomialFunction1D[] quadraticFirstDerivative = new RealPolynomialFunction1D[intervalCount - 1];
         for (int i = 1; i < intervalCount; i++)
         {
             quadraticFirstDerivative[i - 1] = Bound.quadraticFirstDerivative(x, y, i);
         }
         return(quadraticFirstDerivative);
     }
 }
Пример #6
0
        /// <summary>
        /// {@inheritDoc} </summary>
        /// <exception cref="IllegalArgumentException"> If the function is not a quadratic </exception>
        /// <exception cref="MathException"> If the roots are not real </exception>
        public virtual double?[] getRoots(RealPolynomialFunction1D function)
        {
            ArgChecker.notNull(function, "function");
            double[] coefficients = function.Coefficients;
            ArgChecker.isTrue(coefficients.Length == 3, "Function is not a quadratic");
            double c            = coefficients[0];
            double b            = coefficients[1];
            double a            = coefficients[2];
            double discriminant = b * b - 4 * a * c;

            if (discriminant < 0)
            {
                throw new MathException("No real roots for quadratic");
            }
            double q = -0.5 * (b + Math.Sign(b) * discriminant);

            return(new double?[] { q / a, c / q });
        }
        public virtual double?[] getRoots(RealPolynomialFunction1D function)
        {
            ArgChecker.notNull(function, "function");
            double[] coefficients = function.Coefficients;
            if (coefficients.Length != 4)
            {
                throw new System.ArgumentException("Function is not a cubic");
            }
            ComplexNumber[] result = ROOT_FINDER.getRoots(function);
            IList <double>  reals  = new List <double>();

            foreach (ComplexNumber c in result)
            {
                if (DoubleMath.fuzzyEquals(c.Imaginary, 0d, 1e-16))
                {
                    reals.Add(c.Real);
                }
            }
            ArgChecker.isTrue(reals.Count > 0, "Could not find any real roots");
            return(reals.toArray(EMPTY_ARRAY));
        }
 /// <summary>
 /// Gets the polynomials.
 /// </summary>
 /// <param name="n">  the n value </param>
 /// <param name="alpha">  the alpha value </param>
 /// <returns> the result </returns>
 public virtual DoubleFunction1D[] getPolynomials(int n, double alpha)
 {
     ArgChecker.isTrue(n >= 0);
     DoubleFunction1D[] polynomials = new DoubleFunction1D[n + 1];
     for (int i = 0; i <= n; i++)
     {
         if (i == 0)
         {
             polynomials[i] = One;
         }
         else if (i == 1)
         {
             polynomials[i] = new RealPolynomialFunction1D(new double[] { 1 + alpha, -1 });
         }
         else
         {
             polynomials[i] = (polynomials[i - 1].multiply(2.0 * i + alpha - 1).subtract(polynomials[i - 1].multiply(X)).subtract(polynomials[i - 2].multiply((i - 1.0 + alpha))).divide(i));
         }
     }
     return(polynomials);
 }
        /// <summary>
        /// {@inheritDoc} </summary>
        /// <exception cref="IllegalArgumentException"> If the function is not cubic </exception>
        public virtual ComplexNumber[] getRoots(RealPolynomialFunction1D function)
        {
            ArgChecker.notNull(function, "function");
            double[] coefficients = function.Coefficients;
            ArgChecker.isTrue(coefficients.Length == 4, "Function is not a cubic");
            double divisor  = coefficients[3];
            double a        = coefficients[2] / divisor;
            double b        = coefficients[1] / divisor;
            double c        = coefficients[0] / divisor;
            double aSq      = a * a;
            double q        = (aSq - 3 * b) / 9;
            double r        = (2 * a * aSq - 9 * a * b + 27 * c) / 54;
            double rSq      = r * r;
            double qCb      = q * q * q;
            double constant = a / 3;

            if (rSq < qCb)
            {
                double mult  = -2 * Math.Sqrt(q);
                double theta = Math.Acos(r / Math.Sqrt(qCb));
                return(new ComplexNumber[]
                {
                    new ComplexNumber(mult * Math.Cos(theta / 3) - constant, 0),
                    new ComplexNumber(mult * Math.Cos((theta + TWO_PI) / 3) - constant, 0),
                    new ComplexNumber(mult * Math.Cos((theta - TWO_PI) / 3) - constant, 0)
                });
            }
            double s         = -Math.Sign(r) * Math.cbrt(Math.Abs(r) + Math.Sqrt(rSq - qCb));
            double t         = DoubleMath.fuzzyEquals(s, 0d, 1e-16) ? 0 : q / s;
            double sum       = s + t;
            double real      = -0.5 * sum - constant;
            double imaginary = Math.Sqrt(3) * (s - t) / 2;

            return(new ComplexNumber[]
            {
                new ComplexNumber(sum - constant, 0),
                new ComplexNumber(real, imaginary),
                new ComplexNumber(real, -imaginary)
            });
        }
 /// <summary>
 /// Calculates polynomials. </summary>
 /// <param name="n">  the n value </param>
 /// <param name="alpha">  the alpha value </param>
 /// <param name="beta">  the beta value </param>
 /// <returns> the result </returns>
 public virtual DoubleFunction1D[] getPolynomials(int n, double alpha, double beta)
 {
     ArgChecker.isTrue(n >= 0);
     DoubleFunction1D[] polynomials = new DoubleFunction1D[n + 1];
     for (int i = 0; i <= n; i++)
     {
         if (i == 0)
         {
             polynomials[i] = One;
         }
         else if (i == 1)
         {
             polynomials[i] = new RealPolynomialFunction1D(new double[] { (alpha - beta) / 2, (alpha + beta + 2) / 2 });
         }
         else
         {
             int j = i - 1;
             polynomials[i] = (polynomials[j].multiply(getB(alpha, beta, j)).add(polynomials[j].multiply(X).multiply(getC(alpha, beta, j)).add(polynomials[j - 1].multiply(getD(alpha, beta, j))))).divide(getA(alpha, beta, j));
         }
     }
     return(polynomials);
 }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void testAlpha2()
        public virtual void testAlpha2()
        {
            const int n = 14;

//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final com.opengamma.strata.collect.tuple.Pair<com.opengamma.strata.math.impl.function.DoubleFunction1D, com.opengamma.strata.math.impl.function.DoubleFunction1D>[] polynomialAndDerivative1 = LAGUERRE.getPolynomialsAndFirstDerivative(n);
            Pair <DoubleFunction1D, DoubleFunction1D>[] polynomialAndDerivative1 = LAGUERRE.getPolynomialsAndFirstDerivative(n);
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final com.opengamma.strata.collect.tuple.Pair<com.opengamma.strata.math.impl.function.DoubleFunction1D, com.opengamma.strata.math.impl.function.DoubleFunction1D>[] polynomialAndDerivative2 = LAGUERRE.getPolynomialsAndFirstDerivative(n, 0);
            Pair <DoubleFunction1D, DoubleFunction1D>[] polynomialAndDerivative2 = LAGUERRE.getPolynomialsAndFirstDerivative(n, 0);
            for (int i = 0; i < n; i++)
            {
                assertTrue(polynomialAndDerivative1[i].First is RealPolynomialFunction1D);
                assertTrue(polynomialAndDerivative2[i].First is RealPolynomialFunction1D);
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final com.opengamma.strata.math.impl.function.RealPolynomialFunction1D first = (com.opengamma.strata.math.impl.function.RealPolynomialFunction1D) polynomialAndDerivative1[i].getFirst();
                RealPolynomialFunction1D first = (RealPolynomialFunction1D)polynomialAndDerivative1[i].First;
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final com.opengamma.strata.math.impl.function.RealPolynomialFunction1D second = (com.opengamma.strata.math.impl.function.RealPolynomialFunction1D) polynomialAndDerivative2[i].getFirst();
                RealPolynomialFunction1D second = (RealPolynomialFunction1D)polynomialAndDerivative2[i].First;
                assertEquals(first, second);
            }
        }
        /// <summary>
        /// Checks coefficients of polynomial f(x) are recovered and residuals, { y_i -f(x_i) }, are accurate
        /// </summary>
        public virtual void PolynomialFunctionRecoverTest()
        {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final PolynomialsLeastSquaresFitter regObj = new PolynomialsLeastSquaresFitter();
            PolynomialsLeastSquaresFitter regObj = new PolynomialsLeastSquaresFitter();

//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double[] coeff = new double[] {3.4, 5.6, 1.0, -4.0 };
            double[] coeff = new double[] { 3.4, 5.6, 1.0, -4.0 };

            DoubleFunction1D func = new RealPolynomialFunction1D(coeff);

//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final int degree = coeff.length - 1;
            int degree = coeff.Length - 1;

            const int nPts = 7;

            double[] xValues = new double[nPts];
            double[] yValues = new double[nPts];

            for (int i = 0; i < nPts; ++i)
            {
                xValues[i] = -5.0 + 10 * i / (nPts - 1);
                yValues[i] = func.applyAsDouble(xValues[i]);
            }

            double[] yValuesNorm = new double[nPts];

//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double mean = _meanCal.apply(xValues);
            double mean = _meanCal.apply(xValues);
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double std = _stdCal.apply(xValues);
            double std = _stdCal.apply(xValues);
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double ratio = mean / std;
            double ratio = mean / std;

            for (int i = 0; i < nPts; ++i)
            {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double tmp = xValues[i] / std - ratio;
                double tmp = xValues[i] / std - ratio;
                yValuesNorm[i] = func.applyAsDouble(tmp);
            }

            /// <summary>
            /// Tests for regress(..)
            /// </summary>

            LeastSquaresRegressionResult result = regObj.regress(xValues, yValues, degree);

            double[] coeffResult = result.Betas;

            for (int i = 0; i < degree + 1; ++i)
            {
                assertEquals(coeff[i], coeffResult[i], EPS * Math.Abs(coeff[i]));
            }

//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double[] residuals = result.getResiduals();
            double[] residuals = result.Residuals;
            func = new RealPolynomialFunction1D(coeffResult);
            double[] yValuesFit = new double[nPts];
            for (int i = 0; i < nPts; ++i)
            {
                yValuesFit[i] = func.applyAsDouble(xValues[i]);
            }

            for (int i = 0; i < nPts; ++i)
            {
                assertEquals(Math.Abs(yValuesFit[i] - yValues[i]), 0.0, Math.Abs(yValues[i]) * EPS);
            }

            for (int i = 0; i < nPts; ++i)
            {
                assertEquals(Math.Abs(yValuesFit[i] - yValues[i]), Math.Abs(residuals[i]), Math.Abs(yValues[i]) * EPS);
            }

            double sum = 0.0;

            for (int i = 0; i < nPts; ++i)
            {
                sum += residuals[i] * residuals[i];
            }
            sum = Math.Sqrt(sum);

            /// <summary>
            /// Tests for regressVerbose(.., false)
            /// </summary>

            PolynomialsLeastSquaresFitterResult resultVer = regObj.regressVerbose(xValues, yValues, degree, false);

            coeffResult = resultVer.Coeff;
            func        = new RealPolynomialFunction1D(coeffResult);
            for (int i = 0; i < nPts; ++i)
            {
                yValuesFit[i] = func.applyAsDouble(xValues[i]);
            }

            assertEquals(nPts - (degree + 1), resultVer.Dof, 0);
            for (int i = 0; i < degree + 1; ++i)
            {
                assertEquals(coeff[i], coeffResult[i], EPS * Math.Abs(coeff[i]));
            }

            for (int i = 0; i < nPts; ++i)
            {
                assertEquals(Math.Abs(yValuesFit[i] - yValues[i]), 0.0, Math.Abs(yValues[i]) * EPS);
            }

            assertEquals(sum, resultVer.DiffNorm, EPS);

            /// <summary>
            /// Tests for regressVerbose(.., true)
            /// </summary>

            PolynomialsLeastSquaresFitterResult resultNorm = regObj.regressVerbose(xValues, yValuesNorm, degree, true);

            coeffResult = resultNorm.Coeff;
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double[] meanAndStd = resultNorm.getMeanAndStd();
            double[] meanAndStd = resultNorm.MeanAndStd;

            assertEquals(nPts - (degree + 1), resultNorm.Dof, 0);
            assertEquals(mean, meanAndStd[0], EPS);
            assertEquals(std, meanAndStd[1], EPS);
            for (int i = 0; i < degree + 1; ++i)
            {
                assertEquals(coeff[i], coeffResult[i], EPS * Math.Abs(coeff[i]));
            }

            func = new RealPolynomialFunction1D(coeffResult);
            for (int i = 0; i < nPts; ++i)
            {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final double tmp = xValues[i] / std - ratio;
                double tmp = xValues[i] / std - ratio;
                yValuesFit[i] = func.applyAsDouble(tmp);
            }

            for (int i = 0; i < nPts; ++i)
            {
                assertEquals(Math.Abs(yValuesFit[i] - yValuesNorm[i]), 0.0, Math.Abs(yValuesNorm[i]) * EPS);
            }

            sum = 0.0;
            for (int i = 0; i < nPts; ++i)
            {
                sum += (yValuesFit[i] - yValuesNorm[i]) * (yValuesFit[i] - yValuesNorm[i]);
            }
            sum = Math.Sqrt(sum);

            assertEquals(sum, resultNorm.DiffNorm, EPS);
        }