///
/// 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 double precision
///
/// This class extends the system value types for real numbers to complex double
/// 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.),
/// 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 complex value into system
/// value types.
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct complex : IEquatable {
///
/// Real part of this complex number
///
public double real;
///
/// Imaginary part of this complex number
///
public double imag;
///
/// Imaginary unit
///
public static readonly complex i = new complex(0.0f,1.0f);
///
/// Constructor creating a new complex value
///
/// Real part
/// Imaginary part
public complex(double real, double imag) {
this.real = real;
this.imag = imag;
}
///
/// Complex conjugate
///
public complex conj {
get{
return new complex(real,-imag);
}
}
///
/// Positive infinity for real and imag part of complex value
///
public static complex INF {
get {
return new complex(
double.PositiveInfinity,
double.PositiveInfinity
);
}
}
///
/// New complex, real and imaginary parts are zero
///
public static complex Zero {
get {
return new complex(0.0,0.0);
}
}
///
/// Complex quantity, marked as being "not a number"
///
public static complex NaN {
get {
return new complex(double.NaN,double.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 complex && ((complex)obj) == this)
return true;
return false;
}
///
/// Check if a complex number equals this complex number
///
/// other complex number
/// true if both, real and imaginary parts of both complex number are (binary) equal, false otherwise
public bool Equals(complex other) {
return real.Equals(other.real) && imag.Equals(other.imag);
}
///
/// Hash code of this comples
///
/// Hash code of this complex
public override int GetHashCode() {
return 77101 * real.GetHashCode() + imag.GetHashCode();
}
///
/// Add two complex numbers
///
/// First summand
/// Second summand
/// result
public static complex operator +( complex 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 -( complex 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 *( complex 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 /( complex 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 ==( complex 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 !=( complex 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 > ( complex 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 < ( complex 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 >=( complex 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 <=( complex A, complex B) {
return (A.real <= B.real );
}
#region HYCALPER AUTO GENERATED CODE
///
/// Add two complex numbers
///
/// First summand
/// Second summand
/// result
public static complex operator +( complex A, fcomplex 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 -( complex A, fcomplex 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 *( complex A, fcomplex 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 /( complex 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 ( 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 ==( complex 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 !=( complex 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 > ( complex 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 < ( complex 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 >=( complex 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 <=( complex A, fcomplex B) {
return (A.real <= B.real );
}
#endregion HYCALPER AUTO GENERATED CODE
///
/// Add two complex numbers
///
/// First summand
/// Second summand
/// Result
public static complex operator +( complex A, double B) {
complex ret;
ret.real = (double) (A.real + B);
ret.imag = (double) A.imag;
return ret;
}
///
/// Subtract two values
///
/// Minuend
/// Subtrahend
/// result
public static complex operator -( complex A, double B) {
complex ret;
ret.real = (double) (A.real - B);
ret.imag = (double) A.imag;
return ret;
}
///
/// Multiply two values
///
/// First factor
/// Second factor
/// result
public static complex operator *( complex A, double B) {
complex ret;
ret.real = (double) (A.real * B);
ret.imag = (double) (A.imag * B);
return ret;
}
///
/// Divide two numbers
///
/// Divident
/// Divisor
/// result
public static complex operator /( complex 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 ( complex )0;
} else {
if (double .IsInfinity(B))
{
if (IsInfinity(A)) {
return NaN;
} else {
return ( complex )0;
}
}
}
complex ret;
if (B == 0) return INF ;
ret.real = (double) (A.real / B);
ret.imag = (double) (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 ==( complex 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 !=( complex 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 > ( complex 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 <( complex 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 >=( complex 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 <=( complex A, double B) {
return (A.real <= B);
}
#region HYCALPER AUTO GENERATED CODE
///
/// Add two complex numbers
///
/// First summand
/// Second summand
/// Result
public static complex operator +( complex A, Int64 B) {
complex ret;
ret.real = (double) (A.real + B);
ret.imag = (double) A.imag;
return ret;
}
///
/// Subtract two values
///
/// Minuend
/// Subtrahend
/// result
public static complex operator -( complex A, Int64 B) {
complex ret;
ret.real = (double) (A.real - B);
ret.imag = (double) A.imag;
return ret;
}
///
/// Multiply two values
///
/// First factor
/// Second factor
/// result
public static complex operator *( complex A, Int64 B) {
complex ret;
ret.real = (double) (A.real * B);
ret.imag = (double) (A.imag * B);
return ret;
}
///
/// Divide two numbers
///
/// Divident
/// Divisor
/// result
public static complex operator /( complex A, Int64 B) {
if (IsNaN(A)) return NaN;
if (A.real == 0 && A.imag == 0) {
if (B == 0) return NaN;
return ( complex )0;
} else {
if (false)
{
if (IsInfinity(A)) {
return NaN;
} else {
return ( complex )0;
}
}
}
complex ret;
if (B == 0) return INF ;
ret.real = (double) (A.real / B);
ret.imag = (double) (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 ==( complex 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 !=( complex 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 > ( complex 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 <( complex 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 >=( complex 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 <=( complex A, Int64 B) {
return (A.real <= B);
}
///
/// Add two complex numbers
///
/// First summand
/// Second summand
/// Result
public static complex operator +( complex A, Int32 B) {
complex ret;
ret.real = (double) (A.real + B);
ret.imag = (double) A.imag;
return ret;
}
///
/// Subtract two values
///
/// Minuend
/// Subtrahend
/// result
public static complex operator -( complex A, Int32 B) {
complex ret;
ret.real = (double) (A.real - B);
ret.imag = (double) A.imag;
return ret;
}
///
/// Multiply two values
///
/// First factor
/// Second factor
/// result
public static complex operator *( complex A, Int32 B) {
complex ret;
ret.real = (double) (A.real * B);
ret.imag = (double) (A.imag * B);
return ret;
}
///
/// Divide two numbers
///
/// Divident
/// Divisor
/// result
public static complex operator /( complex A, Int32 B) {
if (IsNaN(A)) return NaN;
if (A.real == 0 && A.imag == 0) {
if (B == 0) return NaN;
return ( complex )0;
} else {
if (false)
{
if (IsInfinity(A)) {
return NaN;
} else {
return ( complex )0;
}
}
}
complex ret;
if (B == 0) return INF ;
ret.real = (double) (A.real / B);
ret.imag = (double) (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 ==( complex 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 !=( complex 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 > ( complex 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 <( complex 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 >=( complex 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 <=( complex A, Int32 B) {
return (A.real <= B);
}
///
/// Add two complex numbers
///
/// First summand
/// Second summand
/// Result
public static complex operator +( complex A, float B) {
complex ret;
ret.real = (double) (A.real + B);
ret.imag = (double) A.imag;
return ret;
}
///
/// Subtract two values
///
/// Minuend
/// Subtrahend
/// result
public static complex operator -( complex A, float B) {
complex ret;
ret.real = (double) (A.real - B);
ret.imag = (double) A.imag;
return ret;
}
///
/// Multiply two values
///
/// First factor
/// Second factor
/// result
public static complex operator *( complex A, float B) {
complex ret;
ret.real = (double) (A.real * B);
ret.imag = (double) (A.imag * B);
return ret;
}
///
/// Divide two numbers
///
/// Divident
/// Divisor
/// result
public static complex operator /( complex 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 ( complex )0;
} else {
if (float.IsInfinity(B))
{
if (IsInfinity(A)) {
return NaN;
} else {
return ( complex )0;
}
}
}
complex ret;
if (B == 0) return INF ;
ret.real = (double) (A.real / B);
ret.imag = (double) (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 ==( complex 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 !=( complex 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 > ( complex 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 <( complex 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 >=( complex 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 <=( complex A, float B) {
return (A.real <= B);
}
///
/// Add two complex numbers
///
/// First summand
/// Second summand
/// Result
public static complex operator +( complex A, byte B) {
complex ret;
ret.real = (double) (A.real + B);
ret.imag = (double) A.imag;
return ret;
}
///
/// Subtract two values
///
/// Minuend
/// Subtrahend
/// result
public static complex operator -( complex A, byte B) {
complex ret;
ret.real = (double) (A.real - B);
ret.imag = (double) A.imag;
return ret;
}
///
/// Multiply two values
///
/// First factor
/// Second factor
/// result
public static complex operator *( complex A, byte B) {
complex ret;
ret.real = (double) (A.real * B);
ret.imag = (double) (A.imag * B);
return ret;
}
///
/// Divide two numbers
///
/// Divident
/// Divisor
/// result
public static complex operator /( complex A, byte B) {
if (IsNaN(A)) return NaN;
if (A.real == 0 && A.imag == 0) {
if (B == 0) return NaN;
return ( complex )0;
} else {
if (false)
{
if (IsInfinity(A)) {
return NaN;
} else {
return ( complex )0;
}
}
}
complex ret;
if (B == 0) return INF ;
ret.real = (double) (A.real / B);
ret.imag = (double) (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 ==( complex 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 !=( complex 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 > ( complex 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 <( complex 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 >=( complex 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 <=( complex A, byte B) {
return (A.real <= B);
}
#endregion HYCALPER AUTO GENERATED CODE
///
/// Add two complex values
///
/// First summand
/// Second summand
/// Result
public static complex operator +( double A, complex B) {
complex ret;
ret.real = (double) (A + B.real);
ret.imag = (double) B.imag;
return ret;
}
///
/// Subtract two values
///
/// Minuend
/// Subtrahend
/// Result
public static complex operator -( double A, complex B) {
complex ret;
ret.real = (double) (A - B.real);
ret.imag = - (double) B.imag;
return ret;
}
///
/// Multiply two values
///
/// First factor
/// Second factor
/// Result
public static complex operator *( double A, complex B) {
complex ret;
ret.real = (double) (A * B.real);
ret.imag = (double) (A * B.imag);
return ret;
}
///
/// Divide two values
///
/// Divident
/// Divisor
/// Result
public static complex operator /( double A, complex B) {
complex ret;
if (A == 0) {
if (IsInfinity(B)) return NaN;
} else {
if (IsInfinity(B)) return ( complex )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 = (double) (B.imag * (1/B.real));
ret.imag = (double) (B.real + B.imag*tmp);
ret.real = (double) A/ret.imag;
ret.imag = - (double) (A*tmp)/ret.imag;
} else {
tmp = (double) (B.real * (1/B.imag));
ret.imag = (double) (B.imag + B.real*tmp);
ret.real = (double) (A*tmp)/ret.imag;
ret.imag = - (double) 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 ==( double A, complex 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 !=( double A, complex 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 > ( double A, complex 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 < ( double A, complex 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 >=( double A, complex 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 <=( double A, complex B) {
return (A <= B.real);
}
#region HYCALPER AUTO GENERATED CODE
///
/// Add two complex values
///
/// First summand
/// Second summand
/// Result
public static complex operator +( Int64 A, complex B) {
complex ret;
ret.real = (double) (A + B.real);
ret.imag = (double) B.imag;
return ret;
}
///
/// Subtract two values
///
/// Minuend
/// Subtrahend
/// Result
public static complex operator -( Int64 A, complex B) {
complex ret;
ret.real = (double) (A - B.real);
ret.imag = - (double) B.imag;
return ret;
}
///
/// Multiply two values
///
/// First factor
/// Second factor
/// Result
public static complex operator *( Int64 A, complex B) {
complex ret;
ret.real = (double) (A * B.real);
ret.imag = (double) (A * B.imag);
return ret;
}
///
/// Divide two values
///
/// Divident
/// Divisor
/// Result
public static complex operator /( Int64 A, complex B) {
complex ret;
if (A == 0) {
if (IsInfinity(B)) return NaN;
} else {
if (IsInfinity(B)) return ( complex )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 = (double) (B.imag * (1/B.real));
ret.imag = (double) (B.real + B.imag*tmp);
ret.real = (double) A/ret.imag;
ret.imag = - (double) (A*tmp)/ret.imag;
} else {
tmp = (double) (B.real * (1/B.imag));
ret.imag = (double) (B.imag + B.real*tmp);
ret.real = (double) (A*tmp)/ret.imag;
ret.imag = - (double) 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, complex 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, complex 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, complex 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, complex 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, complex 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, complex B) {
return (A <= B.real);
}
///
/// Add two complex values
///
/// First summand
/// Second summand
/// Result
public static complex operator +( Int32 A, complex B) {
complex ret;
ret.real = (double) (A + B.real);
ret.imag = (double) B.imag;
return ret;
}
///
/// Subtract two values
///
/// Minuend
/// Subtrahend
/// Result
public static complex operator -( Int32 A, complex B) {
complex ret;
ret.real = (double) (A - B.real);
ret.imag = - (double) B.imag;
return ret;
}
///
/// Multiply two values
///
/// First factor
/// Second factor
/// Result
public static complex operator *( Int32 A, complex B) {
complex ret;
ret.real = (double) (A * B.real);
ret.imag = (double) (A * B.imag);
return ret;
}
///
/// Divide two values
///
/// Divident
/// Divisor
/// Result
public static complex operator /( Int32 A, complex B) {
complex ret;
if (A == 0) {
if (IsInfinity(B)) return NaN;
} else {
if (IsInfinity(B)) return ( complex )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 = (double) (B.imag * (1/B.real));
ret.imag = (double) (B.real + B.imag*tmp);
ret.real = (double) A/ret.imag;
ret.imag = - (double) (A*tmp)/ret.imag;
} else {
tmp = (double) (B.real * (1/B.imag));
ret.imag = (double) (B.imag + B.real*tmp);
ret.real = (double) (A*tmp)/ret.imag;
ret.imag = - (double) 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, complex 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, complex 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, complex 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, complex 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, complex 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, complex B) {
return (A <= B.real);
}
///
/// Add two complex values
///
/// First summand
/// Second summand
/// Result
public static complex operator +( float A, complex B) {
complex ret;
ret.real = (double) (A + B.real);
ret.imag = (double) B.imag;
return ret;
}
///
/// Subtract two values
///
/// Minuend
/// Subtrahend
/// Result
public static complex operator -( float A, complex B) {
complex ret;
ret.real = (double) (A - B.real);
ret.imag = - (double) B.imag;
return ret;
}
///
/// Multiply two values
///
/// First factor
/// Second factor
/// Result
public static complex operator *( float A, complex B) {
complex ret;
ret.real = (double) (A * B.real);
ret.imag = (double) (A * B.imag);
return ret;
}
///
/// Divide two values
///
/// Divident
/// Divisor
/// Result
public static complex operator /( float A, complex B) {
complex ret;
if (A == 0) {
if (IsInfinity(B)) return NaN;
} else {
if (IsInfinity(B)) return ( complex )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 = (double) (B.imag * (1/B.real));
ret.imag = (double) (B.real + B.imag*tmp);
ret.real = (double) A/ret.imag;
ret.imag = - (double) (A*tmp)/ret.imag;
} else {
tmp = (double) (B.real * (1/B.imag));
ret.imag = (double) (B.imag + B.real*tmp);
ret.real = (double) (A*tmp)/ret.imag;
ret.imag = - (double) 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, complex 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, complex 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, complex 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, complex 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, complex 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, complex B) {
return (A <= B.real);
}
///
/// Add two complex values
///
/// First summand
/// Second summand
/// Result
public static complex operator +( byte A, complex B) {
complex ret;
ret.real = (double) (A + B.real);
ret.imag = (double) B.imag;
return ret;
}
///
/// Subtract two values
///
/// Minuend
/// Subtrahend
/// Result
public static complex operator -( byte A, complex B) {
complex ret;
ret.real = (double) (A - B.real);
ret.imag = - (double) B.imag;
return ret;
}
///
/// Multiply two values
///
/// First factor
/// Second factor
/// Result
public static complex operator *( byte A, complex B) {
complex ret;
ret.real = (double) (A * B.real);
ret.imag = (double) (A * B.imag);
return ret;
}
///
/// Divide two values
///
/// Divident
/// Divisor
/// Result
public static complex operator /( byte A, complex B) {
complex ret;
if (A == 0) {
if (IsInfinity(B)) return NaN;
} else {
if (IsInfinity(B)) return ( complex )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 = (double) (B.imag * (1/B.real));
ret.imag = (double) (B.real + B.imag*tmp);
ret.real = (double) A/ret.imag;
ret.imag = - (double) (A*tmp)/ret.imag;
} else {
tmp = (double) (B.real * (1/B.imag));
ret.imag = (double) (B.imag + B.real*tmp);
ret.real = (double) (A*tmp)/ret.imag;
ret.imag = - (double) 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, complex 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, complex 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, complex 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, complex 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, complex 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, complex B) {
return (A <= B.real);
}
#endregion HYCALPER AUTO GENERATED CODE
#region unary minus
///
/// Unary minus operator
///
/// Complex input
/// Complex number similar to A, having real and imag part negated
public static complex operator -( complex A) {
complex ret = new complex();
ret.imag = -A.imag;
ret.real = -A.real;
return ret;
}
#endregion
#region CAST_OPERATORS
///
/// Cast value to complex number
///
/// Value to cast
/// Complex number with the real part having the same value as a and the imaginary part is 0.
public static implicit operator complex(double a) {
return new complex(a, 0.0);
}
///
/// Cast value to complex number
///
/// Value to cast
/// Complex number with the real part having the same value as the a and the imaginary part is 0.
public static implicit operator complex(float a) {
return new complex(a, 0.0);
}
///
/// Cast value to complex number
///
/// Value to cast
/// Complex number being a copy of the real and imaginary parts of a.
public static implicit operator complex(fcomplex a) {
return new complex(a.real, a.imag);
}
///
/// Cast value to complex number
///
/// Value to cast
/// Complex number with the real part having the same value as a and the imaginary part is 0.
public static implicit operator complex(byte a) {
return new complex(a, 0.0);
}
///
/// Cast value to complex number
///
/// Value to cast
/// Complex number with the real part having the same value as a and the imaginary part is 0.
public static implicit operator complex(Int32 a) {
return new complex(a, 0.0);
}
///
/// Cast value to complex number
///
/// Value to cast
/// Complex number with the real part having the same value as a and the imaginary part is 0.
public static implicit operator complex(Int64 a) {
return new complex(a, 0.0);
}
///
/// Cast value from complex number
///
/// Complex value to cast
/// Double number with the real part of a
public static explicit operator double(complex a) {
return a.real;
}
///
/// Cast value from complex number
///
/// Complex value to cast
/// number with the real part of a
/// the return value is the result of a cast from double to float.
public static explicit operator float(complex a) {
return (float)a.real;
}
///
/// Cast value from complex number
///
/// Complex value to cast
/// float complex number with the real and imaginary parts being a copy of a
/// The real and imaginary parts are the result of a cast to float.
public static explicit operator fcomplex(complex a) {
return new fcomplex((float)a.real, (float)a.imag);
}
///
/// Cast value from complex number
///
/// Complex value to cast
/// Number with the real part of a
/// The return value is the result of a cast to byte.
public static explicit operator byte(complex a) {
return (byte) a.real;
}
///
/// Cast value from complex number
///
/// Complex value to cast
/// Number with the real part of a
/// The return value is the result of a cast to Int32.
public static explicit operator Int32(complex a) {
return (Int32) a.real;
}
///
/// Cast value from complex number
///
/// Complex value to cast
/// number with the real part of a
/// the return value is the result of a cast to Int64.
public static explicit operator Int64(complex a) {
return (Int64) a.real;
}
public static implicit operator complex(System.Numerics.Complex a) {
return new complex(a.Real, a.Imaginary);
}
#endregion CAST_OPERATORS
#region Functions Basic Math
///
/// Absolute value of input
///
/// Input value
/// The absolute value of the input
public static double Abs(complex input) {
return Math.Sqrt(input.real * input.real + input.imag * input.imag);
}
///
/// Phase angle of complex number
///
/// Input value
/// The phase angle of the input
/// For the result the Atan2 function of the class is used.
public static double Angle(complex input) {
return Math.Atan2(input.imag, input.real);
}
///
/// Arcus tangens of complex input
///
/// Complex input
/// Arcus tangens of complex input
///
public static complex Atan(complex input) {
complex ret = new complex(0, (float)0.5);
return (ret * Log((complex.i + input) / (complex.i - input)));
}
///
/// Arcus cosinus of complex input
///
/// Complex input
/// Arcus cosinus of input
public static complex Acos(complex input) {
complex ni = complex.i * -1.0;
return complex.Log(complex.Sqrt(input * input - 1)
+ input) * ni;
}
///
/// Arcus cosinus of input
///
/// Input value
/// Arcus cosinus of input
public static complex Acos(double input) {
if (Math.Abs(input) <= 1.0)
return new complex(Math.Acos(input), 0.0);
else {
return Acos((complex)input);
}
}
///
/// Arcus sinus of complex input
///
/// Input value
/// Arcus sinus of input
public static complex Asin(double input) {
if (Math.Abs(input) <= 1.0)
return new complex(Math.Asin(input), 0.0);
else {
return Asin((complex)input);
}
}
///
/// Arcus sinus of input
///
/// Input value
/// Arcus sinus of input
public static complex Asin(complex input) {
complex ret = Acos(input);
ret.real = Math.PI / 2 - ret.real;
return ret;
}
///
/// Round towards positive infinity
///
/// Input value
/// Result is the next integer value greater then input
/// ILMath.Ceiling operates in both: real and imaginary parts seperately
public static complex Ceiling (complex input){
return new complex(
Math.Ceiling(input.real),
Math.Ceiling(input.imag)
);
}
///
/// Round towards negative infinity
///
/// Input value
/// Result is the next integer value lower then input
/// ILMath.Floor operates in both: real and imaginary parts seperately
public static complex Floor (complex input){
return new complex(
Math.Floor(input.real),
Math.Floor(input.imag)
);
}
///
/// Rounds towards nearest integer
///
/// Input value
/// Result is the nearest integer value for input
/// ILMath.Round operates in both: real and imaginary parts deperately
public static complex Round (complex input){
return new complex(
Math.Round(input.real),
Math.Round(input.imag)
);
}
///
/// Signum function
///
/// Complex input
/// Sesult as input / Abs(input)
/// Sign(input) with input being complex returns the projection onto
/// the unit circle. If input is 0+0i the result will be 0+0i.
public static complex Sign (complex input){
if (input.real == 0.0 && input.imag == 0.0)
return new complex();
else {
double mag = Math.Sqrt(input.real * input.real + input.imag * input.imag);
return new complex(
input.real / mag,
input.imag / mag);
}
}
///
/// Truncate a floating point complex value
///
/// Input value
/// Integer part of input
/// Operates on real and imaginary parts seperately.
public static complex Truncate (complex input){
return new complex(
Math.Truncate(input.real),
Math.Truncate(input.imag)
);
}
///
/// Cosinus
///
/// Input value
/// Cosine of input
/// The cosine is computed by the trigonometric euler equation:
/// 0.5 * [exp(i input) + exp(-i input)]
public static complex Cos(complex input) {
complex i = new complex(0, 1.0);
complex mi = new complex(0, -1.0);
return (Exp(i * input) + Exp(mi * input)) / 2.0;
}
///
/// Cosinus hyperbolicus
///
/// Input
/// Cosine hyperbolicus of input
/// The cosine is computed by the trigonometric euler equation:
/// (Exp(input) + Exp(-1.0 * input)) / 2.0
public static complex Cosh(complex input) {
return (Exp(input) + Exp(-1.0 * input)) / 2.0;
}
///
/// Sinus
///
/// Input value
/// 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 complex Sin(complex input) {
complex i = new complex(0, 1.0);
complex mi = new complex(0, -1.0);
return (Exp(i * input) - Exp(mi * input)) / (2.0 * i);
}
///
/// Sinus hyperbolicus
///
/// 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 complex Sinh(complex input) {
return (Exp(input) - Exp(-1.0 * input)) / 2.0;
}
///
/// Complex exponent
///
/// Exponent
/// Result of exp(exponent)
/// For complex exponents, exp(exponent) is computed by
/// complex.FromPol(Math.Exp(exponent.real), exponent.imag)
public static complex Exp(complex exponent) {
return complex.FromPol(Math.Exp(exponent.real), exponent.imag);
}
///
/// Complex power for real exponent
///
/// Basis
/// Exponent
/// Result of input power exponent
/// The computation will be carried out by
/// exp(log(input) * exponent)
public static complex Pow(complex input, double exponent) {
complex ret = input.Log();
ret.imag *= exponent;
ret.real *= exponent;
return ret.Exp();
}
///
/// Complex power - real basis, real exponent
///
/// Basis
/// Exponent
/// Complex number.
/// The result will be a complex number. For negative basis
/// the basis will be converted to a complex number and the power
/// will be computed in the complex plane.
public static complex Pow(double basis, double exponent) {
if (basis >= 0.0)
return Math.Pow(basis, exponent);
else
return Pow((complex)basis, exponent);
}
///
/// Complex power - complex exponent
///
/// Basis
/// Exponent
/// Complex number exp(log(basis) * exponent).
/// The result will be the complex number exp(log(basis) * exponent).
public static complex Pow(complex basis, complex exponent) {
complex ret = (basis.Log() * exponent);
return ret.Exp();
}
///
/// Square root
///
/// Input value
/// The square root of input
/// If input is smaller than 0.0, the computation will be done in the complex plane.
public static complex Sqrt(double input) {
if (input > 0.0)
return new complex(Math.Sqrt(input), 0.0);
else
return Sqrt(input);
}
///
/// Square root
///
/// Input value
/// The square root of input
/// Numerical recipes in C: Appendix C
public static complex Sqrt(complex input) {
// Reference : numerical recipes in C: Appendix C
complex ret = new complex();
double x, y, w, r;
if (input.real == 0.0 && input.imag == 0.0)
return ret;
else {
x = (double)Math.Abs(input.real);
y = (double)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 = w;
ret.imag = input.imag / (2.0 * w);
} else {
ret.imag = (input.imag >= 0) ? w : -w;
ret.real = input.imag / (2.0 * ret.imag);
}
return ret;
}
}
///
/// Tangens
///
/// Input value
/// Tangens of input
/// The tangens is
/// sin(input) / cos(input)
/// if cos(input) == 0.0+0.0i, INF will be returned.
public static complex Tan(complex input) {
complex ci = Cos(input);
if (ci.real == 0.0 && ci.imag == 0.0)
return INF;
return (Sin(input) / ci);
}
///
/// Tangens hyperbolicus
///
/// Input value
/// Tangens hyperbolicus
/// The tangens hyperbolicus is
/// sinh(input) / cosh(input)
/// if cosh(input) == 0.0+0.0i, INF will be returned.
public static complex Tanh(complex input) {
complex si = Cosh(input);
if (si.real == 0.0 && si.imag == 0.0)
return INF;
return (Sinh(input) / si);
}
///
/// Complex logarithm
///
/// Input value
/// Complex logarithm of input
/// The real part of the logarithm is computed by
/// log (abs (input))
/// The imaginary part holds the phase of input.
///
public static complex Log(complex input) {
complex ret = new complex();
ret.real = Math.Log(Math.Sqrt(input.real * input.real + input.imag * input.imag));
ret.imag = Math.Atan2(input.imag, input.real);
return ret;
}
///
/// Logarithm of real input
///
/// Input value - may be negative
/// Complex logarithm
public static complex Log(double input) {
return Log (new complex(input,0.0));
}
///
/// Logarithm of base 10 of real input
///
/// Input value - may be negative
/// Complex logarithm of base 10
public static complex Log10(double input) {
return Log(new complex(input,0.0)) * 0.43429448190325176;
}
///
/// Logarithm of base 2 of real input
///
/// Input value - may be negative
/// Complex logarithm of base 2
public static complex Log2(double input) {
return Log(new complex(input,0.0)) * 1.4426950408889641;
}
///
/// Logarithm of base 10
///
/// Input value
/// Logarithm of base 10
///
public static complex Log10(complex input) {
return Log(input) * 0.43429448190325176;
}
///
/// Logarithm of base 2
///
/// Input value
/// Logarithm of base 2.
///
public static complex Log2(complex input) {
return Log(input) * 1.4426950408889634;
}
///
/// Convert polar notation into cartesian notation
///
/// Magnitude
/// Phase
/// Complex value having magnitude and phase
public static complex FromPol(double magnitude, double angle) {
return new complex(
magnitude * Math.Cos(angle),
magnitude * Math.Sin(angle)
);
}
///
/// Convert to string
///
/// String displaying the comlex number (full precision)
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
/// Formated 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 complex instance
///
/// Magnitude
public double Abs() {
return Math.Sqrt(real * real + imag * imag);
}
///
/// Phase of this complex instance
///
/// Phase
public double Angle() {
return Math.Atan2(imag, real);
}
///
/// Arcus cosinus of this complex instance
///
/// Arcus cosinus
public complex Acos() {
complex ret = new complex(0, -1);
return complex.Log(complex.Sqrt(this * this - 1)
+ this) * ret;
}
///
/// Arcus sinus of this complex instance
///
/// arcus sinus
public complex Asin() {
complex ret = Acos(this);
ret.real = Math.PI / 2 - ret.real;
return ret;
}
///
/// Exponential / power of base e
///
/// Power of base e
public complex Exp() {
return complex.FromPol(Math.Exp(real), imag);
}
///
/// Complex power real exponent
///
/// Exponent
/// New complex number with result
/// If this instance is a and the exponent is e than
/// the result will be the complex number exp(log(a) * e).
public complex Pow(double exponent) {
complex ret = Log();
ret.imag *= exponent;
ret.real *= exponent;
return ret.Exp();
}
///
/// Complex power - complex exponent
///
/// Exponent
/// Complex number exp(log(this) * exponent).
/// If this instance is a than
/// the result will be the complex number exp(log(a) * exponent).
public complex Pow(complex exponent) {
complex ret = (Log() * exponent);
return ret.Exp();
}
///
/// Square root of this complex value
///
/// Square root of this complex value
public complex Sqrt() {
// Reference : numerical recipes in C: Appendix C
complex ret = new complex();
double x, y, w, r;
if (real == 0.0 && imag == 0.0)
return ret;
else {
x = (double)Math.Abs(real);
y = (double)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 = w;
ret.imag = imag / (2.0 * w);
} else {
ret.imag = (imag >= 0) ? w : -w;
ret.real = imag / ( 2.0 * ret.imag );
}
return ret;
}
}
///
/// Logarithm of base e
///
/// Logarithm of base e
/// The logarithm of a complex number A is defined as follows:
/// - real part: log(abs(A))
/// - imag part: Atan2(imag(A),real(A))
///
public complex Log() {
complex ret = new complex();
ret.real = Math.Log(Math.Sqrt(real * real + imag * imag));
ret.imag = Math.Atan2(imag, real);
return ret;
}
///
/// Test if any of real or imaginary parts are NAN's
///
/// Complex number to test
/// true if any of real or imag part is not a number
public static bool IsNaN(complex input) {
if (double.IsNaN(input.real) || double.IsNaN(input.imag))
return true;
else
return false;
}
///
/// Test if any of real or imaginary parts are infinite
///
/// Complex number to test
/// true if any of real or imag part is infinite
public static bool IsInfinity(complex input) {
if (double.IsInfinity(input.real) || double.IsInfinity(input.imag))
return true;
else
return false;
}
///
/// Test if any of real or imaginary parts are pos.nfinite
///
/// Complex number to test
/// true if any of real or imag part is positive infinite
public static bool IsPositiveInfinity(complex input) {
if (double.IsPositiveInfinity(input.real) || double.IsPositiveInfinity(input.imag))
return true;
else
return false;
}
///
/// Test if any of real or imaginary parts are neg. infinite
///
/// Complex number to test
/// true if any of real or imag part is negative infinite
public static bool IsNegativeInfinity(complex input) {
if (double.IsNegativeInfinity(input.real) || double.IsNegativeInfinity(input.imag))
return true;
else
return false;
}
///
/// Test if any of real or imaginary parts are finite
///
/// Complex number to test
/// true if any of real and imag part is finite
public static bool IsFinite (complex input) {
if (ILMath.isfinite(input.real) && ILMath.isfinite(input.imag))
return true;
else
return false;
}
///
/// Test if both of real or imaginary parts are 0
///
/// true if real and imag part is 0
public bool iszero() {
if (real == 0.0 && imag == 0.0)
return true;
else
return false;
}
#endregion Functions Basic Math
}
}