/// <summary> /// Finds the node sensitivity. /// </summary> /// <param name="pp"> the <seealso cref="PiecewisePolynomialResultsWithSensitivity"/> </param> /// <param name="xKey"> the key </param> /// <returns> Node sensitivity value at x=xKey </returns> public virtual DoubleArray nodeSensitivity(PiecewisePolynomialResultsWithSensitivity pp, double xKey) { ArgChecker.notNull(pp, "null pp"); ArgChecker.isFalse(double.IsNaN(xKey), "xKey containing NaN"); ArgChecker.isFalse(double.IsInfinity(xKey), "xKey containing Infinity"); if (pp.Dimensions > 1) { throw new System.NotSupportedException(); } DoubleArray knots = pp.Knots; int nKnots = knots.size(); int interval = FunctionUtils.getLowerBoundIndex(knots, xKey); if (interval == nKnots - 1) { interval--; // there is 1 less interval that knots } double s = xKey - knots.get(interval); DoubleMatrix a = pp.getCoefficientSensitivity(interval); int nCoefs = a.rowCount(); DoubleArray res = a.row(0); for (int i = 1; i < nCoefs; i++) { res = (DoubleArray)MA.scale(res, s); res = (DoubleArray)MA.add(res, a.row(i)); } return(res); }
public virtual void negativeDataTest() { DoubleArray xValues = DoubleArray.of(-34.5, -27.0, -22.5, -14.2, -10.0, -5.0, -0.3); DoubleArray yValues = DoubleArray.of(4.0, 2.0, 1.0, 5.0, 10.0, 3.5, -2.0); int nData = yValues.size(); DoubleArray pValues = DoubleArray.of(nData, i => xValues.get(i) * yValues.get(i)); System.Func <double, bool> domain = (double?x) => { return(x.Value >= xValues.get(0) && x.Value <= xValues.get(nData - 1)); }; DoubleArray keys = DoubleArray.of(xValues.get(0), -27.7, -21.2, -17.8, -10.0, -1.52, -0.35, xValues.get(nData - 1)); int nKeys = keys.size(); BoundCurveInterpolator bound = INTERP.bind(xValues, yValues); PiecewisePolynomialResultsWithSensitivity ppRes = BASE_INTERP.interpolateWithSensitivity(xValues.toArray(), pValues.toArray()); System.Func <double, double> funcDeriv = x => bound.interpolate(x.Value); for (int i = 0; i < nKeys; ++i) { // interpolate assertEquals(bound.interpolate(keys.get(i)), FUNCTION.evaluate(ppRes, keys.get(i)).get(0) / keys.get(i), TOL); // first derivative double firstExp = DIFF_CALC.differentiate(funcDeriv, domain).apply(keys.get(i)); assertEquals(bound.firstDerivative(keys.get(i)), firstExp, EPS); // parameter sensitivity int index = i; System.Func <DoubleArray, double> funcSensi = x => INTERP.bind(xValues, x).interpolate(keys.get(index)); DoubleArray sensExp = SENS_CALC.differentiate(funcSensi).apply(yValues); assertTrue(DoubleArrayMath.fuzzyEquals(bound.parameterSensitivity(keys.get(i)).toArray(), sensExp.toArray(), EPS)); } }
public virtual void sensitivityTest() { int nExamples = Y.Length; int n = XX.Length; int nData = X.Length; for (int example = 0; example < nExamples; example++) { PiecewisePolynomialResultsWithSensitivity pp = BASE.interpolateWithSensitivity(X, Y[example]); BoundCurveInterpolator bound = PCHIP.bind(DoubleArray.ofUnsafe(X), DoubleArray.ofUnsafe(Y[example]), INTERPOLATOR, INTERPOLATOR); for (int i = 0; i < n; i++) { DoubleArray computed = bound.parameterSensitivity(XX[i]); DoubleArray expected = PPVAL.nodeSensitivity(pp, XX[i]); for (int j = 0; j < nData; j++) { assertTrue(DoubleArrayMath.fuzzyEquals(computed.toArray(), expected.toArray(), TOL)); } } } }
/// <summary> /// Differentiates the node sensitivity. /// </summary> /// <param name="pp"> the <seealso cref="PiecewisePolynomialResultsWithSensitivity"/> </param> /// <param name="xKeys"> the keys </param> /// <returns> the node sensitivity of second derivative value at x=xKeys </returns> public virtual DoubleArray[] differentiateTwiceNodeSensitivity(PiecewisePolynomialResultsWithSensitivity pp, double[] xKeys) { ArgChecker.notNull(pp, "null pp"); if (pp.Dimensions > 1) { throw new System.NotSupportedException(); } int nCoefs = pp.Order; ArgChecker.isFalse(nCoefs < 3, "Polynomial degree is too low"); int nIntervals = pp.NumberOfIntervals; DoubleMatrix[] diffSense = new DoubleMatrix[nIntervals]; DoubleMatrix[] senseMat = pp.CoefficientSensitivityAll; int nData = senseMat[0].columnCount(); for (int i = 0; i < nIntervals; ++i) { double[][] senseMatArray = senseMat[i].toArray(); //JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java: //ORIGINAL LINE: double[][] tmp = new double[nCoefs - 2][nData]; double[][] tmp = RectangularArrays.ReturnRectangularDoubleArray(nCoefs - 2, nData); for (int j = 0; j < nCoefs - 2; ++j) { for (int k = 0; k < nData; ++k) { tmp[j][k] = (nCoefs - 1 - j) * (nCoefs - 2 - j) * senseMatArray[j][k]; } } diffSense[i] = DoubleMatrix.copyOf(tmp); } PiecewisePolynomialResultsWithSensitivity ppDiff = new PiecewisePolynomialResultsWithSensitivity(pp.Knots, pp.CoefMatrix, nCoefs - 2, pp.Dimensions, diffSense); return(nodeSensitivity(ppDiff, xKeys)); }