NumberUtil.java

  1. package org.drip.numerical.common;

  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.  * Copyright (C) 2012 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>NumberUtil</i> implements number utility functions. It exposes the following functions:
  83.  *
  84.  * <br><br>
  85.  *  <ul>
  86.  *      <li>
  87.  *          Verify number/number array validity, and closeness/sign match
  88.  *      </li>
  89.  *      <li>
  90.  *          Factorial Permutation/Combination functionality
  91.  *      </li>
  92.  *      <li>
  93.  *          Dump multi-dimensional array contents
  94.  *      </li>
  95.  *      <li>
  96.  *          Min/Max/Bound the array entries within limits
  97.  *      </li>
  98.  *  </ul>
  99.  *
  100.  * <br><br>
  101.  *  <ul>
  102.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ComputationalCore.md">Computational Core Module</a></li>
  103.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/NumericalAnalysisLibrary.md">Numerical Analysis Library</a></li>
  104.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/numerical">Numerical Quadrature, Differentiation, Eigenization, Linear Algebra, and Utilities</a></li>
  105.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/numerical/common">Primitives/Array Manipulate Format Display Utilities</a></li>
  106.  *  </ul>
  107.  * <br><br>
  108.  *
  109.  * @author Lakshmi Krishnamurthy
  110.  */

  111. public class NumberUtil {
  112.     private static final double DEFAULT_ABSOLUTE_TOLERANCE = 1.0e-03;
  113.     private static final double DEFAULT_RELATIVE_TOLERANCE = 1.0e-03;

  114.     /**
  115.      * Check if the Input Long is MIN_VALUE or MAX_VALUE
  116.      *
  117.      * @param l Input Long
  118.      *
  119.      * @return TRUE - Input Long is MIN_VALUE or MAX_VALUE
  120.      */

  121.     public static final boolean IsValid (
  122.         final long l)
  123.     {
  124.         return java.lang.Long.MIN_VALUE != l && java.lang.Long.MAX_VALUE != l;
  125.     }

  126.     /**
  127.      * Check if the Input Long Array contains a MIN_VALUE or MAX_VALUE
  128.      *
  129.      * @param al Input Long Array
  130.      *
  131.      * @return TRUE - Input Long Array contains a MIN_VALUE or MAX_VALUE
  132.      */

  133.     public static final boolean IsValid (
  134.         final long[] al)
  135.     {
  136.         if (null == al) return true;

  137.         for (int i = 0; i < al.length; ++i) {
  138.             if (!IsValid (al[i])) return false;
  139.         }

  140.         return true;
  141.     }

  142.     /**
  143.      * Checks if the input double is Infinite or NaN
  144.      *
  145.      * @param dbl Input double
  146.      *
  147.      * @return TRUE - Input double is Infinite or NaN
  148.      */

  149.     public static final boolean IsValid (
  150.         final double dbl)
  151.     {
  152.         return !java.lang.Double.isNaN (dbl) && !java.lang.Double.isInfinite (dbl);
  153.     }

  154.     /**
  155.      * Checks if the input double array contains an Infinite or an NaN
  156.      *
  157.      * @param adbl Input double array
  158.      *
  159.      * @return TRUE - Input double contains an Infinite or an NaN
  160.      */

  161.     public static final boolean IsValid (
  162.         final double[] adbl)
  163.     {
  164.         if (null == adbl) return true;

  165.         for (int i = 0; i < adbl.length; ++i) {
  166.             if (!IsValid (adbl[i])) return false;
  167.         }

  168.         return true;
  169.     }

  170.     /**
  171.      * Compare and checks if the two input numbers fall within a specified tolerance
  172.      *
  173.      * @param dbl1 Number #1
  174.      * @param dbl2 Number #2
  175.      * @param dblAbsoluteTolerance Absolute Tolerance
  176.      * @param dblRelativeTolerance Relative Tolerance
  177.      *
  178.      * @return TRUE if they fall within the tolerance
  179.      */

  180.     public static final boolean WithinTolerance (
  181.         final double dbl1,
  182.         final double dbl2,
  183.         final double dblAbsoluteTolerance,
  184.         final double dblRelativeTolerance)
  185.     {
  186.         if (!IsValid (dbl1) || !IsValid (dbl2)) return false;

  187.         if (dblAbsoluteTolerance >= java.lang.Math.abs (dbl1)) {
  188.             if (dblAbsoluteTolerance >= java.lang.Math.abs (dbl2)) return true;

  189.             return false;
  190.         }

  191.         if (dblRelativeTolerance >= java.lang.Math.abs ((dbl2 - dbl1) / dbl1)) return true;

  192.         return false;
  193.     }

  194.     /**
  195.      * Compare and checks if the two input numbers fall within a specified tolerance
  196.      *
  197.      * @param dbl1 Number #1
  198.      * @param dbl2 Number #2
  199.      *
  200.      * @return TRUE if they fall within the tolerance
  201.      */

  202.     public static final boolean WithinTolerance (
  203.         final double dbl1,
  204.         final double dbl2)
  205.     {
  206.         return WithinTolerance (dbl1, dbl2, DEFAULT_ABSOLUTE_TOLERANCE, DEFAULT_RELATIVE_TOLERANCE);
  207.     }

  208.     /**
  209.      * This function implements Factorial N.
  210.      *
  211.      * @param n N
  212.      *
  213.      * @return Factorial N
  214.      */

  215.     public static final int Factorial (
  216.         final int n)
  217.     {
  218.         int iNFact = 1;

  219.         for (int i = 1; i <= n; ++i)
  220.             iNFact *= i;

  221.         return iNFact;
  222.     }

  223.     /**
  224.      * This function implements N Permute K.
  225.      *
  226.      * @param n N
  227.      * @param k K
  228.      *
  229.      * @return N Permute K
  230.      */

  231.     public static final int NPK (
  232.         final int n,
  233.         final int k)
  234.     {
  235.         int iK = n < k ? n : k;
  236.         int iN = n > k ? n : k;

  237.         return Factorial (iN) / Factorial (iK);
  238.     }

  239.     /**
  240.      * This function implements N choose K.
  241.      *
  242.      * @param n N
  243.      * @param k K
  244.      *
  245.      * @return N choose K
  246.      */

  247.     public static final int NCK (
  248.         final int n,
  249.         final int k)
  250.     {
  251.         int iK = n < k ? n : k;
  252.         int iN = n > k ? n : k;

  253.         return Factorial (iN) / Factorial (iK) / Factorial (iN - iK);
  254.     }

  255.     /**
  256.      * Bound the input to within (floor, Ceiling), i.e., compute Min (Max (floor, X), Ceiling)
  257.      *
  258.      * @param dblX Input Number
  259.      * @param dblFloor Floor
  260.      * @param dblCeiling Ceiling
  261.      *
  262.      * @return Min (Max (floor, X), Ceiling)
  263.      *
  264.      * @throws java.lang.Exception Thrown if the inputs are invalid
  265.      */

  266.     public static final double Bound (
  267.         final double dblX,
  268.         final double dblFloor,
  269.         final double dblCeiling)
  270.         throws java.lang.Exception
  271.     {
  272.         if (!IsValid (dblX) || !IsValid (dblFloor)|| !IsValid (dblCeiling) || dblFloor > dblCeiling)
  273.             throw new java.lang.Exception ("NumberUtil::Bound => Invalid Inputs");

  274.         double dblBound = dblX < dblFloor ? dblFloor : dblX;
  275.         return dblBound > dblCeiling ? dblCeiling : dblBound;
  276.     }

  277.     /**
  278.      * Retrieve the Minimum Element in the specified Array
  279.      *
  280.      * @param adbl Array of elements
  281.      *
  282.      * @return The Minimum Element
  283.      *
  284.      * @throws java.lang.Exception Thrown if the Inputs are invalid
  285.      */

  286.     public static final double Minimum (
  287.         final double[] adbl)
  288.         throws java.lang.Exception
  289.     {
  290.         if (!IsValid (adbl)) throw new java.lang.Exception ("NumberUtil::Minimum => Invalid Inputs");

  291.         double dblMinimum = adbl[0];
  292.         int iNumElement = adbl.length;

  293.         for (int i = 1; i < iNumElement; ++i)
  294.             dblMinimum = dblMinimum < adbl[i] ? dblMinimum : adbl[i];

  295.         return dblMinimum;
  296.     }

  297.     /**
  298.      * Retrieve the Maximum Element in the specified Array
  299.      *
  300.      * @param adbl Array of elements
  301.      *
  302.      * @return The Maximum Element
  303.      *
  304.      * @throws java.lang.Exception Thrown if the Inputs are invalid
  305.      */

  306.     public static final double Maximum (
  307.         final double[] adbl)
  308.         throws java.lang.Exception
  309.     {
  310.         if (!IsValid (adbl)) throw new java.lang.Exception ("NumberUtil::Maximum => Invalid Inputs");

  311.         double dblMaximum = adbl[0];
  312.         int iNumElement = adbl.length;

  313.         for (int i = 1; i < iNumElement; ++i)
  314.             dblMaximum = dblMaximum > adbl[i] ? dblMaximum : adbl[i];

  315.         return dblMaximum;
  316.     }

  317.     /**
  318.      * Check if the specified array contains elements all of the same sign
  319.      *
  320.      * @param adbl Array of elements
  321.      *
  322.      * @return TRUE - Same Sign
  323.      *
  324.      * @throws java.lang.Exception Thrown if the Inputs are invalid
  325.      */

  326.     public static final boolean SameSign (
  327.         final double[] adbl)
  328.         throws java.lang.Exception
  329.     {
  330.         if (!IsValid (adbl)) throw new java.lang.Exception ("NumberUtil::SameSign => Invalid Inputs");

  331.         if (adbl[0] <= 0.) return false;

  332.         int iNumElement = adbl.length;

  333.         for (int i = 1; i < iNumElement; ++i) {
  334.             if (adbl[0] * adbl[i] <= 0.) return false;
  335.         }

  336.         return true;
  337.     }

  338.     /**
  339.      * Print the contents of the 1D array
  340.      *
  341.      * @param strName Label Name
  342.      * @param adblA The 1D array
  343.      * @param bBailOnNaN Bail on encountering an NaN
  344.      *
  345.      * @return TRUE - Print Successful
  346.      */

  347.     public static final boolean Print1DArray (
  348.         final java.lang.String strName,
  349.         final double[] adblA,
  350.         final boolean bBailOnNaN)
  351.     {
  352.         if (null == adblA || 0 == adblA.length) return false;

  353.         int iSize = adblA.length;

  354.         for (int i = 0; i < iSize; ++i) {
  355.             if (!org.drip.numerical.common.NumberUtil.IsValid (adblA[i]) && bBailOnNaN) return false;

  356.             System.out.println (strName + "[" + i + "] = " + adblA[i]);
  357.         }

  358.         return true;
  359.     }

  360.     /**
  361.      * Print the contents of the 1D array to the Specified Decimal Location
  362.      *
  363.      * @param strName Label Name
  364.      * @param adblA The 1D array
  365.      * @param iNumDecimal Number of Decimal Places to Display
  366.      * @param bBailOnNaN Bail on encountering an NaN
  367.      *
  368.      * @return TRUE - Print Successful
  369.      */

  370.     public static final boolean Print1DArray (
  371.         final java.lang.String strName,
  372.         final double[] adblA,
  373.         final int iNumDecimal,
  374.         final boolean bBailOnNaN)
  375.     {
  376.         if (null == adblA || 0 == adblA.length) return false;

  377.         int iSize = adblA.length;

  378.         for (int i = 0; i < iSize; ++i) {
  379.             if (!org.drip.numerical.common.NumberUtil.IsValid (adblA[i]) && bBailOnNaN) return false;

  380.             System.out.println (strName + "[" + i + "] = " + org.drip.numerical.common.FormatUtil.FormatDouble
  381.                 (adblA[i], 1, iNumDecimal, 1.));
  382.         }

  383.         return true;
  384.     }

  385.     /**
  386.      * Print the contents of the 2D array
  387.      *
  388.      * @param strName Label Name
  389.      * @param aadblA The 2D array
  390.      * @param bBailOnNaN Bail on encountering an NaN
  391.      *
  392.      * @return TRUE - Print Successful
  393.      */

  394.     public static final boolean Print2DArray (
  395.         final java.lang.String strName,
  396.         final double[][] aadblA,
  397.         final boolean bBailOnNaN)
  398.     {
  399.         if (null == aadblA) return false;

  400.         int iRowSize = aadblA.length;

  401.         if (0 == iRowSize || null == aadblA[0]) return false;

  402.         int iColSize = aadblA[0].length;

  403.         if (0 == iColSize) return false;

  404.         for (int i = 0; i < iRowSize; ++i) {
  405.             for (int j = 0; j < iColSize; ++j) {
  406.                 if (!org.drip.numerical.common.NumberUtil.IsValid (aadblA[i][j]) && bBailOnNaN) return false;

  407.                 System.out.println (strName + "[" + i + "][" + j + "] = " +
  408.                     org.drip.numerical.common.FormatUtil.FormatDouble (aadblA[i][j], 1, 6, 1.));
  409.             }
  410.         }

  411.         return true;
  412.     }

  413.     /**
  414.      * Print the Contents of the 2D Array Pair
  415.      *
  416.      * @param strLeftLabel Left Label
  417.      * @param strRightLabel Right Label
  418.      * @param aadblLeft The Left 2D array
  419.      * @param aadblRight The Right 2D array
  420.      * @param bBailOnNaN Bail on encountering an NaN
  421.      *
  422.      * @return TRUE - Print Successful
  423.      */

  424.     public static final boolean Print2DArrayPair (
  425.         final java.lang.String strLeftLabel,
  426.         final java.lang.String strRightLabel,
  427.         final double[][] aadblLeft,
  428.         final double[][] aadblRight,
  429.         final boolean bBailOnNaN)
  430.     {
  431.         if (null == aadblLeft || null == aadblRight) return false;

  432.         int iSize = aadblLeft.length;

  433.         if (0 == iSize || iSize != aadblRight.length) return false;

  434.         for (int i = 0; i < iSize; ++i) {
  435.             for (int j = 0; j < iSize; ++j) {
  436.                 if (!org.drip.numerical.common.NumberUtil.IsValid (aadblLeft[i][j]) &&
  437.                     !org.drip.numerical.common.NumberUtil.IsValid (aadblRight[i][j]) && bBailOnNaN)
  438.                     return false;

  439.                 System.out.println (strLeftLabel + "[" + i + "][" + j + "] = " +
  440.                     org.drip.numerical.common.FormatUtil.FormatDouble (aadblLeft[i][j], 1, 6, 1.) + "  |  " +
  441.                         strRightLabel + "[" + i + "][" + j + "] = " +
  442.                             org.drip.numerical.common.FormatUtil.FormatDouble (aadblRight[i][j], 1, 6, 1.));
  443.             }
  444.         }

  445.         return true;
  446.     }

  447.     /**
  448.      * Print the Contents of the 2D Array Triplet
  449.      *
  450.      * @param strLeftLabel Left Label
  451.      * @param strMiddleLabel Middle Label
  452.      * @param strRightLabel Right Label
  453.      * @param aadblLeft The Left 2D array
  454.      * @param aadblMiddle The Middle 2D array
  455.      * @param aadblRight The Right 2D array
  456.      * @param bBailOnNaN Bail on encountering an NaN
  457.      *
  458.      * @return TRUE - Print Successful
  459.      */

  460.     public static final boolean Print2DArrayTriplet (
  461.         final java.lang.String strLeftLabel,
  462.         final java.lang.String strMiddleLabel,
  463.         final java.lang.String strRightLabel,
  464.         final double[][] aadblLeft,
  465.         final double[][] aadblMiddle,
  466.         final double[][] aadblRight,
  467.         final boolean bBailOnNaN)
  468.     {
  469.         if (null == aadblLeft || null == aadblMiddle || null == aadblRight) return false;

  470.         int iSize = aadblLeft.length;

  471.         if (0 == iSize || iSize != aadblMiddle.length || iSize != aadblRight.length) return false;

  472.         for (int i = 0; i < iSize; ++i) {
  473.             for (int j = 0; j < iSize; ++j) {
  474.                 if (!org.drip.numerical.common.NumberUtil.IsValid (aadblLeft[i][j]) &&
  475.                         !org.drip.numerical.common.NumberUtil.IsValid (aadblLeft[i][j]) &&
  476.                             !org.drip.numerical.common.NumberUtil.IsValid (aadblRight[i][j]) && bBailOnNaN)
  477.                     return false;

  478.                 System.out.println (strLeftLabel + "[" + i + "][" + j + "] = " +
  479.                     org.drip.numerical.common.FormatUtil.FormatDouble (aadblLeft[i][j], 1, 6, 1.) + "  |  " +
  480.                         strMiddleLabel + "[" + i + "][" + j + "] = " +
  481.                             org.drip.numerical.common.FormatUtil.FormatDouble (aadblMiddle[i][j], 1, 6, 1.) +
  482.                                 "  |  " + strRightLabel + "[" + i + "][" + j + "] = " +
  483.                                     org.drip.numerical.common.FormatUtil.FormatDouble (aadblRight[i][j], 1, 6,
  484.                                         1.));
  485.             }
  486.         }

  487.         return true;
  488.     }

  489.     /**
  490.      * Print the Matrix Contents
  491.      *
  492.      * @param strName Name of the Matrix
  493.      * @param aadblA Matrix
  494.      *
  495.      * @return TRUE - Matrix Contents Successfully printed
  496.      */

  497.     public static final boolean PrintMatrix (
  498.         final java.lang.String strName,
  499.         final double[][] aadblA)
  500.     {
  501.         if (null == aadblA || 0 == aadblA.length) return false;

  502.         int iSize = aadblA.length;

  503.         for (int i = 0; i < iSize; ++i) {
  504.             java.lang.String strDump = strName  + " => ";

  505.             for (int j = 0; j < iSize; ++j)
  506.                 strDump += org.drip.numerical.common.FormatUtil.FormatDouble (aadblA[i][j], 1, 6, 1.) + " |";

  507.             System.out.println (strDump);
  508.         }

  509.         return true;
  510.     }

  511.     /**
  512.      * Compute (n - 0.5)!
  513.      *
  514.      * @param n n
  515.      *
  516.      * @return (n - 0.5)! Value
  517.      *
  518.      * @throws java.lang.Exception Thrown if the Inputs are Invalid
  519.      */

  520.     public static final double HalfDownShiftedFactorial (
  521.         final int n)
  522.         throws java.lang.Exception
  523.     {
  524.         if (-1 >= n)
  525.         {
  526.             throw new java.lang.Exception ("NumberUtil::HalfDownShiftedFactorial => Invalid Inputs");
  527.         }

  528.         double halfDownShiftedFactorial = java.lang.Math.sqrt (java.lang.Math.PI);

  529.         for (double index = 1; index < n; ++index)
  530.         {
  531.             halfDownShiftedFactorial = halfDownShiftedFactorial * (index + 0.5);
  532.         }

  533.         return halfDownShiftedFactorial;
  534.     }

  535.     /**
  536.      * Compute (2n - 1)!!
  537.      *
  538.      * @param n n
  539.      *
  540.      * @return (2n - 1)!!
  541.      *
  542.      * @throws java.lang.Exception Thrown if the Inputs are Invalid
  543.      */

  544.     public static final double DoubleFactorial (
  545.         final int n)
  546.         throws java.lang.Exception
  547.     {
  548.         if (-1 >= n)
  549.         {
  550.             throw new java.lang.Exception ("NumberUtil::DoubleFactorial => Invalid Inputs");
  551.         }

  552.         double doubleFactorial = 1.;

  553.         for (int index = 1; index <= n; ++index)
  554.         {
  555.             doubleFactorial = doubleFactorial * (2. * n - 1.);
  556.         }

  557.         return doubleFactorial;
  558.     }

  559.     /**
  560.      * Compute the Rising Pochhammer Symbol for the Specified s and k
  561.      *
  562.      * @param s s
  563.      * @param k k
  564.      *
  565.      * @return The Rising Pochhammer Symbol
  566.      *
  567.      * @throws java.lang.Exception Thrown if the Inputs are Invalid
  568.      */

  569.     public static final double RisingPochhammerSymbol (
  570.         final double s,
  571.         final int k)
  572.         throws java.lang.Exception
  573.     {
  574.         if (!org.drip.numerical.common.NumberUtil.IsValid (s) || 0 > k)
  575.         {
  576.             throw new java.lang.Exception ("NumberUtil::RisingPochhammerSymbol => Invalid Inputs");
  577.         }

  578.         if (0 == k)
  579.         {
  580.             return 1.;
  581.         }

  582.         double pochhammerSymbol = s;

  583.         for (int index = 1; index < k; ++index)
  584.         {
  585.             pochhammerSymbol = pochhammerSymbol * (s + index);
  586.         }

  587.         return pochhammerSymbol;
  588.     }

  589.     /**
  590.      * Compute the Pochhammer Symbol for the Specified s and k
  591.      *
  592.      * @param s s
  593.      * @param k k
  594.      *
  595.      * @return Pochhammer Symbol
  596.      *
  597.      * @throws java.lang.Exception Thrown if the Inputs are Invalid
  598.      */

  599.     public static final double PochhammerSymbol (
  600.         final double s,
  601.         final int k)
  602.         throws java.lang.Exception
  603.     {
  604.         if (!org.drip.numerical.common.NumberUtil.IsValid (s) || 0 > k)
  605.         {
  606.             throw new java.lang.Exception ("NumberUtil::PochhammerSymbol => Invalid Inputs");
  607.         }

  608.         double pochhammerSymbol = s;

  609.         for (int index = 1; index < k; ++index)
  610.         {
  611.             pochhammerSymbol = pochhammerSymbol * (s + index);
  612.         }

  613.         return pochhammerSymbol;
  614.     }

  615.     /**
  616.      * Indicate if z is an Integer
  617.      *
  618.      * @param z Z
  619.      *
  620.      * @return TRUE - z is an Integer
  621.      *
  622.      * @throws java.lang.Exception Thrown if the Inputs are Invalid
  623.      */

  624.     public static final boolean IsInteger (
  625.         final double z)
  626.         throws java.lang.Exception
  627.     {
  628.         if (!org.drip.numerical.common.NumberUtil.IsValid (z))
  629.         {
  630.             throw new java.lang.Exception ("NumberUtil::IsInteger => Invalid Inputs");
  631.         }

  632.         double absoluteZ = java.lang.Math.abs (z);

  633.         return 0. == absoluteZ - (int) absoluteZ;
  634.     }

  635.     /**
  636.      * Indicate if z is a Positive Integer
  637.      *
  638.      * @param z Z
  639.      *
  640.      * @return TRUE - z is a Positive Integer
  641.      *
  642.      * @throws java.lang.Exception Thrown if the Inputs are Invalid
  643.      */

  644.     public static final boolean IsPositiveInteger (
  645.         final double z)
  646.         throws java.lang.Exception
  647.     {
  648.         return IsInteger (z) && z > 0.;
  649.     }

  650.     /**
  651.      * Indicate if z is a Non-Positive Integer
  652.      *
  653.      * @param z Z
  654.      *
  655.      * @return TRUE - z is a Non-Positive Integer
  656.      *
  657.      * @throws java.lang.Exception Thrown if the Inputs are Invalid
  658.      */

  659.     public static final boolean IsNonPositiveInteger (
  660.         final double z)
  661.         throws java.lang.Exception
  662.     {
  663.         return IsInteger (z) && z <= 0.;
  664.     }

  665.     /**
  666.      * Indicate if z is a Negative Integer
  667.      *
  668.      * @param z Z
  669.      *
  670.      * @return TRUE - z is a Negative Integer
  671.      *
  672.      * @throws java.lang.Exception Thrown if the Inputs are Invalid
  673.      */

  674.     public static final boolean IsNegativeInteger (
  675.         final double z)
  676.         throws java.lang.Exception
  677.     {
  678.         return IsInteger (z) && z < 0.;
  679.     }

  680.     /**
  681.      * Indicate if z is a Non-Negative Integer
  682.      *
  683.      * @param z Z
  684.      *
  685.      * @return TRUE - z is a Non-Negative Integer
  686.      *
  687.      * @throws java.lang.Exception Thrown if the Inputs are Invalid
  688.      */

  689.     public static final boolean IsNonNegativeInteger (
  690.         final double z)
  691.         throws java.lang.Exception
  692.     {
  693.         return IsInteger (z) && z >= 0.;
  694.     }

  695.     /**
  696.      * Indicate the Sign of z
  697.      *
  698.      * @param z Z
  699.      *
  700.      * @return Sign of z
  701.      *
  702.      * @throws java.lang.Exception Thrown if the Inputs are Invalid
  703.      */

  704.     public static final double Sign (
  705.         final double z)
  706.         throws java.lang.Exception
  707.     {
  708.         if (!IsValid (z))
  709.         {
  710.             throw new java.lang.Exception ("NumberUtil::Sign => Invalid Inputs");
  711.         }

  712.         return 0. == z ? 1. : java.lang.Math.abs (z) / z;
  713.     }

  714.     /**
  715.      * Check if the Array Elements are Normalized and Positive
  716.      *
  717.      * @param array Array
  718.      *
  719.      * @return TRUE - The Array Elements are Normalized and Positive
  720.      */

  721.     public static final boolean NormalizedPositive (
  722.         final double[] array)
  723.     {
  724.         if (null == array)
  725.         {
  726.             return false;
  727.         }

  728.         double sum = 0.;
  729.         int size = array.length;

  730.         if (0 == size)
  731.         {
  732.             return false;
  733.         }

  734.         for (int index = 0; index < size; ++index)
  735.         {
  736.             if (!org.drip.numerical.common.NumberUtil.IsValid (array[index]) || 0. >= array[index])
  737.             {
  738.                 return false;
  739.             }

  740.             sum = sum + array[index];
  741.         }

  742.         return 1. == sum;
  743.     }

  744.     /**
  745.      * Retrieve the Fractional Part of z
  746.      *
  747.      * @param z Z
  748.      *
  749.      * @return The Fractional Part of z
  750.      *
  751.      * @throws java.lang.Exception Thrown if the Inputs are Invalid
  752.      */

  753.     public static final double Fractional (
  754.         final double z)
  755.         throws java.lang.Exception
  756.     {
  757.         if (!IsValid (
  758.             z
  759.         ))
  760.         {
  761.             throw new java.lang.Exception (
  762.                 "NumberUtil::Fractional => Invalid Inputs"
  763.             );
  764.         }

  765.         return z - (int) z;
  766.     }

  767.     /**
  768.      * Retrieve the Reciprocal Integer Floor of z
  769.      *
  770.      * @param z Z
  771.      *
  772.      * @return The Reciprocal Integer Floor of z
  773.      *
  774.      * @throws java.lang.Exception Thrown if the Inputs are Invalid
  775.      */

  776.     public static final int ReciprocalIntegerFloor (
  777.         final double z)
  778.         throws java.lang.Exception
  779.     {
  780.         if (!IsValid (
  781.             z
  782.         ))
  783.         {
  784.             throw new java.lang.Exception (
  785.                 "NumberUtil::ReciprocalIntegerFloor => Invalid Inputs"
  786.             );
  787.         }

  788.         return (int) (1. / z);
  789.     }
  790. }