Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- namespace Equamatics
- {
- /// <summary>
- /// Represents a Complex Number.
- /// x + iy
- /// </summary>
- public struct Complex
- {
- #region Fields
- double _Real, _Imaginary;
- public const double FormattingEpsilon = 1e-10;
- #endregion
- #region Constructors
- /// <summary>
- /// Creates a Complex Number.
- /// </summary>
- /// <param name="Real">The Real Part.</param>
- /// <param name="Imaginary">The Imaginary Part.</param>
- public Complex(double Real = 0, double Imaginary = 0) { _Real = Real; _Imaginary = Imaginary; }
- /// <summary>
- /// Polar form Constructor. r(cosɵ + isinɵ).
- /// where 'r' is the Magnitude and 'ɵ' is the Phase.
- /// </summary>
- /// <param name="Modulus">The Magnitude of the Complex Vector in Argand Plane.</param>
- /// <param name="Phase">The Inclination of the Complex Vector with the Possitive direction of x-axis.</param>
- public Complex Polar(double Magnitude, double Phase)
- {
- return new Complex(Magnitude * Math.Cos(Phase), Magnitude * Math.Sin(Phase));
- }
- #endregion
- #region Formatting
- /// <summary>
- /// Reads a Complex Number from a String.
- /// </summary>
- public static Complex Parse(string Input)
- {
- Input = Input.Replace(" ", "");
- double Real = 0;
- double Imaginary = 0;
- string[] Temp = Input.Replace("-", "+-").Split("+".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
- try
- {
- foreach (string Item in Temp)
- {
- if (Item == "-i") --Imaginary;
- else if (Item == "i") ++Imaginary;
- else if (Item.Contains("i")) Imaginary += double.Parse(Item.Replace("i", ""));
- else Real += double.Parse(Item);
- }
- }
- catch { throw new FormatException(); }
- return new Complex(Real, Imaginary);
- }
- /// <summary>
- /// Returns a String Representation of the Complex Number.
- /// </summary>
- /// <returns>A String representing the Complex Number.</returns>
- public override string ToString()
- {
- //Trim Real Part
- try { if (Math.Abs(Real) < FormattingEpsilon) Real = 0; }
- catch { }
- // Trim Imaginary Part
- try { if (Math.Abs(Imaginary) < FormattingEpsilon) Imaginary = 0; }
- catch { }
- if (this == 0) return "0";
- else if (this == Iota) return "i";
- else if (this == -Iota) return "-i";
- else if (IsPurelyImaginary) return Imaginary.ToString() + "i";
- else if (IsReal) return Real.ToString();
- else if (Math.Abs(Imaginary - 1) < FormattingEpsilon) return Real.ToString() + " + i";
- else if (Math.Abs(Imaginary + 1) < FormattingEpsilon) return Real.ToString() + " - i";
- return Real.ToString() + (Imaginary > 0 ? " + " : " - ") + Math.Abs(Imaginary).ToString() + "i";
- }
- #endregion
- #region Predefined Numbers
- /// <summary>
- /// The Imaginary Unit. (i)
- /// </summary>
- public static Complex Iota { get { return new Complex(0, 1); } }
- /// <summary>
- /// Cube Root of Unity. (ω)
- /// </summary>
- public static Complex Omega { get { return new Complex((-0.5), (Math.Sqrt(3) / 2)); } }
- /// <summary>
- /// Not a Number.
- /// </summary>
- public static Complex NaN { get { return new Complex(Double.NaN, Double.NaN); } }
- #endregion
- #region Properties
- /// <summary> Real Part. </summary>
- public double Real { get { return _Real; } set { _Real = value; } }
- /// <summary> Imaginary Part. </summary>
- public double Imaginary { get { return _Imaginary; } set { _Imaginary = value; } }
- /// <summary> Magnitude of the Complex Number. </summary>
- public double Modulus
- {
- get
- {
- Complex A = new Complex(Math.Abs(Real), Math.Abs(Imaginary));
- if (A.Real < A.Imaginary) return A.Imaginary * Math.Sqrt(1 + Math.Pow(A.Real / A.Imaginary, 2));
- else if (A.Real > A.Imaginary) return A.Real * Math.Sqrt(1 + Math.Pow(A.Imaginary / A.Real, 2));
- else return A.Real * Math.Sqrt(2);
- }
- }
- public static Complex Sqrt(Complex Z)
- {
- return new Complex(Math.Sqrt((Z.Modulus + Z.Real) / 2),
- (Z.Imaginary < 0 ? -1 : 1) * Math.Sqrt((Z.Modulus - Z.Real) / 2));
- }
- /// <summary> Is a Real Number. </summary>
- public bool IsReal { get { return Imaginary == 0; } }
- /// <summary> Is Purely Imaginary. No Real Part. </summary>
- public bool IsPurelyImaginary { get { return Real == 0; } }
- /// <summary>
- /// The Inclination of the Complex Number Vector with the Possitive direction of the X-Axis.
- /// </summary>
- public double Phase
- {
- get
- {
- double Alpha = Math.Atan2(Imaginary, Real);
- if (this == 0) return Double.NaN;
- else if (IsReal) return Real > 0 ? 0 : Math.PI;
- else if (IsPurelyImaginary) return Imaginary > 0 ? Math.PI / 2 : -Math.PI / 2;
- else if (Real > 0 && Imaginary > 0) return Alpha;
- else if (Real < 0 && Imaginary > 0) return Math.PI - Alpha;
- else if (Real < 0 && Imaginary < 0) return Alpha - Math.PI;
- else if (Real > 0 && Imaginary < 0) return -Alpha;
- else return Alpha;
- }
- }
- public Complex Conjugate { get { return new Complex(Real, -Imaginary); } }
- public bool IsNaN { get { return Double.IsNaN(this.Real) || Double.IsNaN(this.Imaginary); } }
- /// <summary> Is an Imaginary Number. </summary>
- public bool IsImaginary { get { return !IsReal; } }
- #endregion
- #region Logarithmic
- /// If the non-zero complex number z is expressed in polar coordinates as z = r * e^(i*t)
- /// with r > 0 and t is between -pi and pi, then log(z) = ln(r) + i*t, where ln(r) is the
- /// usual natural logarithm of a real number.
- public static Complex Log(Complex Z)
- {
- return new Complex(Math.Log(Z.Modulus), Z.Phase);
- }
- public static Complex operator ^(Complex Z1, Complex Z2) { return Pow(Z1, Z2); }
- public static Complex Log10(Complex Z)
- {
- const double log10 = 2.3025850929940459;
- Complex temp = Log(Z);
- temp.Real /= log10;
- temp.Imaginary /= log10;
- return temp;
- }
- // Needs to be Verified.
- public static Complex Log(Complex Z, double Base)
- {
- double logBase = Math.Log(Base);
- Complex temp = Log(Z);
- temp.Real /= logBase;
- temp.Imaginary /= logBase;
- return temp;
- }
- /// exp(z) = exp(a) * (cos(b) + i*sin(b)).
- public static Complex Exp(Complex Z)
- {
- double Modulus = Math.Exp(Z.Real);
- return new Complex(Modulus * Math.Cos(Z.Imaginary), Modulus * Math.Sin(Z.Imaginary));
- }
- public static Complex Pow(Complex Z, Complex Index)
- {
- return Exp(Index * Log(Z));
- }
- #endregion
- #region Trigonometric
- #region Basic
- /// sin(z) = ( exp(i*z) - exp(-i*z) ) / (2*i).
- public static Complex Sin(Complex Z)
- {
- Complex Z1 = Exp(new Complex(-Z.Imaginary, Z.Real));
- Complex Z2 = Exp(new Complex(Z.Imaginary, -Z.Real));
- return new Complex(0.5 * (Z1.Imaginary - Z2.Imaginary), 0.5 * (Z2.Real - Z1.Real));
- }
- /// cos(z) = ( exp(i*z) + exp(-i*z) ) / 2.
- public static Complex Cos(Complex Z)
- {
- Complex Z1 = Exp(new Complex(-Z.Imaginary, Z.Real));
- Complex Z2 = Exp(new Complex(Z.Imaginary, -Z.Real));
- return new Complex(0.5 * (Z1.Real + Z2.Real), 0.5 * (Z1.Imaginary + Z2.Imaginary));
- }
- public static Complex Tan(Complex Z)
- {
- return (Sin(Z) / Cos(Z));
- }
- #endregion
- #region Inverse
- public static Complex Asin(Complex Z)
- {
- // asin(z) = -i ln (i z + sqrt (1 - z^2))
- Complex z1 = new Complex(1.0, 0.0);
- Complex zi = new Complex(0.0, -1.0);
- Complex w = zi * Log(zi * Z + Sqrt(z1 - (Z ^ 2)));
- w = -w;
- return w;
- }
- public static Complex Acos(Complex Z)
- {
- // acos(z) = -i ln (z + i sqrt (1 - z^2))
- Complex z1 = new Complex(1.0, 0.0);
- Complex zi = new Complex(0.0, -1.0);
- Complex w = zi * Log(Z + zi * Sqrt(z1 - (Z ^ 2)));
- w = -w;
- return w;
- }
- public static Complex Atan(Complex Z)
- {
- // atan(z) = -i ln ((1 + i z) / (1 - i z)) / 2
- Complex zi = new Complex(0.0, -1.0);
- Complex z1 = new Complex(1.0, 0.0);
- Complex z2 = new Complex(2.0, 0.0);
- Complex w = zi * Log((z1 + zi * Z) / (z1 - zi * Z)) / z2;
- w = -w;
- return w;
- }
- #endregion
- #region Hyperbolic
- /// cosh(z) = ( exp(z) + exp(-z) ) / 2.
- public static Complex Cosh(Complex Z)
- {
- Complex Z1 = Exp(Z);
- Complex Z2 = Exp(-Z);
- return new Complex(0.5 * (Z1.Real + Z2.Real), 0.5 * (Z1.Imaginary + Z2.Imaginary));
- }
- /// sinh(z) = ( exp(z) - exp(-z) ) / 2.
- public static Complex Sinh(Complex Z)
- {
- Complex Z1 = Exp(Z);
- Complex Z2 = Exp(-Z);
- return new Complex(0.5 * (Z1.Real - Z2.Real), 0.5 * (Z1.Imaginary - Z2.Imaginary));
- }
- public static Complex Tanh(Complex Z)
- {
- return Sinh(Z) / Cosh(Z);
- }
- #endregion
- #endregion
- #region Operator Overloading
- #region Arithmetic Operators
- public static Complex operator +(Complex Z1, Complex Z2)
- {
- return new Complex(Z1.Real + Z2.Real, Z1.Imaginary + Z2.Imaginary);
- }
- public static Complex operator -(Complex Z1, Complex Z2) { return Z1 + (-Z2); }
- public static Complex operator *(Complex Z1, Complex Z2)
- {
- double REAL = Z1.Real * Z2.Real - Z1.Imaginary * Z2.Imaginary;
- double IMAG = Z1.Real * Z2.Imaginary + Z1.Imaginary * Z2.Real;
- return new Complex(REAL, IMAG);
- }
- public static Complex operator /(Complex Z1, Complex Z2)
- {
- double r = 0;
- double d = 0;
- if (Z2 == 0) return new Complex(Double.MaxValue, Double.MaxValue);
- if ((Math.Abs(Z2.Real) < Math.Abs(Z2.Imaginary)))
- {
- r = Z2.Real / Z2.Imaginary;
- d = Z2.Imaginary + r * Z2.Real;
- return new Complex((Z1.Real * r + Z1.Imaginary) / d, (Z1.Imaginary * r - Z1.Real) / d);
- }
- r = Z2.Imaginary / Z2.Real;
- d = Z2.Real + r * Z2.Imaginary;
- return new Complex((Z1.Real + Z1.Imaginary * r) / d, (Z1.Imaginary - Z1.Real * r) / d);
- }
- public static Complex operator -(Complex Z) { return new Complex(-Z.Real, -Z.Imaginary); }
- #endregion
- #region Logical Operators
- public static bool operator ==(Complex Z1, Complex Z2) { return ((Z1.Real == Z2.Real) && (Z1.Imaginary == Z2.Imaginary)); }
- public static bool operator !=(Complex Z1, Complex Z2) { return !(Z1 == Z2); }
- #endregion
- #endregion
- public static implicit operator Complex(double Z) { return new Complex(Z); }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement