FunctionSetBuilder.java

  1. package org.drip.spline.basis;

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

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

  80. /**
  81.  * <i>FunctionSetBuilder</i> implements the basis set and spline builder for the following types of splines:
  82.  *
  83.  * <br><br>
  84.  *  <ul>
  85.  *      <li>
  86.  *          Exponential basis tension splines
  87.  *      </li>
  88.  *      <li>
  89.  *          Hyperbolic basis tension splines
  90.  *      </li>
  91.  *      <li>
  92.  *          Polynomial basis splines
  93.  *      </li>
  94.  *      <li>
  95.  *          Bernstein Polynomial basis splines
  96.  *      </li>
  97.  *      <li>
  98.  *          Kaklis Pandelis basis tension splines
  99.  *      </li>
  100.  *  </ul>
  101.  *
  102.  * This elastic coefficients for the segment using Ck basis splines inside [0,...,1) - Globally
  103.  *  [x_0,...,x_1) are extracted for:
  104.  *
  105.  *          y = Estimator (Ck, x) * ShapeControl (x)
  106.  *
  107.  *      where x is the normalized ordinate mapped as
  108.  *
  109.  *          x becomes (x - x_i-1) / (x_i - x_i-1)
  110.  *
  111.  * The inverse quadratic/rational spline is a typical shape controller spline used.
  112.  *
  113.  * <br><br>
  114.  *  <ul>
  115.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ComputationalCore.md">Computational Core Module</a></li>
  116.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/SplineBuilderLibrary.md">Spline Builder Library</a></li>
  117.  *      <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>
  118.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/spline/basis/README.md">Basis Spline Construction/Customization Parameters</a></li>
  119.  *  </ul>
  120.  * <br><br>
  121.  *
  122.  * @author Lakshmi Krishnamurthy
  123.  */

  124. public class FunctionSetBuilder {

  125.     /**
  126.      * This function implements the elastic coefficients for the segment using tension exponential basis
  127.      *  splines inside - [0,...,1) - Globally [x_0,...,x_1). The segment equation is
  128.      *
  129.      *      y = A + B * x + C * exp (Tension * x / (x_i - x_i-1)) + D * exp (-Tension * x / (x_i - x_i-1))
  130.      *
  131.      *  where x is the normalized ordinate mapped as
  132.      *
  133.      *      x .gte. (x - x_i-1) / (x_i - x_i-1)
  134.      *
  135.      * @param etsp Exponential Tension Basis set Builder Parameters
  136.      *
  137.      * @return Exponential Tension Basis Functions
  138.      */

  139.     public static final org.drip.spline.basis.FunctionSet ExponentialTensionBasisSet (
  140.         final org.drip.spline.basis.ExponentialTensionSetParams etsp)
  141.     {
  142.         if (null == etsp) return null;

  143.         double dblTension = etsp.tension();

  144.         try {
  145.             return new org.drip.spline.basis.FunctionSet (new org.drip.function.definition.R1ToR1[]
  146.                 {new org.drip.function.r1tor1.Polynomial (0), new org.drip.function.r1tor1.Polynomial (1),
  147.                     new org.drip.function.r1tor1.ExponentialTension (java.lang.Math.E, dblTension), new
  148.                         org.drip.function.r1tor1.ExponentialTension (java.lang.Math.E, -dblTension)});
  149.         } catch (java.lang.Exception e) {
  150.             e.printStackTrace();
  151.         }

  152.         return null;
  153.     }

  154.     /**
  155.      * This function implements the elastic coefficients for the segment using tension hyperbolic basis
  156.      *  splines inside - [0,...,1) - Globally [x_0,...,x_1). The segment equation is
  157.      *
  158.      *      y = A + B * x + C * sinh (Tension * x / (x_i - x_i-1)) + D * cosh (Tension * x / (x_i - x_i-1))
  159.      *
  160.      *  where x is the normalized ordinate mapped as
  161.      *
  162.      *      x .ge. (x - x_i-1) / (x_i - x_i-1)
  163.      *
  164.      * @param etsp Exponential Tension Basis set Builder Parameters
  165.      *
  166.      * @return Hyperbolic Tension Basis Set
  167.      */

  168.     public static final org.drip.spline.basis.FunctionSet HyperbolicTensionBasisSet (
  169.         final org.drip.spline.basis.ExponentialTensionSetParams etsp)
  170.     {
  171.         if (null == etsp) return null;

  172.         double dblTension = etsp.tension();

  173.         try {
  174.             return new org.drip.spline.basis.FunctionSet (new org.drip.function.definition.R1ToR1[]
  175.                 {new org.drip.function.r1tor1.Polynomial (0), new org.drip.function.r1tor1.Polynomial (1),
  176.                     new org.drip.function.r1tor1.HyperbolicTension
  177.                         (org.drip.function.r1tor1.HyperbolicTension.COSH, dblTension), new
  178.                             org.drip.function.r1tor1.HyperbolicTension
  179.                                 (org.drip.function.r1tor1.HyperbolicTension.SINH, dblTension)});
  180.         } catch (java.lang.Exception e) {
  181.             e.printStackTrace();
  182.         }

  183.         return null;
  184.     }

  185.     /**
  186.      * This function implements the elastic coefficients for the segment using polynomial basis splines
  187.      *      inside [0,...,1) - Globally [x_0,...,x_1):
  188.      *
  189.      *          y = Sum (A_i*x^i) i = 0,...,n (0 and n inclusive)
  190.      *
  191.      *      where x is the normalized ordinate mapped as
  192.      *
  193.      *          x .gte. (x - x_i-1) / (x_i - x_i-1)
  194.      *
  195.      * @param pfsp Polynomial Basis set Builder Parameters
  196.      *
  197.      * @return The Polynomial Basis Spline Set
  198.      */

  199.     public static final org.drip.spline.basis.FunctionSet PolynomialBasisSet (
  200.         final org.drip.spline.basis.PolynomialFunctionSetParams pfsp)
  201.     {
  202.         if (null == pfsp) return null;

  203.         int iNumBasis = pfsp.numBasis();

  204.         org.drip.function.definition.R1ToR1[] aAU = new
  205.             org.drip.function.definition.R1ToR1[iNumBasis];

  206.         try {
  207.             for (int i = 0; i < iNumBasis; ++i)
  208.                 aAU[i] = new org.drip.function.r1tor1.Polynomial (i);

  209.             return new org.drip.spline.basis.FunctionSet (aAU);
  210.         } catch (java.lang.Exception e) {
  211.             e.printStackTrace();
  212.         }

  213.         return null;
  214.     }

  215.     /**
  216.      * This function implements the elastic coefficients for the segment using Bernstein polynomial basis
  217.      *  splines inside - [0,...,1) - Globally [x_0,...,x_1):
  218.      *
  219.      *          y = Sum (A_i*B^i(x)) i = 0,...,n (0 and n inclusive)
  220.      *
  221.      *      where x is the normalized ordinate mapped as
  222.      *
  223.      *          x .gte. (x - x_i-1) / (x_i - x_i-1)
  224.      *
  225.      *      and B^i(x) is the Bernstein basis polynomial of order i.
  226.      *
  227.      * @param pfsp Polynomial Basis set Builder Parameters
  228.      *
  229.      * @return The Bernstein polynomial basis
  230.      */

  231.     public static final org.drip.spline.basis.FunctionSet BernsteinPolynomialBasisSet (
  232.         final org.drip.spline.basis.PolynomialFunctionSetParams pfsp)
  233.     {
  234.         if (null == pfsp) return null;

  235.         int iNumBasis = pfsp.numBasis();

  236.         org.drip.function.definition.R1ToR1[] aAU = new
  237.             org.drip.function.definition.R1ToR1[iNumBasis];

  238.         try {
  239.             for (int i = 0; i < iNumBasis; ++i)
  240.                 aAU[i] = new org.drip.function.r1tor1.BernsteinPolynomial (i, iNumBasis - 1 - i);

  241.             return new org.drip.spline.basis.FunctionSet (aAU);
  242.         } catch (java.lang.Exception e) {
  243.             e.printStackTrace();
  244.         }

  245.         return null;
  246.     }

  247.     /**
  248.      * Construct KaklisPandelis from the polynomial tension basis function set
  249.      *
  250.      *      y = A * (1-x) + B * x + C * x * (1-x)^m + D * x^m * (1-x)
  251.      *
  252.      * @param kpsp Kaklis Pandelis Basis set Builder Parameters
  253.      *
  254.      * @return The KaklisPandelis Basis Set
  255.      */

  256.     public static final org.drip.spline.basis.FunctionSet KaklisPandelisBasisSet (
  257.         final org.drip.spline.basis.KaklisPandelisSetParams kpsp)
  258.     {
  259.         if (null == kpsp) return null;

  260.         try {
  261.             org.drip.function.definition.R1ToR1 auLinearPoly = new org.drip.function.r1tor1.Polynomial
  262.                 (1);

  263.             org.drip.function.definition.R1ToR1 auReflectedLinearPoly = new
  264.                 org.drip.function.r1tor1.UnivariateReflection (auLinearPoly);

  265.             org.drip.function.definition.R1ToR1 auKaklisPandelisPolynomial = new
  266.                 org.drip.function.r1tor1.Polynomial (kpsp.polynomialTensionDegree());

  267.             return new org.drip.spline.basis.FunctionSet (new org.drip.function.definition.R1ToR1[]
  268.                 {auReflectedLinearPoly, auLinearPoly, new org.drip.function.r1tor1.UnivariateConvolution
  269.                     (auLinearPoly, new org.drip.function.r1tor1.UnivariateReflection
  270.                         (auKaklisPandelisPolynomial)), new org.drip.function.r1tor1.UnivariateConvolution
  271.                             (auKaklisPandelisPolynomial, auReflectedLinearPoly)});
  272.         } catch (java.lang.Exception e) {
  273.             e.printStackTrace();
  274.         }

  275.         return null;
  276.     }

  277.     /**
  278.      * Construct the Exponential Rational Basis Set
  279.      *
  280.      *      y = A + B / (1+x) + C * exp(-x) + D * exp(-x) / (1+x)
  281.      *
  282.      * @param ersp Exponential Rational Basis set Parameters
  283.      *
  284.      * @return The Exponential Rational Basis Set
  285.      */

  286.     public static final org.drip.spline.basis.FunctionSet ExponentialRationalBasisSet (
  287.         final org.drip.spline.basis.ExponentialRationalSetParams ersp)
  288.     {
  289.         if (null == ersp) return null;

  290.         try {
  291.             org.drip.function.definition.R1ToR1 auLinearPoly = new org.drip.function.r1tor1.Polynomial
  292.                 (0);

  293.             org.drip.function.definition.R1ToR1 auLRSC = new
  294.                 org.drip.function.r1tor1.LinearRationalShapeControl (ersp.rationalTension());

  295.             org.drip.function.definition.R1ToR1 auET = new
  296.                 org.drip.function.r1tor1.ExponentialTension (java.lang.Math.E, -ersp.exponentialTension());

  297.             org.drip.function.definition.R1ToR1 auLRET = new
  298.                 org.drip.function.r1tor1.LinearRationalTensionExponential (-ersp.exponentialTension(),
  299.                     ersp.rationalTension());

  300.             return new org.drip.spline.basis.FunctionSet (new org.drip.function.definition.R1ToR1[]
  301.                 {auLinearPoly, auLRSC, auET, auLRET});
  302.         } catch (java.lang.Exception e) {
  303.             e.printStackTrace();
  304.         }

  305.         return null;
  306.     }

  307.     /**
  308.      * Construct the Exponential Mixture Basis Set
  309.      *
  310.      *      y = A + B * exp(-l_1 * x) + C * exp(-l_2 * x) + D * exp(-l_3 * x)
  311.      *
  312.      * @param emsp Exponential Mixture Basis set Parameters
  313.      *
  314.      * @return The Exponential Mixture Basis Set
  315.      */

  316.     public static final org.drip.spline.basis.FunctionSet ExponentialMixtureBasisSet (
  317.         final org.drip.spline.basis.ExponentialMixtureSetParams emsp)
  318.     {
  319.         if (null == emsp) return null;

  320.         try {
  321.             org.drip.function.definition.R1ToR1 auLinearPoly = new
  322.                 org.drip.function.r1tor1.Polynomial (0);

  323.             org.drip.function.definition.R1ToR1 auExp1 = new
  324.                 org.drip.function.r1tor1.ExponentialTension (java.lang.Math.E, -emsp.tension (0));

  325.             org.drip.function.definition.R1ToR1 auExp2 = new
  326.                 org.drip.function.r1tor1.ExponentialTension (java.lang.Math.E, -emsp.tension (1));

  327.             org.drip.function.definition.R1ToR1 auExp3 = new
  328.                 org.drip.function.r1tor1.ExponentialTension (java.lang.Math.E, -emsp.tension (2));

  329.             return new org.drip.spline.basis.FunctionSet (new org.drip.function.definition.R1ToR1[]
  330.                 {auLinearPoly, auExp1, auExp2, auExp3});
  331.         } catch (java.lang.Exception e) {
  332.             e.printStackTrace();
  333.         }

  334.         return null;
  335.     }

  336.     /**
  337.      * Construct the BSpline Basis Function Set
  338.      *
  339.      * @param bssp BSpline Basis Set Parameters
  340.      *
  341.      * @return The BSpline Basis Function Set
  342.      */

  343.     public static final org.drip.spline.basis.FunctionSet BSplineBasisSet (
  344.         final org.drip.spline.basis.BSplineSequenceParams bssp)
  345.     {
  346.         if (null == bssp) return null;

  347.         org.drip.spline.bspline.SegmentBasisFunction[] aSBF =
  348.             org.drip.spline.bspline.SegmentBasisFunctionGenerator.MonicSequence (bssp.hat(),
  349.                 bssp.shapeControl(), bssp.predictorOrdinates(), bssp.procBasisDerivOrder(), bssp.tension());

  350.         if (null == aSBF || bssp.numBasis() >= aSBF.length) return null;

  351.         int iBSplineOrder = bssp.bSplineOrder();

  352.         try {
  353.             return new org.drip.spline.bspline.SegmentBasisFunctionSet (bssp.numBasis(), bssp.tension(), 2 ==
  354.                 iBSplineOrder ? aSBF : org.drip.spline.bspline.SegmentBasisFunctionGenerator.MulticSequence
  355.                     (iBSplineOrder, aSBF));
  356.         } catch (java.lang.Exception e) {
  357.             e.printStackTrace();
  358.         }

  359.         return null;
  360.     }

  361.     public static final void main (
  362.         final java.lang.String[] astrArgs)
  363.         throws java.lang.Exception
  364.     {
  365.         org.drip.spline.basis.BSplineSequenceParams bssp = new org.drip.spline.basis.BSplineSequenceParams
  366.             (org.drip.spline.bspline.BasisHatPairGenerator.RAW_TENSION_HYPERBOLIC,
  367.                 org.drip.spline.bspline.BasisHatShapeControl.SHAPE_CONTROL_RATIONAL_LINEAR, 2, 4, 1., -1);

  368.         org.drip.numerical.common.NumberUtil.Print1DArray ("BSSP", bssp.predictorOrdinates(), false);

  369.         org.drip.spline.basis.FunctionSet fsBSS = BSplineBasisSet (bssp);

  370.         System.out.println ("fsBSS Size = " + fsBSS.numBasis());
  371.     }
  372. }