InteriorFixedPointFinder.java

  1. package org.drip.function.rdtor1solver;

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

  77. /**
  78.  * <i>InteriorFixedPointFinder</i> generates the Iterators for solving R<sup>d</sup> To R<sup>1</sup>
  79.  * Convex/Non-Convex Functions Under Inequality Constraints loaded using a Barrier Coefficient.
  80.  *
  81.  *  <br><br>
  82.  *  <ul>
  83.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/NumericalCore.md">Numerical Core Module</a></li>
  84.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/NumericalOptimizerLibrary.md">Numerical Optimizer</a></li>
  85.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/feed/README.md">Function</a></li>
  86.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/feed/rdtor1solver/README.md">R<sup>d</sup> To R<sup>1</sup> Solver</a></li>
  87.  *  </ul>
  88.  *
  89.  * @author Lakshmi Krishnamurthy
  90.  */

  91. public class InteriorFixedPointFinder
  92.     extends org.drip.function.rdtor1solver.FixedRdFinder
  93. {
  94.     private double _barrierStrength = java.lang.Double.NaN;
  95.     private org.drip.function.rdtor1.BoundMultivariate[] _boundMultivariateFunctionArray = null;
  96.     private org.drip.function.definition.RdToR1[] _inequalityConstraintMultivariateFunctionArray = null;

  97.     private org.drip.function.rdtor1solver.VariateInequalityConstraintMultiplier incremental (
  98.         final org.drip.function.rdtor1solver.ObjectiveFunctionPointMetrics objectiveFunctionPointMetrics,
  99.         final org.drip.function.rdtor1solver.ConstraintFunctionPointMetrics
  100.             inequalityConstraintFunctionPointMetrics)
  101.     {
  102.         if (null == objectiveFunctionPointMetrics ||
  103.             null == inequalityConstraintFunctionPointMetrics)
  104.         {
  105.             return null;
  106.         }

  107.         int objectiveFunctionDimension = objectiveFunctionPointMetrics.dimension();

  108.         double[] objectiveFunctionJacobian = objectiveFunctionPointMetrics.jacobian();

  109.         double[][] objectiveFunctionHessian = objectiveFunctionPointMetrics.hessian();

  110.         int inequalityConstraintCount = inequalityConstraintFunctionPointMetrics.count();

  111.         double[] variateIncrementArray = new double[objectiveFunctionDimension];
  112.         double[] inequalityConstraintIncrementCount = new double[inequalityConstraintCount];
  113.         int constrainedObjectiveFunctionDimension = objectiveFunctionDimension + inequalityConstraintCount;
  114.         double[][] constrainedObjectiveFunctionJacobianArray =
  115.             new double[constrainedObjectiveFunctionDimension][constrainedObjectiveFunctionDimension];
  116.         double[] constrainedObjectiveFunctionRHSArray = new double[constrainedObjectiveFunctionDimension];

  117.         if (0 == objectiveFunctionDimension ||
  118.             objectiveFunctionDimension != inequalityConstraintFunctionPointMetrics.dimension())
  119.         {
  120.             return null;
  121.         }

  122.         double[] inequalityConstraintFunctionMultiplierArray =
  123.             inequalityConstraintFunctionPointMetrics.constraintFunctionMultiplierArray();

  124.         double[][] inequalityConstraintFunctionJacobianArray =
  125.             inequalityConstraintFunctionPointMetrics.constraintFunctionJacobianArray();

  126.         double[] inequalityConstraintFunctionValueArray =
  127.             inequalityConstraintFunctionPointMetrics.constraintFunctionValueArray();

  128.         for (int objectiveFunctionDimensionIndexI = 0;
  129.             objectiveFunctionDimensionIndexI < objectiveFunctionDimension;
  130.             ++objectiveFunctionDimensionIndexI)
  131.         {
  132.             for (int objectiveFunctionDimensionIndexJ = 0;
  133.                 objectiveFunctionDimensionIndexJ < objectiveFunctionDimension;
  134.                 ++objectiveFunctionDimensionIndexJ)
  135.             {
  136.                 constrainedObjectiveFunctionJacobianArray[objectiveFunctionDimensionIndexI][objectiveFunctionDimensionIndexJ]
  137.                     = objectiveFunctionHessian[objectiveFunctionDimensionIndexI][objectiveFunctionDimensionIndexJ];
  138.             }

  139.             for (int inequalityConstraintIndex = 0;
  140.                 inequalityConstraintIndex < inequalityConstraintCount;
  141.                 ++inequalityConstraintIndex)
  142.             {
  143.                 constrainedObjectiveFunctionJacobianArray[objectiveFunctionDimensionIndexI][inequalityConstraintIndex + objectiveFunctionDimension] =
  144.                     -1. * inequalityConstraintFunctionJacobianArray[objectiveFunctionDimensionIndexI][inequalityConstraintIndex];
  145.             }
  146.         }

  147.         for (int inequalityConstraintIndexI = 0;
  148.             inequalityConstraintIndexI < inequalityConstraintCount;
  149.             ++inequalityConstraintIndexI)
  150.         {
  151.             for (int inequalityConstraintIndexJ = 0;
  152.                 inequalityConstraintIndexJ < inequalityConstraintCount;
  153.                 ++inequalityConstraintIndexJ)
  154.             {
  155.                 constrainedObjectiveFunctionJacobianArray[inequalityConstraintIndexI + objectiveFunctionDimension][inequalityConstraintIndexJ + objectiveFunctionDimension]
  156.                     = inequalityConstraintIndexI == inequalityConstraintIndexJ ? inequalityConstraintFunctionValueArray[inequalityConstraintIndexI] : 0.;
  157.             }

  158.             for (int objectiveFunctionIndex = 0;
  159.                 objectiveFunctionIndex < objectiveFunctionDimension;
  160.                 ++objectiveFunctionIndex)
  161.             {
  162.                 constrainedObjectiveFunctionJacobianArray[inequalityConstraintIndexI + objectiveFunctionDimension][objectiveFunctionIndex] =
  163.                     inequalityConstraintFunctionMultiplierArray[inequalityConstraintIndexI] *
  164.                     inequalityConstraintFunctionJacobianArray[objectiveFunctionIndex][inequalityConstraintIndexI];
  165.             }
  166.         }

  167.         for (int constrainedObjectiveFunctionIndex = 0;
  168.             constrainedObjectiveFunctionIndex < constrainedObjectiveFunctionDimension;
  169.             ++constrainedObjectiveFunctionIndex)
  170.         {
  171.             if (constrainedObjectiveFunctionIndex < objectiveFunctionDimension)
  172.             {
  173.                 constrainedObjectiveFunctionRHSArray[constrainedObjectiveFunctionIndex] =
  174.                     -1. * objectiveFunctionJacobian[constrainedObjectiveFunctionIndex];

  175.                 for (int inequalityConstraintIndex = 0;
  176.                     inequalityConstraintIndex < inequalityConstraintCount;
  177.                     ++inequalityConstraintIndex)
  178.                 {
  179.                     constrainedObjectiveFunctionRHSArray[constrainedObjectiveFunctionIndex] +=
  180.                         inequalityConstraintFunctionJacobianArray[constrainedObjectiveFunctionIndex][inequalityConstraintIndex]
  181.                         * inequalityConstraintFunctionMultiplierArray[inequalityConstraintIndex];
  182.                 }
  183.             }
  184.             else
  185.             {
  186.                 int constraintIndex = constrainedObjectiveFunctionIndex - objectiveFunctionDimension;
  187.                 constrainedObjectiveFunctionRHSArray[constrainedObjectiveFunctionIndex] =
  188.                     _barrierStrength - inequalityConstraintFunctionValueArray[constraintIndex] *
  189.                     inequalityConstraintFunctionMultiplierArray[constraintIndex];
  190.             }
  191.         }

  192.         org.drip.numerical.linearalgebra.LinearizationOutput linearizationOutput =
  193.             org.drip.numerical.linearalgebra.LinearSystemSolver.SolveUsingMatrixInversion (
  194.                 constrainedObjectiveFunctionJacobianArray,
  195.                 constrainedObjectiveFunctionRHSArray
  196.             );

  197.         if (null == linearizationOutput)
  198.         {
  199.             return null;
  200.         }

  201.         double[] variateConstraintIncrementArray = linearizationOutput.getTransformedRHS();

  202.         if (null == variateConstraintIncrementArray ||
  203.             variateConstraintIncrementArray.length != constrainedObjectiveFunctionDimension)
  204.         {
  205.             return null;
  206.         }

  207.         for (int constrainedObjectiveFunctionIndex = 0;
  208.             constrainedObjectiveFunctionIndex < constrainedObjectiveFunctionDimension;
  209.             ++constrainedObjectiveFunctionIndex)
  210.         {
  211.             if (constrainedObjectiveFunctionIndex < objectiveFunctionDimension)
  212.             {
  213.                 variateIncrementArray[constrainedObjectiveFunctionIndex] =
  214.                     variateConstraintIncrementArray[constrainedObjectiveFunctionIndex];
  215.             }
  216.             else
  217.             {
  218.                 inequalityConstraintIncrementCount[constrainedObjectiveFunctionIndex - objectiveFunctionDimension]
  219.                     = variateConstraintIncrementArray[constrainedObjectiveFunctionIndex];
  220.             }
  221.         }

  222.         try
  223.         {
  224.             return new org.drip.function.rdtor1solver.VariateInequalityConstraintMultiplier (
  225.                 true,
  226.                 variateIncrementArray,
  227.                 inequalityConstraintIncrementCount
  228.             );
  229.         }
  230.         catch (java.lang.Exception e)
  231.         {
  232.             e.printStackTrace();
  233.         }

  234.         return null;
  235.     }

  236.     /**
  237.      * InteriorFixedPointFinder Constructor
  238.      *
  239.      * @param rdToR1ObjectiveFunction The Objective Function
  240.      * @param inequalityConstraintMultivariateFunctionArray Array of Inequality Constraints
  241.      * @param lsec The Line Step Evolution Control
  242.      * @param cc Convergence Control Parameters
  243.      * @param barrierStrength Barrier Strength
  244.      *
  245.      * @throws java.lang.Exception Thrown if the Inputs are Invalid
  246.      */

  247.     public InteriorFixedPointFinder (
  248.         final org.drip.function.definition.RdToR1 rdToR1ObjectiveFunction,
  249.         final org.drip.function.definition.RdToR1[] inequalityConstraintMultivariateFunctionArray,
  250.         final org.drip.function.rdtor1descent.LineStepEvolutionControl lsec,
  251.         final org.drip.function.rdtor1solver.ConvergenceControl cc,
  252.         final double barrierStrength)
  253.         throws java.lang.Exception
  254.     {
  255.         super (
  256.             rdToR1ObjectiveFunction,
  257.             lsec,
  258.             cc
  259.         );

  260.         if (null == (_inequalityConstraintMultivariateFunctionArray = inequalityConstraintMultivariateFunctionArray) ||
  261.             !org.drip.numerical.common.NumberUtil.IsValid (_barrierStrength = barrierStrength))
  262.         {
  263.             throw new java.lang.Exception ("InteriorFixedPointFinder Constructor => Invalid Inputs");
  264.         }

  265.         int inequalityConstraintCount = _inequalityConstraintMultivariateFunctionArray.length;
  266.         _boundMultivariateFunctionArray = 0 == inequalityConstraintCount ? null : new
  267.             org.drip.function.rdtor1.BoundMultivariate[inequalityConstraintCount];

  268.         if (0 == inequalityConstraintCount)
  269.         {
  270.             throw new java.lang.Exception ("InteriorFixedPointFinder Constructor => Invalid Inputs");
  271.         }

  272.         for (int inequalityConstraintIndex = 0;
  273.             inequalityConstraintIndex < inequalityConstraintCount;
  274.             ++inequalityConstraintIndex)
  275.         {
  276.             if (null == _inequalityConstraintMultivariateFunctionArray[inequalityConstraintIndex])
  277.             {
  278.                 throw new java.lang.Exception ("InteriorFixedPointFinder Constructor => Invalid Inputs");
  279.             }

  280.             if (_inequalityConstraintMultivariateFunctionArray[inequalityConstraintIndex] instanceof
  281.                 org.drip.function.rdtor1.BoundMultivariate)
  282.             {
  283.                 _boundMultivariateFunctionArray[inequalityConstraintIndex] =
  284.                     (org.drip.function.rdtor1.BoundMultivariate)
  285.                     _inequalityConstraintMultivariateFunctionArray[inequalityConstraintIndex];
  286.             }
  287.         }
  288.     }

  289.     /**
  290.      * Retrieve the Array of Inequality Constraint Function
  291.      *
  292.      * @return The Array of Inequality Constraint Function
  293.      */

  294.     public org.drip.function.definition.RdToR1[] inequalityConstraintMultivariateFunctionArray()
  295.     {
  296.         return _inequalityConstraintMultivariateFunctionArray;
  297.     }

  298.     /**
  299.      * Retrieve the Barrier Strength
  300.      *
  301.      * @return The Barrier Strength
  302.      */

  303.     public double barrierStrength()
  304.     {
  305.         return _barrierStrength;
  306.     }

  307.     @Override public org.drip.function.rdtor1solver.VariateInequalityConstraintMultiplier increment (
  308.         final org.drip.function.rdtor1solver.VariateInequalityConstraintMultiplier currentVariateConstraint)
  309.     {
  310.         if (null == currentVariateConstraint)
  311.         {
  312.             return null;
  313.         }

  314.         double[] variateArray = currentVariateConstraint.variateArray();

  315.         int variateCount = variateArray.length;
  316.         int constraintCount = _inequalityConstraintMultivariateFunctionArray.length;
  317.         double[][] constraintJacobianArray = new double[variateCount][constraintCount];
  318.         double[] constraintValueArray = new double[constraintCount];

  319.         if (0 == constraintCount)
  320.         {
  321.             return null;
  322.         }

  323.         for (int constraintIndex = 0;
  324.             constraintIndex < constraintCount;
  325.             ++constraintIndex)
  326.         {
  327.             try
  328.             {
  329.                 constraintValueArray[constraintIndex] =
  330.                     _inequalityConstraintMultivariateFunctionArray[constraintIndex].evaluate (
  331.                         variateArray
  332.                     );
  333.             }
  334.             catch (java.lang.Exception e)
  335.             {
  336.                 e.printStackTrace();

  337.                 return null;
  338.             }

  339.             double[] constraintJacobian =
  340.                 _inequalityConstraintMultivariateFunctionArray[constraintIndex].jacobian (
  341.                     variateArray
  342.                 );

  343.             if (null == constraintJacobian)
  344.             {
  345.                 return null;
  346.             }

  347.             for (int variateIndex = 0;
  348.                 variateIndex < variateCount;
  349.                 ++variateIndex)
  350.             {
  351.                 constraintJacobianArray[variateIndex][constraintIndex] = constraintJacobian[variateIndex];
  352.             }
  353.         }

  354.         org.drip.function.definition.RdToR1 objectiveFunction = objectiveFunction();

  355.         try
  356.         {
  357.             return incremental (
  358.                 new org.drip.function.rdtor1solver.ObjectiveFunctionPointMetrics (
  359.                     objectiveFunction.jacobian (
  360.                         variateArray
  361.                     ),
  362.                     objectiveFunction.hessian (
  363.                         variateArray
  364.                     )
  365.                 ),
  366.                 new org.drip.function.rdtor1solver.ConstraintFunctionPointMetrics (
  367.                     constraintValueArray,
  368.                     constraintJacobianArray,
  369.                     currentVariateConstraint.constraintMultiplierArray()
  370.                 )
  371.             );
  372.         }
  373.         catch (java.lang.Exception e)
  374.         {
  375.             e.printStackTrace();
  376.         }

  377.         return null;
  378.     }

  379.     @Override public org.drip.function.rdtor1solver.VariateInequalityConstraintMultiplier next (
  380.         final org.drip.function.rdtor1solver.VariateInequalityConstraintMultiplier currentVariateConstraint,
  381.         final org.drip.function.rdtor1solver.VariateInequalityConstraintMultiplier
  382.             incrementalVariateConstraint,
  383.         final double incrementFraction)
  384.     {
  385.         return org.drip.function.rdtor1solver.VariateInequalityConstraintMultiplier.Add (
  386.             currentVariateConstraint,
  387.             incrementalVariateConstraint,
  388.             incrementFraction,
  389.             _boundMultivariateFunctionArray
  390.         );
  391.     }
  392. }