private static int getIndicator(double xValue, DoubleArray knots) { // check for 1 less interval than knots int lowerBound = FunctionUtils.getLowerBoundIndex(knots, xValue); return lowerBound == knots.size() - 1 ? lowerBound - 1 : lowerBound; }
private static double evaluate( double xValue, DoubleArray knots, DoubleMatrix coefMatrix, int dimensions) { // check for 1 less interval than knots int lowerBound = FunctionUtils.getLowerBoundIndex(knots, xValue); int indicator = lowerBound == knots.size() - 1 ? lowerBound - 1 : lowerBound; DoubleArray coefs = coefMatrix.row(dimensions * indicator); return getValue(coefs.toArrayUnsafe(), xValue, knots.get(indicator)); }
private static double evaluate( double xValue, DoubleArray knots, DoubleMatrix coefMatrix, int dimensions) { // check for 1 less interval than knots int lowerBound = FunctionUtils.getLowerBoundIndex(knots, xValue); int indicator = lowerBound == knots.size() - 1 ? lowerBound - 1 : lowerBound; DoubleArray coefs = coefMatrix.row(dimensions * indicator); return getValue(coefs.toArrayUnsafe(), xValue, knots.get(indicator)); }
private static double evaluate( double xValue, DoubleArray knots, DoubleMatrix coefMatrix, int dimensions) { // check for 1 less interval than knots int lowerBound = FunctionUtils.getLowerBoundIndex(knots, xValue); int indicator = lowerBound == knots.size() - 1 ? lowerBound - 1 : lowerBound; DoubleArray coefs = coefMatrix.row(dimensions * indicator); return getValue(coefs.toArrayUnsafe(), xValue, knots.get(indicator)); }
private static double evaluate( double xValue, DoubleArray knots, DoubleMatrix coefMatrix, int dimensions) { // check for 1 less interval than knots int lowerBound = FunctionUtils.getLowerBoundIndex(knots, xValue); int indicator = lowerBound == knots.size() - 1 ? lowerBound - 1 : lowerBound; DoubleArray coefs = coefMatrix.row(dimensions * indicator); return getValue(coefs.toArrayUnsafe(), xValue, knots.get(indicator)); }
/** * Computes the sensitivity of the Smith-Wilson curve function to weights parameters at a x value. * <p> * The {@code nodes} must be sorted in ascending order. * * @param x the x value * @param alpha the alpha parameter * @param nodes the nodes * @return the value */ public DoubleArray parameterSensitivity(double x, double alpha, DoubleArray nodes) { int size = nodes.size(); double[] res = new double[size]; double expOmega = Math.exp(-omega * x); int bound = x < nodes.get(0) ? 0 : FunctionUtils.getLowerBoundIndex(nodes, x) + 1; for (int i = 0; i < bound; ++i) { res[i] = expOmega * wilsonFunctionLeft(x, alpha, nodes.get(i)); } for (int i = bound; i < size; ++i) { res[i] = expOmega * wilsonFunctionRight(x, alpha, nodes.get(i)); } return DoubleArray.ofUnsafe(res); }
/** * Evaluates the function. * * @param pp the PiecewisePolynomialResult * @param xKey the key * @return the values of piecewise polynomial functions at xKey * When _dim in PiecewisePolynomialResult is greater than 1, i.e., the struct contains * multiple splines, an element in the return values corresponds to each spline */ public DoubleArray evaluate(PiecewisePolynomialResult pp, double xKey) { ArgChecker.notNull(pp, "pp"); ArgChecker.isFalse(Double.isNaN(xKey), "xKey containing NaN"); ArgChecker.isFalse(Double.isInfinite(xKey), "xKey containing Infinity"); DoubleArray knots = pp.getKnots(); int nKnots = knots.size(); DoubleMatrix coefMatrix = pp.getCoefMatrix(); // check for 1 less interval that knots int lowerBound = FunctionUtils.getLowerBoundIndex(knots, xKey); int indicator = lowerBound == nKnots - 1 ? lowerBound - 1 : lowerBound; return DoubleArray.of(pp.getDimensions(), i -> { DoubleArray coefs = coefMatrix.row(pp.getDimensions() * indicator + i); double res = getValue(coefs, xKey, knots.get(indicator)); ArgChecker.isFalse(Double.isInfinite(res), "Too large input"); ArgChecker.isFalse(Double.isNaN(res), "Too large input"); return res; }); }
@Test public void getLowerBoundIndexTest() { int i = FunctionUtils.getLowerBoundIndex(DoubleArray.of(-2., -1.), -0.); assertEquals(i, 1); i = FunctionUtils.getLowerBoundIndex(DoubleArray.of(1., 2.), -0.); assertEquals(i, 0); i = FunctionUtils.getLowerBoundIndex(DoubleArray.of(1., 2., 3.), 2.5); assertEquals(i, 1); i = FunctionUtils.getLowerBoundIndex(DoubleArray.of(1., 2., 3.), 2.); assertEquals(i, 1); i = FunctionUtils.getLowerBoundIndex(DoubleArray.of(1., 2., 3.), -2.); assertEquals(i, 0); i = FunctionUtils.getLowerBoundIndex(DoubleArray.of(-2., -1., 0.), -0.); assertEquals(i, 2); i = FunctionUtils.getLowerBoundIndex(DoubleArray.of(-2., -1., 0.), 0.); assertEquals(i, 2); i = FunctionUtils.getLowerBoundIndex(DoubleArray.of(-2., -1., 0.), -0.); assertEquals(i, 2); i = FunctionUtils.getLowerBoundIndex(DoubleArray.of(-2., -1., -0.), -0.); assertEquals(i, 2); i = FunctionUtils.getLowerBoundIndex(DoubleArray.of(-1., 0., 1.), -0.); assertEquals(i, 1); i = FunctionUtils.getLowerBoundIndex(DoubleArray.of(-1., 0., 1.), 0.); assertEquals(i, 1); i = FunctionUtils.getLowerBoundIndex(DoubleArray.of(-1., -0., 1.), 0.); assertEquals(i, 1); i = FunctionUtils.getLowerBoundIndex(DoubleArray.of(-1., -0., 1.), -0.); assertEquals(i, 1); i = FunctionUtils.getLowerBoundIndex(DoubleArray.of(0., 1., 2.), -0.); assertEquals(i, 0);
/** * Finds the node sensitivity. * * @param pp the {@link PiecewisePolynomialResultsWithSensitivity} * @param xKey the key * @return Node sensitivity value at x=xKey */ public DoubleArray nodeSensitivity(PiecewisePolynomialResultsWithSensitivity pp, double xKey) { ArgChecker.notNull(pp, "null pp"); ArgChecker.isFalse(Double.isNaN(xKey), "xKey containing NaN"); ArgChecker.isFalse(Double.isInfinite(xKey), "xKey containing Infinity"); if (pp.getDimensions() > 1) { throw new UnsupportedOperationException(); } DoubleArray knots = pp.getKnots(); 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; }
@Override protected DoubleArray doParameterSensitivity(double xValue) { int interval = FunctionUtils.getLowerBoundIndex(poly.getKnots(), xValue); if (interval == poly.getKnots().size() - 1) { interval--; // there is 1 less interval than knots } DoubleMatrix coefficientSensitivity = polySens.get().getCoefficientSensitivity(interval); int nCoefs = coefficientSensitivity.rowCount(); double s = xValue - poly.getKnots().get(interval); DoubleArray res = coefficientSensitivity.row(0); for (int i = 1; i < nCoefs; i++) { res = (DoubleArray) MA.scale(res, s); res = (DoubleArray) MA.add(res, coefficientSensitivity.row(i)); } return res; }
@Override protected DoubleArray doParameterSensitivity(double xValue) { int interval = FunctionUtils.getLowerBoundIndex(poly.getKnots(), xValue); if (interval == poly.getKnots().size() - 1) { interval--; // there is 1 less interval than knots } DoubleMatrix coefficientSensitivity = polySens.get().getCoefficientSensitivity(interval); int nCoefs = coefficientSensitivity.rowCount(); double s = xValue - poly.getKnots().get(interval); DoubleArray res = coefficientSensitivity.row(0); for (int i = 1; i < nCoefs; i++) { res = (DoubleArray) MA.scale(res, s); res = (DoubleArray) MA.add(res, coefficientSensitivity.row(i)); } return res; }
@Override protected DoubleArray doParameterSensitivity(double xValue) { int interval = FunctionUtils.getLowerBoundIndex(poly.getKnots(), xValue); if (interval == poly.getKnots().size() - 1) { interval--; // there is 1 less interval that knots } DoubleMatrix coefficientSensitivity = polySens.get().getCoefficientSensitivity(interval); double[] resSense = nodeSensitivity( xValue, poly.getKnots(), poly.getCoefMatrix(), poly.getDimensions(), interval, coefficientSensitivity).toArray(); double resValue = Math.exp(evaluate(xValue, poly.getKnots(), poly.getCoefMatrix(), poly.getDimensions())); double[] knotValues = getValues(logYValues); final int knotValuesLength = knotValues.length; double[] res = new double[knotValuesLength]; for (int i = 0; i < knotValuesLength; ++i) { res[i] = resSense[i] * resValue / knotValues[i]; } return DoubleArray.ofUnsafe(res); }
@Override protected DoubleArray doParameterSensitivity(double xValue) { int interval = FunctionUtils.getLowerBoundIndex(poly.getKnots(), xValue); if (interval == poly.getKnots().size() - 1) { interval--; // there is 1 less interval that knots } DoubleMatrix coefficientSensitivity = polySens.get().getCoefficientSensitivity(interval); double[] resSense = nodeSensitivity( xValue, poly.getKnots(), poly.getCoefMatrix(), poly.getDimensions(), interval, coefficientSensitivity).toArray(); double resValue = Math.exp(evaluate(xValue, poly.getKnots(), poly.getCoefMatrix(), poly.getDimensions())); double[] knotValues = getValues(logYValues); final int knotValuesLength = knotValues.length; double[] res = new double[knotValuesLength]; for (int i = 0; i < knotValuesLength; ++i) { res[i] = resSense[i + 1] * resValue / knotValues[i]; } return DoubleArray.ofUnsafe(res); }
int interval = FunctionUtils.getLowerBoundIndex(knots, xKey); if (interval == nKnots - 1) {
/** * Evaluates the Smith-Wilson curve function at a x value. * <p> * The {@code nodes} must be sorted in ascending order and coherent to {@code weights}. * * @param x the x value * @param alpha the alpha parameter * @param nodes the nodes * @param weights the weights * @return the value */ public double value(double x, double alpha, DoubleArray nodes, DoubleArray weights) { int size = nodes.size(); ArgChecker.isTrue(size == weights.size(), "nodes and weights must be the same size"); double res = 1d; int bound = x < nodes.get(0) ? 0 : FunctionUtils.getLowerBoundIndex(nodes, x) + 1; for (int i = 0; i < bound; ++i) { res += weights.get(i) * wilsonFunctionLeft(x, alpha, nodes.get(i)); } for (int i = bound; i < size; ++i) { res += weights.get(i) * wilsonFunctionRight(x, alpha, nodes.get(i)); } res *= Math.exp(-omega * x); return res; }
/** * Computes the gradient of the Smith-Wilson curve function at a x value. * <p> * The {@code nodes} must be sorted in ascending order and coherent to {@code weights}. * * @param x the x value * @param alpha the alpha parameter * @param nodes the nodes * @param weights the weights * @return the gradient */ public double firstDerivative(double x, double alpha, DoubleArray nodes, DoubleArray weights) { int size = nodes.size(); ArgChecker.isTrue(size == weights.size(), "nodes and weights must be the same size"); double res = -omega; int bound = x < nodes.get(0) ? 0 : FunctionUtils.getLowerBoundIndex(nodes, x) + 1; for (int i = 0; i < bound; ++i) { res += weights.get(i) * wilsonFunctionLeftDerivative(x, alpha, nodes.get(i)); } for (int i = bound; i < size; ++i) { res += weights.get(i) * wilsonFunctionRightDerivative(x, alpha, nodes.get(i)); } res *= Math.exp(-omega * x); return res; }
int interval = FunctionUtils.getLowerBoundIndex(knots, xKey); if (interval == nKnots - 1) {
int interval = FunctionUtils.getLowerBoundIndex(knots, xKey); if (interval == nKnots - 1) {
int interval = FunctionUtils.getLowerBoundIndex(knots, xKey); if (interval == nKnots - 1) {