SingleSegmentLagrangePolynomial.java

  1.    
  2. package org.drip.spline.stretch;

  3. /*
  4.  * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  5.  */

  6. /*!
  7.  * Copyright (C) 2020 Lakshmi Krishnamurthy
  8.  * Copyright (C) 2019 Lakshmi Krishnamurthy
  9.  * Copyright (C) 2018 Lakshmi Krishnamurthy
  10.  * Copyright (C) 2017 Lakshmi Krishnamurthy
  11.  * Copyright (C) 2016 Lakshmi Krishnamurthy
  12.  * Copyright (C) 2015 Lakshmi Krishnamurthy
  13.  * Copyright (C) 2014 Lakshmi Krishnamurthy
  14.  * Copyright (C) 2013 Lakshmi Krishnamurthy
  15.  *
  16.  *  This file is part of DROP, an open-source library targeting analytics/risk, transaction cost analytics,
  17.  *      asset liability management analytics, capital, exposure, and margin analytics, valuation adjustment
  18.  *      analytics, and portfolio construction analytics within and across fixed income, credit, commodity,
  19.  *      equity, FX, and structured products. It also includes auxiliary libraries for algorithm support,
  20.  *      numerical analysis, numerical optimization, spline builder, model validation, statistical learning,
  21.  *      and computational support.
  22.  *  
  23.  *      https://lakshmidrip.github.io/DROP/
  24.  *  
  25.  *  DROP is composed of three modules:
  26.  *  
  27.  *  - DROP Product Core - https://lakshmidrip.github.io/DROP-Product-Core/
  28.  *  - DROP Portfolio Core - https://lakshmidrip.github.io/DROP-Portfolio-Core/
  29.  *  - DROP Computational Core - https://lakshmidrip.github.io/DROP-Computational-Core/
  30.  *
  31.  *  DROP Product Core implements libraries for the following:
  32.  *  - Fixed Income Analytics
  33.  *  - Loan Analytics
  34.  *  - Transaction Cost Analytics
  35.  *
  36.  *  DROP Portfolio Core implements libraries for the following:
  37.  *  - Asset Allocation Analytics
  38.  *  - Asset Liability Management Analytics
  39.  *  - Capital Estimation Analytics
  40.  *  - Exposure Analytics
  41.  *  - Margin Analytics
  42.  *  - XVA Analytics
  43.  *
  44.  *  DROP Computational Core implements libraries for the following:
  45.  *  - Algorithm Support
  46.  *  - Computation Support
  47.  *  - Function Analysis
  48.  *  - Model Validation
  49.  *  - Numerical Analysis
  50.  *  - Numerical Optimizer
  51.  *  - Spline Builder
  52.  *  - Statistical Learning
  53.  *
  54.  *  Documentation for DROP is Spread Over:
  55.  *
  56.  *  - Main                     => https://lakshmidrip.github.io/DROP/
  57.  *  - Wiki                     => https://github.com/lakshmiDRIP/DROP/wiki
  58.  *  - GitHub                   => https://github.com/lakshmiDRIP/DROP
  59.  *  - Repo Layout Taxonomy     => https://github.com/lakshmiDRIP/DROP/blob/master/Taxonomy.md
  60.  *  - Javadoc                  => https://lakshmidrip.github.io/DROP/Javadoc/index.html
  61.  *  - Technical Specifications => https://github.com/lakshmiDRIP/DROP/tree/master/Docs/Internal
  62.  *  - Release Versions         => https://lakshmidrip.github.io/DROP/version.html
  63.  *  - Community Credits        => https://lakshmidrip.github.io/DROP/credits.html
  64.  *  - Issues Catalog           => https://github.com/lakshmiDRIP/DROP/issues
  65.  *  - JUnit                    => https://lakshmidrip.github.io/DROP/junit/index.html
  66.  *  - Jacoco                   => https://lakshmidrip.github.io/DROP/jacoco/index.html
  67.  *
  68.  *  Licensed under the Apache License, Version 2.0 (the "License");
  69.  *      you may not use this file except in compliance with the License.
  70.  *  
  71.  *  You may obtain a copy of the License at
  72.  *      http://www.apache.org/licenses/LICENSE-2.0
  73.  *  
  74.  *  Unless required by applicable law or agreed to in writing, software
  75.  *      distributed under the License is distributed on an "AS IS" BASIS,
  76.  *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  77.  *  
  78.  *  See the License for the specific language governing permissions and
  79.  *      limitations under the License.
  80.  */

  81. /**
  82.  * <i>SingleSegmentLagrangePolynomial</i> implements the SingleSegmentSequence Stretch interface using the
  83.  * Lagrange Polynomial Estimator. As such it provides a perfect fit that travels through all the
  84.  * predictor/response pairs causing Runge's instability.
  85.  *
  86.  * <br><br>
  87.  *  <ul>
  88.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ComputationalCore.md">Computational Core Module</a></li>
  89.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/SplineBuilderLibrary.md">Spline Builder Library</a></li>
  90.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/spline/README.md">Basis Splines and Linear Compounders across a Broad Family of Spline Basis Functions</a></li>
  91.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/spline/stretch/README.md">Multi-Segment Sequence Spline Stretch</a></li>
  92.  *  </ul>
  93.  * <br><br>
  94.  *
  95.  * @author Lakshmi Krishnamurthy
  96.  */

  97. public class SingleSegmentLagrangePolynomial implements org.drip.spline.stretch.SingleSegmentSequence {
  98.     private static final double DIFF_SCALE = 1.0e-06;
  99.     private static final int MAXIMA_PREDICTOR_ORDINATE_NODE = 1;
  100.     private static final int MINIMA_PREDICTOR_ORDINATE_NODE = 2;
  101.     private static final int MONOTONE_PREDICTOR_ORDINATE_NODE = 4;

  102.     private double[] _adblResponseValue = null;
  103.     private double[] _adblPredictorOrdinate = null;

  104.     private static final double CalcAbsoluteMin (
  105.         final double[] adblY)
  106.         throws java.lang.Exception
  107.     {
  108.         if (null == adblY)
  109.             throw new java.lang.Exception
  110.                 ("SingleSegmentLagrangePolynomial::CalcAbsoluteMin => Invalid Inputs");

  111.         int iNumPoints = adblY.length;

  112.         if (1 >= iNumPoints)
  113.             throw new java.lang.Exception
  114.                 ("SingleSegmentLagrangePolynomial::CalcAbsoluteMin => Invalid Inputs");

  115.         double dblMin = java.lang.Math.abs (adblY[0]);

  116.         for (int i = 0; i < iNumPoints; ++i) {
  117.             double dblValue = java.lang.Math.abs (adblY[i]);

  118.             dblMin = dblMin > dblValue ? dblValue : dblMin;
  119.         }

  120.         return dblMin;
  121.     }

  122.     private static final double CalcMinDifference (
  123.         final double[] adblY)
  124.         throws java.lang.Exception
  125.     {
  126.         if (null == adblY)
  127.             throw new java.lang.Exception
  128.                 ("SingleSegmentLagrangePolynomial::CalcMinDifference => Invalid Inputs");

  129.         int iNumPoints = adblY.length;

  130.         if (1 >= iNumPoints)
  131.             throw new java.lang.Exception
  132.                 ("SingleSegmentLagrangePolynomial::CalcMinDifference => Invalid Inputs");

  133.         double dblMinDiff = java.lang.Math.abs (adblY[0] - adblY[1]);

  134.         for (int i = 0; i < iNumPoints; ++i) {
  135.             for (int j = i + 1; j < iNumPoints; ++j) {
  136.                 double dblDiff = java.lang.Math.abs (adblY[i] - adblY[j]);

  137.                 dblMinDiff = dblMinDiff > dblDiff ? dblDiff : dblMinDiff;
  138.             }
  139.         }

  140.         return dblMinDiff;
  141.     }

  142.     private static final double EstimateBumpDelta (
  143.         final double[] adblY)
  144.         throws java.lang.Exception
  145.     {
  146.         double dblBumpDelta = CalcMinDifference (adblY);

  147.         if (!org.drip.numerical.common.NumberUtil.IsValid (dblBumpDelta) || 0. == dblBumpDelta)
  148.             dblBumpDelta = CalcAbsoluteMin (adblY);

  149.         return 0. == dblBumpDelta ? DIFF_SCALE : dblBumpDelta * DIFF_SCALE;
  150.     }

  151.     /**
  152.      * SingleSegmentLagrangePolynomial constructor
  153.      *
  154.      * @param adblPredictorOrdinate Array of Predictor Ordinates
  155.      *
  156.      * @throws java.lang.Exception Thrown if inputs are invalid
  157.      */

  158.     public SingleSegmentLagrangePolynomial (
  159.         final double[] adblPredictorOrdinate)
  160.         throws java.lang.Exception
  161.     {
  162.         if (null == (_adblPredictorOrdinate = adblPredictorOrdinate))
  163.             throw new java.lang.Exception ("SingleSegmentLagrangePolynomial ctr: Invalid Inputs");

  164.         int iNumPredictorOrdinate = _adblPredictorOrdinate.length;

  165.         if (1 >= iNumPredictorOrdinate)
  166.             throw new java.lang.Exception ("SingleSegmentLagrangePolynomial ctr: Invalid Inputs");

  167.         for (int i = 0; i < iNumPredictorOrdinate; ++i) {
  168.             for (int j = i + 1; j < iNumPredictorOrdinate; ++j) {
  169.                 if (_adblPredictorOrdinate[i] == _adblPredictorOrdinate[j])
  170.                     throw new java.lang.Exception ("SingleSegmentLagrangePolynomial ctr: Invalid Inputs");
  171.             }
  172.         }
  173.     }

  174.     @Override public boolean setup (
  175.         final double dblYLeading,
  176.         final double[] adblResponseValue,
  177.         final org.drip.spline.params.StretchBestFitResponse rbfr,
  178.         final org.drip.spline.stretch.BoundarySettings bs,
  179.         final int iCalibrationDetail)
  180.     {
  181.         return null != (_adblResponseValue = adblResponseValue) && _adblResponseValue.length ==
  182.             _adblPredictorOrdinate.length;
  183.     }

  184.     @Override public double responseValue (
  185.         final double dblPredictorOrdinate)
  186.         throws java.lang.Exception
  187.     {
  188.         if (!org.drip.numerical.common.NumberUtil.IsValid (dblPredictorOrdinate))
  189.             throw new java.lang.Exception
  190.                 ("SingleSegmentLagrangePolynomial::responseValue => Invalid inputs!");

  191.         int iNumPredictorOrdinate = _adblPredictorOrdinate.length;

  192.         if (_adblPredictorOrdinate[0] > dblPredictorOrdinate ||
  193.             _adblPredictorOrdinate[iNumPredictorOrdinate - 1] < dblPredictorOrdinate)
  194.             throw new java.lang.Exception
  195.                 ("SingleSegmentLagrangePolynomial::responseValue => Input out of range!");

  196.         double dblResponse = 0;

  197.         for (int i = 0; i < iNumPredictorOrdinate; ++i) {
  198.             double dblResponsePredictorOrdinateContribution = _adblResponseValue[i];

  199.             for (int j = 0; j < iNumPredictorOrdinate; ++j) {
  200.                 if (i != j)
  201.                     dblResponsePredictorOrdinateContribution = dblResponsePredictorOrdinateContribution *
  202.                         (dblPredictorOrdinate - _adblPredictorOrdinate[j]) / (_adblPredictorOrdinate[i] -
  203.                             _adblPredictorOrdinate[j]);
  204.             }

  205.             dblResponse += dblResponsePredictorOrdinateContribution;
  206.         }

  207.         return dblResponse;
  208.     }

  209.     @Override public double responseValueDerivative (
  210.         final double dblPredictorOrdinate,
  211.         final int iOrder)
  212.         throws java.lang.Exception
  213.     {
  214.         if (!org.drip.numerical.common.NumberUtil.IsValid (dblPredictorOrdinate) || 0 >= iOrder)
  215.             throw new java.lang.Exception
  216.                 ("SingleSegmentLagrangePolynomial::responseValueDerivative => Invalid inputs!");

  217.         org.drip.function.definition.R1ToR1 au = new org.drip.function.definition.R1ToR1
  218.             (null) {
  219.             @Override public double evaluate (
  220.                 double dblX)
  221.                 throws java.lang.Exception
  222.             {
  223.                 return responseValue (dblX);
  224.             }
  225.         };

  226.         return au.derivative (dblPredictorOrdinate, iOrder);
  227.     }

  228.     @Override public org.drip.numerical.differentiation.WengertJacobian jackDResponseDCalibrationInput (
  229.         final double dblPredictorOrdinate,
  230.         final int iOrder)
  231.     {
  232.         if (!org.drip.numerical.common.NumberUtil.IsValid (dblPredictorOrdinate)) return null;

  233.         int iNumPredictorOrdinate = _adblPredictorOrdinate.length;
  234.         double dblInputResponseSensitivityShift = java.lang.Double.NaN;
  235.         double dblResponseWithUnadjustedResponseInput = java.lang.Double.NaN;
  236.         org.drip.numerical.differentiation.WengertJacobian wjDResponseDResponseInput = null;

  237.         if (_adblPredictorOrdinate[0] > dblPredictorOrdinate ||
  238.             _adblPredictorOrdinate[iNumPredictorOrdinate - 1] < dblPredictorOrdinate)
  239.             return null;

  240.         try {
  241.             if (!org.drip.numerical.common.NumberUtil.IsValid (dblInputResponseSensitivityShift =
  242.                 EstimateBumpDelta (_adblResponseValue)) || !org.drip.numerical.common.NumberUtil.IsValid
  243.                     (dblResponseWithUnadjustedResponseInput = responseValue (dblPredictorOrdinate)))
  244.                 return null;

  245.             wjDResponseDResponseInput = new org.drip.numerical.differentiation.WengertJacobian (1,
  246.                 iNumPredictorOrdinate);
  247.         } catch (java.lang.Exception e) {
  248.             e.printStackTrace();

  249.             return null;
  250.         }

  251.         for (int i = 0; i < iNumPredictorOrdinate; ++i) {
  252.             double[] adblSensitivityShiftedInputResponse = new double[iNumPredictorOrdinate];

  253.             for (int j = 0; j < iNumPredictorOrdinate; ++j)
  254.                 adblSensitivityShiftedInputResponse[j] = i == j ? _adblResponseValue[j] +
  255.                     dblInputResponseSensitivityShift : _adblResponseValue[j];

  256.             try {
  257.                 SingleSegmentLagrangePolynomial lps = new SingleSegmentLagrangePolynomial
  258.                     (_adblPredictorOrdinate);

  259.                 if (!lps.setup (adblSensitivityShiftedInputResponse[0], adblSensitivityShiftedInputResponse,
  260.                     null, org.drip.spline.stretch.BoundarySettings.FloatingStandard(),
  261.                         org.drip.spline.stretch.MultiSegmentSequence.CALIBRATE) ||
  262.                             !wjDResponseDResponseInput.accumulatePartialFirstDerivative (0, i,
  263.                                 (lps.responseValue (dblPredictorOrdinate) -
  264.                                     dblResponseWithUnadjustedResponseInput) /
  265.                                         dblInputResponseSensitivityShift))
  266.                     return null;
  267.             } catch (java.lang.Exception e) {
  268.                 e.printStackTrace();

  269.                 return null;
  270.             }
  271.         }

  272.         return wjDResponseDResponseInput;
  273.     }

  274.     @Override public org.drip.numerical.differentiation.WengertJacobian jackDResponseDManifestMeasure (
  275.         final java.lang.String strManifestMeasure,
  276.         final double dblPredictorOrdinate,
  277.         final int iOrder)
  278.     {
  279.         return null;
  280.     }

  281.     @Override public org.drip.spline.segment.Monotonocity monotoneType (
  282.         final double dblPredictorOrdinate)
  283.     {
  284.         if (!org.drip.numerical.common.NumberUtil.IsValid (dblPredictorOrdinate)) return null;

  285.         int iNumPredictorOrdinate = _adblPredictorOrdinate.length;

  286.         if (_adblPredictorOrdinate[0] > dblPredictorOrdinate ||
  287.             _adblPredictorOrdinate[iNumPredictorOrdinate - 1] < dblPredictorOrdinate)
  288.             return null;

  289.         if (2 == iNumPredictorOrdinate) {
  290.             try {
  291.                 return new org.drip.spline.segment.Monotonocity
  292.                     (org.drip.spline.segment.Monotonocity.MONOTONIC);
  293.             } catch (java.lang.Exception e) {
  294.                 e.printStackTrace();

  295.                 return null;
  296.             }
  297.         }

  298.         org.drip.function.definition.R1ToR1 auDeriv = new
  299.             org.drip.function.definition.R1ToR1 (null) {
  300.             @Override public double evaluate (
  301.                 final double dblX)
  302.                 throws java.lang.Exception
  303.             {
  304.                 double dblDeltaX = CalcMinDifference (_adblPredictorOrdinate) * DIFF_SCALE;

  305.                 return (responseValue (dblX + dblDeltaX) - responseValue (dblX)) / dblDeltaX;
  306.             }

  307.             @Override public double integrate (
  308.                 final double dblBegin,
  309.                 final double dblEnd)
  310.                 throws java.lang.Exception
  311.             {
  312.                 return org.drip.numerical.integration.R1ToR1Integrator.Boole (this, dblBegin, dblEnd);
  313.             }
  314.         };

  315.         try {
  316.             org.drip.function.r1tor1solver.FixedPointFinderOutput fpop = new
  317.                 org.drip.function.r1tor1solver.FixedPointFinderBrent (0., auDeriv, true).findRoot
  318.                     (org.drip.function.r1tor1solver.InitializationHeuristics.FromHardSearchEdges (0., 1.));

  319.             if (null == fpop || !fpop.containsRoot())
  320.                 return new org.drip.spline.segment.Monotonocity
  321.                     (org.drip.spline.segment.Monotonocity.MONOTONIC);

  322.             double dblExtremum = fpop.getRoot();

  323.             if (!org.drip.numerical.common.NumberUtil.IsValid (dblExtremum) || dblExtremum <= 0. || dblExtremum
  324.                 >= 1.)
  325.                 return new org.drip.spline.segment.Monotonocity
  326.                     (org.drip.spline.segment.Monotonocity.MONOTONIC);

  327.             double dblDeltaX = CalcMinDifference (_adblPredictorOrdinate) * DIFF_SCALE;

  328.             double dbl2ndDeriv = responseValue (dblExtremum + dblDeltaX) + responseValue (dblExtremum -
  329.                 dblDeltaX) - 2. * responseValue (dblPredictorOrdinate);

  330.             if (0. > dbl2ndDeriv)
  331.                 return new org.drip.spline.segment.Monotonocity
  332.                     (org.drip.spline.segment.Monotonocity.MAXIMA);

  333.             if (0. < dbl2ndDeriv)
  334.                 return new org.drip.spline.segment.Monotonocity
  335.                     (org.drip.spline.segment.Monotonocity.MINIMA);

  336.             if (0. == dbl2ndDeriv)
  337.                 return new org.drip.spline.segment.Monotonocity
  338.                     (org.drip.spline.segment.Monotonocity.INFLECTION);

  339.             return new org.drip.spline.segment.Monotonocity
  340.                 (org.drip.spline.segment.Monotonocity.NON_MONOTONIC);
  341.         } catch (java.lang.Exception e) {
  342.             e.printStackTrace();
  343.         }

  344.         try {
  345.             return new org.drip.spline.segment.Monotonocity
  346.                 (org.drip.spline.segment.Monotonocity.MONOTONIC);
  347.         } catch (java.lang.Exception e) {
  348.             e.printStackTrace();
  349.         }

  350.         return null;
  351.     }

  352.     @Override public boolean isLocallyMonotone()
  353.         throws java.lang.Exception
  354.     {
  355.         org.drip.spline.segment.Monotonocity sm = monotoneType (0.5 * (_adblPredictorOrdinate[0] +
  356.             _adblPredictorOrdinate[_adblPredictorOrdinate.length - 1]));

  357.         return null != sm && org.drip.spline.segment.Monotonocity.MONOTONIC == sm.type();
  358.     }

  359.     @Override public boolean isCoMonotone (
  360.         final double[] adblMeasuredResponse)
  361.         throws java.lang.Exception
  362.     {
  363.         if (null == adblMeasuredResponse) return false;

  364.         int iNumMeasuredResponse = adblMeasuredResponse.length;

  365.         if (2 >= iNumMeasuredResponse) return false;

  366.         int[] aiNodeMiniMax = new int[iNumMeasuredResponse];
  367.         int[] aiMonotoneType = new int[iNumMeasuredResponse];

  368.         for (int i = 0; i < iNumMeasuredResponse; ++i) {
  369.             if (0 == i || iNumMeasuredResponse - 1 == i)
  370.                 aiNodeMiniMax[i] = 0;
  371.             else {
  372.                 if (adblMeasuredResponse[i - 1] < adblMeasuredResponse[i] && adblMeasuredResponse[i + 1] <
  373.                     adblMeasuredResponse[i])
  374.                     aiNodeMiniMax[i] = MAXIMA_PREDICTOR_ORDINATE_NODE;
  375.                 else if (adblMeasuredResponse[i - 1] > adblMeasuredResponse[i] && adblMeasuredResponse[i + 1]
  376.                     > adblMeasuredResponse[i])
  377.                     aiNodeMiniMax[i] = MINIMA_PREDICTOR_ORDINATE_NODE;
  378.                 else
  379.                     aiNodeMiniMax[i] = MONOTONE_PREDICTOR_ORDINATE_NODE;
  380.             }

  381.             org.drip.spline.segment.Monotonocity sm = monotoneType (adblMeasuredResponse[i]);

  382.             aiMonotoneType[i] = null != sm ? sm.type() :
  383.                 org.drip.spline.segment.Monotonocity.NON_MONOTONIC;
  384.         }

  385.         for (int i = 1; i < iNumMeasuredResponse - 1; ++i) {
  386.             if (MAXIMA_PREDICTOR_ORDINATE_NODE == aiNodeMiniMax[i]) {
  387.                 if (org.drip.spline.segment.Monotonocity.MAXIMA != aiMonotoneType[i] &&
  388.                     org.drip.spline.segment.Monotonocity.MAXIMA != aiMonotoneType[i - 1])
  389.                     return false;
  390.             } else if (MINIMA_PREDICTOR_ORDINATE_NODE == aiNodeMiniMax[i]) {
  391.                 if (org.drip.spline.segment.Monotonocity.MINIMA != aiMonotoneType[i] &&
  392.                     org.drip.spline.segment.Monotonocity.MINIMA != aiMonotoneType[i - 1])
  393.                     return false;
  394.             }
  395.         }

  396.         return true;
  397.     }

  398.     @Override public boolean isKnot (
  399.         final double dblPredictorOrdinate)
  400.     {
  401.         if (!org.drip.numerical.common.NumberUtil.IsValid (dblPredictorOrdinate)) return false;

  402.         int iNumPredictorOrdinate = _adblPredictorOrdinate.length;

  403.         if (_adblPredictorOrdinate[0] > dblPredictorOrdinate ||
  404.             _adblPredictorOrdinate[iNumPredictorOrdinate - 1] < dblPredictorOrdinate)
  405.             return false;

  406.         for (int i = 0; i < iNumPredictorOrdinate; ++i) {
  407.             if (dblPredictorOrdinate == _adblPredictorOrdinate[i]) return true;
  408.         }

  409.         return false;
  410.     }

  411.     @Override public boolean resetNode (
  412.         final int iPredictorOrdinateNodeIndex,
  413.         final double dblResetResponse)
  414.     {
  415.         if (!org.drip.numerical.common.NumberUtil.IsValid (dblResetResponse)) return false;

  416.         if (iPredictorOrdinateNodeIndex > _adblPredictorOrdinate.length) return false;

  417.         _adblResponseValue[iPredictorOrdinateNodeIndex] = dblResetResponse;
  418.         return true;
  419.     }

  420.     @Override public boolean resetNode (
  421.         final int iPredictorOrdinateNodeIndex,
  422.         final org.drip.spline.params.SegmentResponseValueConstraint sprcReset)
  423.     {
  424.         return false;
  425.     }

  426.     @Override public org.drip.function.definition.R1ToR1 toAU()
  427.     {
  428.         org.drip.function.definition.R1ToR1 au = new
  429.             org.drip.function.definition.R1ToR1 (null)
  430.         {
  431.             @Override public double evaluate (
  432.                 final double dblVariate)
  433.                 throws java.lang.Exception
  434.             {
  435.                 return responseValue (dblVariate);
  436.             }

  437.             @Override public double derivative (
  438.                 final double dblVariate,
  439.                 final int iOrder)
  440.                 throws java.lang.Exception
  441.             {
  442.                 return responseValueDerivative (dblVariate, iOrder);
  443.             }
  444.         };

  445.         return au;
  446.     }

  447.     @Override public double getLeftPredictorOrdinateEdge()
  448.     {
  449.         return _adblPredictorOrdinate[0];
  450.     }

  451.     @Override public double getRightPredictorOrdinateEdge()
  452.     {
  453.         return _adblPredictorOrdinate[_adblPredictorOrdinate.length - 1];
  454.     }
  455. }