//------------------------------------------------------------------------- // shift the curve private NodalCurve withShift(InterpolatedNodalCurve curve, IList <ParameterMetadata> parameterMetadata, DoubleMatrix sensitivity, bool computeJacobian, double shift) { int nNode = curve.ParameterCount; if (shift < curve.XValues.get(0)) { //offset less than t value of 1st knot, so no knots are not removed double eta = curve.YValues.get(0) * shift; DoubleArray time = DoubleArray.of(nNode, i => curve.XValues.get(i) - shift); DoubleArray rate = DoubleArray.of(nNode, i => (curve.YValues.get(i) * curve.XValues.get(i) - eta) / time.get(i)); CurveMetadata metadata = curve.Metadata.withParameterMetadata(parameterMetadata); if (computeJacobian) { //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[][] transf = new double[nNode][nNode]; double[][] transf = RectangularArrays.ReturnRectangularDoubleArray(nNode, nNode); for (int i = 0; i < nNode; ++i) { transf[i][0] = -shift / time.get(i); transf[i][i] += curve.XValues.get(i) / time.get(i); } DoubleMatrix jacobianMatrix = (DoubleMatrix)MATRIX_ALGEBRA.multiply(DoubleMatrix.ofUnsafe(transf), MATRIX_ALGEBRA.getInverse(sensitivity)); JacobianCalibrationMatrix jacobian = JacobianCalibrationMatrix.of(ImmutableList.of(CurveParameterSize.of(curve.Name, nNode)), jacobianMatrix); return(curve.withValues(time, rate).withMetadata(metadata.withInfo(CurveInfoType.JACOBIAN, jacobian))); } return(curve.withValues(time, rate).withMetadata(metadata)); } if (shift >= curve.XValues.get(nNode - 1)) { //new base after last knot. The new 'curve' has a constant zero rate which we represent with a nominal knot at 1.0 double time = 1d; double interval = curve.XValues.get(nNode - 1) - curve.XValues.get(nNode - 2); double rate = (curve.YValues.get(nNode - 1) * curve.XValues.get(nNode - 1) - curve.YValues.get(nNode - 2) * curve.XValues.get(nNode - 2)) / interval; if (computeJacobian) { //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[][] transf = new double[1][nNode]; double[][] transf = RectangularArrays.ReturnRectangularDoubleArray(1, nNode); transf[0][nNode - 2] = -curve.XValues.get(nNode - 2) / interval; transf[0][nNode - 1] = curve.XValues.get(nNode - 1) / interval; DoubleMatrix jacobianMatrix = (DoubleMatrix)MATRIX_ALGEBRA.multiply(DoubleMatrix.ofUnsafe(transf), MATRIX_ALGEBRA.getInverse(sensitivity)); JacobianCalibrationMatrix jacobian = JacobianCalibrationMatrix.of(ImmutableList.of(CurveParameterSize.of(curve.Name, nNode)), jacobianMatrix); return(ConstantNodalCurve.of(curve.Metadata.withInfo(CurveInfoType.JACOBIAN, jacobian), time, rate)); } return(ConstantNodalCurve.of(curve.Metadata, time, rate)); } //offset greater than (or equal to) t value of 1st knot, so at least one knot must be removed int index = Arrays.binarySearch(curve.XValues.toArray(), shift); if (index < 0) { index = -(index + 1); } else { index++; } double interval = curve.XValues.get(index) - curve.XValues.get(index - 1); double tt1 = curve.XValues.get(index - 1) * (curve.XValues.get(index) - shift); double tt2 = curve.XValues.get(index) * (shift - curve.XValues.get(index - 1)); double eta = (curve.YValues.get(index - 1) * tt1 + curve.YValues.get(index) * tt2) / interval; int m = nNode - index; CurveMetadata metadata = curve.Metadata.withParameterMetadata(parameterMetadata.subList(index, nNode)); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final int indexFinal = index; int indexFinal = index; DoubleArray time = DoubleArray.of(m, i => curve.XValues.get(i + indexFinal) - shift); DoubleArray rate = DoubleArray.of(m, i => (curve.YValues.get(i + indexFinal) * curve.XValues.get(i + indexFinal) - eta) / time.get(i)); if (computeJacobian) { //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[][] transf = new double[m][nNode]; double[][] transf = RectangularArrays.ReturnRectangularDoubleArray(m, nNode); for (int i = 0; i < m; ++i) { transf[i][index - 1] -= tt1 / (time.get(i) * interval); transf[i][index] -= tt2 / (time.get(i) * interval); transf[i][i + index] += curve.XValues.get(i + index) / time.get(i); } DoubleMatrix jacobianMatrix = (DoubleMatrix)MATRIX_ALGEBRA.multiply(DoubleMatrix.ofUnsafe(transf), MATRIX_ALGEBRA.getInverse(sensitivity)); JacobianCalibrationMatrix jacobian = JacobianCalibrationMatrix.of(ImmutableList.of(CurveParameterSize.of(curve.Name, nNode)), jacobianMatrix); return(curve.withValues(time, rate).withMetadata(metadata.withInfo(CurveInfoType.JACOBIAN, jacobian))); } return(curve.withValues(time, rate).withMetadata(metadata)); }