/// /// This file is part of ILNumerics Community Edition. /// /// ILNumerics Community Edition - high performance computing for applications. /// Copyright (C) 2006 - 2012 Haymo Kutschbach, http://ilnumerics.net /// /// ILNumerics Community Edition is free software: you can redistribute it and/or modify /// it under the terms of the GNU General Public License version 3 as published by /// the Free Software Foundation. /// /// ILNumerics Community Edition is distributed in the hope that it will be useful, /// but WITHOUT ANY WARRANTY; without even the implied warranty of /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /// GNU General Public License for more details. /// /// You should have received a copy of the GNU General Public License /// along with ILNumerics Community Edition. See the file License.txt in the root /// of your distribution package. If not, see . /// /// In addition this software uses the following components and/or licenses: /// /// ================================================================================= /// The Open Toolkit Library License /// /// Copyright (c) 2006 - 2009 the Open Toolkit library. /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal /// in the Software without restriction, including without limitation the rights to /// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of /// the Software, and to permit persons to whom the Software is furnished to do /// so, subject to the following conditions: /// /// The above copyright notice and this permission notice shall be included in all /// copies or substantial portions of the Software. /// /// ================================================================================= /// #pragma warning disable 162 using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace ILNumerics { /// /// Floating point complex value data type of float (single) precision /// /// This class extends the system value types for real numbers to complex float /// values. Besides the publicly available members 'real' and 'imag' it provides all the /// basis functionality the floating point System.double brings (abs, log, sqrt, tan etc.) for /// float precision complex, /// as well as it overrides the basic unary and binary operators for all common system value /// types including rarely used types (e.g. UInt16). This includes the basic numerical operations /// like '+','-','/','*' and the relational operators: '==','>','>=' etc. Also there are some /// explicit and some implicit casting operators from / to fcomplex values into system /// value types. [Serializable] [StructLayout(LayoutKind.Sequential)] public struct fcomplex : IEquatable { /// /// Real part of this complex number /// public float real; /// /// Imaginary part of this complex number /// public float imag; /// /// Imaginary unit /// public static readonly fcomplex i = new fcomplex(0.0f,1.0f); /// /// Construct new float complex number /// /// Real part /// Imaginary part public fcomplex(float real, float imag) { this.real = real; this.imag = imag; } /// /// Complex conjugate /// public fcomplex conj { get{ return new fcomplex(real,imag * (-1.0f)); } } /// /// Positive infinity for real and imag part of complex value /// public static fcomplex INF { get { return new fcomplex( float.PositiveInfinity, float.PositiveInfinity ); } } /// /// New fcomplex, real and imaginary parts are zero /// public static fcomplex Zero { get { return new fcomplex(0f,0f); } } /// /// fcomplex quantity, marked as being "not a number" /// public static fcomplex NaN { get { return new fcomplex(float.NaN,float.NaN); } } /// /// Are obj's real and imaginary part identical to the real and imaginary parts of this fcomplex /// /// fcomplex object to determine the equality for /// true if obj is of fcomplex type and its real and imag part has the same /// values as the real and imaginary part of this array. public override bool Equals(object obj) { if (obj is fcomplex && ((fcomplex)obj) == this) return true; return false; } /// /// Check if a fcomplex number equals this fcomplex number /// /// other complex number /// true if both, real and imaginary parts of both complex number are (binary) equal, false otherwise public bool Equals(fcomplex other) { return real.Equals(other.real) && imag.Equals(other.imag); } /// /// Give HashCode of this fcomplex number /// /// HashCode of this fcomplex number public override int GetHashCode() { return 31 * real.GetHashCode() + imag.GetHashCode(); } #region HYCALPER AUTO GENERATED CODE /// /// Add two complex numbers /// /// First summand /// Second summand /// result public static complex operator +( fcomplex A, complex B) { complex ret; ret.real = (double) (A.real + B.real ); ret.imag = (double) (A.imag + B.imag ); return ret; } /// /// Subtract two complex values /// /// Minuend /// Subtrahend /// result public static complex operator -( fcomplex A, complex B) { complex ret; ret.real = (double) (A.real - B.real ); ret.imag = (double) (A.imag - B.imag ); return ret; } /// /// Multiply two complex values /// /// First factor /// Second factor /// result public static complex operator *( fcomplex A, complex B) { complex ret; ret.real = (double) ((A.real * B.real ) - (A.imag * B.imag )); ret.imag = (double) ((A.real * B.imag ) + (A.imag * B.real )); return ret; } /// /// Divide two numbers /// /// Divident /// Divisor /// Result /// Unless the operator must handle special inputs (Inf or 0 values), /// the algorithm described in [1] is used for division. This is considered to be /// more robust against floating point overflow than the naive approach of simple /// cartesian division. /// References: [1]: Smith, R.L., Algorithm 116: Complex division. Commun.ACM 5,8 (1962),435
/// [2]: Stewart, G.W., A note on complex division, ACM trans.on math software, Vol.11, N.3 (1985)
public static complex operator /( fcomplex A, complex B) { if (B.imag == 0) return A / B.real; return A * (1 / B); if (IsNaN(A) || complex .IsNaN(B)) return NaN; //if ( complex .IsInfinity(B)) return NaN; //if (A.real == 0 && A.imag == 0) return ( complex )0; complex ret; if (B.real == 0) { ret.imag = (double) -(A.real / B.imag); ret.real = (double) (A.imag / B.imag); return ret; } // this would be the naive approach. But it come with to little robustness against overflow //double norm2 = B.real * B.real + B.imag * B.imag; //if (norm2 == 0) return INF; // this may be removed, since division by 0 results in inf anyway ? //ret.real = (double) (((A.real * B.real ) + (A.imag * B.imag )) / norm2); //ret.imag = (double) (((A.imag * B.real ) - (A.real * B.imag )) / norm2); // this algorithm is taken from [1]. The one described in [2] was not taken. Tests // did not show any advantage when using double precision floating point arithmetic. double tmp1, tmp2; if (Math.Abs(B.real) >= Math.Abs(B.imag)) { tmp1 = (double) (B.imag * (1/B.real)); tmp2 = (double) (B.real + B.imag*tmp1); ret.real = (double) (A.real + A.imag*tmp1)/tmp2; ret.imag = (double) (A.imag - A.real*tmp1)/tmp2; } else { tmp1 = (double) (B.real * (1/B.imag)); tmp2 = (double) (B.imag + B.real*tmp1); ret.real = (double) (A.imag + A.real*tmp1)/tmp2; ret.imag = - (double) (A.real - A.imag*tmp1)/tmp2; } return ret; } /// /// Equality comparison for complex numbers /// /// Left side /// Right side /// true, if real and imaginary part are identical public static bool operator ==( fcomplex A, complex B) { return (A.imag == B.imag ) && (A.real == B.real ); } /// /// Unequality comparison for complex numbers /// /// Left side /// Right side /// true if real and imaginary parts of A and B are not equal, false otherwise public static bool operator !=( fcomplex A, complex B) { return (A.imag != B.imag ) || (A.real != B.real ); } /// /// Greater than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator > ( fcomplex A, complex B) { return (A.real > B.real ); } /// /// Lower than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator < ( fcomplex A, complex B) { return (A.real < B.real ); } /// /// Greater than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator >=( fcomplex A, complex B) { return (A.real >= B.real ); } /// /// Lower than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator <=( fcomplex A, complex B) { return (A.real <= B.real ); } /// /// Add two complex numbers /// /// First summand /// Second summand /// result public static fcomplex operator +( fcomplex A, fcomplex B) { fcomplex ret; ret.real = (float) (A.real + B.real ); ret.imag = (float) (A.imag + B.imag ); return ret; } /// /// Subtract two complex values /// /// Minuend /// Subtrahend /// result public static fcomplex operator -( fcomplex A, fcomplex B) { fcomplex ret; ret.real = (float) (A.real - B.real ); ret.imag = (float) (A.imag - B.imag ); return ret; } /// /// Multiply two complex values /// /// First factor /// Second factor /// result public static fcomplex operator *( fcomplex A, fcomplex B) { fcomplex ret; ret.real = (float) ((A.real * B.real ) - (A.imag * B.imag )); ret.imag = (float) ((A.real * B.imag ) + (A.imag * B.real )); return ret; } /// /// Divide two numbers /// /// Divident /// Divisor /// Result /// Unless the operator must handle special inputs (Inf or 0 values), /// the algorithm described in [1] is used for division. This is considered to be /// more robust against floating point overflow than the naive approach of simple /// cartesian division. /// References: [1]: Smith, R.L., Algorithm 116: Complex division. Commun.ACM 5,8 (1962),435
/// [2]: Stewart, G.W., A note on complex division, ACM trans.on math software, Vol.11, N.3 (1985)
public static fcomplex operator /( fcomplex A, fcomplex B) { if (B.imag == 0) return A / B.real; return A * (1 / B); if (IsNaN(A) || fcomplex .IsNaN(B)) return NaN; //if ( fcomplex .IsInfinity(B)) return NaN; //if (A.real == 0 && A.imag == 0) return ( fcomplex )0; fcomplex ret; if (B.real == 0) { ret.imag = (float) -(A.real / B.imag); ret.real = (float) (A.imag / B.imag); return ret; } // this would be the naive approach. But it come with to little robustness against overflow //double norm2 = B.real * B.real + B.imag * B.imag; //if (norm2 == 0) return INF; // this may be removed, since division by 0 results in inf anyway ? //ret.real = (float) (((A.real * B.real ) + (A.imag * B.imag )) / norm2); //ret.imag = (float) (((A.imag * B.real ) - (A.real * B.imag )) / norm2); // this algorithm is taken from [1]. The one described in [2] was not taken. Tests // did not show any advantage when using double precision floating point arithmetic. float tmp1, tmp2; if (Math.Abs(B.real) >= Math.Abs(B.imag)) { tmp1 = (float) (B.imag * (1/B.real)); tmp2 = (float) (B.real + B.imag*tmp1); ret.real = (float) (A.real + A.imag*tmp1)/tmp2; ret.imag = (float) (A.imag - A.real*tmp1)/tmp2; } else { tmp1 = (float) (B.real * (1/B.imag)); tmp2 = (float) (B.imag + B.real*tmp1); ret.real = (float) (A.imag + A.real*tmp1)/tmp2; ret.imag = - (float) (A.real - A.imag*tmp1)/tmp2; } return ret; } /// /// Equality comparison for complex numbers /// /// Left side /// Right side /// true, if real and imaginary part are identical public static bool operator ==( fcomplex A, fcomplex B) { return (A.imag == B.imag ) && (A.real == B.real ); } /// /// Unequality comparison for complex numbers /// /// Left side /// Right side /// true if real and imaginary parts of A and B are not equal, false otherwise public static bool operator !=( fcomplex A, fcomplex B) { return (A.imag != B.imag ) || (A.real != B.real ); } /// /// Greater than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator > ( fcomplex A, fcomplex B) { return (A.real > B.real ); } /// /// Lower than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator < ( fcomplex A, fcomplex B) { return (A.real < B.real ); } /// /// Greater than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator >=( fcomplex A, fcomplex B) { return (A.real >= B.real ); } /// /// Lower than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator <=( fcomplex A, fcomplex B) { return (A.real <= B.real ); } #endregion HYCALPER AUTO GENERATED CODE #region HYCALPER AUTO GENERATED CODE /// /// Add two complex numbers /// /// First summand /// Second summand /// Result public static fcomplex operator +( fcomplex A, Int64 B) { fcomplex ret; ret.real = (float) (A.real + B); ret.imag = (float) A.imag; return ret; } /// /// Subtract two values /// /// Minuend /// Subtrahend /// result public static fcomplex operator -( fcomplex A, Int64 B) { fcomplex ret; ret.real = (float) (A.real - B); ret.imag = (float) A.imag; return ret; } /// /// Multiply two values /// /// First factor /// Second factor /// result public static fcomplex operator *( fcomplex A, Int64 B) { fcomplex ret; ret.real = (float) (A.real * B); ret.imag = (float) (A.imag * B); return ret; } /// /// Divide two numbers /// /// Divident /// Divisor /// result public static fcomplex operator /( fcomplex A, Int64 B) { if (IsNaN(A)) return NaN; if (A.real == 0 && A.imag == 0) { if (B == 0) return NaN; return ( fcomplex )0; } else { if (false) { if (IsInfinity(A)) { return NaN; } else { return ( fcomplex )0; } } } fcomplex ret; if (B == 0) return INF ; ret.real = (float) (A.real / B); ret.imag = (float) (A.imag / B); return ret; } /// /// Equality comparison for complex numbers /// /// Left side /// Right side /// result /// Real inputs are converted to a complex number and the result is compared to the complex input. public static bool operator ==( fcomplex A, Int64 B) { return (A.real == B && A.imag == 0.0); } /// /// Unequality comparison for complex numbers /// /// Left side /// Right side /// true if real and imaginary parts of A and B are not equal, false otherwise /// Real inputs are converted to a complex number and the result is compared to the complex input. public static bool operator !=( fcomplex A, Int64 B) { return (A.imag != 0.0) || (A.real != B); } /// /// Freater than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator > ( fcomplex A, Int64 B) { return (A.real > B); } /// /// Lower than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator <( fcomplex A, Int64 B) { return (A.real < B); } /// /// Greater than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator >=( fcomplex A, Int64 B) { return (A.real >= B); } /// /// Lower than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator <=( fcomplex A, Int64 B) { return (A.real <= B); } /// /// Add two complex numbers /// /// First summand /// Second summand /// Result public static fcomplex operator +( fcomplex A, Int32 B) { fcomplex ret; ret.real = (float) (A.real + B); ret.imag = (float) A.imag; return ret; } /// /// Subtract two values /// /// Minuend /// Subtrahend /// result public static fcomplex operator -( fcomplex A, Int32 B) { fcomplex ret; ret.real = (float) (A.real - B); ret.imag = (float) A.imag; return ret; } /// /// Multiply two values /// /// First factor /// Second factor /// result public static fcomplex operator *( fcomplex A, Int32 B) { fcomplex ret; ret.real = (float) (A.real * B); ret.imag = (float) (A.imag * B); return ret; } /// /// Divide two numbers /// /// Divident /// Divisor /// result public static fcomplex operator /( fcomplex A, Int32 B) { if (IsNaN(A)) return NaN; if (A.real == 0 && A.imag == 0) { if (B == 0) return NaN; return ( fcomplex )0; } else { if (false) { if (IsInfinity(A)) { return NaN; } else { return ( fcomplex )0; } } } fcomplex ret; if (B == 0) return INF ; ret.real = (float) (A.real / B); ret.imag = (float) (A.imag / B); return ret; } /// /// Equality comparison for complex numbers /// /// Left side /// Right side /// result /// Real inputs are converted to a complex number and the result is compared to the complex input. public static bool operator ==( fcomplex A, Int32 B) { return (A.real == B && A.imag == 0.0); } /// /// Unequality comparison for complex numbers /// /// Left side /// Right side /// true if real and imaginary parts of A and B are not equal, false otherwise /// Real inputs are converted to a complex number and the result is compared to the complex input. public static bool operator !=( fcomplex A, Int32 B) { return (A.imag != 0.0) || (A.real != B); } /// /// Freater than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator > ( fcomplex A, Int32 B) { return (A.real > B); } /// /// Lower than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator <( fcomplex A, Int32 B) { return (A.real < B); } /// /// Greater than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator >=( fcomplex A, Int32 B) { return (A.real >= B); } /// /// Lower than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator <=( fcomplex A, Int32 B) { return (A.real <= B); } /// /// Add two complex numbers /// /// First summand /// Second summand /// Result public static fcomplex operator +( fcomplex A, float B) { fcomplex ret; ret.real = (float) (A.real + B); ret.imag = (float) A.imag; return ret; } /// /// Subtract two values /// /// Minuend /// Subtrahend /// result public static fcomplex operator -( fcomplex A, float B) { fcomplex ret; ret.real = (float) (A.real - B); ret.imag = (float) A.imag; return ret; } /// /// Multiply two values /// /// First factor /// Second factor /// result public static fcomplex operator *( fcomplex A, float B) { fcomplex ret; ret.real = (float) (A.real * B); ret.imag = (float) (A.imag * B); return ret; } /// /// Divide two numbers /// /// Divident /// Divisor /// result public static fcomplex operator /( fcomplex A, float B) { if (IsNaN(A)) return NaN; if (float.IsNaN(B)) return NaN; if (A.real == 0 && A.imag == 0) { if (B == 0) return NaN; return ( fcomplex )0; } else { if (float.IsInfinity(B)) { if (IsInfinity(A)) { return NaN; } else { return ( fcomplex )0; } } } fcomplex ret; if (B == 0) return INF ; ret.real = (float) (A.real / B); ret.imag = (float) (A.imag / B); return ret; } /// /// Equality comparison for complex numbers /// /// Left side /// Right side /// result /// Real inputs are converted to a complex number and the result is compared to the complex input. public static bool operator ==( fcomplex A, float B) { return (A.real == B && A.imag == 0.0); } /// /// Unequality comparison for complex numbers /// /// Left side /// Right side /// true if real and imaginary parts of A and B are not equal, false otherwise /// Real inputs are converted to a complex number and the result is compared to the complex input. public static bool operator !=( fcomplex A, float B) { return (A.imag != 0.0) || (A.real != B); } /// /// Freater than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator > ( fcomplex A, float B) { return (A.real > B); } /// /// Lower than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator <( fcomplex A, float B) { return (A.real < B); } /// /// Greater than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator >=( fcomplex A, float B) { return (A.real >= B); } /// /// Lower than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator <=( fcomplex A, float B) { return (A.real <= B); } /// /// Add two complex numbers /// /// First summand /// Second summand /// Result public static fcomplex operator +( fcomplex A, byte B) { fcomplex ret; ret.real = (float) (A.real + B); ret.imag = (float) A.imag; return ret; } /// /// Subtract two values /// /// Minuend /// Subtrahend /// result public static fcomplex operator -( fcomplex A, byte B) { fcomplex ret; ret.real = (float) (A.real - B); ret.imag = (float) A.imag; return ret; } /// /// Multiply two values /// /// First factor /// Second factor /// result public static fcomplex operator *( fcomplex A, byte B) { fcomplex ret; ret.real = (float) (A.real * B); ret.imag = (float) (A.imag * B); return ret; } /// /// Divide two numbers /// /// Divident /// Divisor /// result public static fcomplex operator /( fcomplex A, byte B) { if (IsNaN(A)) return NaN; if (A.real == 0 && A.imag == 0) { if (B == 0) return NaN; return ( fcomplex )0; } else { if (false) { if (IsInfinity(A)) { return NaN; } else { return ( fcomplex )0; } } } fcomplex ret; if (B == 0) return INF ; ret.real = (float) (A.real / B); ret.imag = (float) (A.imag / B); return ret; } /// /// Equality comparison for complex numbers /// /// Left side /// Right side /// result /// Real inputs are converted to a complex number and the result is compared to the complex input. public static bool operator ==( fcomplex A, byte B) { return (A.real == B && A.imag == 0.0); } /// /// Unequality comparison for complex numbers /// /// Left side /// Right side /// true if real and imaginary parts of A and B are not equal, false otherwise /// Real inputs are converted to a complex number and the result is compared to the complex input. public static bool operator !=( fcomplex A, byte B) { return (A.imag != 0.0) || (A.real != B); } /// /// Freater than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator > ( fcomplex A, byte B) { return (A.real > B); } /// /// Lower than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator <( fcomplex A, byte B) { return (A.real < B); } /// /// Greater than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator >=( fcomplex A, byte B) { return (A.real >= B); } /// /// Lower than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator <=( fcomplex A, byte B) { return (A.real <= B); } /// /// Add two complex numbers /// /// First summand /// Second summand /// Result public static fcomplex operator +( fcomplex A, double B) { fcomplex ret; ret.real = (float) (A.real + B); ret.imag = (float) A.imag; return ret; } /// /// Subtract two values /// /// Minuend /// Subtrahend /// result public static fcomplex operator -( fcomplex A, double B) { fcomplex ret; ret.real = (float) (A.real - B); ret.imag = (float) A.imag; return ret; } /// /// Multiply two values /// /// First factor /// Second factor /// result public static fcomplex operator *( fcomplex A, double B) { fcomplex ret; ret.real = (float) (A.real * B); ret.imag = (float) (A.imag * B); return ret; } /// /// Divide two numbers /// /// Divident /// Divisor /// result public static fcomplex operator /( fcomplex A, double B) { if (IsNaN(A)) return NaN; if (double.IsNaN(B)) return NaN; if (A.real == 0 && A.imag == 0) { if (B == 0) return NaN; return ( fcomplex )0; } else { if (double.IsInfinity(B)) { if (IsInfinity(A)) { return NaN; } else { return ( fcomplex )0; } } } fcomplex ret; if (B == 0) return INF ; ret.real = (float) (A.real / B); ret.imag = (float) (A.imag / B); return ret; } /// /// Equality comparison for complex numbers /// /// Left side /// Right side /// result /// Real inputs are converted to a complex number and the result is compared to the complex input. public static bool operator ==( fcomplex A, double B) { return (A.real == B && A.imag == 0.0); } /// /// Unequality comparison for complex numbers /// /// Left side /// Right side /// true if real and imaginary parts of A and B are not equal, false otherwise /// Real inputs are converted to a complex number and the result is compared to the complex input. public static bool operator !=( fcomplex A, double B) { return (A.imag != 0.0) || (A.real != B); } /// /// Freater than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator > ( fcomplex A, double B) { return (A.real > B); } /// /// Lower than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator <( fcomplex A, double B) { return (A.real < B); } /// /// Greater than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator >=( fcomplex A, double B) { return (A.real >= B); } /// /// Lower than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator <=( fcomplex A, double B) { return (A.real <= B); } #endregion HYCALPER AUTO GENERATED CODE #region HYCALPER AUTO GENERATED CODE /// /// Add two complex values /// /// First summand /// Second summand /// Result public static fcomplex operator +( Int64 A, fcomplex B) { fcomplex ret; ret.real = (float) (A + B.real); ret.imag = (float) B.imag; return ret; } /// /// Subtract two values /// /// Minuend /// Subtrahend /// Result public static fcomplex operator -( Int64 A, fcomplex B) { fcomplex ret; ret.real = (float) (A - B.real); ret.imag = - (float) B.imag; return ret; } /// /// Multiply two values /// /// First factor /// Second factor /// Result public static fcomplex operator *( Int64 A, fcomplex B) { fcomplex ret; ret.real = (float) (A * B.real); ret.imag = (float) (A * B.imag); return ret; } /// /// Divide two values /// /// Divident /// Divisor /// Result public static fcomplex operator /( Int64 A, fcomplex B) { fcomplex ret; if (A == 0) { if (IsInfinity(B)) return NaN; } else { if (IsInfinity(B)) return ( fcomplex )0; } if (B.real == 0 && B.imag == 0) { return INF; } // this algorithm is taken from [1]. The one described in [2] was not taken. Tests // did not show any advantage when using double precision floating point arithmetic. double tmp; if (Math.Abs(B.real) >= Math.Abs(B.imag)) { tmp = (float) (B.imag * (1/B.real)); ret.imag = (float) (B.real + B.imag*tmp); ret.real = (float) A/ret.imag; ret.imag = - (float) (A*tmp)/ret.imag; } else { tmp = (float) (B.real * (1/B.imag)); ret.imag = (float) (B.imag + B.real*tmp); ret.real = (float) (A*tmp)/ret.imag; ret.imag = - (float) A/ret.imag; } return ret; } /// /// Equality comparison for complex numbers /// /// Left side /// Right side /// Result /// Real inputs are converted to a complex number and the result is compared to the complex input. public static bool operator ==( Int64 A, fcomplex B) { return (B.real == A && B.imag == 0.0); } /// /// Unequality comparison for complex numbers /// /// Left side /// Right side /// true if real and imaginary parts of A and B are not equal, false otherwise /// Real inputs are converted to a complex number and the result is compared to the complex input. public static bool operator !=( Int64 A, fcomplex B) { return (B.imag != 0.0) || (B.real != A); } /// /// Greater than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator > ( Int64 A, fcomplex B) { return (A > B.real); } /// /// Lower than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator < ( Int64 A, fcomplex B) { return (A < B.real); } /// /// Greater than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator >=( Int64 A, fcomplex B) { return (A >= B.real); } /// /// Lower than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator <=( Int64 A, fcomplex B) { return (A <= B.real); } /// /// Add two complex values /// /// First summand /// Second summand /// Result public static fcomplex operator +( Int32 A, fcomplex B) { fcomplex ret; ret.real = (float) (A + B.real); ret.imag = (float) B.imag; return ret; } /// /// Subtract two values /// /// Minuend /// Subtrahend /// Result public static fcomplex operator -( Int32 A, fcomplex B) { fcomplex ret; ret.real = (float) (A - B.real); ret.imag = - (float) B.imag; return ret; } /// /// Multiply two values /// /// First factor /// Second factor /// Result public static fcomplex operator *( Int32 A, fcomplex B) { fcomplex ret; ret.real = (float) (A * B.real); ret.imag = (float) (A * B.imag); return ret; } /// /// Divide two values /// /// Divident /// Divisor /// Result public static fcomplex operator /( Int32 A, fcomplex B) { fcomplex ret; if (A == 0) { if (IsInfinity(B)) return NaN; } else { if (IsInfinity(B)) return ( fcomplex )0; } if (B.real == 0 && B.imag == 0) { return INF; } // this algorithm is taken from [1]. The one described in [2] was not taken. Tests // did not show any advantage when using double precision floating point arithmetic. double tmp; if (Math.Abs(B.real) >= Math.Abs(B.imag)) { tmp = (float) (B.imag * (1/B.real)); ret.imag = (float) (B.real + B.imag*tmp); ret.real = (float) A/ret.imag; ret.imag = - (float) (A*tmp)/ret.imag; } else { tmp = (float) (B.real * (1/B.imag)); ret.imag = (float) (B.imag + B.real*tmp); ret.real = (float) (A*tmp)/ret.imag; ret.imag = - (float) A/ret.imag; } return ret; } /// /// Equality comparison for complex numbers /// /// Left side /// Right side /// Result /// Real inputs are converted to a complex number and the result is compared to the complex input. public static bool operator ==( Int32 A, fcomplex B) { return (B.real == A && B.imag == 0.0); } /// /// Unequality comparison for complex numbers /// /// Left side /// Right side /// true if real and imaginary parts of A and B are not equal, false otherwise /// Real inputs are converted to a complex number and the result is compared to the complex input. public static bool operator !=( Int32 A, fcomplex B) { return (B.imag != 0.0) || (B.real != A); } /// /// Greater than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator > ( Int32 A, fcomplex B) { return (A > B.real); } /// /// Lower than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator < ( Int32 A, fcomplex B) { return (A < B.real); } /// /// Greater than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator >=( Int32 A, fcomplex B) { return (A >= B.real); } /// /// Lower than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator <=( Int32 A, fcomplex B) { return (A <= B.real); } /// /// Add two complex values /// /// First summand /// Second summand /// Result public static fcomplex operator +( float A, fcomplex B) { fcomplex ret; ret.real = (float) (A + B.real); ret.imag = (float) B.imag; return ret; } /// /// Subtract two values /// /// Minuend /// Subtrahend /// Result public static fcomplex operator -( float A, fcomplex B) { fcomplex ret; ret.real = (float) (A - B.real); ret.imag = - (float) B.imag; return ret; } /// /// Multiply two values /// /// First factor /// Second factor /// Result public static fcomplex operator *( float A, fcomplex B) { fcomplex ret; ret.real = (float) (A * B.real); ret.imag = (float) (A * B.imag); return ret; } /// /// Divide two values /// /// Divident /// Divisor /// Result public static fcomplex operator /( float A, fcomplex B) { fcomplex ret; if (A == 0) { if (IsInfinity(B)) return NaN; } else { if (IsInfinity(B)) return ( fcomplex )0; } if (B.real == 0 && B.imag == 0) { return INF; } // this algorithm is taken from [1]. The one described in [2] was not taken. Tests // did not show any advantage when using double precision floating point arithmetic. double tmp; if (Math.Abs(B.real) >= Math.Abs(B.imag)) { tmp = (float) (B.imag * (1/B.real)); ret.imag = (float) (B.real + B.imag*tmp); ret.real = (float) A/ret.imag; ret.imag = - (float) (A*tmp)/ret.imag; } else { tmp = (float) (B.real * (1/B.imag)); ret.imag = (float) (B.imag + B.real*tmp); ret.real = (float) (A*tmp)/ret.imag; ret.imag = - (float) A/ret.imag; } return ret; } /// /// Equality comparison for complex numbers /// /// Left side /// Right side /// Result /// Real inputs are converted to a complex number and the result is compared to the complex input. public static bool operator ==( float A, fcomplex B) { return (B.real == A && B.imag == 0.0); } /// /// Unequality comparison for complex numbers /// /// Left side /// Right side /// true if real and imaginary parts of A and B are not equal, false otherwise /// Real inputs are converted to a complex number and the result is compared to the complex input. public static bool operator !=( float A, fcomplex B) { return (B.imag != 0.0) || (B.real != A); } /// /// Greater than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator > ( float A, fcomplex B) { return (A > B.real); } /// /// Lower than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator < ( float A, fcomplex B) { return (A < B.real); } /// /// Greater than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator >=( float A, fcomplex B) { return (A >= B.real); } /// /// Lower than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator <=( float A, fcomplex B) { return (A <= B.real); } /// /// Add two complex values /// /// First summand /// Second summand /// Result public static fcomplex operator +( byte A, fcomplex B) { fcomplex ret; ret.real = (float) (A + B.real); ret.imag = (float) B.imag; return ret; } /// /// Subtract two values /// /// Minuend /// Subtrahend /// Result public static fcomplex operator -( byte A, fcomplex B) { fcomplex ret; ret.real = (float) (A - B.real); ret.imag = - (float) B.imag; return ret; } /// /// Multiply two values /// /// First factor /// Second factor /// Result public static fcomplex operator *( byte A, fcomplex B) { fcomplex ret; ret.real = (float) (A * B.real); ret.imag = (float) (A * B.imag); return ret; } /// /// Divide two values /// /// Divident /// Divisor /// Result public static fcomplex operator /( byte A, fcomplex B) { fcomplex ret; if (A == 0) { if (IsInfinity(B)) return NaN; } else { if (IsInfinity(B)) return ( fcomplex )0; } if (B.real == 0 && B.imag == 0) { return INF; } // this algorithm is taken from [1]. The one described in [2] was not taken. Tests // did not show any advantage when using double precision floating point arithmetic. double tmp; if (Math.Abs(B.real) >= Math.Abs(B.imag)) { tmp = (float) (B.imag * (1/B.real)); ret.imag = (float) (B.real + B.imag*tmp); ret.real = (float) A/ret.imag; ret.imag = - (float) (A*tmp)/ret.imag; } else { tmp = (float) (B.real * (1/B.imag)); ret.imag = (float) (B.imag + B.real*tmp); ret.real = (float) (A*tmp)/ret.imag; ret.imag = - (float) A/ret.imag; } return ret; } /// /// Equality comparison for complex numbers /// /// Left side /// Right side /// Result /// Real inputs are converted to a complex number and the result is compared to the complex input. public static bool operator ==( byte A, fcomplex B) { return (B.real == A && B.imag == 0.0); } /// /// Unequality comparison for complex numbers /// /// Left side /// Right side /// true if real and imaginary parts of A and B are not equal, false otherwise /// Real inputs are converted to a complex number and the result is compared to the complex input. public static bool operator !=( byte A, fcomplex B) { return (B.imag != 0.0) || (B.real != A); } /// /// Greater than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator > ( byte A, fcomplex B) { return (A > B.real); } /// /// Lower than comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator < ( byte A, fcomplex B) { return (A < B.real); } /// /// Greater than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is greater than real part of B, false otherwise /// Only the real parts are compared! public static bool operator >=( byte A, fcomplex B) { return (A >= B.real); } /// /// Lower than or equal to comparison for complex numbers /// /// Left side /// Right side /// true if real part of A is lower then real part of B, false otherwise /// Only the real parts are compared! public static bool operator <=( byte A, fcomplex B) { return (A <= B.real); } #endregion HYCALPER AUTO GENERATED CODE #region unary minus /// /// Unary minus operator /// /// fcomplex input /// fcomplex number similar to in1, having real and imag part negated public static fcomplex operator -( fcomplex in1) { fcomplex ret = new fcomplex(); ret.imag = -in1.imag; ret.real = -in1.real; return ret; } #endregion /// /// Magnitude value of float complex number /// /// fcomplex number /// Magnitude of input public static float Abs(fcomplex input) { return (float) Math.Sqrt ( input.real * input.real + input.imag * input.imag ); } /// /// Angle of complex number /// /// fcomplex number to compute angle of /// Angle of input public static double Angle(fcomplex input) { return (float) Math.Atan2 ( input.imag, input.real ); } /// /// Arcus cosinus for float complex number /// /// fcomplex input /// Arcus cosinus of input /// The arcus cosinus of a complex number is computed by /// Log(Sqrt(input^2 - 1) + input) * i public static fcomplex Acos(fcomplex input) { fcomplex ret = new fcomplex ( 0, -1 ); return fcomplex.Log ( fcomplex.Sqrt ( input * input - 1 ) + input ) * ret; } /// /// Arcus cosinus of real number /// /// float input /// Arcus cosinus of input /// For input > 1.0, will be used. public static fcomplex Acos(float input) { if (Math.Abs(input) <= 1.0) return new fcomplex((float)Math.Acos(input), 0.0f); else { return Acos((fcomplex)input); } } /// /// Arcus sinus of real number /// /// float input /// Arcus sinus of input /// For input > 1.0, will be used. public static fcomplex Asin(float input) { if (Math.Abs(input) <= 1.0) return new fcomplex((float)Math.Asin(input), 0.0f); else { return Asin((fcomplex)input); } } /// /// Arcus sinus for complex number /// /// fcomplex input /// Arcus sinus of input public static fcomplex Asin(fcomplex input) { fcomplex ret = Acos ( input ); ret.real = (float) (Math.PI / 2 - ret.real); return ret; } /// /// Power of base e for float complex number /// /// fcomplex input /// Result of Exp(input) public static fcomplex Exp(fcomplex input) { return fcomplex.FromPol ( (float) Math.Exp ( input.real ), input.imag ); } /// /// fcomplex power real exponent /// /// Basis /// Exponent /// New fcomplex number with result public static fcomplex Pow(fcomplex input, double exponent) { fcomplex ret = input.Log (); ret.imag *= (float) exponent; ret.real *= (float) exponent; return ret.Exp (); } /// /// Complex power - real basis, real exponent /// /// Basis /// Exponent /// fcomplex number. /// The result will be a fcomplex number. For negative basis /// the basis will be converted to a fcomplex number and the power /// will be computed in the fcomplex plane. public static fcomplex Pow(double basis, double exponent) { if (basis < 0) { return Pow((fcomplex)basis, exponent); } else { return (fcomplex)Math.Pow(basis, exponent); } } /// /// Power: complex base, complex exponent /// /// Basis /// Exponent /// result of basis^exponent public static fcomplex Pow(fcomplex basis, fcomplex exponent) { fcomplex ret = ( basis.Log () * exponent ); return ret.Exp (); } /// /// Square root of real input /// /// float input /// Square root of input public static fcomplex Sqrt(float input) { if (input > 0) return new fcomplex((float)Math.Sqrt(input), 0.0f); else return Sqrt((fcomplex)input); } /// /// Square root of complex number /// /// fcomplex input /// Square root of input public static fcomplex Sqrt(fcomplex input) { // Reference : numerical recipes in C: Appendix C fcomplex ret = new fcomplex (); double x, y, w, r; if (input.real == 0.0 && input.imag == 0.0) return ret; else { x = (float) Math.Abs ( input.real ); y = (float) Math.Abs ( input.imag ); if (x >= y) { r = y / x; w = Math.Sqrt ( x ) * Math.Sqrt ( 0.5 * ( 1.0 + Math.Sqrt ( 1.0 + r * r ) ) ); } else { r = x / y; w = Math.Sqrt ( y ) * Math.Sqrt ( 0.5 * ( r + Math.Sqrt ( 1.0 + r * r ) ) ); } if (input.real >= 0.0) { ret.real = (float) w; ret.imag = (float) (input.imag / ( 2.0 * w )); } else { ret.imag = (float) (( input.imag >= 0 ) ? w : -w); ret.real = (float) (input.imag / ( 2.0 * ret.imag )); } return ret; } } /// /// Tangens of float complex number /// /// fcomplex input /// Tangens of input public static fcomplex Tan(fcomplex input) { fcomplex ci = Cos(input); if (ci.real == (float)0.0 && ci.imag == (float)0.0) return INF; return (Sin(input) / ci); } /// /// Tangens hyperbolicus of float complex input /// /// fcomplex input /// Tangens hyperbolicus public static fcomplex Tanh(fcomplex input) { fcomplex si = Sin(input); if (si.real == (float)0.0 && si.imag == (float)0.0) return INF; return (Cos(input) / si); } /// /// Logarithm of complex input /// /// fcomplex input /// Logarithm of input public static fcomplex Log(fcomplex input) { fcomplex ret = new fcomplex (); ret.real = (float) Math.Log ( Math.Sqrt ( input.real * input.real + input.imag * input.imag ) ); ret.imag = (float) Math.Atan2 ( input.imag, input.real ); return ret; } /// /// Logarithm to base 10 /// /// fcomplex input /// Logarithm of input public static fcomplex Log10(fcomplex input) { return Log(input) / 2.30258509299405f; } /// /// Logarithm of base 2 /// /// fcomplex input /// Logarithm of input public static fcomplex Log2(fcomplex input) { return Log(input) / 0.693147180559945f; } /// /// Logarithm of real input /// /// float input - may be negative /// Complex logarithm public static fcomplex Log(float input) { return Log (new fcomplex(input,0.0f)); } /// /// Logarithm of base 10 of real input /// /// float input - may be negative /// Complex logarithm of base 10 public static fcomplex Log10(float input) { return Log(new fcomplex(input,0.0f)) / 2.30258509299405f; } /// /// Logarithm of base 2 /// /// float input - may be negative /// Complex logarithm of base 2 public static fcomplex Log2(float input) { return Log(new fcomplex(input,0.0f)) / 0.693147180559945f; } /// /// Convert from polar to cartesian form /// /// Magnitude /// Angle /// fcomplex number with magnitude magnitude /// and phase angle public static fcomplex FromPol(float magnitude, float angle) { return new fcomplex ( (magnitude * (float)Math.Cos ( angle )), (magnitude * (float)Math.Sin ( angle )) ); } /// /// Convert this float complex number to string /// /// String representation of this float complex number public override String ToString() { if (imag>=0) return String.Format("{0} + {1}i",real,imag); else return String.Format("{0} {1}i",real,imag); } private static string m_precSpecI = ""; private static string m_precSpecR = ""; private static int m_lastDigits = 0; /// /// Print formated output of this number, determine number of digits /// /// Number of digits /// Formatted output public string ToString(int digits) { if (digits < 1) return ""; if (digits != m_lastDigits) { m_lastDigits = digits; m_precSpecR = String.Format("{{0:f{0}}}",digits); m_precSpecI = String.Format("{{1:f{0}}}i",digits); } if (imag >= 0) { return String.Format(m_precSpecR+"+"+m_precSpecI,real,imag); } else { return String.Format(m_precSpecR+m_precSpecI,real,imag); } } /// /// Magnitude of this float complex number /// /// Magnitude public float Abs() { return (float)Math.Sqrt(real * real + imag * imag); } /// /// Phase angle of this float complex number /// /// Phase angle public double Angle() { return (float)Math.Atan2(imag, real); } /// /// Arcus cosinus of this float complex number /// /// Arcus cosinus public fcomplex Acos() { fcomplex ret = new fcomplex(0, -1); return fcomplex.Log(fcomplex.Sqrt(this * this - 1) + this) * ret; } /// /// Arcus sinus of this float complex number /// /// Arcus sinus public fcomplex Asin() { fcomplex ret = Acos(this); ret.real = (float)(Math.PI / 2 - ret.real); return ret; } /// /// Arcus tangens of float complex number /// /// fcomplex input /// Arcus tangens of input public static fcomplex Atan(fcomplex input) { fcomplex ret = new fcomplex(0, (float)0.5); return (ret * Log((fcomplex.i + input) / (fcomplex.i - input))); } /// /// Round towards next greater integer /// /// fcomplex input /// Rounded float complex number /// Real and imaginary parts are independently rounded /// towards the next integer value towards positive infinity. public static fcomplex Ceiling (fcomplex input){ return new fcomplex( (float)Math.Ceiling(input.real), (float)Math.Ceiling(input.imag) ); } /// /// Round towards next lower integer /// /// fcomplex input /// Rounded float complex number /// Real and imaginary parts are independently rounded /// towards the next integer value towards negative infinity. public static fcomplex Floor (fcomplex input){ return new fcomplex( (float)Math.Floor(input.real), (float)Math.Floor(input.imag) ); } /// /// Round mercantilistic /// /// fcomplex number /// Rounded number /// Real and imaginaty parts are rounded independently. public static fcomplex Round (fcomplex input){ return new fcomplex( (float)Math.Round(input.real), (float)Math.Round(input.imag) ); } /// /// Signum function /// /// fcomplex input /// Signum of input /// /// For numbers a = 0.0 + 0.0i, sign(a)'s real and imag parts are 0.0. /// For all other numbers sign(a) is the projection onto the unit circle. public static fcomplex Sign(fcomplex input){ if (input.real == 0.0 && input.imag == 0.0) return new fcomplex(); else { float mag = (float)Math.Sqrt(input.real * input.real + input.imag * input.imag); return new fcomplex( input.real / mag, input.imag / mag); } } /// /// Truncate a floating point complex value /// /// fcomplex input /// Integer part of input /// Operates on real and imaginary parts seperately. public static fcomplex Truncate (fcomplex input){ return new fcomplex( (float)Math.Truncate(input.real), (float)Math.Truncate(input.imag) ); } /// /// Cosinus /// /// fcomplex input /// Cosinus of input /// The cosinus is computed by the trigonometric euler equation: /// 0.5 * [exp(i input) + exp(-i input)] public static fcomplex Cos(fcomplex input) { fcomplex i = new fcomplex(0, 1.0f); fcomplex ni = new fcomplex(0, -1.0f); return (Exp(i * input) + Exp(ni * input)) / 2.0f; } /// /// Cosinus hyperbolicus /// /// fcomplex input /// Cosinus hyperbolicus of input /// The cosinus is computed by the trigonometric euler equation: /// (Exp(input) + Exp(-1.0 * input)) / 2.0 public static fcomplex Cosh(fcomplex input) { return (Exp(input) + Exp(-1.0f * input)) / 2.0f; } /// /// Sinus /// /// fcomplex input /// Sinus of input /// The sinus is computed by the trigonometric euler equation: /// (Exp(i * input) - Exp(-1.0 * i * input)) / (2.0 * i) public static fcomplex Sin(fcomplex input) { fcomplex i = new fcomplex(0, (float)1.0); fcomplex mi = new fcomplex(0, (float)-1.0); return (Exp(i * input) - Exp(mi * input)) / (2.0 * i); } /// /// Sinus hyperbolicus /// /// fcomplex input /// Sinus hyperbolicus of input /// The sinus hyperbolicus is computed by the trigonometric euler equation: /// (Exp(input) - Exp(-1.0 * input)) / 2.0 public static fcomplex Sinh(fcomplex input) { fcomplex ret = new fcomplex(0, 2); fcomplex i = new fcomplex(0, (float)1.0); fcomplex mi = new fcomplex(0, (float)-1.0); return (Exp(input) - Exp(-1.0 * input)) / 2.0; } /// /// Exponential / power of base e /// /// Power of base e public fcomplex Exp() { return fcomplex.FromPol((float)Math.Exp(real), imag); } /// /// Power of fcomplex number, real exponent /// /// Exponent /// New fcomplex number with result public fcomplex Pow(double exponent) { fcomplex ret = Log(); ret.imag *= (float)exponent; ret.real *= (float)exponent; return ret.Exp(); } /// /// Power of fcomplex number, complex exponent /// /// Exponent /// New fcomplex number with result public fcomplex Pow(fcomplex exponent) { fcomplex ret = (Log() * exponent); return ret.Exp(); } /// /// Square root of fcomplex number /// /// Square root public fcomplex Sqrt() { // Reference : numerical recipes in C: Appendix C fcomplex ret = new fcomplex(); double x, y, w, r; if ( real == 0.0 && imag == 0.0) return ret; else { x = (float)Math.Abs(real); y = (float)Math.Abs( imag); if (x >= y) { r = y / x; w = Math.Sqrt(x) * Math.Sqrt(0.5 * (1.0 + Math.Sqrt(1.0 + r * r))); } else { r = x / y; w = Math.Sqrt(y) * Math.Sqrt(0.5 * (r + Math.Sqrt(1.0 + r * r))); } if ( real >= 0.0) { ret.real = (float)w; ret.imag = (float)( imag / (2.0 * w)); } else { ret.imag = (float)(( imag >= 0) ? w : -w); ret.real = (float)( imag / (2.0 * ret.imag)); } return ret; } } /// /// Logarithm of fcomplex number /// /// Natural logarithm /// The logarithm of a complex number A is defined as follows:
/// real part: log(abs(A)) /// imag part: Atan2(imag(A),real(A)) ///
public fcomplex Log() { fcomplex ret = new fcomplex(); ret.real = (float)Math.Log(Math.Sqrt( real * real + imag * imag)); ret.imag = (float)Math.Atan2( imag, real); return ret; } /// /// Test if any of real or imaginary parts are NAN's /// /// fcomplex input /// true if any of real or imag part is not a number public static bool IsNaN(fcomplex input) { if (Single.IsNaN(input.real) || Single.IsNaN(input.imag)) return true; else return false; } /// /// Test if any of real or imaginary parts are infinite /// /// fcomplex input /// true if any of real or imag part is infinite public static bool IsInfinity(fcomplex input) { if (Single.IsInfinity(input.real) || Single.IsInfinity(input.imag)) return true; else return false; } /// /// Test if any of real or imaginary parts are pos. infinite /// /// fcomplex input /// true if any of real or imag part is positive infinite public static bool IsPositiveInfinity(fcomplex input) { if (Single.IsPositiveInfinity(input.real) || Single.IsPositiveInfinity(input.imag)) return true; else return false; } /// /// Test if any of real or imaginary parts are neg. infinite /// /// fcomplex input /// true if any of real or imag part is negative infinite public static bool IsNegativeInfinity(fcomplex input) { if (Single.IsNegativeInfinity(input.real) || Single.IsNegativeInfinity(input.imag)) return true; else return false; } /// /// Test if any of real or imaginary parts are finite /// /// fcomplex input /// true if any of real and imag part is finite public static bool IsFinite (fcomplex input) { if (ILMath.isfinite(input.real) && ILMath.isfinite(input.imag)) return true; else return false; } #region CAST_OPERATORS /// /// Implicit cast real number into complex number /// /// double /// fcomplex number with real part equals a public static implicit operator fcomplex(double a) { return new fcomplex((float)a, 0.0F); } /// /// Implicit cast real number into complex number /// /// float /// fcomplex number with real part equals a public static implicit operator fcomplex(float a) { return new fcomplex(a, 0.0F); } /// /// Implicit cast real number into complex number /// /// byte /// fcomplex number with real part equals a public static implicit operator fcomplex(byte a) { return new fcomplex(a, 0.0F); } /// /// Implicit cast real number into complex number /// /// char /// fcomplex number with real part equals a public static implicit operator fcomplex(char a) { return new fcomplex(a, 0.0F); } /// /// Implicit cast real number into complex number /// /// Int16 /// fcomplex number with real part equals a public static implicit operator fcomplex(Int16 a) { return new fcomplex(a, 0.0F); } /// /// Implicit cast real number into complex number /// /// Int32 /// fcomplex number with real part equals a public static implicit operator fcomplex(Int32 a) { return new fcomplex((float)a, 0.0F); } /// /// Implicit cast real number into complex number /// /// Int64 /// fcomplex number with real part equals a public static implicit operator fcomplex(Int64 a) { return new fcomplex((float)a, 0.0F); } /// /// Implicit cast real number into complex number /// /// UInt16 /// fcomplex number with real part equals a public static implicit operator fcomplex(UInt16 a) { return new fcomplex((float)a, 0.0F); } /// /// Implicit cast real number into complex number /// /// UInt32 /// fcomplex number with real part equals a public static implicit operator fcomplex(UInt32 a) { return new fcomplex((float)a, 0.0F); } /// /// Implicit cast real number into complex number /// /// UInt64 /// fcomplex number with real part equals a public static implicit operator fcomplex(UInt64 a) { return new fcomplex((float)a, 0.0F); } /// /// Explicit cast complex number into real number /// /// fcomplex number /// Real number with real part of a public static explicit operator double(fcomplex a) { return a.real; } /// /// Explicit cast complex number into real number /// /// fcomplex number /// Real number with real part of a public static explicit operator float(fcomplex a) { return (float)a.real; } /// /// Explicit cast complex number into real number /// /// fcomplex number /// Real number with real part of a public static explicit operator byte(fcomplex a) { return (byte) a.real; } /// /// Explicit cast complex number into real number /// /// fcomplex number /// Real number with real part of a public static explicit operator char(fcomplex a) { return (char) a.real; } /// /// Explicit cast complex number into real number /// /// fcomplex number /// Real number with real part of a public static explicit operator Int16(fcomplex a) { return (Int16) a.real; } /// /// Explicit cast complex number into real number /// /// complex number /// Real number with real part of a public static explicit operator Int32(fcomplex a) { return (Int32) a.real; } /// /// Explicit cast complex number into real number /// /// fcomplex number /// Real number with real part of a public static explicit operator Int64(fcomplex a) { return (Int64) a.real; } /// /// Explicit cast complex number into real number /// /// fcomplex number /// Real number with real part of a public static explicit operator UInt16(fcomplex a) { return (UInt16) a.real; } /// /// Explicit cast complex number into real number /// /// fcomplex number /// Real number with real part of a public static explicit operator UInt32(fcomplex a) { return (UInt32) a.real; } /// /// Explicit cast complex number into real number /// /// fcomplex number /// Real number with real part of a public static explicit operator UInt64(fcomplex a) { return (UInt64) a.real; } /// /// Test if real and imag part are zero /// /// true if real and imag parts are zero, false else public bool iszero() { if (real == 0.0f && imag == 0.0f) return true; else return false; } #endregion CAST_OPERATORS } }