//------------------------------------------------------------------------- /// <summary> /// Calculates the price sensitivity of the bond future option product based on curves. /// <para> /// The price sensitivity of the product is the sensitivity of the price to the underlying curves. /// The volatility is unchanged for a fixed strike in the sensitivity computation, hence the "StickyStrike" name. /// </para> /// <para> /// This calculates the underlying future price using the future pricer. /// /// </para> /// </summary> /// <param name="futureOption"> the option product </param> /// <param name="discountingProvider"> the discounting provider </param> /// <param name="volatilities"> the volatilities </param> /// <returns> the price curve sensitivity of the product </returns> public PointSensitivities priceSensitivityRatesStickyStrike(ResolvedBondFutureOption futureOption, LegalEntityDiscountingProvider discountingProvider, BlackBondFutureVolatilities volatilities) { ArgChecker.isTrue(futureOption.PremiumStyle.Equals(FutureOptionPremiumStyle.DAILY_MARGIN), "Premium style should be DAILY_MARGIN"); double futurePrice = this.futurePrice(futureOption, discountingProvider); return(priceSensitivityRatesStickyStrike(futureOption, discountingProvider, volatilities, futurePrice)); }
/// <summary> /// Solves the system Ax = y for the unknown vector x, where A is a tridiagonal matrix and y is a vector. /// This takes order n operations where n is the size of the system /// (number of linear equations), as opposed to order n^3 for the general problem. </summary> /// <param name="aM"> tridiagonal matrix </param> /// <param name="b"> known vector (must be same length as rows/columns of matrix) </param> /// <returns> vector (as an array of doubles) with same length as y </returns> public static double[] solvTriDag(TridiagonalMatrix aM, double[] b) { ArgChecker.notNull(aM, "null matrix"); ArgChecker.notNull(b, "null vector"); double[] d = aM.Diagonal; //b is modified, so get copy of diagonal int n = d.Length; ArgChecker.isTrue(n == b.Length, "vector y wrong length for matrix"); double[] y = Arrays.copyOf(b, n); double[] l = aM.LowerSubDiagonalData; double[] u = aM.UpperSubDiagonalData; double[] x = new double[n]; for (int i = 1; i < n; i++) { double m = l[i - 1] / d[i - 1]; d[i] = d[i] - m * u[i - 1]; y[i] = y[i] - m * y[i - 1]; } x[n - 1] = y[n - 1] / d[n - 1]; for (int i = n - 2; i >= 0; i--) { x[i] = (y[i] - u[i] * x[i + 1]) / d[i]; } return(x); }
/// <summary> /// Creates an instance. /// </summary> /// <param name="x1"> the lower edge </param> /// <param name="x2"> the upper edge, must be greater than x1 </param> /// <param name="y"> the height </param> public TopHatFunction(double x1, double x2, double y) { ArgChecker.isTrue(x1 < x2, "x1 must be less than x2"); _x1 = x1; _x2 = x2; _y = y; }
/// <summary> /// Gamma is in the form gamma^i_{j,k} =\partial^2y_j/\partial x_i \partial x_k, where i is the /// index of the matrix in the stack (3rd index of the tensor), and j,k are the individual /// matrix indices. We would like it in the form H^i_{j,k} =\partial^2y_i/\partial x_j \partial x_k, /// so that each matrix is a Hessian (for the dependent variable y_i), hence the reshaping below. /// </summary> /// <param name="gamma"> the rank 3 tensor </param> /// <returns> the reshaped rank 3 tensor </returns> private DoubleMatrix[] reshapeTensor(DoubleMatrix[] gamma) { int m = gamma.Length; int n = gamma[0].rowCount(); ArgChecker.isTrue(gamma[0].columnCount() == m, "tenor wrong size. Seond index is {}, should be {}", gamma[0].columnCount(), m); DoubleMatrix[] res = new DoubleMatrix[n]; for (int i = 0; i < n; i++) { //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[][] temp = new double[m][m]; double[][] temp = RectangularArrays.ReturnRectangularDoubleArray(m, m); for (int j = 0; j < m; j++) { DoubleMatrix gammaJ = gamma[j]; for (int k = j; k < m; k++) { temp[j][k] = gammaJ.get(i, k); } } for (int j = 0; j < m; j++) { for (int k = 0; k < j; k++) { temp[j][k] = temp[k][j]; } } res[i] = DoubleMatrix.copyOf(temp); } return(res); }
public override Pair <DoubleFunction1D, DoubleFunction1D>[] getPolynomialsAndFirstDerivative(int n) { ArgChecker.isTrue(n >= 0); //JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @SuppressWarnings("unchecked") com.opengamma.strata.collect.tuple.Pair<com.opengamma.strata.math.impl.function.DoubleFunction1D, com.opengamma.strata.math.impl.function.DoubleFunction1D>[] polynomials = new com.opengamma.strata.collect.tuple.Pair[n + 1]; Pair <DoubleFunction1D, DoubleFunction1D>[] polynomials = new Pair[n + 1]; DoubleFunction1D p, dp; for (int i = 0; i <= n; i++) { if (i == 0) { polynomials[i] = Pair.of(One, Zero); } else if (i == 1) { polynomials[i] = Pair.of(X, One); } else { p = (polynomials[i - 1].First.multiply(X).multiply(2 * i - 1).subtract(polynomials[i - 2].First.multiply(i - 1))).multiply(1.0 / i); dp = p.derivative(); polynomials[i] = Pair.of(p, dp); } } return(polynomials); }
/// <summary> /// Creates an instance specifying the value of eps. /// </summary> /// <param name="eps"> the step size used to approximate the derivative </param> public MatrixFieldFirstOrderDifferentiator(double eps) { ArgChecker.isTrue(eps > 1e-15, "eps of {} is below machine tolerance of 1e-15. Please choose a higher value", eps); this.eps = eps; this.twoEps = 2 * eps; this.oneOverTwpEps = 1.0 / twoEps; }
/// <summary> /// Calculates polynomials and derivative. </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 Pair <DoubleFunction1D, DoubleFunction1D>[] getPolynomialsAndFirstDerivative(int n, double alpha, double beta) { ArgChecker.isTrue(n >= 0); //JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @SuppressWarnings("unchecked") com.opengamma.strata.collect.tuple.Pair<com.opengamma.strata.math.impl.function.DoubleFunction1D, com.opengamma.strata.math.impl.function.DoubleFunction1D>[] polynomials = new com.opengamma.strata.collect.tuple.Pair[n + 1]; Pair <DoubleFunction1D, DoubleFunction1D>[] polynomials = new Pair[n + 1]; DoubleFunction1D p, dp, p1, p2; for (int i = 0; i <= n; i++) { if (i == 0) { polynomials[i] = Pair.of(One, Zero); } else if (i == 1) { double a1 = (alpha + beta + 2) / 2; polynomials[i] = Pair.of((DoubleFunction1D) new RealPolynomialFunction1D(new double[] { (alpha - beta) / 2, a1 }), (DoubleFunction1D) new RealPolynomialFunction1D(new double[] { a1 })); } else { int j = i - 1; p1 = polynomials[j].First; p2 = polynomials[j - 1].First; DoubleFunction1D temp1 = p1.multiply(getB(alpha, beta, j)); DoubleFunction1D temp2 = p1.multiply(X).multiply(getC(alpha, beta, j)); DoubleFunction1D temp3 = p2.multiply(getD(alpha, beta, j)); p = (temp1.add(temp2).add(temp3)).divide(getA(alpha, beta, j)); dp = p.derivative(); polynomials[i] = Pair.of(p, dp); } } return(polynomials); }
protected internal override QuantileResult expectedShortfall(double level, DoubleArray sample) { ArgChecker.isTrue(level > 0, "Quantile should be above 0."); ArgChecker.isTrue(level < 1, "Quantile should be below 1."); int sampleSize = sampleCorrection(sample.size()); double[] order = createIndexArray(sample.size()); double[] s = sample.toArray(); DoubleArrayMath.sortPairs(s, order); double fractionalIndex = level * sampleSize; int index = (int)checkIndex(this.index(fractionalIndex), sample.size(), true); int[] indices = new int[index]; double[] weights = new double[index]; double interval = 1d / (double)sampleSize; double losses = s[0] * interval *indexShift(); for (int i = 0; i < index - 1; i++) { losses += s[i] * interval; indices[i] = (int)order[i]; weights[i] = interval; } losses += s[index - 1] * (fractionalIndex - index + 1 - indexShift()) * interval; indices[index - 1] = (int)order[index - 1]; weights[0] += interval * indexShift(); weights[index - 1] = (fractionalIndex - index + 1 - indexShift()) * interval; return(QuantileResult.of(losses / level, indices, DoubleArray.ofUnsafe(weights).dividedBy(level))); }
public virtual double pvbp(RatePaymentPeriod paymentPeriod, RatesProvider provider) { ArgChecker.isTrue(!paymentPeriod.FxReset.Present, "FX reset is not supported"); int accPeriodCount = paymentPeriod.AccrualPeriods.size(); ArgChecker.isTrue(accPeriodCount == 1 || paymentPeriod.CompoundingMethod.Equals(CompoundingMethod.FLAT), "Only one accrued period or Flat compounding supported"); // no compounding if (accPeriodCount == 1) { RateAccrualPeriod accrualPeriod = paymentPeriod.AccrualPeriods.get(0); double df = provider.discountFactor(paymentPeriod.Currency, paymentPeriod.PaymentDate); return(df * accrualPeriod.YearFraction * paymentPeriod.Notional); } else { // Flat compounding switch (paymentPeriod.CompoundingMethod) { case FLAT: return(pvbpCompoundedFlat(paymentPeriod, provider)); default: throw new System.NotSupportedException("PVBP not implemented yet for non FLAT compounding"); } } }
/// <summary> /// Gets the polynomials and derivative. /// </summary> /// <param name="n"> the n value </param> /// <param name="alpha"> the alpha value </param> /// <returns> the result </returns> public virtual Pair <DoubleFunction1D, DoubleFunction1D>[] getPolynomialsAndFirstDerivative(int n, double alpha) { ArgChecker.isTrue(n >= 0); //JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @SuppressWarnings("unchecked") com.opengamma.strata.collect.tuple.Pair<com.opengamma.strata.math.impl.function.DoubleFunction1D, com.opengamma.strata.math.impl.function.DoubleFunction1D>[] polynomials = new com.opengamma.strata.collect.tuple.Pair[n + 1]; Pair <DoubleFunction1D, DoubleFunction1D>[] polynomials = new Pair[n + 1]; DoubleFunction1D p, dp, p1, p2; for (int i = 0; i <= n; i++) { if (i == 0) { polynomials[i] = Pair.of(One, Zero); } else if (i == 1) { polynomials[i] = Pair.of(F1, DF1); } else { p1 = polynomials[i - 1].First; p2 = polynomials[i - 2].First; p = (p1.multiply(2.0 * i + alpha - 1).subtract(p1.multiply(X)).subtract(p2.multiply((i - 1.0 + alpha))).divide(i)); dp = (p.multiply(i).subtract(p1.multiply(i + alpha))).divide(X); polynomials[i] = Pair.of(p, dp); } } return(polynomials); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the price sensitivity of the Ibor future option product based on curves. /// <para> /// The price sensitivity of the product is the sensitivity of the price to the underlying curves. /// The volatility is unchanged for a fixed strike in the sensitivity computation, hence the "StickyStrike" name. /// </para> /// <para> /// This calculates the underlying future price using the future pricer. /// /// </para> /// </summary> /// <param name="futureOption"> the option product </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="volatilities"> the volatilities </param> /// <returns> the price curve sensitivity of the product </returns> public virtual PointSensitivities priceSensitivityRatesStickyStrike(ResolvedIborFutureOption futureOption, RatesProvider ratesProvider, NormalIborFutureOptionVolatilities volatilities) { ArgChecker.isTrue(futureOption.PremiumStyle.Equals(FutureOptionPremiumStyle.DAILY_MARGIN), "Premium style should be DAILY_MARGIN"); double futurePrice = this.futurePrice(futureOption, ratesProvider); return(priceSensitivityRatesStickyStrike(futureOption, ratesProvider, volatilities, futurePrice)); }
/// <summary> /// Returns the quotient of two matrices $C = \frac{A}{B} = AB^{-1}$, where /// $B^{-1}$ is the pseudo-inverse of $B$ i.e. $BB^{-1} = \mathbb{1}$. </summary> /// <param name="m1"> The numerator matrix, not null. This matrix must be a <seealso cref="DoubleMatrix"/>. </param> /// <param name="m2"> The denominator, not null. This matrix must be a <seealso cref="DoubleMatrix"/>. </param> /// <returns> The result </returns> public virtual Matrix divide(Matrix m1, Matrix m2) { ArgChecker.notNull(m1, "m1"); ArgChecker.notNull(m2, "m2"); ArgChecker.isTrue(m1 is DoubleMatrix, "Can only divide a 2D matrix"); ArgChecker.isTrue(m2 is DoubleMatrix, "Can only perform division with a 2D matrix"); return(multiply(m1, getInverse(m2))); }
/// <param name="abscissas"> An array containing the abscissas, not null </param> /// <param name="weights"> An array containing the weights, not null, must be the same length as the abscissa array </param> public GaussianQuadratureData(double[] abscissas, double[] weights) { ArgChecker.notNull(abscissas, "abscissas"); ArgChecker.notNull(weights, "weights"); ArgChecker.isTrue(abscissas.Length == weights.Length, "Abscissa and weight arrays must be the same length"); _weights = weights; _abscissas = abscissas; }
/// <summary> /// Creates an instance. /// </summary> /// <param name="n"> The number of sample points to be used in the integration, not negative or zero </param> /// <param name="generator"> The generator of weights and abscissas </param> public GaussianQuadratureIntegrator1D(int n, QuadratureWeightAndAbscissaFunction generator) { ArgChecker.isTrue(n > 0, "number of intervals must be > 0"); ArgChecker.notNull(generator, "generating function"); this.size = n; this.generator = generator; this.quadrature = generator.generate(size); }
public override double?apply(double[] x) { ArgChecker.notNull(x, "x"); int n = x.Length; ArgChecker.isTrue(n >= 2, "Need at least two points to calculate the population variance"); return(_variance.apply(x) * (n - 1) / n); }
/// <summary> /// Tests that the inputs to the root-finder are not null, and that a root is bracketed by the bounding values. /// </summary> /// <param name="function"> The function, not null </param> /// <param name="x1"> The first bound, not null </param> /// <param name="x2"> The second bound, not null, must be greater than x1 </param> /// <exception cref="IllegalArgumentException"> if x1 and x2 do not bracket a root </exception> protected internal virtual void checkInputs(DoubleFunction1D function, double?x1, double?x2) { ArgChecker.notNull(function, "function"); ArgChecker.notNull(x1, "x1"); ArgChecker.notNull(x2, "x2"); ArgChecker.isTrue(x1 <= x2, "x1 must be less or equal to x2"); ArgChecker.isTrue(function.applyAsDouble(x1) * function.applyAsDouble(x2) <= 0, "x1 and x2 do not bracket a root"); }
//------------------------------------------------------------------------- // gets the settlement price private double settlementPrice(ResolvedDsfTrade trade, RatesProvider ratesProvider) { StandardId standardId = trade.Product.SecurityId.StandardId; QuoteId id = QuoteId.of(standardId, FieldName.SETTLEMENT_PRICE); double price = ratesProvider.data(id); ArgChecker.isTrue(price < 10, "Price must be in decimal form, such as 1.007 for a 0.7% present value, but was: {}", price); return(price); }
protected internal virtual double[] writeArrayAsVector(double[][] x) { ArgChecker.isTrue(x[0].Length == 1, "Trying to convert matrix to vector"); double[] result = new double[x.Length]; for (int i = 0; i < x.Length; i++) { result[i] = x[i][0]; } return(result); }
/// <summary> /// Calculates the delta of the Ibor future option product /// based on the price of the underlying future. /// <para> /// The delta of the product is the sensitivity of the option price to the future price. /// The volatility is unchanged for a fixed strike in the sensitivity computation, hence the "StickyStrike" name. /// /// </para> /// </summary> /// <param name="futureOption"> the option product </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="volatilities"> the volatilities </param> /// <param name="futurePrice"> the price of the underlying future, in decimal form </param> /// <returns> the price curve sensitivity of the product </returns> public virtual double deltaStickyStrike(ResolvedIborFutureOption futureOption, RatesProvider ratesProvider, NormalIborFutureOptionVolatilities volatilities, double futurePrice) { ArgChecker.isTrue(futureOption.PremiumStyle.Equals(FutureOptionPremiumStyle.DAILY_MARGIN), "Premium style should be DAILY_MARGIN"); double timeToExpiry = volatilities.relativeTime(futureOption.Expiry); double strike = futureOption.StrikePrice; ResolvedIborFuture future = futureOption.UnderlyingFuture; double volatility = volatilities.volatility(timeToExpiry, future.LastTradeDate, strike, futurePrice); return(NormalFormulaRepository.delta(futurePrice, strike, timeToExpiry, volatility, futureOption.PutCall)); }
//------------------------------------------------------------------------- /// <summary> /// Evaluates the function. /// </summary> /// <param name="x"> The argument of the function, not null. Must have $x_1 < x < x_2$ </param> /// <returns> The value of the function </returns> public override double?apply(double?x) { ArgChecker.notNull(x, "x"); ArgChecker.isTrue(x.Value != _x1, "Function is undefined for x = x1"); ArgChecker.isTrue(x.Value != _x2, "Function is undefined for x = x2"); if (x.Value > _x1 && x.Value < _x2) { return(_y); } return(0.0); }
/// <summary> /// Calculates the theta of the bond future option product based on the price of the underlying future. /// <para> /// The theta of the product is minus of the option price sensitivity to the time to expiry. /// The volatility is unchanged for a fixed strike in the sensitivity computation, hence the "StickyStrike" name. /// /// </para> /// </summary> /// <param name="futureOption"> the option product </param> /// <param name="discountingProvider"> the discounting provider </param> /// <param name="volatilities"> the volatilities </param> /// <param name="futurePrice"> the price of the underlying future </param> /// <returns> the price curve sensitivity of the product </returns> public double theta(ResolvedBondFutureOption futureOption, LegalEntityDiscountingProvider discountingProvider, BlackBondFutureVolatilities volatilities, double futurePrice) { ArgChecker.isTrue(futureOption.PremiumStyle.Equals(FutureOptionPremiumStyle.DAILY_MARGIN), "Premium style should be DAILY_MARGIN"); double strike = futureOption.StrikePrice; ResolvedBondFuture future = futureOption.UnderlyingFuture; double volatility = volatilities.volatility(futureOption.Expiry, future.LastTradeDate, strike, futurePrice); double timeToExpiry = volatilities.relativeTime(futureOption.Expiry); double theta = BlackFormulaRepository.driftlessTheta(futurePrice, strike, timeToExpiry, volatility); return(theta); }
/// <summary> /// Creates an instance. /// </summary> /// <param name="a"> a, $a > 0$ </param> /// <param name="b"> b, $b > 0$ </param> /// <param name="eps"> approximation accuracy, $\epsilon \geq 0$ </param> /// <param name="maxIter"> maximum number of iterations, $\iter \geq 1$ </param> public IncompleteBetaFunction(double a, double b, double eps, int maxIter) { ArgChecker.isTrue(a > 0, "a must be > 0"); ArgChecker.isTrue(b > 0, "b must be > 0"); ArgChecker.isTrue(eps >= 0, "eps must not be negative"); ArgChecker.isTrue(maxIter >= 1, "maximum number of iterations must be greater than zero"); _a = a; _b = b; _eps = eps; _maxIter = maxIter; }
/// <summary> /// Calculates the price sensitivity to the Black volatility used for the pricing of the bond future option /// based on the price of the underlying future. /// </summary> /// <param name="futureOption"> the option product </param> /// <param name="discountingProvider"> the discounting provider </param> /// <param name="volatilities"> the volatilities </param> /// <param name="futurePrice"> the underlying future price </param> /// <returns> the sensitivity </returns> public BondFutureOptionSensitivity priceSensitivityModelParamsVolatility(ResolvedBondFutureOption futureOption, LegalEntityDiscountingProvider discountingProvider, BlackBondFutureVolatilities volatilities, double futurePrice) { ArgChecker.isTrue(futureOption.PremiumStyle.Equals(FutureOptionPremiumStyle.DAILY_MARGIN), "Premium style should be DAILY_MARGIN"); double strike = futureOption.StrikePrice; ResolvedBondFuture future = futureOption.UnderlyingFuture; double volatility = volatilities.volatility(futureOption.Expiry, future.LastTradeDate, strike, futurePrice); double timeToExpiry = volatilities.relativeTime(futureOption.Expiry); double vega = BlackFormulaRepository.vega(futurePrice, strike, timeToExpiry, volatility); return(BondFutureOptionSensitivity.of(volatilities.Name, timeToExpiry, future.LastTradeDate, strike, futurePrice, future.Currency, vega)); }
//------------------------------------------------------------------------- /// <summary> /// Evaluates the function. /// </summary> /// <param name="x"> x </param> /// <returns> the value of the function </returns> /// <exception cref="IllegalArgumentException"> if $x < 0$ or $x > 1$ </exception> public override double?apply(double?x) { ArgChecker.isTrue(x >= 0 && x <= 1, "x must be in the range 0 to 1"); try { return(Beta.regularizedBeta(x, _a, _b, _eps, _maxIter)); } catch (MaxCountExceededException e) { throw new MathException(e); } }
/// <param name="a"> An array containing the diagonal values of the matrix, not null </param> /// <param name="b"> An array containing the upper sub-diagonal values of the matrix, not null. /// Its length must be one less than the length of the diagonal array </param> /// <param name="c"> An array containing the lower sub-diagonal values of the matrix, not null. /// Its length must be one less than the length of the diagonal array </param> public TridiagonalMatrix(double[] a, double[] b, double[] c) { ArgChecker.notNull(a, "a"); ArgChecker.notNull(b, "b"); ArgChecker.notNull(c, "c"); int n = a.Length; ArgChecker.isTrue(b.Length == n - 1, "Length of subdiagonal b is incorrect"); ArgChecker.isTrue(c.Length == n - 1, "Length of subdiagonal c is incorrect"); _a = a; _b = b; _c = c; }
/// <summary> /// Calculates the price sensitivity to the normal volatility used for the pricing of the Ibor future option /// based on the price of the underlying future. /// <para> /// This sensitivity is also called the <i>price normal vega</i>. /// /// </para> /// </summary> /// <param name="futureOption"> the option product </param> /// <param name="ratesProvider"> the rates provider </param> /// <param name="volatilities"> the volatilities </param> /// <param name="futurePrice"> the underlying future price, in decimal form </param> /// <returns> the sensitivity </returns> public virtual IborFutureOptionSensitivity priceSensitivityModelParamsVolatility(ResolvedIborFutureOption futureOption, RatesProvider ratesProvider, NormalIborFutureOptionVolatilities volatilities, double futurePrice) { ArgChecker.isTrue(futureOption.PremiumStyle.Equals(FutureOptionPremiumStyle.DAILY_MARGIN), "Premium style should be DAILY_MARGIN"); double timeToExpiry = volatilities.relativeTime(futureOption.Expiry); double strike = futureOption.StrikePrice; ResolvedIborFuture future = futureOption.UnderlyingFuture; double volatility = volatilities.volatility(timeToExpiry, future.LastTradeDate, strike, futurePrice); double vega = NormalFormulaRepository.vega(futurePrice, strike, timeToExpiry, volatility, futureOption.PutCall); return(IborFutureOptionSensitivity.of(volatilities.Name, timeToExpiry, future.LastTradeDate, strike, futurePrice, future.Currency, vega)); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @SuppressWarnings("synthetic-access") @Override public com.opengamma.strata.collect.array.DoubleMatrix[] apply(com.opengamma.strata.collect.array.DoubleArray x) public override DoubleMatrix[] apply(DoubleArray x) { ArgChecker.notNull(x, "x"); ArgChecker.isTrue(domain(x), "point {} is not in the function domain", x.ToString()); int n = x.size(); DoubleMatrix[] y = new DoubleMatrix[3]; DoubleMatrix[] res = new DoubleMatrix[n]; double[] w; for (int i = 0; i < n; i++) { double xi = x.get(i); DoubleArray xPlusOneEps = x.with(i, xi + outerInstance.eps); DoubleArray xMinusOneEps = x.with(i, xi - outerInstance.eps); if (!domain(xPlusOneEps)) { DoubleArray xMinusTwoEps = x.with(i, xi - outerInstance.twoEps); if (!domain(xMinusTwoEps)) { throw new MathException("cannot get derivative at point " + x.ToString() + " in direction " + i); } y[0] = function(xMinusTwoEps); y[2] = function(x); y[1] = function(xMinusOneEps); w = wBack; } else { if (!domain(xMinusOneEps)) { y[1] = function(xPlusOneEps); y[0] = function(x); y[2] = function(x.with(i, xi + outerInstance.twoEps)); w = wFwd; } else { y[2] = function(xPlusOneEps); y[0] = function(xMinusOneEps); w = wCent; } } res[i] = (DoubleMatrix)MA.add(MA.scale(y[0], w[0]), MA.scale(y[2], w[2])); if (w[1] != 0) { res[i] = (DoubleMatrix)MA.add(res[i], MA.scale(y[1], w[1])); } } return(res); }
/// <summary> /// Creates an instance. /// </summary> /// <param name="xValues"> the x-values of the curve, must be sorted from low to high </param> /// <param name="yValues"> the y-values of the curve </param> protected internal AbstractBoundCurveInterpolator(DoubleArray xValues, DoubleArray yValues) { ArgChecker.notNull(xValues, "xValues"); ArgChecker.notNull(yValues, "yValues"); int size = xValues.size(); ArgChecker.isTrue(size == yValues.size(), "Curve node arrays must have same size"); ArgChecker.isTrue(size > 1, "Curve node arrays must have at least two nodes"); this.extrapolatorLeft = ExceptionCurveExtrapolator.INSTANCE; this.extrapolatorRight = ExceptionCurveExtrapolator.INSTANCE; this.firstXValue = xValues.get(0); this.lastXValue = xValues.get(size - 1); this.lastYValue = yValues.get(size - 1); }
public LeastSquareResults(double chiSq, DoubleArray parameters, DoubleMatrix covariance, DoubleMatrix inverseJacobian) { ArgChecker.isTrue(chiSq >= 0, "chi square < 0"); ArgChecker.notNull(parameters, "parameters"); ArgChecker.notNull(covariance, "covariance"); int n = parameters.size(); ArgChecker.isTrue(covariance.columnCount() == n, "covariance matrix not square"); ArgChecker.isTrue(covariance.rowCount() == n, "covariance matrix wrong size"); //TODO test size of inverse Jacobian _chiSq = chiSq; _parameters = parameters; _covariance = covariance; _inverseJacobian = inverseJacobian; }
protected internal override QuantileResult quantile(double level, DoubleArray sample, bool isExtrapolated) { ArgChecker.isTrue(level > 0, "Quantile should be above 0."); ArgChecker.isTrue(level < 1, "Quantile should be below 1."); int sampleSize = sampleCorrection(sample.size()); double[] order = createIndexArray(sample.size()); double[] s = sample.toArray(); DoubleArrayMath.sortPairs(s, order); int index = (int)checkIndex(this.index(level * sampleSize), sample.size(), isExtrapolated); int[] ind = new int[1]; ind[0] = (int)order[index - 1]; return(QuantileResult.of(s[index - 1], ind, DoubleArray.of(1))); }