CartesianComplexNumber.java
package org.drip.function.definition;
/*
* -*- mode: java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*/
/*!
* Copyright (C) 2020 Lakshmi Krishnamurthy
* Copyright (C) 2019 Lakshmi Krishnamurthy
* Copyright (C) 2018 Lakshmi Krishnamurthy
* Copyright (C) 2017 Lakshmi Krishnamurthy
* Copyright (C) 2016 Lakshmi Krishnamurthy
* Copyright (C) 2015 Lakshmi Krishnamurthy
* Copyright (C) 2014 Lakshmi Krishnamurthy
*
* This file is part of DROP, an open-source library targeting analytics/risk, transaction cost analytics,
* asset liability management analytics, capital, exposure, and margin analytics, valuation adjustment
* analytics, and portfolio construction analytics within and across fixed income, credit, commodity,
* equity, FX, and structured products. It also includes auxiliary libraries for algorithm support,
* numerical analysis, numerical optimization, spline builder, model validation, statistical learning,
* and computational support.
*
* https://lakshmidrip.github.io/DROP/
*
* DROP is composed of three modules:
*
* - DROP Product Core - https://lakshmidrip.github.io/DROP-Product-Core/
* - DROP Portfolio Core - https://lakshmidrip.github.io/DROP-Portfolio-Core/
* - DROP Computational Core - https://lakshmidrip.github.io/DROP-Computational-Core/
*
* DROP Product Core implements libraries for the following:
* - Fixed Income Analytics
* - Loan Analytics
* - Transaction Cost Analytics
*
* DROP Portfolio Core implements libraries for the following:
* - Asset Allocation Analytics
* - Asset Liability Management Analytics
* - Capital Estimation Analytics
* - Exposure Analytics
* - Margin Analytics
* - XVA Analytics
*
* DROP Computational Core implements libraries for the following:
* - Algorithm Support
* - Computation Support
* - Function Analysis
* - Model Validation
* - Numerical Analysis
* - Numerical Optimizer
* - Spline Builder
* - Statistical Learning
*
* Documentation for DROP is Spread Over:
*
* - Main => https://lakshmidrip.github.io/DROP/
* - Wiki => https://github.com/lakshmiDRIP/DROP/wiki
* - GitHub => https://github.com/lakshmiDRIP/DROP
* - Repo Layout Taxonomy => https://github.com/lakshmiDRIP/DROP/blob/master/Taxonomy.md
* - Javadoc => https://lakshmidrip.github.io/DROP/Javadoc/index.html
* - Technical Specifications => https://github.com/lakshmiDRIP/DROP/tree/master/Docs/Internal
* - Release Versions => https://lakshmidrip.github.io/DROP/version.html
* - Community Credits => https://lakshmidrip.github.io/DROP/credits.html
* - Issues Catalog => https://github.com/lakshmiDRIP/DROP/issues
* - JUnit => https://lakshmidrip.github.io/DROP/junit/index.html
* - Jacoco => https://lakshmidrip.github.io/DROP/jacoco/index.html
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* <i>CartesianComplexNumber</i> implements the functionality for dealing with the Cartesian Form of Complex
* Numbers.
*
* <br><br>
* <ul>
* <li><b>Module </b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/ComputationalCore.md">Computational Core Module</a></li>
* <li><b>Library</b> = <a href = "https://github.com/lakshmiDRIP/DROP/tree/master/NumericalAnalysisLibrary.md">Numerical Analysis Library</a></li>
* <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>
* <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>
* </ul>
* <br><br>
*
* @author Lakshmi Krishnamurthy
*/
public class CartesianComplexNumber
{
private double _real = java.lang.Double.NaN;
private double _imaginary = java.lang.Double.NaN;
/**
* Add the 2 Complex Numbers
*
* @param complexNumber1 The First Complex Number
* @param complexNumber2 The Second Complex Number
*
* @return The Complex Number instance that is a sum of the two
*/
public static final CartesianComplexNumber Add (
final CartesianComplexNumber complexNumber1,
final CartesianComplexNumber complexNumber2)
{
if (null == complexNumber1 || null == complexNumber2)
{
return null;
}
try
{
return new CartesianComplexNumber (
complexNumber1.real() + complexNumber2.real(),
complexNumber1.imaginary() + complexNumber2.imaginary()
);
}
catch (java.lang.Exception e)
{
e.printStackTrace();
}
return null;
}
/**
* Scale the Complex Number with the factor
*
* @param complexNumber The Complex Number
* @param scale The Scaling Factor
*
* @return The Scaled Complex Number
*/
public static final CartesianComplexNumber Scale (
final CartesianComplexNumber complexNumber,
final double scale)
{
if (null == complexNumber || !org.drip.numerical.common.NumberUtil.IsValid (scale))
{
return null;
}
try
{
return new CartesianComplexNumber (
scale * complexNumber.real(),
scale * complexNumber.imaginary()
);
}
catch (java.lang.Exception e)
{
e.printStackTrace();
}
return null;
}
/**
* Subtract the Second Complex Number from the First
*
* @param complexNumber1 The First Complex Number
* @param complexNumber2 The Second Complex Number
*
* @return The "Difference" Complex Number
*/
public static final CartesianComplexNumber Subtract (
final CartesianComplexNumber complexNumber1,
final CartesianComplexNumber complexNumber2)
{
if (null == complexNumber1 || null == complexNumber2)
{
return null;
}
try {
return new CartesianComplexNumber (
complexNumber1.real() - complexNumber2.real(),
complexNumber1.imaginary() - complexNumber2.imaginary()
);
}
catch (java.lang.Exception e)
{
e.printStackTrace();
}
return null;
}
/**
* Multiply the 2 Complex Numbers
*
* @param complexNumber1 The First Complex Number
* @param complexNumber2 The Second Complex Number
*
* @return The Complex Number instance that is a product of the two
*/
public static final CartesianComplexNumber Multiply (
final CartesianComplexNumber complexNumber1,
final CartesianComplexNumber complexNumber2)
{
if (null == complexNumber1 || null == complexNumber2)
{
return null;
}
double real1 = complexNumber1.real();
double real2 = complexNumber2.real();
double imaginary1 = complexNumber1.imaginary();
double imaginary2 = complexNumber2.imaginary();
try
{
return new CartesianComplexNumber (
real1 * real2 - imaginary1 * imaginary2,
real1 * imaginary2 + real2 * imaginary1
);
}
catch (java.lang.Exception e)
{
e.printStackTrace();
}
return null;
}
/**
* Divide the Numerator Complex Number by the Denominator Complex Number
*
* @param numerator The Numerator Complex Number
* @param denominator The Denominator Complex Number
*
* @return The "Divided" Complex Number
*/
public static final CartesianComplexNumber Divide (
final CartesianComplexNumber numerator,
final CartesianComplexNumber denominator)
{
if (null == numerator || null == denominator)
{
return null;
}
double numeratorReal = numerator.real();
double denominatorReal = denominator.real();
double numeratorImaginary = numerator.imaginary();
double denominatorImaginary = denominator.imaginary();
if (0. == denominatorReal && 0. == denominatorImaginary)
{
return null;
}
double inverseDenominatorModulus = 1. / denominator.modulus();
try
{
return new CartesianComplexNumber (
(numeratorReal * denominatorReal + numeratorImaginary * denominatorImaginary) *
inverseDenominatorModulus,
(denominatorReal * numeratorImaginary - numeratorReal * denominatorImaginary) *
inverseDenominatorModulus
);
}
catch (java.lang.Exception e)
{
e.printStackTrace();
}
return null;
}
/**
* Square the Complex Number
*
* @param complexNumber The Complex Number
*
* @return The Squared Complex Number Instance
*/
public static final CartesianComplexNumber Square (
final CartesianComplexNumber complexNumber)
{
if (null == complexNumber)
{
return null;
}
double modulus = complexNumber.modulus();
if (0. == modulus)
{
try
{
return new CartesianComplexNumber (
0.,
0.
);
}
catch (java.lang.Exception e)
{
e.printStackTrace();
}
return null;
}
double argument = 2. * complexNumber.argument();
try
{
return new CartesianComplexNumber (
modulus * java.lang.Math.cos (argument),
modulus * java.lang.Math.sin (argument)
);
}
catch (java.lang.Exception e)
{
e.printStackTrace();
}
return null;
}
/**
* Compute the Square Root of the Complex Number
*
* @param complexNumber The Complex Number
*
* @return The Square Root Complex Number Instance
*/
public static final CartesianComplexNumber SquareRoot (
final CartesianComplexNumber complexNumber)
{
if (null == complexNumber)
{
return null;
}
double modulus = java.lang.Math.sqrt (complexNumber.modulus());
if (0. == modulus)
{
try
{
return new CartesianComplexNumber (
0.,
0.
);
}
catch (java.lang.Exception e)
{
e.printStackTrace();
}
return null;
}
double argument = 0.5 * complexNumber.argument();
try
{
return new CartesianComplexNumber (
modulus * java.lang.Math.cos (argument),
modulus * java.lang.Math.sin (argument)
);
}
catch (java.lang.Exception e)
{
e.printStackTrace();
}
return null;
}
/**
* Exponentiate the Complex Number
*
* @param complexNumber The Complex Number
*
* @return The Exponentiated Complex Number Instance
*/
public static final CartesianComplexNumber Exponentiate (
final CartesianComplexNumber complexNumber)
{
if (null == complexNumber)
{
return null;
}
double argument = complexNumber.imaginary();
double modulus = java.lang.Math.exp (complexNumber.real());
try
{
return new CartesianComplexNumber (
modulus * java.lang.Math.cos (argument),
modulus * java.lang.Math.sin (argument)
);
}
catch (java.lang.Exception e)
{
e.printStackTrace();
}
return null;
}
/**
* Compute Logarithm of the Complex Number
*
* @param complexNumber The Complex Number
*
* @return The Complex Number Logarithm Instance
*/
public static final CartesianComplexNumber Logarithm (
final CartesianComplexNumber complexNumber)
{
if (null == complexNumber)
{
return null;
}
double modulus = complexNumber.modulus();
if (0. == modulus)
{
return null;
}
try
{
return new CartesianComplexNumber (
0.5 * java.lang.Math.log (modulus),
complexNumber.argument()
);
}
catch (java.lang.Exception e)
{
e.printStackTrace();
}
return null;
}
/**
* Construct the Complex Number from its Polar Representation
*
* @param r r
* @param theta theta
*
* @return Complex Number from its Polar Representation
*/
public static final CartesianComplexNumber FromPolar (
final double r,
final double theta)
{
try
{
return !org.drip.numerical.common.NumberUtil.IsValid (r) ||
!org.drip.numerical.common.NumberUtil.IsValid (theta) ? null :
new CartesianComplexNumber (
r * java.lang.Math.cos (theta),
r * java.lang.Math.sin (theta)
);
}
catch (java.lang.Exception e)
{
e.printStackTrace();
}
return null;
}
/**
* CartesianComplexNumber constructor
*
* @param real Real Part
* @param imaginary Imaginary Part
*
* @throws java.lang.Exception Thrown if the Inputs are invalid
*/
public CartesianComplexNumber (
final double real,
final double imaginary)
throws java.lang.Exception
{
if (!org.drip.numerical.common.NumberUtil.IsValid (_real = real) ||
!org.drip.numerical.common.NumberUtil.IsValid (_imaginary = imaginary))
{
throw new java.lang.Exception ("CartesianComplexNumber Constructor => Invalid Inputs");
}
}
/**
* Retrieve the Real Part
*
* @return The Real Part
*/
public double real()
{
return _real;
}
/**
* Retrieve the Imaginary Part
*
* @return The Imaginary Part
*/
public double imaginary()
{
return _imaginary;
}
/**
* Retrieve the Modulus
*
* @return The Modulus
*/
public double modulus()
{
return _real * _real + _imaginary * _imaginary;
}
/**
* Retrieve the Absolute Value
*
* @return The Absolute Value
*/
public double abs()
{
return java.lang.Math.sqrt (modulus());
}
/**
* Retrieve the Argument
*
* @return The Argument
*/
public double argument()
{
return 0. == _real && 0. == _imaginary ? 0. : java.lang.Math.atan (_imaginary / _real);
}
/**
* Display the Real/Imaginary Contents
*
* @return The Real/Imaginary Contents
*/
public java.lang.String display()
{
return "\t[" + _real + ", " + _imaginary + "]";
}
}