MultipleRecursiveGeneratorLEcuyer.java

  1. package org.drip.measure.crng;

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

  76. /**
  77.  * <i>MultipleRecursiveGeneratorLEcuyer</i> - L'Ecuyer's Multiple Recursive Generator - combines Multiple
  78.  * Recursive Sequences to produce a Large State Space with good Randomness Properties. MRG32k3a is a special
  79.  * Type of MultipleRecursiveGeneratorLEcuyer.
  80.  *
  81.  *  <br><br>
  82.  *  <ul>
  83.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ComputationalCore.md">Computational Core Module</a></li>
  84.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/NumericalAnalysisLibrary.md">Numerical Analysis Library</a></li>
  85.  *      <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>
  86.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/measure/crng/README.md">Continuous Random Number Stream Generator</a></li>
  87.  *  </ul>
  88.  *
  89.  * @author Lakshmi Krishnamurthy
  90.  */

  91. public class MultipleRecursiveGeneratorLEcuyer implements org.drip.measure.crng.RecursiveGenerator {
  92.     private long _lM1 = java.lang.Long.MIN_VALUE;
  93.     private long _lM2 = java.lang.Long.MIN_VALUE;
  94.     private long _lA12 = java.lang.Long.MIN_VALUE;
  95.     private long _lA13 = java.lang.Long.MIN_VALUE;
  96.     private long _lA21 = java.lang.Long.MIN_VALUE;
  97.     private long _lA23 = java.lang.Long.MIN_VALUE;
  98.     private long _lY1Prev = java.lang.Long.MIN_VALUE;
  99.     private long _lY2Prev = java.lang.Long.MIN_VALUE;
  100.     private long _lY1PrevPrev = java.lang.Long.MIN_VALUE;
  101.     private long _lY2PrevPrev = java.lang.Long.MIN_VALUE;
  102.     private long _lY1PrevPrevPrev = java.lang.Long.MIN_VALUE;
  103.     private long _lY2PrevPrevPrev = java.lang.Long.MIN_VALUE;

  104.     /**
  105.      * Generate the MRG32k3a Variant of the L'Ecuyer's Multiple Recursive Generator
  106.      *
  107.      * @return The MRG32k3a Variant of the L'Ecuyer's Multiple Recursive Generator
  108.      */

  109.     public static final MultipleRecursiveGeneratorLEcuyer MRG32k3a()
  110.     {
  111.         long l2Power32 = 1;

  112.         for (int i = 0; i < 32; ++i)
  113.             l2Power32 *= 2;

  114.         try {
  115.             return new MultipleRecursiveGeneratorLEcuyer (
  116.                 System.nanoTime(),
  117.                 System.nanoTime(),
  118.                 System.nanoTime(),
  119.                 System.nanoTime(),
  120.                 System.nanoTime(),
  121.                 System.nanoTime(),
  122.                 1403580,
  123.                 -810728,
  124.                  527612,
  125.                 -1370589,
  126.                 l2Power32 - 209,
  127.                 l2Power32 - 22853
  128.             );
  129.         } catch (java.lang.Exception e) {
  130.             e.printStackTrace();
  131.         }

  132.         return null;
  133.     }

  134.     /**
  135.      * MultipleRecursiveGeneratorLEcuyer Constructor
  136.      *
  137.      * @param lY1Prev Y1 Previous
  138.      * @param lY1PrevPrev Y1 Previous Previous
  139.      * @param lY1PrevPrevPrev Y1 Previous Previous Previous
  140.      * @param lY2Prev Y2 Previous
  141.      * @param lY2PrevPrev Y2 Previous Previous
  142.      * @param lY2PrevPrevPrev Y2 Previous Previous Previous
  143.      * @param lA12 A12
  144.      * @param lA13 A13
  145.      * @param lA21 A21
  146.      * @param lA23 A23
  147.      * @param lM1 M1
  148.      * @param lM2 M2
  149.      *
  150.      * @throws java.lang.Exception Thrown if the Inputs are Invalid
  151.      */

  152.     public MultipleRecursiveGeneratorLEcuyer (
  153.         final long lY1Prev,
  154.         final long lY1PrevPrev,
  155.         final long lY1PrevPrevPrev,
  156.         final long lY2Prev,
  157.         final long lY2PrevPrev,
  158.         final long lY2PrevPrevPrev,
  159.         final long lA12,
  160.         final long lA13,
  161.         final long lA21,
  162.         final long lA23,
  163.         final long lM1,
  164.         final long lM2)
  165.         throws java.lang.Exception
  166.     {
  167.         if (!org.drip.numerical.common.NumberUtil.IsValid (_lY1Prev = lY1Prev) ||
  168.             !org.drip.numerical.common.NumberUtil.IsValid (_lY1PrevPrev = lY1PrevPrev) ||
  169.             !org.drip.numerical.common.NumberUtil.IsValid (_lY1PrevPrevPrev = lY1PrevPrevPrev) ||
  170.             !org.drip.numerical.common.NumberUtil.IsValid (_lY2Prev = lY2Prev) ||
  171.             !org.drip.numerical.common.NumberUtil.IsValid (_lY2PrevPrev = lY2PrevPrev) ||
  172.             !org.drip.numerical.common.NumberUtil.IsValid (_lY2PrevPrevPrev = lY2PrevPrevPrev) ||
  173.             !org.drip.numerical.common.NumberUtil.IsValid (_lA12 = lA12) ||
  174.             !org.drip.numerical.common.NumberUtil.IsValid (_lA13 = lA13) ||
  175.             !org.drip.numerical.common.NumberUtil.IsValid (_lA21 = lA21) ||
  176.             !org.drip.numerical.common.NumberUtil.IsValid (_lA23 = lA23) ||
  177.             !org.drip.numerical.common.NumberUtil.IsValid (_lM1 = lM1) ||
  178.             !org.drip.numerical.common.NumberUtil.IsValid (_lM2 = lM2))
  179.             throw new java.lang.Exception
  180.                 ("MultipleRecursiveGeneratorLEcuyer Constructor => Invalid Inputs");
  181.     }

  182.     /**
  183.      * Retrieve M1
  184.      *
  185.      * @return M1
  186.      */

  187.     public long m1()
  188.     {
  189.         return _lM1;
  190.     }

  191.     /**
  192.      * Retrieve M2
  193.      *
  194.      * @return M2
  195.      */

  196.     public long m2()
  197.     {
  198.         return _lM2;
  199.     }

  200.     /**
  201.      * Retrieve A12
  202.      *
  203.      * @return A12
  204.      */

  205.     public long a12()
  206.     {
  207.         return _lA12;
  208.     }

  209.     /**
  210.      * Retrieve A13
  211.      *
  212.      * @return A13
  213.      */

  214.     public long a13()
  215.     {
  216.         return _lA13;
  217.     }

  218.     /**
  219.      * Retrieve A21
  220.      *
  221.      * @return A21
  222.      */

  223.     public long a21()
  224.     {
  225.         return _lA21;
  226.     }

  227.     /**
  228.      * Retrieve A23
  229.      *
  230.      * @return A23
  231.      */

  232.     public long a23()
  233.     {
  234.         return _lA23;
  235.     }

  236.     /**
  237.      * Retrieve Y1 Previous
  238.      *
  239.      * @return Y1 Previous
  240.      */

  241.     public long y1Prev()
  242.     {
  243.         return _lY1Prev;
  244.     }

  245.     /**
  246.      * Retrieve Y1 Previous Previous
  247.      *
  248.      * @return Y1 Previous Previous
  249.      */

  250.     public long y1PrevPrev()
  251.     {
  252.         return _lY1PrevPrev;
  253.     }

  254.     /**
  255.      * Retrieve Y1 Previous Previous Previous
  256.      *
  257.      * @return Y1 Previous Previous Previous
  258.      */

  259.     public long y1PrevPrevPrev()
  260.     {
  261.         return _lY1PrevPrevPrev;
  262.     }

  263.     /**
  264.      * Retrieve Y2 Previous
  265.      *
  266.      * @return Y2 Previous
  267.      */

  268.     public long y2Prev()
  269.     {
  270.         return _lY2Prev;
  271.     }

  272.     /**
  273.      * Retrieve Y2 Previous Previous
  274.      *
  275.      * @return Y2 Previous Previous
  276.      */

  277.     public long y2PrevPrev()
  278.     {
  279.         return _lY2PrevPrev;
  280.     }

  281.     /**
  282.      * Retrieve Y2 Previous Previous Previous
  283.      *
  284.      * @return Y2 Previous Previous Previous
  285.      */

  286.     public long y2PrevPrevPrev()
  287.     {
  288.         return _lY2PrevPrevPrev;
  289.     }

  290.     @Override public long next()
  291.     {
  292.         long lY1 = (_lA12 * _lY1PrevPrev + _lA13 * _lY1PrevPrevPrev) % _lM1;
  293.         long lY2 = (_lA21 * _lY2Prev     + _lA23 * _lY2PrevPrevPrev) % _lM2;
  294.         _lY2PrevPrevPrev = _lY2PrevPrev;
  295.         _lY1PrevPrevPrev = _lY1PrevPrev;
  296.         _lY2PrevPrev = _lY2Prev;
  297.         _lY1PrevPrev = _lY1Prev;
  298.         _lY2Prev = lY2;
  299.         _lY1Prev = lY1;
  300.         return lY1 + lY2;
  301.     }
  302. }