///
/// 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
}
}