ExecutionInitializer.java
- package org.drip.function.r1tor1solver;
- /*
- * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- */
- /*!
- * Copyright (C) 2020 Lakshmi Krishnamurthy
- * Copyright (C) 2019 Lakshmi Krishnamurthy
- * Copyright (C) 2018 Lakshmi Krishnamurthy
- * Copyright (C) 2017 Lakshmi Krishnamurthy
- * Copyright (C) 2016 Lakshmi Krishnamurthy
- * Copyright (C) 2015 Lakshmi Krishnamurthy
- * Copyright (C) 2014 Lakshmi Krishnamurthy
- * Copyright (C) 2013 Lakshmi Krishnamurthy
- * Copyright (C) 2012 Lakshmi Krishnamurthy
- *
- * This file is part of DROP, an open-source library targeting analytics/risk, transaction cost analytics,
- * asset liability management analytics, capital, exposure, and margin analytics, valuation adjustment
- * analytics, and portfolio construction analytics within and across fixed income, credit, commodity,
- * equity, FX, and structured products. It also includes auxiliary libraries for algorithm support,
- * numerical analysis, numerical optimization, spline builder, model validation, statistical learning,
- * and computational support.
- *
- * https://lakshmidrip.github.io/DROP/
- *
- * DROP is composed of three modules:
- *
- * - DROP Product Core - https://lakshmidrip.github.io/DROP-Product-Core/
- * - DROP Portfolio Core - https://lakshmidrip.github.io/DROP-Portfolio-Core/
- * - DROP Computational Core - https://lakshmidrip.github.io/DROP-Computational-Core/
- *
- * DROP Product Core implements libraries for the following:
- * - Fixed Income Analytics
- * - Loan Analytics
- * - Transaction Cost Analytics
- *
- * DROP Portfolio Core implements libraries for the following:
- * - Asset Allocation Analytics
- * - Asset Liability Management Analytics
- * - Capital Estimation Analytics
- * - Exposure Analytics
- * - Margin Analytics
- * - XVA Analytics
- *
- * DROP Computational Core implements libraries for the following:
- * - Algorithm Support
- * - Computation Support
- * - Function Analysis
- * - Model Validation
- * - Numerical Analysis
- * - Numerical Optimizer
- * - Spline Builder
- * - Statistical Learning
- *
- * Documentation for DROP is Spread Over:
- *
- * - Main => https://lakshmidrip.github.io/DROP/
- * - Wiki => https://github.com/lakshmiDRIP/DROP/wiki
- * - GitHub => https://github.com/lakshmiDRIP/DROP
- * - Repo Layout Taxonomy => https://github.com/lakshmiDRIP/DROP/blob/master/Taxonomy.md
- * - Javadoc => https://lakshmidrip.github.io/DROP/Javadoc/index.html
- * - Technical Specifications => https://github.com/lakshmiDRIP/DROP/tree/master/Docs/Internal
- * - Release Versions => https://lakshmidrip.github.io/DROP/version.html
- * - Community Credits => https://lakshmidrip.github.io/DROP/credits.html
- * - Issues Catalog => https://github.com/lakshmiDRIP/DROP/issues
- * - JUnit => https://lakshmidrip.github.io/DROP/junit/index.html
- * - Jacoco => https://lakshmidrip.github.io/DROP/jacoco/index.html
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- *
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /**
- * <i>ExecutionInitializer</i> implements the initialization execution and customization functionality.
- * <br><br>
- * ExecutionInitializer performs two types of variate initialization:
- * <br>
- * <ul>
- * <li>
- * Bracketing initialization: This brackets the fixed point using the bracketing algorithm described in
- * https://lakshmidrip.github.io/DROP-Numerical-Core/. If successful, a pair of variate/OF
- * coordinate nodes that bracket the fixed point are generated. These brackets are eventually used
- * by routines that iteratively determine the fixed point. Bracketing initialization is controlled
- * by the parameters in BracketingControlParams.
- * </li>
- * <li>
- * Convergence Zone initialization: This generates a variate that lies within the convergence zone for
- * the iterative determination of the fixed point using the Newton's method. Convergence Zone
- * Determination is controlled by the parameters in ConvergenceControlParams.
- * </li>
- * </ul>
- *
- * ExecutionInitializer behavior can be customized/optimized through several of the initialization heuristics
- * techniques implemented in the InitializationHeuristics class.
- *
- * <br><br>
- * <ul>
- * <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ComputationalCore.md">Computational Core Module</a></li>
- * <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/NumericalAnalysisLibrary.md">Numerical Analysis Library</a></li>
- * <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/function/README.md">R<sup>d</sup> To R<sup>d</sup> Function Analysis</a></li>
- * <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/function/r1tor1solver/README.md">Built-in R<sup>1</sup> To R<sup>1</sup> Solvers</a></li>
- * </ul>
- *
- * @author Lakshmi Krishnamurthy
- */
- public class ExecutionInitializer {
- class StartingVariateOF {
- public double _dblOF = java.lang.Double.NaN;
- public double _dblVariate = java.lang.Double.NaN;
- public StartingVariateOF (
- final double dblVariate,
- final double dblOF)
- throws java.lang.Exception
- {
- if (!org.drip.numerical.common.NumberUtil.IsValid (_dblOF = dblOF) ||
- !org.drip.numerical.common.NumberUtil.IsValid (_dblVariate = dblVariate))
- throw new java.lang.Exception ("StartingVariateOF constructor: Invalid inputs!");
- }
- }
- private boolean _bTrendBracketRight = false;
- private org.drip.function.definition.R1ToR1 _of = null;
- private org.drip.function.r1tor1solver.ConvergenceControlParams _ccp = null;
- private java.util.SortedMap<java.lang.Double, java.lang.Double> _mapOFMap = new
- java.util.TreeMap<java.lang.Double, java.lang.Double>();
- private double evaluateOF (
- final double dblVariate)
- throws java.lang.Exception
- {
- if (_mapOFMap.containsKey (dblVariate)) return _mapOFMap.get (dblVariate);
- double dblOF = _of.evaluate (dblVariate);
- if (org.drip.numerical.common.NumberUtil.IsValid (dblOF)) _mapOFMap.put (dblVariate, dblOF);
- return dblOF;
- }
- private StartingVariateOF validateVariate (
- final double dblVariate,
- final org.drip.function.r1tor1solver.BracketingOutput bop)
- {
- double dblOF = java.lang.Double.NaN;
- try {
- dblOF = evaluateOF (dblVariate);
- } catch (java.lang.Exception e) {
- dblOF = java.lang.Double.NaN;
- }
- if (!bop.incrOFCalcs() || !org.drip.numerical.common.NumberUtil.IsValid (dblOF)) return null;
- _mapOFMap.put (dblVariate, dblOF);
- try {
- return new StartingVariateOF (dblVariate, dblOF);
- } catch (java.lang.Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- private StartingVariateOF initializeBracketingVariate (
- final int iNumExpansions,
- final double dblBracketVariateStart,
- final double dblBracketWidthStart,
- final double dblBracketWidthExpansionFactor,
- final org.drip.function.r1tor1solver.BracketingOutput bop)
- {
- StartingVariateOF sv = validateVariate (dblBracketVariateStart, bop);
- if (null != sv) return sv;
- double dblVariate = dblBracketVariateStart;
- int iNumExpansionsCurrent = iNumExpansions;
- double dblBracketWidth = dblBracketWidthStart;
- double dblBracketLeft = dblVariate - dblBracketWidth;
- double dblBracketRight = dblVariate + dblBracketWidth;
- while (0 <= iNumExpansionsCurrent--) {
- if (_bTrendBracketRight) {
- if (null != (sv = validateVariate (dblBracketRight, bop))) return sv;
- if (null != (sv = validateVariate (dblBracketLeft, bop))) return sv;
- } else {
- if (null != (sv = validateVariate (dblBracketLeft, bop))) return sv;
- if (null != (sv = validateVariate (dblBracketRight, bop))) return sv;
- }
- dblBracketWidth *= dblBracketWidthExpansionFactor;
- dblBracketLeft = dblVariate - dblBracketWidth;
- dblBracketRight = dblVariate + dblBracketWidth;
- }
- return null;
- }
- private boolean bracketingDone (
- final double dblVariateLeft,
- final double dblVariateRight,
- final double dblOFLeft,
- final double dblOFRight,
- final double dblOFGoal,
- final org.drip.function.r1tor1solver.BracketingOutput bop)
- {
- if (!org.drip.numerical.common.NumberUtil.IsValid (dblOFLeft) || !org.drip.numerical.common.NumberUtil.IsValid
- (dblOFRight))
- return false;
- if (((dblOFLeft - dblOFGoal) * (dblOFRight - dblOFGoal)) > 0.) return false;
- double dblOF = java.lang.Double.NaN;
- double dblOFPrev = java.lang.Double.NaN;
- double dblVariate = java.lang.Double.NaN;
- double dblVariatePrev = java.lang.Double.NaN;
- for (java.util.Map.Entry<java.lang.Double, java.lang.Double> me : _mapOFMap.entrySet()) {
- dblVariate = me.getKey();
- dblOF = me.getValue();
- if (org.drip.numerical.common.NumberUtil.IsValid (dblVariatePrev) &&
- org.drip.numerical.common.NumberUtil.IsValid (dblOFPrev) && (((dblOF - dblOFGoal) * (dblOFPrev -
- dblOFGoal)) < 0.)) {
- try {
- bop.done (dblVariatePrev, dblVariate, dblOFPrev, dblOF,
- org.drip.function.r1tor1solver.VariateIteratorPrimitive.Bisection (dblVariatePrev,
- dblVariate));
- } catch (java.lang.Exception e) {
- }
- return true;
- }
- dblOFPrev = dblOF;
- dblVariatePrev = dblVariate;
- }
- try {
- bop.done (dblVariateLeft, dblVariateRight, dblOFLeft, dblOFRight,
- org.drip.function.r1tor1solver.VariateIteratorPrimitive.Bisection (dblVariateLeft, dblVariateRight));
- } catch (java.lang.Exception e) {
- }
- return true;
- }
- private boolean isInConvergenceZone (
- final double dblConvergenceZoneVariate,
- final double dblOFGoal,
- final org.drip.function.r1tor1solver.ConvergenceOutput cop)
- throws java.lang.Exception
- {
- if (!cop.incrOFCalcs())
- throw new java.lang.Exception
- ("ExecutionInitializer::isInConvergenceZone => Cannot increment OF in the output");
- double dblOFValue = evaluateOF (dblConvergenceZoneVariate) - dblOFGoal;
- if (!org.drip.numerical.common.NumberUtil.IsValid (dblOFValue))
- throw new java.lang.Exception
- ("ExecutionInitializer::isInConvergenceZone => Cannot evaluate OF for variate " +
- dblConvergenceZoneVariate);
- if (!cop.incrOFDerivCalcs())
- throw new java.lang.Exception
- ("ExecutionInitializer::isInConvergenceZone => Cannot increment OF deriv count in the output");
- org.drip.numerical.differentiation.Differential diff1D = _of.differential (dblConvergenceZoneVariate, 1);
- if (null == diff1D)
- throw new java.lang.Exception
- ("ExecutionInitializer::isInConvergenceZone => Cannot evaluate OF first deriv for variate " +
- dblConvergenceZoneVariate);
- if (!cop.incrOFDerivCalcs() && !cop.incrOFDerivCalcs())
- throw new java.lang.Exception
- ("ExecutionInitializer::isInConvergenceZone => Cannot increment OF deriv in the output");
- org.drip.numerical.differentiation.Differential diff2D = _of.differential (dblConvergenceZoneVariate, 2);
- if (null == diff2D)
- throw new java.lang.Exception
- ("ExecutionInitializer::isInConvergenceZone => Cannot evaluate OF second deriv for variate "
- + dblConvergenceZoneVariate);
- return java.lang.Math.abs (dblOFValue * diff2D.calcSlope (false)) < (diff1D.calcSlope (false) *
- diff1D.calcSlope (false) * _ccp.getConvergenceZoneEdgeLimit());
- }
- private boolean leftOFValidityEdgeReached (
- final double dblVariateLeft,
- final double dblOFLeft,
- final org.drip.function.r1tor1solver.InitializationHeuristics ih)
- {
- return !org.drip.numerical.common.NumberUtil.IsValid (dblOFLeft) || (null != ih &&
- org.drip.numerical.common.NumberUtil.IsValid (ih.getBracketFloor()) && dblVariateLeft <
- ih.getBracketFloor());
- }
- private boolean rightOFValidityEdgeReached (
- final double dblVariateRight,
- final double dblOFRight,
- final org.drip.function.r1tor1solver.InitializationHeuristics ih)
- {
- return !org.drip.numerical.common.NumberUtil.IsValid (dblOFRight) || (null != ih &&
- org.drip.numerical.common.NumberUtil.IsValid (ih.getBracketCeiling()) && dblVariateRight >
- ih.getBracketCeiling());
- }
- private double getStartingBracketVariate (
- final org.drip.function.r1tor1solver.BracketingControlParams bcp,
- final org.drip.function.r1tor1solver.InitializationHeuristics ih)
- {
- if (null != ih && org.drip.numerical.common.NumberUtil.IsValid (ih.getStartingBracketMid()))
- return ih.getStartingBracketMid();
- if (null != ih && org.drip.numerical.common.NumberUtil.IsValid (ih.getStartingBracketLeft()) &&
- org.drip.numerical.common.NumberUtil.IsValid (ih.getStartingBracketRight()))
- return 0.5 * (ih.getStartingBracketLeft() + ih.getStartingBracketRight());
- return bcp.getVariateStart();
- }
- private double getStartingBracketWidth (
- final org.drip.function.r1tor1solver.BracketingControlParams bcp,
- final org.drip.function.r1tor1solver.InitializationHeuristics ih)
- {
- if (null != ih) {
- double dblBracketStartLeft = ih.getStartingBracketLeft();
- double dblBracketStartRight = ih.getStartingBracketRight();
- if (org.drip.numerical.common.NumberUtil.IsValid (dblBracketStartLeft) &&
- org.drip.numerical.common.NumberUtil.IsValid (dblBracketStartRight) && dblBracketStartRight >
- dblBracketStartLeft)
- return dblBracketStartRight - dblBracketStartLeft;
- }
- return bcp.getStartingBracketWidth();
- }
- /**
- * ExecutionInitializer constructor
- *
- * @param of Objective Function
- * @param ccp Convergence Control Parameters
- * @param bTrendBracketRight TRUE - Start Right Trending in search of a Bracket Variate
- *
- * @throws java.lang.Exception Thrown if inputs are invalid
- */
- public ExecutionInitializer (
- final org.drip.function.definition.R1ToR1 of,
- final org.drip.function.r1tor1solver.ConvergenceControlParams ccp,
- final boolean bTrendBracketRight)
- throws java.lang.Exception
- {
- if (null == (_of = of))
- throw new java.lang.Exception ("ExecutionInitializer constructor: Invalid inputs");
- if (null == (_ccp = ccp)) _ccp = new org.drip.function.r1tor1solver.ConvergenceControlParams();
- _bTrendBracketRight = bTrendBracketRight;
- }
- /**
- * Set up the bracket to be used for the eventual search kick-off
- *
- * @param ih Optional InitializationHeuristics instance
- * @param dblOFGoal The OF Goal
- *
- * @return The Bracketing Output
- */
- public org.drip.function.r1tor1solver.BracketingOutput initializeBracket (
- final org.drip.function.r1tor1solver.InitializationHeuristics ih,
- final double dblOFGoal)
- {
- org.drip.function.r1tor1solver.BracketingControlParams bcp = (null != ih && null != ih.getCustomBCP()) ?
- ih.getCustomBCP() : new org.drip.function.r1tor1solver.BracketingControlParams();
- int iNumExpansions = bcp.getNumExpansions();
- org.drip.function.r1tor1solver.BracketingOutput bop = new
- org.drip.function.r1tor1solver.BracketingOutput();
- StartingVariateOF sv = initializeBracketingVariate (iNumExpansions, getStartingBracketVariate (bcp,
- ih), getStartingBracketWidth (bcp, ih), bcp.getBracketWidthExpansionFactor(), bop);
- if (null == sv) return bop;
- double dblOFLeft = sv._dblOF;
- double dblOFRight = sv._dblOF;
- double dblPreviousOFLeft = sv._dblOF;
- double dblPreviousOFRight = sv._dblOF;
- double dblVariateLeft = sv._dblVariate;
- double dblVariateRight = sv._dblVariate;
- boolean bLeftOFValidityEdgeReached = false;
- boolean bRightOFValidityEdgeReached = false;
- double dblPreviousVariateLeft = sv._dblVariate;
- double dblPreviousVariateRight = sv._dblVariate;
- double dblBracketWidth = bcp.getStartingBracketWidth();
- while (0 <= iNumExpansions--) {
- if (!bop.incrIterations()) return null;
- if (bLeftOFValidityEdgeReached && bRightOFValidityEdgeReached) return bop;
- if (!bLeftOFValidityEdgeReached) {
- dblPreviousVariateLeft = dblVariateLeft;
- dblVariateLeft -= dblBracketWidth;
- dblPreviousOFLeft = dblOFLeft;
- try {
- if (bracketingDone (dblVariateLeft, dblVariateRight, dblOFLeft = evaluateOF
- (dblVariateLeft), dblOFRight, dblOFGoal, bop) && bop.incrOFCalcs())
- return bop;
- } catch (java.lang.Exception e) {
- dblOFLeft = java.lang.Double.NaN;
- }
- if (bLeftOFValidityEdgeReached = leftOFValidityEdgeReached (dblVariateLeft, dblOFLeft, ih)) {
- dblOFLeft = dblPreviousOFLeft;
- dblVariateLeft = dblPreviousVariateLeft;
- }
- }
- if (!bRightOFValidityEdgeReached) {
- dblPreviousVariateRight = dblVariateRight;
- dblVariateRight += dblBracketWidth;
- dblPreviousOFRight = dblOFRight;
- try {
- if (bracketingDone (dblVariateLeft, dblVariateRight, dblOFLeft, dblOFRight = evaluateOF
- (dblVariateRight), dblOFGoal, bop) && bop.incrOFCalcs())
- return bop;
- } catch (java.lang.Exception e) {
- dblOFRight = java.lang.Double.NaN;
- }
- if (bRightOFValidityEdgeReached = rightOFValidityEdgeReached (dblVariateRight, dblOFRight,
- ih)) {
- dblOFRight = dblPreviousOFRight;
- dblVariateRight = dblPreviousVariateRight;
- }
- }
- if (bracketingDone (dblVariateLeft, dblVariateRight, dblOFLeft, dblOFRight, dblOFGoal, bop))
- return bop;
- dblBracketWidth *= bcp.getBracketWidthExpansionFactor();
- }
- return null;
- }
- /**
- * Initialize the starting variate to within the fixed point convergence zone
- *
- * @param ih Optional InitializationHeuristics instance
- * @param dblOFGoal The OF Goal
- *
- * @return The Convergence Zone Output
- */
- public org.drip.function.r1tor1solver.ConvergenceOutput initializeVariate (
- final org.drip.function.r1tor1solver.InitializationHeuristics ih,
- final double dblOFGoal)
- {
- if (!org.drip.numerical.common.NumberUtil.IsValid (dblOFGoal)) return null;
- org.drip.function.r1tor1solver.ConvergenceOutput cop = new org.drip.function.r1tor1solver.ConvergenceOutput();
- org.drip.function.r1tor1solver.BracketingOutput bop = initializeBracket (ih, dblOFGoal);
- if (null != bop && bop.done()) return bop.makeConvergenceVariate();
- double dblConvergenceZoneVariate = _ccp.getConvergenceZoneVariateBegin();
- int iFixedPointConvergenceIterations = _ccp.getFixedPointConvergenceIterations();
- while (0 != iFixedPointConvergenceIterations--) {
- if (!cop.incrIterations()) return cop;
- try {
- if (isInConvergenceZone (dblConvergenceZoneVariate, dblOFGoal, cop)) {
- cop.done (dblConvergenceZoneVariate);
- return cop;
- }
- } catch (java.lang.Exception e) {
- // e.printStackTrace();
- }
- try {
- if (isInConvergenceZone (-1. * dblConvergenceZoneVariate, dblOFGoal, cop)) {
- cop.done (-1. * dblConvergenceZoneVariate);
- return cop;
- }
- } catch (java.lang.Exception e) {
- // e.printStackTrace();
- }
- dblConvergenceZoneVariate *= _ccp.getConvergenceZoneVariateBumpFactor();
- }
- return null;
- }
- /**
- * Initialize the starting bracket within the specified boundary
- *
- * @param ih Initialization Heuristics containing the hard search edges
- * @param dblOFGoal The OF Goal
- *
- * @return Results of the Verification
- */
- public org.drip.function.r1tor1solver.BracketingOutput verifyHardSearchEdges (
- final org.drip.function.r1tor1solver.InitializationHeuristics ih,
- final double dblOFGoal)
- {
- if (null == ih || !org.drip.numerical.common.NumberUtil.IsValid (ih.getSearchStartLeft()) ||
- !org.drip.numerical.common.NumberUtil.IsValid (ih.getSearchStartRight()) ||
- !org.drip.numerical.common.NumberUtil.IsValid (dblOFGoal))
- return null;
- try {
- org.drip.function.r1tor1solver.BracketingOutput bop = new
- org.drip.function.r1tor1solver.BracketingOutput();
- if (bracketingDone (ih.getSearchStartLeft(), ih.getSearchStartRight(), evaluateOF
- (ih.getSearchStartLeft()), evaluateOF (ih.getSearchStartRight()), dblOFGoal, bop) &&
- bop.incrOFCalcs())
- return bop;
- } catch (java.lang.Exception e) {
- }
- return null;
- }
- }