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); } }
//------------------------------------------------------------------------- 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])); }
//------------------------------------------------------------------------- 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); }
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); } }
/// <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); }