DiscreteF.java

  1. package org.drip.sample.gammadistribution;

  2. import org.drip.function.definition.R1ToR1;
  3. import org.drip.function.definition.R2ToR1;
  4. import org.drip.measure.gamma.R1ShapeScaleComposite;
  5. import org.drip.measure.gamma.R1ShapeScaleDiscrete;
  6. import org.drip.measure.statistics.UnivariateDiscreteThin;
  7. import org.drip.numerical.common.FormatUtil;
  8. import org.drip.service.env.EnvManager;
  9. import org.drip.specialfunction.digamma.CumulativeSeriesEstimator;
  10. import org.drip.specialfunction.gamma.EulerIntegralSecondKind;
  11. import org.drip.specialfunction.incompletegamma.LowerEulerIntegral;

  12. /*
  13.  * -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  14.  */

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

  84. /**
  85.  * <i>DiscreteF</i> illustrates the Generation of Discrete F Random Numbers using the Ahlers-Dieter and the
  86.  *  Marsaglia Schemes. The References are:
  87.  *
  88.  * <br><br>
  89.  *  <ul>
  90.  *      <li>
  91.  *          Devroye, L. (1986): <i>Non-Uniform Random Variate Generation</i> <b>Springer-Verlag</b> New York
  92.  *      </li>
  93.  *      <li>
  94.  *          Gamma Distribution (2019): Gamma Distribution
  95.  *              https://en.wikipedia.org/wiki/Chi-squared_distribution
  96.  *      </li>
  97.  *      <li>
  98.  *          Louzada, F., P. L. Ramos, and E. Ramos (2019): A Note on Bias of Closed-Form Estimators for the
  99.  *              Gamma Distribution Derived From Likelihood Equations <i>The American Statistician</i> <b>73
  100.  *              (2)</b> 195-199
  101.  *      </li>
  102.  *      <li>
  103.  *          Minka, T. (2002): Estimating a Gamma distribution https://tminka.github.io/papers/minka-gamma.pdf
  104.  *      </li>
  105.  *      <li>
  106.  *          Ye, Z. S., and N. Chen (2017): Closed-Form Estimators for the Gamma Distribution Derived from
  107.  *              Likelihood Equations <i>The American Statistician</i> <b>71 (2)</b> 177-181
  108.  *      </li>
  109.  *  </ul>
  110.  *
  111.  *  <br><br>
  112.  *  <ul>
  113.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ComputationalCore.md">Computational Core Module</a></li>
  114.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/NumericalAnalysisLibrary.md">Numerical Analysis Library</a></li>
  115.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/measure/README.md">R<sup>d</sup> Continuous/Discrete Probability Measures</a></li>
  116.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/measure/dynamics/README.md">R<sup>1</sup> Gamma Distribution Implementation/Properties</a></li>
  117.  *  </ul>
  118.  *
  119.  * @author Lakshmi Krishnamurthy
  120.  */

  121. public class DiscreteF
  122. {

  123.     private static final R2ToR1 LowerIncompleteGamma()
  124.         throws Exception
  125.     {
  126.         return new R2ToR1()
  127.         {
  128.             @Override public double evaluate (
  129.                 final double s,
  130.                 final double t)
  131.                 throws Exception
  132.             {
  133.                 return new LowerEulerIntegral (
  134.                     null,
  135.                     t
  136.                 ).evaluate (
  137.                     s
  138.                 );
  139.             }
  140.         };
  141.     }

  142.     private static final void StatisticsArray (
  143.         final UnivariateDiscreteThin ahrensDieterThinStatistics,
  144.         final UnivariateDiscreteThin marsagliaThinStatistics)
  145.         throws Exception
  146.     {
  147.         System.out.println (
  148.             "\t| Average => " + FormatUtil.FormatDouble (
  149.                 ahrensDieterThinStatistics.average(), 2, 6, 1.
  150.             ) + " | " + FormatUtil.FormatDouble (
  151.                 marsagliaThinStatistics.average(), 2, 6, 1.
  152.             ) + " ||"
  153.         );

  154.         System.out.println (
  155.             "\t| Error   => " + FormatUtil.FormatDouble (
  156.                 ahrensDieterThinStatistics.error(), 2, 6, 1.
  157.             ) + " | " + FormatUtil.FormatDouble (
  158.                 marsagliaThinStatistics.error(), 2, 6, 1.
  159.             ) + " ||"
  160.         );

  161.         System.out.println (
  162.             "\t| Maximum => " + FormatUtil.FormatDouble (
  163.                 ahrensDieterThinStatistics.maximum(), 2, 6, 1.
  164.             ) + " | " + FormatUtil.FormatDouble (
  165.                 marsagliaThinStatistics.maximum(), 2, 6, 1.
  166.             ) + " ||"
  167.         );

  168.         System.out.println (
  169.             "\t| Minimum => " + FormatUtil.FormatDouble (
  170.                 ahrensDieterThinStatistics.minimum(), 2, 6, 1.
  171.             ) + " | " + FormatUtil.FormatDouble (
  172.                 marsagliaThinStatistics.minimum(), 2, 6, 1.
  173.             ) + " ||"
  174.         );
  175.     }

  176.     private static final void GenerateAndComputeStatistics (
  177.         final R1ToR1 gammaEstimator,
  178.         final R1ToR1 digammaEstimator,
  179.         final R2ToR1 lowerIncompleteGammaEstimator,
  180.         final double k1,
  181.         final double theta1,
  182.         final double k2,
  183.         final double theta2,
  184.         final int simulationCount)
  185.         throws Exception
  186.     {
  187.         double[] marsagliaRandomArray = new double[simulationCount];
  188.         double[] ahrensDieterRandomArray = new double[simulationCount];

  189.         R1ShapeScaleDiscrete ahrensDieterGammaDiscrete1 = new R1ShapeScaleDiscrete (
  190.             k1,
  191.             theta1,
  192.             gammaEstimator,
  193.             digammaEstimator,
  194.             lowerIncompleteGammaEstimator,
  195.             R1ShapeScaleDiscrete.DISCRETE_RANDOM_FROM_AHRENS_DIETER
  196.         );

  197.         R1ShapeScaleDiscrete ahrensDieterGammaDiscrete2 = new R1ShapeScaleDiscrete (
  198.             k2,
  199.             theta2,
  200.             gammaEstimator,
  201.             digammaEstimator,
  202.             lowerIncompleteGammaEstimator,
  203.             R1ShapeScaleDiscrete.DISCRETE_RANDOM_FROM_AHRENS_DIETER
  204.         );

  205.         R1ShapeScaleDiscrete marsagilaGammaDiscrete1 = new R1ShapeScaleDiscrete (
  206.             k1,
  207.             theta1,
  208.             gammaEstimator,
  209.             digammaEstimator,
  210.             lowerIncompleteGammaEstimator,
  211.             R1ShapeScaleDiscrete.DISCRETE_RANDOM_FROM_MARSAGLIA
  212.         );

  213.         R1ShapeScaleDiscrete marsagilaGammaDiscrete2 = new R1ShapeScaleDiscrete (
  214.             k2,
  215.             theta2,
  216.             gammaEstimator,
  217.             digammaEstimator,
  218.             lowerIncompleteGammaEstimator,
  219.             R1ShapeScaleDiscrete.DISCRETE_RANDOM_FROM_MARSAGLIA
  220.         );

  221.         for (int simulationIndex = 0;
  222.             simulationIndex < simulationCount;
  223.             ++simulationIndex)
  224.         {
  225.             marsagliaRandomArray[simulationIndex] = R1ShapeScaleComposite.RandomF (
  226.                 marsagilaGammaDiscrete1,
  227.                 marsagilaGammaDiscrete2
  228.             );

  229.             ahrensDieterRandomArray[simulationIndex] = R1ShapeScaleComposite.RandomF (
  230.                 ahrensDieterGammaDiscrete1,
  231.                 ahrensDieterGammaDiscrete2
  232.             );
  233.         }

  234.         System.out.println (
  235.             "\t|-------------------------------------------------||"
  236.         );

  237.         System.out.println (
  238.             "\t|       DISCRETE F RANDOM NUMBER GENERATION       ||"
  239.         );

  240.         System.out.println (
  241.             "\t|-------------------------------------------------||"
  242.         );

  243.         System.out.println (
  244.             "\t|          k1      => " + k1
  245.         );

  246.         System.out.println (
  247.             "\t|          theta1  => " + theta1
  248.         );

  249.         System.out.println (
  250.             "\t|          k2      => " + k2
  251.         );

  252.         System.out.println (
  253.             "\t|          theta2  => " + theta2
  254.         );

  255.         System.out.println (
  256.             "\t|-------------------------------------------------||"
  257.         );

  258.         System.out.println (
  259.             "\t|          - Using Ahrens-Dieter (1982)           ||"
  260.         );

  261.         System.out.println (
  262.             "\t|          - Using Marsaglia (1977)               ||"
  263.         );

  264.         System.out.println (
  265.             "\t|-------------------------------------------------||"
  266.         );

  267.         StatisticsArray (
  268.             new UnivariateDiscreteThin (
  269.                 ahrensDieterRandomArray
  270.             ),
  271.             new UnivariateDiscreteThin (
  272.                 marsagliaRandomArray
  273.             )
  274.         );

  275.         System.out.println (
  276.             "\t|-------------------------------------------------||"
  277.         );

  278.         System.out.println();
  279.     }

  280.     public static final void main (
  281.         final String[] argumentArray)
  282.         throws Exception
  283.     {
  284.         EnvManager.InitEnv (
  285.             ""
  286.         );

  287.         double[] k1Array = {
  288.             1.5,
  289.             1.0,
  290.             0.5,
  291.         };
  292.         double[] k2Array = {
  293.             1.5,
  294.             1.0,
  295.             0.5,
  296.         };
  297.         double[] theta1Array = {
  298.             0.5,
  299.             1.0,
  300.             2.0,
  301.         };
  302.         double[] theta2Array = {
  303.             0.5,
  304.             1.0,
  305.             2.0,
  306.         };
  307.         int simulationCount = 100000;
  308.         int digammaTermCount = 1000;

  309.         R1ToR1 gammaEstimator = new EulerIntegralSecondKind (
  310.             null
  311.         );

  312.         R2ToR1 lowerIncompleteGammaEstimator = LowerIncompleteGamma();

  313.         R1ToR1 digammaEstimator = CumulativeSeriesEstimator.AbramowitzStegun2007 (
  314.             digammaTermCount
  315.         );

  316.         for (double k1 : k1Array)
  317.         {
  318.             for (double theta1 : theta1Array)
  319.             {
  320.                 for (double k2 : k2Array)
  321.                 {
  322.                     for (double theta2 : theta2Array)
  323.                     {
  324.                         GenerateAndComputeStatistics (
  325.                             gammaEstimator,
  326.                             digammaEstimator,
  327.                             lowerIncompleteGammaEstimator,
  328.                             k1,
  329.                             theta1,
  330.                             k2,
  331.                             theta2,
  332.                             simulationCount
  333.                         );
  334.                     }
  335.                 }
  336.             }
  337.         }

  338.         EnvManager.TerminateEnv();
  339.     }
  340. }