CartesianComplexNumber.java

  1. package org.drip.function.definition;

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

  79. /**
  80.  * <i>CartesianComplexNumber</i> implements the functionality for dealing with the Cartesian Form of Complex
  81.  * Numbers.
  82.  *
  83.  * <br><br>
  84.  *  <ul>
  85.  *      <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ComputationalCore.md">Computational Core Module</a></li>
  86.  *      <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/NumericalAnalysisLibrary.md">Numerical Analysis Library</a></li>
  87.  *      <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>
  88.  *      <li><b>Package</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/src/main/java/org/drip/function/definition/README.md">Function Implementation Ancillary Support Objects</a></li>
  89.  *  </ul>
  90.  * <br><br>
  91.  *
  92.  * @author Lakshmi Krishnamurthy
  93.  */

  94. public class CartesianComplexNumber
  95. {
  96.     private double _real = java.lang.Double.NaN;
  97.     private double _imaginary = java.lang.Double.NaN;

  98.     /**
  99.      * Add the 2 Complex Numbers
  100.      *
  101.      * @param complexNumber1 The First Complex Number
  102.      * @param complexNumber2 The Second Complex Number
  103.      *
  104.      * @return The Complex Number instance that is a sum of the two
  105.      */

  106.     public static final CartesianComplexNumber Add (
  107.         final CartesianComplexNumber complexNumber1,
  108.         final CartesianComplexNumber complexNumber2)
  109.     {
  110.         if (null == complexNumber1 || null == complexNumber2)
  111.         {
  112.             return null;
  113.         }

  114.         try
  115.         {
  116.             return new CartesianComplexNumber (
  117.                 complexNumber1.real() + complexNumber2.real(),
  118.                 complexNumber1.imaginary() + complexNumber2.imaginary()
  119.             );
  120.         }
  121.         catch (java.lang.Exception e)
  122.         {
  123.             e.printStackTrace();
  124.         }

  125.         return null;
  126.     }

  127.     /**
  128.      * Scale the Complex Number with the factor
  129.      *
  130.      * @param complexNumber The Complex Number
  131.      * @param scale The Scaling Factor
  132.      *
  133.      * @return The Scaled Complex Number
  134.      */

  135.     public static final CartesianComplexNumber Scale (
  136.         final CartesianComplexNumber complexNumber,
  137.         final double scale)
  138.     {
  139.         if (null == complexNumber || !org.drip.numerical.common.NumberUtil.IsValid (scale))
  140.         {
  141.             return null;
  142.         }

  143.         try
  144.         {
  145.             return new CartesianComplexNumber (
  146.                 scale * complexNumber.real(),
  147.                 scale * complexNumber.imaginary()
  148.             );
  149.         }
  150.         catch (java.lang.Exception e)
  151.         {
  152.             e.printStackTrace();
  153.         }

  154.         return null;
  155.     }

  156.     /**
  157.      * Subtract the Second Complex Number from the First
  158.      *
  159.      * @param complexNumber1 The First Complex Number
  160.      * @param complexNumber2 The Second Complex Number
  161.      *
  162.      * @return The "Difference" Complex Number
  163.      */

  164.     public static final CartesianComplexNumber Subtract (
  165.         final CartesianComplexNumber complexNumber1,
  166.         final CartesianComplexNumber complexNumber2)
  167.     {
  168.         if (null == complexNumber1 || null == complexNumber2)
  169.         {
  170.             return null;
  171.         }

  172.         try {
  173.             return new CartesianComplexNumber (
  174.                 complexNumber1.real() - complexNumber2.real(),
  175.                 complexNumber1.imaginary() - complexNumber2.imaginary()
  176.             );
  177.         }
  178.         catch (java.lang.Exception e)
  179.         {
  180.             e.printStackTrace();
  181.         }

  182.         return null;
  183.     }

  184.     /**
  185.      * Multiply the 2 Complex Numbers
  186.      *
  187.      * @param complexNumber1 The First Complex Number
  188.      * @param complexNumber2 The Second Complex Number
  189.      *
  190.      * @return The Complex Number instance that is a product of the two
  191.      */

  192.     public static final CartesianComplexNumber Multiply (
  193.         final CartesianComplexNumber complexNumber1,
  194.         final CartesianComplexNumber complexNumber2)
  195.     {
  196.         if (null == complexNumber1 || null == complexNumber2)
  197.         {
  198.             return null;
  199.         }

  200.         double real1 = complexNumber1.real();

  201.         double real2 = complexNumber2.real();

  202.         double imaginary1 = complexNumber1.imaginary();

  203.         double imaginary2 = complexNumber2.imaginary();

  204.         try
  205.         {
  206.             return new CartesianComplexNumber (
  207.                 real1 * real2 - imaginary1 * imaginary2,
  208.                 real1 * imaginary2 + real2 * imaginary1
  209.             );
  210.         }
  211.         catch (java.lang.Exception e)
  212.         {
  213.             e.printStackTrace();
  214.         }

  215.         return null;
  216.     }

  217.     /**
  218.      * Divide the Numerator Complex Number by the Denominator Complex Number
  219.      *
  220.      * @param numerator The Numerator Complex Number
  221.      * @param denominator The Denominator Complex Number
  222.      *
  223.      * @return The "Divided" Complex Number
  224.      */

  225.     public static final CartesianComplexNumber Divide (
  226.         final CartesianComplexNumber numerator,
  227.         final CartesianComplexNumber denominator)
  228.     {
  229.         if (null == numerator || null == denominator)
  230.         {
  231.             return null;
  232.         }

  233.         double numeratorReal = numerator.real();

  234.         double denominatorReal = denominator.real();

  235.         double numeratorImaginary = numerator.imaginary();

  236.         double denominatorImaginary = denominator.imaginary();

  237.         if (0. == denominatorReal && 0. == denominatorImaginary)
  238.         {
  239.             return null;
  240.         }

  241.         double inverseDenominatorModulus = 1. / denominator.modulus();

  242.         try
  243.         {
  244.             return new CartesianComplexNumber (
  245.                 (numeratorReal * denominatorReal + numeratorImaginary * denominatorImaginary) *
  246.                     inverseDenominatorModulus,
  247.                 (denominatorReal * numeratorImaginary - numeratorReal * denominatorImaginary) *
  248.                     inverseDenominatorModulus
  249.             );
  250.         }
  251.         catch (java.lang.Exception e)
  252.         {
  253.             e.printStackTrace();
  254.         }

  255.         return null;
  256.     }

  257.     /**
  258.      * Square the Complex Number
  259.      *
  260.      * @param complexNumber The Complex Number
  261.      *
  262.      * @return The Squared Complex Number Instance
  263.      */

  264.     public static final CartesianComplexNumber Square (
  265.         final CartesianComplexNumber complexNumber)
  266.     {
  267.         if (null == complexNumber)
  268.         {
  269.             return null;
  270.         }

  271.         double modulus = complexNumber.modulus();

  272.         if (0. == modulus)
  273.         {
  274.             try
  275.             {
  276.                 return new CartesianComplexNumber (
  277.                     0.,
  278.                     0.
  279.                 );
  280.             }
  281.             catch (java.lang.Exception e)
  282.             {
  283.                 e.printStackTrace();
  284.             }

  285.             return null;
  286.         }

  287.         double argument = 2. * complexNumber.argument();

  288.         try
  289.         {
  290.             return new CartesianComplexNumber (
  291.                 modulus * java.lang.Math.cos (argument),
  292.                 modulus * java.lang.Math.sin (argument)
  293.             );
  294.         }
  295.         catch (java.lang.Exception e)
  296.         {
  297.             e.printStackTrace();
  298.         }

  299.         return null;
  300.     }

  301.     /**
  302.      * Compute the Square Root of the Complex Number
  303.      *
  304.      * @param complexNumber The Complex Number
  305.      *
  306.      * @return The Square Root Complex Number Instance
  307.      */

  308.     public static final CartesianComplexNumber SquareRoot (
  309.         final CartesianComplexNumber complexNumber)
  310.     {
  311.         if (null == complexNumber)
  312.         {
  313.             return null;
  314.         }

  315.         double modulus = java.lang.Math.sqrt (complexNumber.modulus());

  316.         if (0. == modulus)
  317.         {
  318.             try
  319.             {
  320.                 return new CartesianComplexNumber (
  321.                     0.,
  322.                     0.
  323.                 );
  324.             }
  325.             catch (java.lang.Exception e)
  326.             {
  327.                 e.printStackTrace();
  328.             }

  329.             return null;
  330.         }

  331.         double argument = 0.5 * complexNumber.argument();

  332.         try
  333.         {
  334.             return new CartesianComplexNumber (
  335.                 modulus * java.lang.Math.cos (argument),
  336.                 modulus * java.lang.Math.sin (argument)
  337.             );
  338.         }
  339.         catch (java.lang.Exception e)
  340.         {
  341.             e.printStackTrace();
  342.         }

  343.         return null;
  344.     }

  345.     /**
  346.      * Exponentiate the Complex Number
  347.      *
  348.      * @param complexNumber The Complex Number
  349.      *
  350.      * @return The Exponentiated Complex Number Instance
  351.      */

  352.     public static final CartesianComplexNumber Exponentiate (
  353.         final CartesianComplexNumber complexNumber)
  354.     {
  355.         if (null == complexNumber)
  356.         {
  357.             return null;
  358.         }

  359.         double argument = complexNumber.imaginary();

  360.         double modulus = java.lang.Math.exp (complexNumber.real());

  361.         try
  362.         {
  363.             return new CartesianComplexNumber (
  364.                 modulus * java.lang.Math.cos (argument),
  365.                 modulus * java.lang.Math.sin (argument)
  366.             );
  367.         }
  368.         catch (java.lang.Exception e)
  369.         {
  370.             e.printStackTrace();
  371.         }

  372.         return null;
  373.     }

  374.     /**
  375.      * Compute Logarithm of the Complex Number
  376.      *
  377.      * @param complexNumber The Complex Number
  378.      *
  379.      * @return The Complex Number Logarithm Instance
  380.      */

  381.     public static final CartesianComplexNumber Logarithm (
  382.         final CartesianComplexNumber complexNumber)
  383.     {
  384.         if (null == complexNumber)
  385.         {
  386.             return null;
  387.         }

  388.         double modulus = complexNumber.modulus();

  389.         if (0. == modulus)
  390.         {
  391.             return null;
  392.         }

  393.         try
  394.         {
  395.             return new CartesianComplexNumber (
  396.                 0.5 * java.lang.Math.log (modulus),
  397.                 complexNumber.argument()
  398.             );
  399.         }
  400.         catch (java.lang.Exception e)
  401.         {
  402.             e.printStackTrace();
  403.         }

  404.         return null;
  405.     }

  406.     /**
  407.      * Construct the Complex Number from its Polar Representation
  408.      *
  409.      * @param r r
  410.      * @param theta theta
  411.      *
  412.      * @return Complex Number from its Polar Representation
  413.      */

  414.     public static final CartesianComplexNumber FromPolar (
  415.         final double r,
  416.         final double theta)
  417.     {
  418.         try
  419.         {
  420.             return !org.drip.numerical.common.NumberUtil.IsValid (r) ||
  421.                 !org.drip.numerical.common.NumberUtil.IsValid (theta) ? null :
  422.                 new CartesianComplexNumber (
  423.                     r * java.lang.Math.cos (theta),
  424.                     r * java.lang.Math.sin (theta)
  425.                 );
  426.         }
  427.         catch (java.lang.Exception e)
  428.         {
  429.             e.printStackTrace();
  430.         }

  431.         return null;
  432.     }

  433.     /**
  434.      * CartesianComplexNumber constructor
  435.      *
  436.      * @param real Real Part
  437.      * @param imaginary Imaginary Part
  438.      *
  439.      * @throws java.lang.Exception Thrown if the Inputs are invalid
  440.      */

  441.     public CartesianComplexNumber (
  442.         final double real,
  443.         final double imaginary)
  444.         throws java.lang.Exception
  445.     {
  446.         if (!org.drip.numerical.common.NumberUtil.IsValid (_real = real) ||
  447.             !org.drip.numerical.common.NumberUtil.IsValid (_imaginary = imaginary))
  448.         {
  449.             throw new java.lang.Exception ("CartesianComplexNumber Constructor => Invalid Inputs");
  450.         }
  451.     }

  452.     /**
  453.      * Retrieve the Real Part
  454.      *
  455.      * @return The Real Part
  456.      */

  457.     public double real()
  458.     {
  459.         return _real;
  460.     }

  461.     /**
  462.      * Retrieve the Imaginary Part
  463.      *
  464.      * @return The Imaginary Part
  465.      */

  466.     public double imaginary()
  467.     {
  468.         return _imaginary;
  469.     }

  470.     /**
  471.      * Retrieve the Modulus
  472.      *
  473.      * @return The Modulus
  474.      */

  475.     public double modulus()
  476.     {
  477.         return _real * _real + _imaginary * _imaginary;
  478.     }

  479.     /**
  480.      * Retrieve the Absolute Value
  481.      *
  482.      * @return The Absolute Value
  483.      */

  484.     public double abs()
  485.     {
  486.         return java.lang.Math.sqrt (modulus());
  487.     }

  488.     /**
  489.      * Retrieve the Argument
  490.      *
  491.      * @return The Argument
  492.      */

  493.     public double argument()
  494.     {
  495.         return 0. == _real && 0. == _imaginary ? 0. : java.lang.Math.atan (_imaginary / _real);
  496.     }

  497.     /**
  498.      * Display the Real/Imaginary Contents
  499.      *
  500.      * @return The Real/Imaginary Contents
  501.      */

  502.     public java.lang.String display()
  503.     {
  504.         return "\t[" + _real + ", " + _imaginary + "]";
  505.     }
  506. }