SinglyLinkedNode.java

  1. package org.drip.spaces.graph;

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

  75. /**
  76.  * <i>SinglyLinkedNode</i> implements the Node behind a Singly Linked List. The References are:
  77.  *
  78.  * <br><br>
  79.  *  <ul>
  80.  *      <li>
  81.  *          Knuth, D. (1973): <i>The Art of Computer Programming</i> <b>Addison-Wesley</b>
  82.  *      </li>
  83.  *      <li>
  84.  *          Oracle (2018): LinkedList (Java Platform SE 7)
  85.  *              https://docs.oracle.com/javase/7/docs/api/java/util/LinkedList.html
  86.  *      </li>
  87.  *      <li>
  88.  *          Wikipedia (2018a): Linked List https://en.wikipedia.org/wiki/Linked_list
  89.  *      </li>
  90.  *      <li>
  91.  *          Wikipedia (2018b): Doubly Linked List https://en.wikipedia.org/wiki/Doubly_linked_list
  92.  *      </li>
  93.  *      <li>
  94.  *          Wikipedia (2018c): Linked Data Structure https://en.wikipedia.org/wiki/Linked_data_structure
  95.  *      </li>
  96.  *  </ul>
  97.  *
  98.  * <br><br>
  99.  *  <ul>
  100.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ComputationalCore.md">Computational Core Module</a></li>
  101.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/StatisticalLearningLibrary.md">Statistical Learning Library</a></li>
  102.  *      <li><b>Project</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/spaces/README.md">R<sup>1</sup> and R<sup>d</sup> Vector/Tensor Spaces (Validated and/or Normed), and Function Classes</a></li>
  103.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/spaces/graph/README.md">Graph Representation and Traversal Algorithms</a></li>
  104.  *  </ul>
  105.  * <br><br>
  106.  *
  107.  * @author Lakshmi Krishnamurthy
  108.  */

  109. public class SinglyLinkedNode
  110. {
  111.     private SinglyLinkedNode _tail = null;
  112.     private SinglyLinkedNode _adjacent = null;
  113.     private double _value = java.lang.Double.NaN;

  114.     /**
  115.      * Generate a FIFO Linked List from the Value Array
  116.      *
  117.      * @param valueArray The Value Array
  118.      *
  119.      * @return The FIFO Linked List
  120.      */

  121.     public static final SinglyLinkedNode FIFOListFromArray (
  122.         final double[] valueArray)
  123.     {
  124.         if (null == valueArray)
  125.         {
  126.             return null;
  127.         }

  128.         SinglyLinkedNode singlyLinkedNode = null;
  129.         int arraySize = valueArray.length;

  130.         if (0 == arraySize)
  131.         {
  132.             return null;
  133.         }

  134.         try
  135.         {
  136.             for (int valueIndex = 0; valueIndex < arraySize; ++valueIndex)
  137.             {
  138.                 if (null == singlyLinkedNode)
  139.                 {
  140.                     singlyLinkedNode = new SinglyLinkedNode (
  141.                         valueArray[valueIndex],
  142.                         null
  143.                     );
  144.                 }
  145.                 else
  146.                 {
  147.                     if (null == singlyLinkedNode.addToTail (
  148.                         new SinglyLinkedNode (
  149.                             valueArray[valueIndex],
  150.                             null
  151.                         )
  152.                     ))
  153.                     {
  154.                         return null;
  155.                     }
  156.                 }
  157.             }
  158.         }
  159.         catch (java.lang.Exception e)
  160.         {
  161.             e.printStackTrace();
  162.         }

  163.         return null;
  164.     }

  165.     /**
  166.      * Generate a LIFO Linked List from the Value Array
  167.      *
  168.      * @param valueArray The Value Array
  169.      *
  170.      * @return The LIFO Linked List
  171.      */

  172.     public static final SinglyLinkedNode lIFOListFromArray (
  173.         final double[] valueArray)
  174.     {
  175.         if (null == valueArray)
  176.         {
  177.             return null;
  178.         }

  179.         SinglyLinkedNode singlyLinkedNode = null;
  180.         int arraySize = valueArray.length;

  181.         if (0 == arraySize)
  182.         {
  183.             return null;
  184.         }

  185.         try
  186.         {
  187.             for (int valueIndex = 0; valueIndex < arraySize; ++valueIndex)
  188.             {
  189.                 if (null == singlyLinkedNode)
  190.                 {
  191.                     singlyLinkedNode = new SinglyLinkedNode (
  192.                         valueArray[valueIndex],
  193.                         null
  194.                     );
  195.                 }
  196.                 else
  197.                 {
  198.                     if (null == singlyLinkedNode.addToHead (
  199.                         new SinglyLinkedNode (
  200.                             valueArray[valueIndex],
  201.                             null
  202.                         )
  203.                     ))
  204.                     {
  205.                         return null;
  206.                     }
  207.                 }
  208.             }
  209.         }
  210.         catch (java.lang.Exception e)
  211.         {
  212.             e.printStackTrace();
  213.         }

  214.         return null;
  215.     }

  216.     /**
  217.      * SinglyLinkedNode Constructor
  218.      *
  219.      * @param value The Linked Node Value
  220.      * @param adjacent The Adjacent Node
  221.      *
  222.      * @throws java.lang.Exception Thrown if the Inputs are Invalid
  223.      */

  224.     public SinglyLinkedNode (
  225.         final double value,
  226.         final SinglyLinkedNode adjacent)
  227.         throws java.lang.Exception
  228.     {
  229.         if (!org.drip.numerical.common.NumberUtil.IsValid (_value = value))
  230.         {
  231.             throw new java.lang.Exception ("SinglyLinkedNodeConstructor => Invalid Inputs");
  232.         }

  233.         _adjacent = adjacent;
  234.         _tail = this;
  235.     }

  236.     /**
  237.      * Retrieve the Linked Node Value
  238.      *
  239.      * @return The Linked Node Value
  240.      */

  241.     public double value()
  242.     {
  243.         return _value;
  244.     }

  245.     /**
  246.      * Retrieve the Adjacent Node
  247.      *
  248.      * @return The Adjacent Node
  249.      */

  250.     public SinglyLinkedNode adjacent()
  251.     {
  252.         return _adjacent;
  253.     }

  254.     /**
  255.      * Retrieve the Head Node
  256.      *
  257.      * @return The Head Node
  258.      */

  259.     public SinglyLinkedNode head()
  260.     {
  261.         return this;
  262.     }

  263.     /**
  264.      * Retrieve the Tail Node
  265.      *
  266.      * @return The Tail Node
  267.      */

  268.     public SinglyLinkedNode tail()
  269.     {
  270.         return _tail;
  271.     }

  272.     /**
  273.      * Append "This" to the Tail of the "Other"
  274.      *
  275.      * @param otherList The "Other"
  276.      *
  277.      * @return Appending/Addition successfully done
  278.      */

  279.     public SinglyLinkedNode addToHead (
  280.         final SinglyLinkedNode otherList)
  281.     {
  282.         if (null == otherList)
  283.         {
  284.             return null;
  285.         }

  286.         SinglyLinkedNode otherTail = otherList.tail();

  287.         otherTail._tail = this;
  288.         return otherTail;
  289.     }

  290.     /**
  291.      * Add "Other" to the Tail of "This"
  292.      *
  293.      * @param otherList The "Other"
  294.      *
  295.      * @return Appending/Addition successfully done
  296.      */

  297.     public SinglyLinkedNode addToTail (
  298.         final SinglyLinkedNode otherList)
  299.     {
  300.         _tail = otherList;
  301.         return this;
  302.     }

  303.     /**
  304.      * Locate the Node that contains the specified Value
  305.      *
  306.      * @param value The Value to Search for
  307.      *
  308.      * @return The Node
  309.      */

  310.     public SinglyLinkedNode locate (
  311.         final double value)
  312.     {
  313.         if (!org.drip.numerical.common.NumberUtil.IsValid (value))
  314.         {
  315.             return null;
  316.         }

  317.         SinglyLinkedNode node = this;

  318.         while (null != node)
  319.         {
  320.             if (node.value() == value)
  321.             {
  322.                 return node;
  323.             }

  324.             node = node.adjacent();
  325.         }

  326.         return null;
  327.     }

  328.     /**
  329.      * Check if the Node that containing the specified Value Exists
  330.      *
  331.      * @param value The Value to Check for
  332.      *
  333.      * @return TRUE - The Node Exists
  334.      */

  335.     public boolean containsValue (
  336.         final double value)
  337.     {
  338.         if (!org.drip.numerical.common.NumberUtil.IsValid (value))
  339.         {
  340.             return false;
  341.         }

  342.         SinglyLinkedNode node = this;

  343.         while (null != node)
  344.         {
  345.             if (node.value() == value)
  346.             {
  347.                 return true;
  348.             }

  349.             node = node.adjacent();
  350.         }

  351.         return false;
  352.     }

  353.     /**
  354.      * Insert the given Value after the Specified Location Node
  355.      *
  356.      * @param locationNodeValue The Location Node's Value
  357.      * @param insertionNodeValue The Value to be inserted
  358.      *
  359.      * @return TRUE - The Value was successfully inserted
  360.      */

  361.     public boolean insertAfter (
  362.         final double locationNodeValue,
  363.         final double insertionNodeValue)
  364.     {
  365.         if (!org.drip.numerical.common.NumberUtil.IsValid (locationNodeValue) ||
  366.             !org.drip.numerical.common.NumberUtil.IsValid (insertionNodeValue))
  367.         {
  368.             return false;
  369.         }

  370.         SinglyLinkedNode locationNode = locate (locationNodeValue);

  371.         if (null == locationNode)
  372.         {
  373.             return false;
  374.         }

  375.         SinglyLinkedNode locationNodeAdjacent = locationNode.adjacent();

  376.         try
  377.         {
  378.             locationNode._adjacent = new SinglyLinkedNode (
  379.                 insertionNodeValue,
  380.                 locationNodeAdjacent
  381.             );
  382.         }
  383.         catch (java.lang.Exception e)
  384.         {
  385.             e.printStackTrace();

  386.             return false;
  387.         }

  388.         return true;
  389.     }

  390.     /**
  391.      * Remove the Node at the specified Value
  392.      *
  393.      * @param removalNodeValue The Node to be removed
  394.      *
  395.      * @return The "Removed"
  396.      */

  397.     public SinglyLinkedNode removeAt (
  398.         final double removalNodeValue)
  399.     {
  400.         if (!org.drip.numerical.common.NumberUtil.IsValid (removalNodeValue))
  401.         {
  402.             return null;
  403.         }

  404.         boolean nodeFound = false;
  405.         SinglyLinkedNode priorNode = null;
  406.         SinglyLinkedNode currentNode = this;

  407.         while (null != currentNode)
  408.         {
  409.             if (currentNode.value() == removalNodeValue)
  410.             {
  411.                 nodeFound = true;
  412.                 break;
  413.             }

  414.             priorNode = currentNode;

  415.             currentNode = currentNode.adjacent();
  416.         }

  417.         if (!nodeFound)
  418.         {
  419.             return null;
  420.         }

  421.         if (null == priorNode)
  422.         {
  423.             try
  424.             {
  425.                 return addToHead (
  426.                     new SinglyLinkedNode (
  427.                         removalNodeValue,
  428.                         currentNode.adjacent()
  429.                     )
  430.                 );
  431.             }
  432.             catch (java.lang.Exception e)
  433.             {
  434.                 e.printStackTrace();
  435.             }

  436.             return null;
  437.         }

  438.         try
  439.         {
  440.             priorNode._adjacent = new SinglyLinkedNode (
  441.                 removalNodeValue,
  442.                 currentNode.adjacent()
  443.             );
  444.         }
  445.         catch (java.lang.Exception e)
  446.         {
  447.             e.printStackTrace();

  448.             return null;
  449.         }

  450.         return this;
  451.     }

  452.     /**
  453.      * Convert the Linked List to an Array List
  454.      *
  455.      * @return The Array List
  456.      */

  457.     public java.util.List<java.lang.Double> toList()
  458.     {
  459.         java.util.List<java.lang.Double> valueList = new java.util.ArrayList<java.lang.Double>();

  460.         SinglyLinkedNode node = this;

  461.         while (null != node)
  462.         {
  463.             valueList.add (node.value());

  464.             node = node.adjacent();
  465.         }

  466.         return valueList;
  467.     }
  468. }