Browse Source

synced up complex code to use the .NET 4.0 Complex class

oved the Silverlight project to Silverlight 4 RC2 - needed to support the .NET 4.0 complex class
pull/36/head
Marcus Cuda 17 years ago
parent
commit
abb46af960
  1. 13
      src/Numerics/Algorithms/LinearAlgebra/Atlas/AtlasLinearAlgebraProvider.cs
  2. 2
      src/Numerics/Algorithms/LinearAlgebra/Atlas/SafeNativeMethods.cs
  3. 2
      src/Numerics/Algorithms/LinearAlgebra/ILinearAlgebraProvider.cs
  4. 9
      src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.cs
  5. 13
      src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs
  6. 2
      src/Numerics/Algorithms/LinearAlgebra/Mkl/SafeNativeMethods.cs
  7. 1632
      src/Numerics/Complex.cs
  8. 378
      src/Numerics/Complex32.cs
  9. 580
      src/Numerics/ComplexExtensions.cs
  10. 5
      src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.Bluestein.cs
  11. 1
      src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.Naive.cs
  12. 1
      src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.Options.cs
  13. 1
      src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.RadixN.cs
  14. 1
      src/Numerics/IntegralTransforms/Transform.cs
  15. 3
      src/Numerics/Numerics.csproj
  16. 54
      src/Numerics/Precision.cs
  17. 31
      src/Numerics/Trigonometry.cs
  18. 10
      src/Silverlight/Silverlight.csproj
  19. 19
      src/UnitTests/AssertHelpers.cs
  20. 77
      src/UnitTests/ComplexTests/Complex32Test.cs
  21. 136
      src/UnitTests/ComplexTests/ComplexTest.TextHandling.cs
  22. 604
      src/UnitTests/ComplexTests/ComplexTest.cs
  23. 1
      src/UnitTests/IntegralTransformsTests/FourierTest.cs
  24. 1
      src/UnitTests/IntegralTransformsTests/HartleyTest.cs
  25. 1
      src/UnitTests/IntegralTransformsTests/InverseTransformTest.cs
  26. 1
      src/UnitTests/IntegralTransformsTests/MatchingNaiveTransformTest.cs
  27. 5
      src/UnitTests/IntegralTransformsTests/ParsevalTheoremTest.cs
  28. 2
      src/UnitTests/TrigonometryTest.cs
  29. 1
      src/UnitTests/UnitTests.csproj

13
src/Numerics/Algorithms/LinearAlgebra/Atlas/AtlasLinearAlgebraProvider.cs

@ -29,6 +29,7 @@
namespace MathNet.Numerics.Algorithms.LinearAlgebra.Atlas
{
using System;
using System.Numerics;
using Properties;
/// <summary>
@ -1256,7 +1257,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Atlas
throw new ArgumentException(Resources.ArgumentVectorsSameLength);
}
if (alpha.IsZero)
if (alpha.IsZero())
{
return;
}
@ -1275,9 +1276,9 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Atlas
if (x == null)
{
throw new ArgumentNullException("x");
}
}
if (alpha.IsOne)
if (alpha.IsOne())
{
return;
}
@ -1852,7 +1853,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Atlas
throw new ArgumentException(Resources.ArgumentVectorsSameLength);
}
if (alpha.IsZero)
if (alpha.IsZero())
{
return;
}
@ -1871,9 +1872,9 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Atlas
if (x == null)
{
throw new ArgumentNullException("x");
}
}
if (alpha.IsOne)
if (alpha.IsOne())
{
return;
}

2
src/Numerics/Algorithms/LinearAlgebra/Atlas/SafeNativeMethods.cs

@ -36,6 +36,8 @@ using System.Security;
namespace MathNet.Numerics.Algorithms.LinearAlgebra.Atlas
{
using System.Numerics;
/// <summary>
/// P/Invoke methods to the native math libraries.
/// </summary>

2
src/Numerics/Algorithms/LinearAlgebra/ILinearAlgebraProvider.cs

@ -25,6 +25,8 @@
// INITIAL DRAFT MISSING EXCEPTION SPECIFICATIONS
namespace MathNet.Numerics.Algorithms.LinearAlgebra
{
using System.Numerics;
/// <summary>
/// Interface to linear algebra algorithms that work off 1-D arrays.
/// </summary>

9
src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.cs

@ -24,6 +24,7 @@
namespace MathNet.Numerics.Algorithms.LinearAlgebra
{
using System;
using System.Numerics;
using Properties;
using Threading;
@ -2406,7 +2407,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
throw new ArgumentNullException("x");
}
if (alpha.IsOne)
if (alpha.IsOne())
{
return;
}
@ -2736,7 +2737,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
cColumns = bColumns;
}
if (alpha.IsZero && beta.IsZero)
if (alpha.IsZero() && beta.IsZero())
{
Array.Clear(c, 0, c.Length);
return;
@ -2766,9 +2767,9 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
bdata = b;
}
if (alpha.IsOne)
if (alpha.IsOne())
{
if (beta.IsZero)
if (beta.IsZero())
{
if ((int)transposeA > 111 && (int)transposeB > 111)
{

13
src/Numerics/Algorithms/LinearAlgebra/Mkl/MklLinearAlgebraProvider.cs

@ -29,6 +29,7 @@
namespace MathNet.Numerics.Algorithms.LinearAlgebra.Mkl
{
using System;
using System.Numerics;
using Properties;
/// <summary>
@ -1255,7 +1256,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Mkl
throw new ArgumentException(Resources.ArgumentVectorsSameLength);
}
if (alpha.IsZero)
if (alpha.IsZero())
{
return;
}
@ -1274,9 +1275,9 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Mkl
if (x == null)
{
throw new ArgumentNullException("x");
}
}
if (alpha.IsOne)
if (alpha.IsOne())
{
return;
}
@ -1851,7 +1852,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Mkl
throw new ArgumentException(Resources.ArgumentVectorsSameLength);
}
if (alpha.IsZero)
if (alpha.IsZero())
{
return;
}
@ -1870,9 +1871,9 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra.Mkl
if (x == null)
{
throw new ArgumentNullException("x");
}
}
if (alpha.IsOne)
if (alpha.IsOne())
{
return;
}

2
src/Numerics/Algorithms/LinearAlgebra/Mkl/SafeNativeMethods.cs

@ -36,6 +36,8 @@ using System.Security;
namespace MathNet.Numerics.Algorithms.LinearAlgebra.Mkl
{
using System.Numerics;
/// <summary>
/// P/Invoke methods to the native math libraries.
/// </summary>

1632
src/Numerics/Complex.cs

File diff suppressed because it is too large

378
src/Numerics/Complex32.cs

@ -2,7 +2,7 @@
// Math.NET Numerics, part of the Math.NET Project
// http://mathnet.opensourcedotnet.info
//
// Copyright (c) 2009 Math.NET
// Copyright (c) 2009-2010 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@ -30,6 +30,8 @@ namespace MathNet.Numerics
{
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime;
using System.Runtime.InteropServices;
using System.Text;
using Properties;
@ -124,6 +126,9 @@ namespace MathNet.Numerics
/// <param name="imaginary">
/// The value for the imaginary component.
/// </param>
#if !SILVERLIGHT
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
#endif
public Complex32(float real, float imaginary)
{
_real = real;
@ -195,6 +200,10 @@ namespace MathNet.Numerics
/// <value>The real component of the complex number.</value>
public float Real
{
#if !SILVERLIGHT
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
#endif
get { return _real; }
}
@ -204,6 +213,10 @@ namespace MathNet.Numerics
/// <value>The real imaginary component of the complex number.</value>
public float Imaginary
{
#if !SILVERLIGHT
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
#endif
get { return _imag; }
}
@ -211,27 +224,27 @@ namespace MathNet.Numerics
/// Gets a value indicating whether the <c>Complex32</c> is zero.
/// </summary>
/// <value><c>true</c> if this instance is zero; otherwise, <c>false</c>.</value>
public bool IsZero
public bool IsZero()
{
get { return _real == 0.0f && _imag == 0.0f; }
return _real == 0.0f && _imag == 0.0f;
}
/// <summary>
/// Gets a value indicating whether the <c>Complex32</c> is one.
/// </summary>
/// <value><c>true</c> if this instance is one; otherwise, <c>false</c>.</value>
public bool IsOne
public bool IsOne()
{
get { return _real == 1.0f && _imag == 0.0f; }
return _real == 1.0f && _imag == 0.0f;
}
/// <summary>
/// Gets a value indicating whether the <c>Complex32</c> is the imaginary unit.
/// </summary>
/// <value><c>true</c> if this instance is ImaginaryOne; otherwise, <c>false</c>.</value>
public bool IsImaginaryOne
public bool IsImaginaryOne()
{
get { return _real == 0.0f && _imag == 1.0f; }
return _real == 0.0f && _imag == 1.0f;
}
/// <summary>
@ -242,9 +255,9 @@ namespace MathNet.Numerics
/// <c>true</c> if this instance is <see cref="NaN"/>; otherwise,
/// <c>false</c>.
/// </value>
public bool IsNaN
public bool IsNaN()
{
get { return float.IsNaN(_real) || float.IsNaN(_imag); }
return float.IsNaN(_real) || float.IsNaN(_imag);
}
/// <summary>
@ -258,18 +271,18 @@ namespace MathNet.Numerics
/// True if it either evaluates to a complex infinity
/// or to a directed infinity.
/// </remarks>
public bool IsInfinity
public bool IsInfinity()
{
get { return float.IsInfinity(_real) || float.IsInfinity(_imag); }
return float.IsInfinity(_real) || float.IsInfinity(_imag);
}
/// <summary>
/// Gets a value indicating whether the provided <c>Complex32</c> is real.
/// </summary>
/// <value><c>true</c> if this instance is a real number; otherwise, <c>false</c>.</value>
public bool IsReal
public bool IsReal()
{
get { return _imag == 0.0f; }
return _imag == 0.0f;
}
/// <summary>
@ -278,9 +291,9 @@ namespace MathNet.Numerics
/// <value>
/// <c>true</c> if this instance is real nonnegative number; otherwise, <c>false</c>.
/// </value>
public bool IsRealNonNegative
public bool IsRealNonNegative()
{
get { return _imag == 0.0f && _real >= 0; }
return _imag == 0.0f && _real >= 0;
}
/// <summary>
@ -298,9 +311,9 @@ namespace MathNet.Numerics
/// a = b.Conjugate
/// </code>
/// </remarks>
public Complex32 Conjugate
public Complex32 Conjugate()
{
get { return new Complex32(_real, -_imag); }
return new Complex32(_real, -_imag);
}
/// <summary>
@ -333,12 +346,12 @@ namespace MathNet.Numerics
{
get
{
if (IsReal && _real < 0)
if (IsReal() && _real < 0)
{
return (float)Math.PI;
}
return IsRealNonNegative ? 0.0f : (float)Math.Atan2(_imag, _real);
return IsRealNonNegative() ? 0.0f : (float)Math.Atan2(_imag, _real);
}
}
@ -391,7 +404,7 @@ namespace MathNet.Numerics
public Complex32 Exponential()
{
var exp = (float)Math.Exp(_real);
if (IsReal)
if (IsReal())
{
return new Complex32(exp, 0.0f);
}
@ -407,7 +420,7 @@ namespace MathNet.Numerics
/// </returns>
public Complex32 NaturalLogarithm()
{
if (IsRealNonNegative)
if (IsRealNonNegative())
{
return new Complex32((float)Math.Log(_real), 0.0f);
}
@ -426,9 +439,9 @@ namespace MathNet.Numerics
/// </returns>
public Complex32 Power(Complex32 exponent)
{
if (IsZero)
if (IsZero())
{
if (exponent.IsZero)
if (exponent.IsZero())
{
return One;
}
@ -476,7 +489,7 @@ namespace MathNet.Numerics
/// </returns>
public Complex32 Square()
{
if (IsReal)
if (IsReal())
{
return new Complex32(_real * _real, 0.0f);
}
@ -492,7 +505,7 @@ namespace MathNet.Numerics
/// </returns>
public Complex32 SquareRoot()
{
if (IsRealNonNegative)
if (IsRealNonNegative())
{
return new Complex32((float)Math.Sqrt(_real), 0.0f);
}
@ -642,12 +655,12 @@ namespace MathNet.Numerics
{
var numberFormatInfo = formatProvider.GetNumberFormatInfo();
if (IsNaN)
if (IsNaN())
{
return numberFormatInfo.NaNSymbol;
}
if (IsInfinity)
if (IsInfinity())
{
return numberFormatInfo.PositiveInfinitySymbol;
}
@ -701,12 +714,12 @@ namespace MathNet.Numerics
/// </param>
public bool Equals(Complex32 other)
{
if (IsNaN || other.IsNaN)
if (IsNaN() || other.IsNaN())
{
return false;
}
if (IsInfinity && other.IsInfinity)
if (IsInfinity() && other.IsInfinity())
{
return true;
}
@ -880,7 +893,7 @@ namespace MathNet.Numerics
/// <param name="divisor">The divisor.</param>
public static Complex32 operator /(Complex32 dividend, Complex32 divisor)
{
if (divisor.IsZero)
if (divisor.IsZero())
{
return Infinity;
}
@ -897,7 +910,7 @@ namespace MathNet.Numerics
/// <param name="divisor">The divisor.</param>
public static Complex32 operator /(float dividend, Complex32 divisor)
{
if (divisor.IsZero)
if (divisor.IsZero())
{
return Infinity;
}
@ -926,6 +939,10 @@ namespace MathNet.Numerics
/// <returns>
/// Returns the same complex number.
/// </returns>
#if !SILVERLIGHT
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
#endif
public Complex32 Plus()
{
return this;
@ -937,6 +954,10 @@ namespace MathNet.Numerics
/// <returns>
/// The negated value of this complex number.
/// </returns>
#if !SILVERLIGHT
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
#endif
public Complex32 Negate()
{
return -this;
@ -951,6 +972,10 @@ namespace MathNet.Numerics
/// <param name="other">
/// The other complex number to add.
/// </param>
#if !SILVERLIGHT
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
#endif
public Complex32 Add(Complex32 other)
{
return this + other;
@ -965,6 +990,10 @@ namespace MathNet.Numerics
/// <param name="other">
/// The other complex number to subtract from this one.
/// </param>
#if !SILVERLIGHT
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
#endif
public Complex32 Subtract(Complex32 other)
{
return this - other;
@ -979,6 +1008,10 @@ namespace MathNet.Numerics
/// <param name="multiplier">
/// The complex number to multiply.
/// </param>
#if !SILVERLIGHT
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
#endif
public Complex32 Multiply(Complex32 multiplier)
{
return this * multiplier;
@ -993,6 +1026,10 @@ namespace MathNet.Numerics
/// <param name="divisor">
/// The divisor.
/// </param>
#if !SILVERLIGHT
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
#endif
public Complex32 Divide(Complex32 divisor)
{
return this / divisor;
@ -1324,6 +1361,28 @@ namespace MathNet.Numerics
return new Complex32(value, 0.0f);
}
/// <summary>
/// Implicit conversion of a signed byte to a <c>Complex32</c>.
/// </summary>
/// <param name="value">The signed byte value to convert.</param>
/// <returns>The result of the conversion.</returns>
[CLSCompliant(false)]
public static implicit operator Complex32(sbyte value)
{
return new Complex32(value, 0.0f);
}
/// <summary>
/// Implicit conversion of a unsgined real short to a <c>Complex32</c>.
/// </summary>
/// <param name="value">The unsgined short value to convert.</param>
/// <returns>The result of the conversion.</returns>
[CLSCompliant(false)]
public static implicit operator Complex32(ushort value)
{
return new Complex32(value, 0.0f);
}
/// <summary>
/// Implicit conversion of a real int to a <c>Complex32</c>.
/// </summary>
@ -1334,6 +1393,16 @@ namespace MathNet.Numerics
return new Complex32(value, 0.0f);
}
/// <summary>
/// Implicit conversion of a BigInteger int to a <c>Complex32</c>.
/// </summary>
/// <param name="value">The BigInteger value to convert.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator Complex32(BigInteger value)
{
return new Complex32((long)value, 0.0f);
}
/// <summary>
/// Implicit conversion of a real long to a <c>Complex32</c>.
/// </summary>
@ -1349,6 +1418,7 @@ namespace MathNet.Numerics
/// </summary>
/// <param name="value">The uint value to convert.</param>
/// <returns>The result of the conversion.</returns>
[CLSCompliant(false)]
public static implicit operator Complex32(uint value)
{
return new Complex32(value, 0.0f);
@ -1359,6 +1429,7 @@ namespace MathNet.Numerics
/// </summary>
/// <param name="value">The ulong value to convert.</param>
/// <returns>The result of the conversion.</returns>
[CLSCompliant(false)]
public static implicit operator Complex32(ulong value)
{
return new Complex32(value, 0.0f);
@ -1384,6 +1455,251 @@ namespace MathNet.Numerics
return new Complex32((float)value, 0.0f);
}
public Complex ToComplex()
{
return new Complex(this._real, this._imag);
}
#endregion
/// <summary>
/// Gets the absolute value (or magnitude) of a complex number.
/// </summary>
/// <param name="value">A complex number.</param>
/// <returns>The absolute value (or magnitude) of a complex number.</returns>
public static double Abs(Complex32 value)
{
return value.Magnitude;
}
/// <summary>
/// Trigonometric Arc Cosine of a <c>Complex</c> number.
/// </summary>
/// <param name="value">A complex number.</param>
/// <returns>
/// The arc cosine of a complex number.
/// </returns>
public static Complex32 Acos(Complex32 value)
{
return (Complex32)value.ToComplex().InverseCosine();
}
/// <summary>
/// Trigonometric Arc Sine of a <c>Complex</c> number.
/// </summary>
/// <param name="value">A complex number.</param>
/// <returns>
/// The arc sine of a complex number.
/// </returns>
public static Complex32 Asin(Complex32 value)
{
return (Complex32)value.ToComplex().InverseSine();
}
/// <summary>
/// Trigonometric Arc Tangent of a <c>Complex</c> number.
/// </summary>
/// <param name="value">A complex number.</param>
/// <returns>
/// The arc tangent of a complex number.
/// </returns>
public static Complex32 Atan(Complex32 value)
{
return (Complex32)value.ToComplex().InverseTangent();
}
/// <summary>
/// Trigonometric Cosine of a <c>Complex</c> number.
/// </summary>
/// <param name="value">A complex number.</param>
/// <returns>
/// The cosine of a complex number.
/// </returns>
public static Complex32 Cos(Complex32 value)
{
return (Complex32)value.ToComplex().Cosine();
}
/// <summary>
/// Trigonometric Sine of a <c>Complex</c> number.
/// </summary>
/// <param name="value">A complex number.</param>
/// <returns>
/// The Sine of a complex number.
/// </returns>
public static Complex32 Sin(Complex32 value)
{
return (Complex32)value.ToComplex().Sine();
}
/// <summary>
/// Trigonometric Tangent of a <c>Complex</c> number.
/// </summary>
/// <param name="value">A complex number.</param>
/// <returns>
/// The tangent of a complex number.
/// </returns>
public static Complex32 Tan(Complex32 value)
{
return (Complex32)value.ToComplex().Tangent();
}
/// <summary>
/// Trigonometric Hyperbolic Cosine of a <c>Complex</c> number.
/// </summary>
/// <param name="value">A complex number.</param>
/// <returns>
/// The hyperbolic cosine of a complex number.
/// </returns>
public static Complex32 Cosh(Complex32 value)
{
return (Complex32)value.ToComplex().HyperbolicCosine();
}
/// <summary>
/// Trigonometric Hyperbolic Sine of a <c>Complex</c> number.
/// </summary>
/// <param name="value">A complex number.</param>
/// <returns>
/// The hyperbolic sine of a complex number.
/// </returns>
public static Complex32 Sinh(Complex32 value)
{
return (Complex32)value.ToComplex().HyperbolicSine();
}
/// <summary>
/// Trigonometric Hyperbolic Tangent of a <c>Complex</c> number.
/// </summary>
/// <param name="value">A complex number.</param>
/// <returns>
/// The hyperbolic tangent of a complex number.
/// </returns>
public static Complex32 Tanh(Complex32 value)
{
return (Complex32)value.ToComplex().HyperbolicTangent();
}
/// <summary>
/// Exponential of a <c>Complex</c> number (exp(x), E^x).
/// </summary>
/// <param name="value">A complex number.</param>
/// <returns>
/// The exponential of a complex number.
/// </returns>
public static Complex32 Exp(Complex32 value)
{
return (Complex32)value.ToComplex().Exponential();
}
/// <summary>
/// Constructs a <c>Complex</c> from its magnitude and phase.
/// </summary>
/// <param name="magnitude">
/// Must be non-negative.
/// </param>
/// <param name="phase">
/// Real number.
/// </param>
/// <returns>
/// A new <c>Complex</c> from the given values.
/// </returns>
/// <seealso cref="WithModulusArgument"/>
public static Complex32 FromPolarCoordinates(float magnitude, float phase)
{
return WithModulusArgument(magnitude, phase);
}
/// <summary>
/// Natural Logarithm of a <c>Complex</c> number (exp(x), E^x).
/// </summary>
/// <param name="value">A complex number.</param>
/// <returns>
/// The natural logarithm of a complex number.
/// </returns>
public static Complex32 Log(Complex32 value)
{
return (Complex32)value.ToComplex().NaturalLogarithm();
}
/// <summary>
/// Returns the logarithm of a specified complex number in a specified base
/// </summary>
/// <param name="value">A complex number.</param>
/// <param name="baseValue">The base of the logarithm.</param>
/// <returns>The logarithm of value in base baseValue.</returns>
public static Complex32 Log(Complex32 value, float baseValue)
{
if (baseValue == 1.0)
{
return float.NaN;
}
return (Complex32)(value.ToComplex().NaturalLogarithm() / Math.Log(baseValue, Math.E));
}
/// <summary>
/// Returns the base-10 logarithm of a specified complex number in a specified base
/// </summary>
/// <param name="value">A complex number.</param>
/// <returns>The base-10 logarithm of the complex number.</returns>
public static Complex32 Log10(Complex32 value)
{
return Log(value, 10);
}
/// <summary>
/// Raise this a <c>Complex</c>number to the given value.
/// </summary>
/// <param name="value">A complex number.</param>
/// <param name="power">The exponent.</param>
/// <returns>
/// The complex number raised to the given exponent.
/// </returns>
public static Complex32 Pow(Complex32 value, Complex32 power)
{
return value.Power(power);
}
/// <summary>
/// Raise this a <c>Complex</c>number to the given value.
/// </summary>
/// <param name="value">A complex number.</param>
/// <param name="power">The exponent.</param>
/// <returns>
/// The complex number raised to the given exponent.
/// </returns>
public static Complex32 Pow(Complex32 value, float power)
{
return value.Power(power);
}
/// <summary>
/// Returns the multiplicative inverse of a complex number.
/// </summary>
/// <param name="value">A complex number.</param>
/// <returns>The reciprocal of value.</returns>
/// <remarks>If value is <see cref="Zero"/>, the method returns <see cref="Zero"/>. Otherwise, it returns the result of the expression <see cref="One"/> / value. </remarks>
public static Complex32 Reciprocal(Complex32 value)
{
if (value.IsZero())
{
return _zero;
}
return 1.0f / value;
}
/// <summary>
/// The Square Root (power 1/2) of a <c>Complex</c> number.
/// </summary>
/// <param name="value">A complex number.</param>
/// <returns>
/// The square root of a complex number.
/// </returns>
public static Complex32 Sqrt(Complex32 value)
{
return value.SquareRoot();
}
}
}

580
src/Numerics/ComplexExtensions.cs

@ -0,0 +1,580 @@
// <copyright file="ComplexExtensions.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://mathnet.opensourcedotnet.info
//
// Copyright (c) 2009-2010 Math.NET
//
// 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.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics
{
using System;
using System.Collections.Generic;
using System.Numerics;
/// <summary>
/// Extension methods
/// </summary>
public static class ComplexExtensions
{
/// <summary>
/// Gets a value indicating whether the <c>Complex32</c> is zero.
/// </summary>
/// <value><c>true</c> if this instance is zero; otherwise, <c>false</c>.</value>
public static bool IsZero(this Complex complex)
{
return complex.Real == 0.0 && complex.Imaginary == 0.0;
}
/// <summary>
/// Gets a value indicating whether the <c>Complex32</c> is one.
/// </summary>
/// <value><c>true</c> if this instance is one; otherwise, <c>false</c>.</value>
public static bool IsOne(this Complex complex)
{
return complex.Real == 1.0 && complex.Imaginary == 0.0;
}
/// <summary>
/// Gets a value indicating whether the <c>Complex32</c> is the imaginary unit.
/// </summary>
/// <value><c>true</c> if this instance is ImaginaryOne; otherwise, <c>false</c>.</value>
public static bool IsImaginaryOne(this Complex complex)
{
return complex.Real == 0.0 && complex.Imaginary == 1.0;
}
/// <summary>
/// Gets a value indicating whether the provided <c>Complex32</c>evaluates
/// to a value that is not a number.
/// </summary>
/// <value>
/// <c>true</c> if this instance is <see cref="NaN"/>; otherwise,
/// <c>false</c>.
/// </value>
public static bool IsNaN(this Complex complex)
{
return double.IsNaN(complex.Real) || double.IsNaN(complex.Imaginary);
}
/// <summary>
/// Gets a value indicating whether the provided <c>Complex32</c> evaluates to an
/// infinite value.
/// </summary>
/// <value>
/// <c>true</c> if this instance is infinite; otherwise, <c>false</c>.
/// </value>
/// <remarks>
/// True if it either evaluates to a complex infinity
/// or to a directed infinity.
/// </remarks>
public static bool IsInfinity(this Complex complex)
{
return double.IsInfinity(complex.Real) || double.IsInfinity(complex.Imaginary);
}
/// <summary>
/// Gets a value indicating whether the provided <c>Complex32</c> is real.
/// </summary>
/// <value><c>true</c> if this instance is a real number; otherwise, <c>false</c>.</value>
public static bool IsReal(this Complex complex)
{
return complex.Imaginary == 0.0;
}
/// <summary>
/// Gets a value indicating whether the provided <c>Complex32</c> is real and not negative, that is &gt;= 0.
/// </summary>
/// <value>
/// <c>true</c> if this instance is real nonnegative number; otherwise, <c>false</c>.
/// </value>
public static bool IsRealNonNegative(this Complex complex)
{
return complex.Imaginary == 0.0f && complex.Real >= 0;
}
/// <summary>
/// Gets the conjugate of this <c>Complex32</c>.
/// </summary>
/// <remarks>
/// The semantic of <i>setting the conjugate</i> is such that
/// <code>
/// // a, b of type Complex32
/// a.Conjugate = b;
/// </code>
/// is equivalent to
/// <code>
/// // a, b of type Complex32
/// a = b.Conjugate
/// </code>
/// </remarks>
public static Complex Conjugate(this Complex complex)
{
return new Complex(complex.Real, -complex.Imaginary);
}
/// <summary>
/// Gets the squared magnitude of this <c>Complex</c>.
/// </summary>
public static double MagnitudeSquared(this Complex complex)
{
return (complex.Real * complex.Real) + (complex.Imaginary * complex.Imaginary);
}
/// <summary>
/// Exponential of this <c>Complex</c> (exp(x), E^x).
/// </summary>
/// <returns>
/// The exponential of this complex number.
/// </returns>
public static Complex Exponential(this Complex complex)
{
var exp = Math.Exp(complex.Real);
if (complex.IsReal())
{
return new Complex(exp, 0.0);
}
return new Complex(exp * Trig.Cosine(complex.Imaginary), exp * Trig.Sine(complex.Imaginary));
}
/// <summary>
/// Natural Logarithm of this <c>Complex</c> (Base E).
/// </summary>
/// <returns>
/// The natural logarithm of this complex number.
/// </returns>
public static Complex NaturalLogarithm(this Complex complex)
{
if (complex.IsRealNonNegative())
{
return new Complex(Math.Log(complex.Real), 0.0);
}
return new Complex(0.5 * Math.Log(complex.MagnitudeSquared()), complex.Phase);
}
/// <summary>
/// Raise this <c>Complex</c> to the given value.
/// </summary>
/// <param name="exponent">
/// The exponent.
/// </param>
/// <returns>
/// The complex number raised to the given exponent.
/// </returns>
public static Complex Power(this Complex complex, Complex exponent)
{
if (complex.IsZero())
{
if (exponent.IsZero())
{
return Complex.One;
}
if (exponent.Real > 0.0)
{
return Complex.Zero;
}
if (exponent.Real < 0)
{
if (exponent.Imaginary == 0.0)
{
return new Complex(double.PositiveInfinity, 0.0);
}
return new Complex(double.PositiveInfinity, double.PositiveInfinity);
}
return double.NaN;
}
return (exponent * complex.NaturalLogarithm()).Exponential();
}
/// <summary>
/// Raise this <c>Complex</c> to the inverse of the given value.
/// </summary>
/// <param name="rootExponent">
/// The root exponent.
/// </param>
/// <returns>
/// The complex raised to the inverse of the given exponent.
/// </returns>
public static Complex Root(this Complex complex, Complex rootExponent)
{
return Power(complex, 1 / rootExponent);
}
/// <summary>
/// The Square (power 2) of this <c>Complex</c>
/// </summary>
/// <returns>
/// The square of this complex number.
/// </returns>
public static Complex Square(this Complex complex)
{
if (complex.IsReal())
{
return new Complex(complex.Real * complex.Real, 0.0);
}
return new Complex((complex.Real * complex.Real) - (complex.Imaginary * complex.Imaginary), 2 * complex.Real * complex.Imaginary);
}
/// <summary>
/// The Square Root (power 1/2) of this <c>Complex</c>
/// </summary>
/// <returns>
/// The square root of this complex number.
/// </returns>
public static Complex SquareRoot(this Complex complex)
{
if (complex.IsRealNonNegative())
{
return new Complex(Math.Sqrt(complex.Real), 0.0);
}
Complex result;
var absReal = Math.Abs(complex.Real);
var absImag = Math.Abs(complex.Imaginary);
double w;
if (absReal >= absImag)
{
var ratio = complex.Imaginary / complex.Real;
w = Math.Sqrt(absReal) * Math.Sqrt(0.5 * (1.0 + Math.Sqrt(1.0 + (ratio * ratio))));
}
else
{
var ratio = complex.Real / complex.Imaginary;
w = Math.Sqrt(absImag) * Math.Sqrt(0.5 * (Math.Abs(ratio) + Math.Sqrt(1.0 + (ratio * ratio))));
}
if (complex.Real >= 0.0)
{
result = new Complex(w, complex.Imaginary / (2.0 * w));
}
else if (complex.Imaginary >= 0.0)
{
result = new Complex(absImag / (2.0 * w), w);
}
else
{
result = new Complex(absImag / (2.0 * w), -w);
}
return result;
}
/// <summary>
/// Returns a Norm of a value of this type, which is appropriate for measuring how
/// close this value is to zero.
/// </summary>
/// <returns>A norm of this value.</returns>
public static double Norm(this Complex complex)
{
return complex.MagnitudeSquared();
}
/// <summary>
/// Returns a Norm of the difference of two values of this type, which is
/// appropriate for measuring how close together these two values are.
/// </summary>
/// <param name="otherValue">The value to compare with.</param>
/// <returns>A norm of the difference between this and the other value.</returns>
public static double NormOfDifference(this Complex complex, Complex otherValue)
{
return (complex- otherValue).MagnitudeSquared();
}
/// <summary>
/// Creates a complex number based on a string. The string can be in the
/// following formats (without the quotes): 'n', 'ni', 'n +/- ni',
/// 'ni +/- n', 'n,n', 'n,ni,' '(n,n)', or '(n,ni)', where n is a double.
/// </summary>
/// <returns>
/// A complex number containing the value specified by the given string.
/// </returns>
/// <param name="value">
/// The string to parse.
/// </param>
public static Complex ToComplex(this string value)
{
return value.ToComplex(null);
}
/// <summary>
/// Creates a complex number based on a string. The string can be in the
/// following formats (without the quotes): 'n', 'ni', 'n +/- ni',
/// 'ni +/- n', 'n,n', 'n,ni,' '(n,n)', or '(n,ni)', where n is a double.
/// </summary>
/// <returns>
/// A complex number containing the value specified by the given string.
/// </returns>
/// <param name="value">
/// the string to parse.
/// </param>
/// <param name="formatProvider">
/// An <see cref="IFormatProvider"/> that supplies culture-specific
/// formatting information.
/// </param>
public static Complex ToComplex(this string value, IFormatProvider formatProvider)
{
if (value == null)
{
throw new ArgumentNullException(value);
}
value = value.Trim();
if (value.Length == 0)
{
throw new FormatException();
}
// strip out parens
if (value.StartsWith("(", StringComparison.Ordinal))
{
if (!value.EndsWith(")", StringComparison.Ordinal))
{
throw new FormatException();
}
value = value.Substring(1, value.Length - 2).Trim();
}
// keywords
var numberFormatInfo = formatProvider.GetNumberFormatInfo();
var textInfo = formatProvider.GetTextInfo();
var keywords =
new[]
{
textInfo.ListSeparator, numberFormatInfo.NaNSymbol,
numberFormatInfo.NegativeInfinitySymbol, numberFormatInfo.PositiveInfinitySymbol,
"+", "-", "i", "j"
};
// lexing
var tokens = new LinkedList<string>();
GlobalizationHelper.Tokenize(tokens.AddFirst(value), keywords, 0);
var token = tokens.First;
// parse the left part
bool isLeftPartImaginary;
double leftPart = ParsePart(ref token, out isLeftPartImaginary, formatProvider);
if (token == null)
{
return isLeftPartImaginary ? new Complex(0, leftPart) : new Complex(leftPart, 0);
}
// parse the right part
if (token.Value == textInfo.ListSeparator)
{
// format: real,imag
token = token.Next;
if (isLeftPartImaginary)
{
// left must not contain 'i', right doesn't matter.
throw new FormatException();
}
bool isRightPartImaginary;
double rightPart = ParsePart(ref token, out isRightPartImaginary, formatProvider);
return new Complex(leftPart, rightPart);
}
else
{
// format: real + imag
bool isRightPartImaginary;
double rightPart = ParsePart(ref token, out isRightPartImaginary, formatProvider);
if (!(isLeftPartImaginary ^ isRightPartImaginary))
{
// either left or right part must contain 'i', but not both.
throw new FormatException();
}
return isLeftPartImaginary ? new Complex(rightPart, leftPart) : new Complex(leftPart, rightPart);
}
}
/// <summary>
/// Parse a part (real or complex) from a complex number.
/// </summary>
/// <param name="token">Start Token.</param>
/// <param name="imaginary">Is set to <c>true</c> if the part identified itself as being imaginary.</param>
/// <param name="format">
/// An <see cref="IFormatProvider"/> that supplies culture-specific
/// formatting information.
/// </param>
/// <returns>Resulting part as double.</returns>
/// <exception cref="FormatException"/>
private static double ParsePart(ref LinkedListNode<string> token, out bool imaginary, IFormatProvider format)
{
imaginary = false;
if (token == null)
{
throw new FormatException();
}
// handle prefix modifiers
if (token.Value == "+")
{
token = token.Next;
if (token == null)
{
throw new FormatException();
}
}
bool negative = false;
if (token.Value == "-")
{
negative = true;
token = token.Next;
if (token == null)
{
throw new FormatException();
}
}
// handle prefix imaginary symbol
if (String.Compare(token.Value, "i", StringComparison.OrdinalIgnoreCase) == 0
|| String.Compare(token.Value, "j", StringComparison.OrdinalIgnoreCase) == 0)
{
imaginary = true;
token = token.Next;
if (token == null)
{
return negative ? -1 : 1;
}
}
#if SILVERLIGHT
var value = GlobalizationHelper.ParseDouble(ref token);
#else
var value = GlobalizationHelper.ParseDouble(ref token, format.GetCultureInfo());
#endif
// handle suffix imaginary symbol
if (token != null && (String.Compare(token.Value, "i", StringComparison.OrdinalIgnoreCase) == 0
|| String.Compare(token.Value, "j", StringComparison.OrdinalIgnoreCase) == 0))
{
if (imaginary)
{
// only one time allowed: either prefix or suffix, or neither.
throw new FormatException();
}
imaginary = true;
token = token.Next;
}
return negative ? -value : value;
}
/// <summary>
/// Converts the string representation of a complex number to a double-precision complex number equivalent.
/// A return value indicates whether the conversion succeeded or failed.
/// </summary>
/// <param name="value">
/// A string containing a complex number to convert.
/// </param>
/// <param name="result">
/// The parsed value.
/// </param>
/// <returns>
/// If the conversion succeeds, the result will contain a complex number equivalent to value.
/// Otherwise the result will contain complex32.Zero. This parameter is passed uninitialized
/// </returns>
public static bool TryToComplex(this string value, out Complex result)
{
return value.TryToComplex(null, out result);
}
/// <summary>
/// Converts the string representation of a complex number to double-precision complex number equivalent.
/// A return value indicates whether the conversion succeeded or failed.
/// </summary>
/// <param name="value">
/// A string containing a complex number to convert.
/// </param>
/// <param name="formatProvider">
/// An <see cref="IFormatProvider"/> that supplies culture-specific formatting information about value.
/// </param>
/// <param name="result">
/// The parsed value.
/// </param>
/// <returns>
/// If the conversion succeeds, the result will contain a complex number equivalent to value.
/// Otherwise the result will contain complex32.Zero. This parameter is passed uninitialized
/// </returns>
public static bool TryToComplex(this string value, IFormatProvider formatProvider, out Complex result)
{
bool ret;
try
{
result = value.ToComplex(formatProvider);
ret = true;
}
catch (ArgumentNullException)
{
result = Complex.Zero;
ret = false;
}
catch (FormatException)
{
result = Complex.Zero;
ret = false;
}
return ret;
}
public static Complex32 ToComplex32(this string value)
{
return Complex32.Parse(value);
}
public static Complex32 ToComplex32(this string value, IFormatProvider formatProvider)
{
return Complex32.Parse(value, formatProvider);
}
public static bool TryToComplex32(this string value, out Complex32 result)
{
return Complex32.TryParse(value, out result);
}
public static bool TryToComplex32(this string value, IFormatProvider formatProvider, out Complex32 result)
{
return Complex32.TryParse(value, formatProvider, out result);
}
}
}

5
src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.Bluestein.cs

@ -29,6 +29,7 @@
namespace MathNet.Numerics.IntegralTransforms.Algorithms
{
using System;
using System.Numerics;
using NumberTheory;
using Threading;
@ -91,7 +92,7 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
// Build and transform padded sequence a_k = x_k * exp(-I*Pi*k^2/N)
for (int i = 0; i < samples.Length; i++)
{
a[i] = sequence[i].Conjugate * samples[i];
a[i] = sequence[i].Conjugate() * samples[i];
}
Radix2(a, -1);
@ -107,7 +108,7 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
var nbinv = 1.0 / m;
for (int i = 0; i < samples.Length; i++)
{
samples[i] = nbinv * sequence[i].Conjugate * a[i];
samples[i] = nbinv * sequence[i].Conjugate() * a[i];
}
}

1
src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.Naive.cs

@ -29,6 +29,7 @@
namespace MathNet.Numerics.IntegralTransforms.Algorithms
{
using System;
using System.Numerics;
using Threading;
/// <summary>

1
src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.Options.cs

@ -29,6 +29,7 @@
namespace MathNet.Numerics.IntegralTransforms.Algorithms
{
using System;
using System.Numerics;
/// <summary>
/// Complex Fast (FFT) Implementation of the Discrete Fourier Transform (DFT).

1
src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.RadixN.cs

@ -29,6 +29,7 @@
namespace MathNet.Numerics.IntegralTransforms.Algorithms
{
using System;
using System.Numerics;
using NumberTheory;
using Properties;
using Threading;

1
src/Numerics/IntegralTransforms/Transform.cs

@ -28,6 +28,7 @@
namespace MathNet.Numerics.IntegralTransforms
{
using System.Numerics;
using Algorithms;
/// <summary>

3
src/Numerics/Numerics.csproj

@ -63,6 +63,7 @@
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Numerics" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
@ -91,7 +92,7 @@
<DependentUpon>SafeNativeMethods.tt</DependentUpon>
</Compile>
<Compile Include="Combinatorics.cs" />
<Compile Include="Complex.cs" />
<Compile Include="ComplexExtensions.cs" />
<Compile Include="Constants.cs" />
<Compile Include="Control.cs" />
<Compile Include="Complex32.cs" />

54
src/Numerics/Precision.cs

@ -30,6 +30,7 @@ namespace MathNet.Numerics
{
using System;
using System.Collections.Generic;
using System.Numerics;
/// <summary>
/// Utilities for working with floating point numbers.
@ -767,6 +768,23 @@ namespace MathNet.Numerics
return AlmostEqualWithError(a.Norm(), b.Norm(), diff, _defaultDoubleRelativeAccuracy);
}
/// <summary>
/// Compares two doubles and determines if they are equal within
/// the specified maximum error.
/// </summary>
/// <param name="a">The first value.</param>
/// <param name="b">The second value.</param>
/// <param name="maximumError">The accuracy required for being almost equal.</param>
/// <returns>
/// <see langword="true" /> if both doubles are almost equal up to the
/// specified maximum error, <see langword="false" /> otherwise.
/// </returns>
public static bool AlmostEqualWithError(this Complex a, Complex b, double maximumError)
{
double diff = a.NormOfDifference(b);
return AlmostEqualWithError(a.Norm(), b.Norm(), diff, maximumError);
}
/// <summary>
/// Compares two doubles and determines if they are equal within
/// the specified maximum error.
@ -819,6 +837,42 @@ namespace MathNet.Numerics
return true;
}
/// <summary>
/// Compares two lists of doubles and determines if they are equal within the
/// specified maximum error.
/// </summary>
/// <param name="a">The first value list.</param>
/// <param name="b">The second value list.</param>
/// <param name="maximumError">
/// The accuracy required for being almost equal.
/// </param>
/// <returns>
/// <see langword="true" /> if both doubles are almost equal up to the specified
/// maximum error, <see langword="false" /> otherwise.
/// </returns>
public static bool AlmostEqualListWithError(this IList<Complex> a, IList<Complex> b, double maximumError)
{
if (a == null && b == null)
{
return true;
}
if (a == null || b == null || a.Count != b.Count)
{
return false;
}
for (int i = 0; i < a.Count; i++)
{
if (!AlmostEqualWithError(a[i].Norm(), b[i].Norm(), a[i].NormOfDifference(b[i]), maximumError))
{
return false;
}
}
return true;
}
/// <summary>
/// Compares two structure with precision support and determines if they are equal
/// within the specified maximum relative error.

31
src/Numerics/Trigonometry.cs

@ -25,6 +25,7 @@
namespace MathNet.Numerics
{
using System;
using System.Numerics;
/// <summary>
/// Double-precision trigonometry toolkit.
@ -61,7 +62,7 @@ namespace MathNet.Numerics
/// </returns>
public static Complex Cosecant(this Complex value)
{
if (value.IsReal)
if (value.IsReal())
{
return new Complex(Cosecant(value.Real), 0d);
}
@ -98,7 +99,7 @@ namespace MathNet.Numerics
/// </returns>
public static Complex Cosine(this Complex value)
{
if (value.IsReal)
if (value.IsReal())
{
return new Complex(Cosine(value.Real), 0.0);
}
@ -133,7 +134,7 @@ namespace MathNet.Numerics
/// </returns>
public static Complex Cotangent(this Complex value)
{
if (value.IsReal)
if (value.IsReal())
{
return new Complex(Cotangent(value.Real), 0d);
}
@ -226,14 +227,14 @@ namespace MathNet.Numerics
/// </returns>
public static Complex HyperbolicCosecant(this Complex value)
{
if (value.IsReal)
if (value.IsReal())
{
return new Complex(HyperbolicCosecant(value.Real), 0.0);
}
var exp = value.Exponential();
if (exp.IsInfinity)
if (exp.IsInfinity())
{
return Complex.Zero;
}
@ -266,7 +267,7 @@ namespace MathNet.Numerics
/// </returns>
public static Complex HyperbolicCosine(this Complex value)
{
if (value.IsReal)
if (value.IsReal())
{
return new Complex(HyperbolicCosine(value.Real), 0.0);
}
@ -313,7 +314,7 @@ namespace MathNet.Numerics
/// </returns>
public static Complex HyperbolicCotangent(this Complex value)
{
if (value.IsReal)
if (value.IsReal())
{
return new Complex(HyperbolicCotangent(value.Real), 0.0);
}
@ -356,14 +357,14 @@ namespace MathNet.Numerics
/// </returns>
public static Complex HyperbolicSecant(this Complex value)
{
if (value.IsReal)
if (value.IsReal())
{
return new Complex(HyperbolicSecant(value.Real), 0.0);
}
var exp = value.Exponential();
if (exp.IsInfinity)
if (exp.IsInfinity())
{
return Complex.Zero;
}
@ -396,7 +397,7 @@ namespace MathNet.Numerics
/// </returns>
public static Complex HyperbolicSine(this Complex value)
{
if (value.IsReal)
if (value.IsReal())
{
return new Complex(HyperbolicSine(value.Real), 0.0);
}
@ -443,7 +444,7 @@ namespace MathNet.Numerics
/// </returns>
public static Complex HyperbolicTangent(this Complex value)
{
if (value.IsReal)
if (value.IsReal())
{
return new Complex(HyperbolicTangent(value.Real), 0.0);
}
@ -549,7 +550,7 @@ namespace MathNet.Numerics
/// </returns>
public static Complex InverseCotangent(this Complex value)
{
if (value.IsZero)
if (value.IsZero())
{
return Math.PI / 2.0;
}
@ -868,7 +869,7 @@ namespace MathNet.Numerics
/// </returns>
public static Complex Secant(this Complex value)
{
if (value.IsReal)
if (value.IsReal())
{
return new Complex(Secant(value.Real), 0d);
}
@ -905,7 +906,7 @@ namespace MathNet.Numerics
/// </returns>
public static Complex Sine(this Complex value)
{
if (value.IsReal)
if (value.IsReal())
{
return new Complex(Sine(value.Real), 0.0);
}
@ -940,7 +941,7 @@ namespace MathNet.Numerics
/// </returns>
public static Complex Tangent(this Complex value)
{
if (value.IsReal)
if (value.IsReal())
{
return new Complex(Tangent(value.Real), 0.0);
}

10
src/Silverlight/Silverlight.csproj

@ -14,7 +14,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MathNet.Numerics</RootNamespace>
<AssemblyName>MathNet.Numerics.Silverlight</AssemblyName>
<TargetFrameworkVersion>v3.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<SilverlightApplication>false</SilverlightApplication>
<ValidateXaml>true</ValidateXaml>
<ThrowErrorsInValidation>true</ThrowErrorsInValidation>
@ -41,6 +41,7 @@
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -66,6 +67,7 @@
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System.Numerics, Version=2.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<Reference Include="System.Windows" />
<Reference Include="mscorlib" />
<Reference Include="system" />
@ -87,12 +89,12 @@
<Compile Include="..\Numerics\Combinatorics.cs">
<Link>Combinatorics.cs</Link>
</Compile>
<Compile Include="..\Numerics\Complex.cs">
<Link>Complex.cs</Link>
</Compile>
<Compile Include="..\Numerics\Complex32.cs">
<Link>Complex32.cs</Link>
</Compile>
<Compile Include="..\Numerics\ComplexExtensions.cs">
<Link>ComplexExtensions.cs</Link>
</Compile>
<Compile Include="..\Numerics\Constants.cs">
<Link>Constants.cs</Link>
</Compile>

19
src/UnitTests/AssertHelpers.cs

@ -30,6 +30,7 @@
namespace MathNet.Numerics.UnitTests
{
using System.Collections.Generic;
using System.Numerics;
using MbUnit.Framework;
/// <summary>
@ -158,5 +159,23 @@ namespace MathNet.Numerics.UnitTests
}
}
}
/// <summary>
/// Asserts that the expected value and the actual value are equal up to a certain
/// maximum error.
/// </summary>
/// <param name="expected">The expected value list.</param>
/// <param name="actual">The actual value list.</param>
/// <param name="maximumError">The accuracy required for being almost equal.</param>
public static void AlmostEqualList(IList<Complex> expected, IList<Complex> actual, double maximumError)
{
for (int i = 0; i < expected.Count; i++)
{
if (!actual[i].AlmostEqualWithError(expected[i], maximumError))
{
Assert.Fail("Not equal within a maximum error {0}. Expected:{1}; Actual:{2}", maximumError, expected[i], actual[i]);
}
}
}
}
}

77
src/UnitTests/ComplexTests/Complex32Test.cs

@ -29,6 +29,7 @@
namespace MathNet.Numerics.UnitTests.ComplexTests
{
using System;
using System.Numerics;
using MbUnit.Framework;
[TestFixture]
@ -38,10 +39,10 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[MultipleAsserts]
public void CanAddComplexNumberAndDoubleUsingOperartor()
{
AssertEx.That(() => (Complex32.NaN + float.NaN).IsNaN);
AssertEx.That(() => (float.NaN + Complex32.NaN).IsNaN);
AssertEx.That(() => (float.PositiveInfinity + Complex32.One).IsInfinity);
AssertEx.That(() => (Complex32.Infinity + 1.0f).IsInfinity);
AssertEx.That(() => (Complex32.NaN + float.NaN).IsNaN());
AssertEx.That(() => (float.NaN + Complex32.NaN).IsNaN());
AssertEx.That(() => (float.PositiveInfinity + Complex32.One).IsInfinity());
AssertEx.That(() => (Complex32.Infinity + 1.0f).IsInfinity());
AssertEx.That(() => (Complex32.One + 0.0f) == Complex32.One);
AssertEx.That(() => (0.0f + Complex32.One) == Complex32.One);
AssertEx.That(() => (new Complex32(1.1f, -2.2f) + 1.1f == new Complex32(2.2f, -2.2f)));
@ -52,8 +53,8 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[MultipleAsserts]
public void CanAddSubtractComplexNumbersUsingOperartor()
{
AssertEx.That(() => (Complex32.NaN - Complex32.NaN).IsNaN);
AssertEx.That(() => (Complex32.Infinity - Complex32.One).IsInfinity);
AssertEx.That(() => (Complex32.NaN - Complex32.NaN).IsNaN());
AssertEx.That(() => (Complex32.Infinity - Complex32.One).IsInfinity());
AssertEx.That(() => (Complex32.One - Complex32.Zero) == Complex32.One);
AssertEx.That(() => (new Complex32(1.1f, -2.2f) - new Complex32(1.1f, -2.2f)) == Complex32.Zero);
}
@ -62,8 +63,8 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[MultipleAsserts]
public void CanAddTwoComplexNumbers()
{
AssertEx.That(() => Complex32.NaN.Add(Complex32.NaN).IsNaN);
AssertEx.That(() => Complex32.Infinity.Add(Complex32.One).IsInfinity);
AssertEx.That(() => Complex32.NaN.Add(Complex32.NaN).IsNaN());
AssertEx.That(() => Complex32.Infinity.Add(Complex32.One).IsInfinity());
AssertEx.That(() => Complex32.One.Add(Complex32.Zero) == Complex32.One);
AssertEx.That(() => new Complex32(1.1f, -2.2f).Add(new Complex32(-1.1f, 2.2f)) == Complex32.Zero);
}
@ -72,8 +73,8 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[MultipleAsserts]
public void CanAddTwoComplexNumbersUsingOperartor()
{
AssertEx.That(() => (Complex32.NaN + Complex32.NaN).IsNaN);
AssertEx.That(() => (Complex32.Infinity + Complex32.One).IsInfinity);
AssertEx.That(() => (Complex32.NaN + Complex32.NaN).IsNaN());
AssertEx.That(() => (Complex32.Infinity + Complex32.One).IsInfinity());
AssertEx.That(() => (Complex32.One + Complex32.Zero) == Complex32.One);
AssertEx.That(() => (new Complex32(1.1f, -2.2f) + new Complex32(-1.1f, 2.2f)) == Complex32.Zero);
}
@ -156,7 +157,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
AssertHelpers.AlmostEqual(new Complex32(float.PositiveInfinity, float.PositiveInfinity), a.Power(b), 7);
a = new Complex32(0.0f, 0.0f);
b = new Complex32(0.0f, 1.0f);
AssertEx.That(() => a.Power(b).IsNaN);
AssertEx.That(() => a.Power(b).IsNaN());
}
[Test]
@ -230,8 +231,8 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[MultipleAsserts]
public void CanConvertDoubleToComplex()
{
AssertEx.That(() => ((Complex32)float.NaN).IsNaN);
AssertEx.That(() => ((Complex32)float.NegativeInfinity).IsInfinity);
AssertEx.That(() => ((Complex32)float.NaN).IsNaN());
AssertEx.That(() => ((Complex32)float.NegativeInfinity).IsInfinity());
Assert.AreEqual(1.1f, new Complex32(1.1f, 0));
}
@ -267,7 +268,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
public void CanDetermineIfImaginaryUnit()
{
var complex = new Complex32(0, 1);
Assert.IsTrue(complex.IsImaginaryOne, "Imaginary unit");
Assert.IsTrue(complex.IsImaginaryOne(), "Imaginary unit");
}
[Test]
@ -275,11 +276,11 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
public void CanDetermineIfInfinity()
{
var complex = new Complex32(float.PositiveInfinity, 1);
Assert.IsTrue(complex.IsInfinity, "Real part is infinity.");
Assert.IsTrue(complex.IsInfinity(), "Real part is infinity.");
complex = new Complex32(1, float.NegativeInfinity);
Assert.IsTrue(complex.IsInfinity, "Imaginary part is infinity.");
Assert.IsTrue(complex.IsInfinity(), "Imaginary part is infinity.");
complex = new Complex32(float.NegativeInfinity, float.PositiveInfinity);
Assert.IsTrue(complex.IsInfinity, "Both parts are infinity.");
Assert.IsTrue(complex.IsInfinity(), "Both parts are infinity.");
}
[Test]
@ -287,46 +288,46 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
public void CanDetermineIfNaN()
{
var complex = new Complex32(float.NaN, 1);
Assert.IsTrue(complex.IsNaN, "Real part is NaN.");
Assert.IsTrue(complex.IsNaN(), "Real part is NaN.");
complex = new Complex32(1, float.NaN);
Assert.IsTrue(complex.IsNaN, "Imaginary part is NaN.");
Assert.IsTrue(complex.IsNaN(), "Imaginary part is NaN.");
complex = new Complex32(float.NaN, float.NaN);
Assert.IsTrue(complex.IsNaN, "Both parts are NaN.");
Assert.IsTrue(complex.IsNaN(), "Both parts are NaN.");
}
[Test]
public void CanDetermineIfOneValueComplexNumber()
{
var complex = new Complex32(1, 0);
Assert.IsTrue(complex.IsOne, "Complex32 number with a value of one.");
Assert.IsTrue(complex.IsOne(), "Complex32 number with a value of one.");
}
[Test]
public void CanDetermineIfRealNonNegativeNumber()
{
var complex = new Complex32(1, 0);
Assert.IsTrue(complex.IsReal, "Is a real non-negative number.");
Assert.IsTrue(complex.IsReal(), "Is a real non-negative number.");
}
[Test]
public void CanDetermineIfRealNumber()
{
var complex = new Complex32(-1, 0);
Assert.IsTrue(complex.IsReal, "Is a real number.");
Assert.IsTrue(complex.IsReal(), "Is a real number.");
}
[Test]
public void CanDetermineIfZeroValueComplexNumber()
{
var complex = new Complex32(0, 0);
Assert.IsTrue(complex.IsZero, "Zero complex number.");
Assert.IsTrue(complex.IsZero(), "Zero complex number.");
}
[Test]
[MultipleAsserts]
public void CanDivideComplexNumberAndDoubleUsingOperators()
{
AssertEx.That(() => (Complex32.NaN * 1.0f).IsNaN);
AssertEx.That(() => (Complex32.NaN * 1.0f).IsNaN());
Assert.AreEqual(new Complex32(-2, 2), new Complex32(4, -4) / -2);
Assert.AreEqual(new Complex32(0.25f, 0.25f), 2 / new Complex32(4, -4));
Assert.AreEqual(Complex32.Infinity, 2.0f / Complex32.Zero);
@ -337,7 +338,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[MultipleAsserts]
public void CanDivideTwoComplexNumbers()
{
AssertEx.That(() => Complex32.NaN.Multiply(Complex32.One).IsNaN);
AssertEx.That(() => Complex32.NaN.Multiply(Complex32.One).IsNaN());
Assert.AreEqual(new Complex32(-2, 0), new Complex32(4, -4).Divide(new Complex32(-2, 2)));
Assert.AreEqual(Complex32.Infinity, Complex32.One.Divide(Complex32.Zero));
}
@ -346,7 +347,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[MultipleAsserts]
public void CanDivideTwoComplexNumbersUsingOperators()
{
AssertEx.That(() => (Complex32.NaN / Complex32.One).IsNaN);
AssertEx.That(() => (Complex32.NaN / Complex32.One).IsNaN());
Assert.AreEqual(new Complex32(-2, 0), new Complex32(4, -4) / new Complex32(-2, 2));
Assert.AreEqual(Complex32.Infinity, Complex32.One / Complex32.Zero);
}
@ -355,7 +356,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[MultipleAsserts]
public void CanMultipleComplexNumberAndDoubleUsingOperators()
{
AssertEx.That(() => (Complex32.NaN * 1.0f).IsNaN);
AssertEx.That(() => (Complex32.NaN * 1.0f).IsNaN());
Assert.AreEqual(new Complex32(8, -8), new Complex32(4, -4) * 2);
Assert.AreEqual(new Complex32(8, -8), 2 * new Complex32(4, -4));
}
@ -364,7 +365,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[MultipleAsserts]
public void CanMultipleTwoComplexNumbers()
{
AssertEx.That(() => Complex32.NaN.Multiply(Complex32.One).IsNaN);
AssertEx.That(() => Complex32.NaN.Multiply(Complex32.One).IsNaN());
Assert.AreEqual(new Complex32(0, 16), new Complex32(4, -4).Multiply(new Complex32(-2, 2)));
}
@ -372,7 +373,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[MultipleAsserts]
public void CanMultipleTwoComplexNumbersUsingOperators()
{
AssertEx.That(() => (Complex32.NaN * Complex32.One).IsNaN);
AssertEx.That(() => (Complex32.NaN * Complex32.One).IsNaN());
Assert.AreEqual(new Complex32(0, 16), new Complex32(4, -4) * new Complex32(-2, 2));
}
@ -394,10 +395,10 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[MultipleAsserts]
public void CanSubtractComplexNumberAndDoubleUsingOperartor()
{
AssertEx.That(() => (Complex32.NaN - float.NaN).IsNaN);
AssertEx.That(() => (float.NaN - Complex32.NaN).IsNaN);
AssertEx.That(() => (float.PositiveInfinity - Complex32.One).IsInfinity);
AssertEx.That(() => (Complex32.Infinity - 1.0f).IsInfinity);
AssertEx.That(() => (Complex32.NaN - float.NaN).IsNaN());
AssertEx.That(() => (float.NaN - Complex32.NaN).IsNaN());
AssertEx.That(() => (float.PositiveInfinity - Complex32.One).IsInfinity());
AssertEx.That(() => (Complex32.Infinity - 1.0f).IsInfinity());
AssertEx.That(() => (Complex32.One - 0.0f) == Complex32.One);
AssertEx.That(() => (0.0f - Complex32.One) == -Complex32.One);
AssertEx.That(() => (new Complex32(1.1f, -2.2f) - 1.1f == new Complex32(0.0f, -2.2f)));
@ -408,8 +409,8 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[MultipleAsserts]
public void CanSubtractTwoComplexNumbers()
{
AssertEx.That(() => Complex32.NaN.Subtract(Complex32.NaN).IsNaN);
AssertEx.That(() => Complex32.Infinity.Subtract(Complex32.One).IsInfinity);
AssertEx.That(() => Complex32.NaN.Subtract(Complex32.NaN).IsNaN());
AssertEx.That(() => Complex32.Infinity.Subtract(Complex32.One).IsInfinity());
AssertEx.That(() => Complex32.One.Subtract(Complex32.Zero) == Complex32.One);
AssertEx.That(() => new Complex32(1.1f, -2.2f).Subtract(new Complex32(1.1f, -2.2f)) == Complex32.Zero);
}
@ -563,8 +564,8 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[Test]
public void CanGetConjugate()
{
var complex = new Complex(123.456, -78.9);
var conjugate = complex.Conjugate;
var complex = new Complex32(123.456f, -78.9f);
var conjugate = complex.Conjugate();
Assert.AreEqual(complex.Real, conjugate.Real);
Assert.AreEqual(-complex.Imaginary, conjugate.Imaginary);
}

136
src/UnitTests/ComplexTests/ComplexTest.TextHandling.cs

@ -31,97 +31,12 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
using System;
using System.Globalization;
using MbUnit.Framework;
using System.Numerics;
[TestFixture]
public class ComplexTextHandlingTest
{
[Test]
[Row(1, -2, "1 -2i")]
[Row(1, 2, "1 + 2i")]
[Row(1, 0, "1")]
[Row(0, -2, "-2i")]
[Row(0, 2, "2i")]
[Row(0, 2, "2i")]
[Row(0, 0, "0")]
[Row(Double.NaN, Double.NaN, "{1}")]
[Row(Double.NaN, 0, "{1}")]
[Row(0, Double.NaN, "{1}")]
[Row(Double.PositiveInfinity, Double.PositiveInfinity, "{2}")]
[Row(1.1, 0, "1{0}1")]
[Row(-1.1, 0, "-1{0}1")]
[Row(0, 1.1, "1{0}1i")]
[Row(0, -1.1, "-1{0}1i")]
[Row(1.1, 1.1, "1{0}1 + 1{0}1i")]
public void CanFormatComplexToString(double real, double imag, string expected)
{
var numberFormat = NumberFormatInfo.CurrentInfo;
var a = new Complex(real, imag);
Assert.AreEqual(
String.Format(
expected,
numberFormat.NumberDecimalSeparator,
numberFormat.NaNSymbol,
numberFormat.PositiveInfinitySymbol),
a.ToString());
}
[Test]
[MultipleAsserts]
[Row("en-US", "NaN", "Infinity", "1.1")]
[Row("tr-TR", "NaN", "Infinity", "1,1")]
[Row("de-DE", "n. def.", "+unendlich", "1,1")]
[Row("de-CH", "n. def.", "+unendlich", "1.1")]
[Row("he-IL", "לא מספר", "אינסוף חיובי", "1.1")]
public void CanFormatComplexToStringWithCulture(
string cultureName, string nan, string infinity, string number)
{
var provider = CultureInfo.GetCultureInfo(cultureName);
Assert.AreEqual(nan, Complex.NaN.ToString(provider));
Assert.AreEqual(infinity, Complex.Infinity.ToString(provider));
Assert.AreEqual("0", Complex.Zero.ToString(provider));
Assert.AreEqual(String.Format("{0}", number), new Complex(1.1, 0).ToString(provider));
Assert.AreEqual(String.Format("-{0}", number), new Complex(-1.1, 0).ToString(provider));
Assert.AreEqual(String.Format("-{0}i", number), new Complex(0, -1.1).ToString(provider));
Assert.AreEqual(String.Format("{0}i", number), new Complex(0, 1.1).ToString(provider));
Assert.AreEqual(String.Format("{0} + {0}i", number), new Complex(1.1, 1.1).ToString(provider));
}
[Test]
[MultipleAsserts]
public void CanFormatComplexToStringWithFormat()
{
Assert.AreEqual("0", String.Format("{0:G}", Complex.Zero));
Assert.AreEqual("1 + 2i", String.Format("{0:G}", new Complex(1, 2)));
Assert.AreEqual("001 + 002i", String.Format("{0:000;minus 000;zero}", new Complex(1, 2)));
Assert.AreEqual("minus 002i", String.Format("{0:000;minus 000;zero}", new Complex(0, -2)));
Assert.AreEqual("zero", String.Format("{0:000;minus 000;zero}", Complex.Zero));
Assert.AreEqual("0", Complex.Zero.ToString("G"));
Assert.AreEqual("1 + 2i", new Complex(1, 2).ToString("G"));
Assert.AreEqual("001 + 002i", new Complex(1, 2).ToString("#000;minus 000;zero"));
Assert.AreEqual("minus 002i", new Complex(0, -2).ToString("#000;minus 000;zero"));
Assert.AreEqual("zero", Complex.Zero.ToString("#000;minus 000;zero"));
}
[Test]
[MultipleAsserts]
public void CanFormatComplexToStringWithFormatInvariant()
{
var culture = CultureInfo.InvariantCulture;
Assert.AreEqual("NaN", String.Format(culture, "{0:.000}", Complex.NaN));
Assert.AreEqual(".000", String.Format(culture, "{0:.000}", Complex.Zero));
Assert.AreEqual("1.100", String.Format(culture, "{0:.000}", new Complex(1.1, 0)));
Assert.AreEqual("1.100 + 1.100i", String.Format(culture, "{0:.000}", new Complex(1.1, 1.1)));
Assert.AreEqual("NaN", Complex.NaN.ToString("#.000", culture));
Assert.AreEqual("Infinity", Complex.Infinity.ToString("#.000", culture));
Assert.AreEqual(".000", Complex.Zero.ToString("#.000", culture));
Assert.AreEqual("1.100", new Complex(1.1, 0).ToString("#.000", culture));
Assert.AreEqual("-1.100i", new Complex(0, -1.1).ToString("#.000", culture));
Assert.AreEqual("1.100i", new Complex(0, 1.1).ToString("#.000", culture));
Assert.AreEqual("1.100 + 1.100i", new Complex(1.1, 1.1).ToString("#.000", culture));
}
[Test]
[Row("-1 -2i", -1, -2, "en-US")]
@ -129,7 +44,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
public void CanParseStringToComplexWithCulture(
string text, double expectedReal, double expectedImaginary, string cultureName)
{
Complex parsed = Complex.Parse(text, CultureInfo.GetCultureInfo(cultureName));
Complex parsed = text.ToComplex(CultureInfo.GetCultureInfo(cultureName));
Assert.AreEqual(expectedReal, parsed.Real);
Assert.AreEqual(expectedImaginary, parsed.Imaginary);
}
@ -167,7 +82,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
{
var invariantCulture = CultureInfo.InvariantCulture;
Complex z;
var ret = Complex.TryParse(str, invariantCulture, out z);
var ret = str.TryToComplex(invariantCulture, out z);
Assert.IsTrue(ret);
Assert.AreEqual(expectedReal, z.Real);
Assert.AreEqual(expectedImaginary, z.Imaginary);
@ -176,7 +91,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[Test]
public void ParseThrowsFormatExceptionIfMissingClosingParen()
{
Assert.Throws<FormatException>(() => Complex.Parse("(1,2"));
Assert.Throws<FormatException>(() => "(1,2".ToComplex());
}
[Test]
@ -185,30 +100,33 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
Complex z;
var ni = NumberFormatInfo.CurrentInfo;
var separator = CultureInfo.CurrentCulture.TextInfo.ListSeparator;
var ret = Complex.TryParse(
ni.NegativeInfinitySymbol + separator + ni.PositiveInfinitySymbol, out z);
var symbol = ni.NegativeInfinitySymbol + separator + ni.PositiveInfinitySymbol;
var ret = symbol.TryToComplex(out z);
Assert.IsTrue(ret, "A1");
Assert.AreEqual(double.NegativeInfinity, z.Real, "A2");
Assert.AreEqual(double.PositiveInfinity, z.Imaginary, "A3");
ret = Complex.TryParse(ni.NaNSymbol + separator + ni.NaNSymbol, out z);
symbol = ni.NaNSymbol + separator + ni.NaNSymbol;
ret = symbol.TryToComplex(out z);
Assert.IsTrue(ret, "B1");
Assert.AreEqual(double.NaN, z.Real, "B2");
Assert.AreEqual(double.NaN, z.Imaginary, "B3");
ret = Complex.TryParse(ni.NegativeInfinitySymbol + "+" + ni.PositiveInfinitySymbol + "i", out z);
symbol = ni.NegativeInfinitySymbol + "+" + ni.PositiveInfinitySymbol + "i";
ret = symbol.TryToComplex(out z);
Assert.IsTrue(ret, "C1");
Assert.AreEqual(double.NegativeInfinity, z.Real, "C2");
Assert.AreEqual(double.PositiveInfinity, z.Imaginary, "C3");
ret = Complex.TryParse(ni.NaNSymbol + "+" + ni.NaNSymbol + "i", out z);
symbol = ni.NaNSymbol + "+" + ni.NaNSymbol + "i";
ret = symbol.TryToComplex(out z);
Assert.IsTrue(ret, "D1");
Assert.AreEqual(double.NaN, z.Real, "D2");
Assert.AreEqual(double.NaN, z.Imaginary, "D3");
ret = Complex.TryParse(
double.MaxValue.ToString("R") + " " + double.MinValue.ToString("R") + "i",
out z);
symbol = double.MaxValue.ToString("R") + " " + double.MinValue.ToString("R") + "i";
ret = symbol.TryToComplex(out z);
Assert.IsTrue(ret, "E1");
Assert.AreEqual(double.MaxValue, z.Real, "E2");
Assert.AreEqual(double.MinValue, z.Imaginary, "E3");
@ -226,31 +144,33 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
var culture = CultureInfo.GetCultureInfo(cultureName);
var ni = culture.NumberFormat;
var separator = culture.TextInfo.ListSeparator;
var ret = Complex.TryParse(
ni.NegativeInfinitySymbol + separator + ni.PositiveInfinitySymbol, culture, out z);
var symbol = ni.NegativeInfinitySymbol + separator + ni.PositiveInfinitySymbol;
var ret = symbol.TryToComplex(culture, out z);
Assert.IsTrue(ret, "A1");
Assert.AreEqual(double.NegativeInfinity, z.Real, "A2");
Assert.AreEqual(double.PositiveInfinity, z.Imaginary, "A3");
ret = Complex.TryParse(ni.NaNSymbol + separator + ni.NaNSymbol, culture, out z);
symbol = ni.NaNSymbol + separator + ni.NaNSymbol;
ret = symbol.TryToComplex(culture, out z);
Assert.IsTrue(ret, "B1");
Assert.AreEqual(double.NaN, z.Real, "B2");
Assert.AreEqual(double.NaN, z.Imaginary, "B3");
ret = Complex.TryParse(ni.NegativeInfinitySymbol + "+" + ni.PositiveInfinitySymbol + "i", culture, out z);
symbol = ni.NegativeInfinitySymbol + "+" + ni.PositiveInfinitySymbol + "i";
ret = symbol.TryToComplex(culture, out z);
Assert.IsTrue(ret, "C1");
Assert.AreEqual(double.NegativeInfinity, z.Real, "C2");
Assert.AreEqual(double.PositiveInfinity, z.Imaginary, "C3");
ret = Complex.TryParse(ni.NaNSymbol + "+" + ni.NaNSymbol + "i", culture, out z);
symbol = ni.NaNSymbol + "+" + ni.NaNSymbol + "i";
ret = symbol.TryToComplex(culture, out z);
Assert.IsTrue(ret, "D1");
Assert.AreEqual(double.NaN, z.Real, "D2");
Assert.AreEqual(double.NaN, z.Imaginary, "D3");
ret = Complex.TryParse(
double.MaxValue.ToString("R", culture) + " " + double.MinValue.ToString("R", culture) + "i",
culture,
out z);
symbol = double.MaxValue.ToString("R", culture) + " " + double.MinValue.ToString("R", culture) + "i";
ret = symbol.TryToComplex(culture, out z);
Assert.IsTrue(ret, "E1");
Assert.AreEqual(double.MaxValue, z.Real, "E2");
Assert.AreEqual(double.MinValue, z.Imaginary, "E3");
@ -275,7 +195,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
public void TryParseReturnsFalseWhenGivenBadValueWithInvariant(string str)
{
Complex z;
var ret = Complex.TryParse(str, CultureInfo.InvariantCulture, out z);
var ret = str.TryToComplex(CultureInfo.InvariantCulture, out z);
Assert.IsFalse(ret);
Assert.AreEqual(0, z.Real);
Assert.AreEqual(0, z.Imaginary);

604
src/UnitTests/ComplexTests/ComplexTest.cs

@ -26,69 +26,15 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.UnitTests.ComplexTests
namespace MathNet.Numerics.UnitTests.ComplexExtensionTests
{
using System;
using System.Numerics;
using MbUnit.Framework;
[TestFixture]
public class ComplexTest
public class ComplexExtensionTest
{
[Test]
[MultipleAsserts]
public void CanAddComplexNumberAndDoubleUsingOperartor()
{
AssertEx.That(() => (Complex.NaN + double.NaN).IsNaN);
AssertEx.That(() => (double.NaN + Complex.NaN).IsNaN);
AssertEx.That(() => (double.PositiveInfinity + Complex.One).IsInfinity);
AssertEx.That(() => (Complex.Infinity + 1.0).IsInfinity);
AssertEx.That(() => (Complex.One + 0.0) == Complex.One);
AssertEx.That(() => (0.0 + Complex.One) == Complex.One);
AssertEx.That(() => (new Complex(1.1, -2.2) + 1.1 == new Complex(2.2, -2.2)));
AssertEx.That(() => -2.2 + new Complex(-1.1, 2.2) == new Complex(-3.3, 2.2));
}
[Test]
[MultipleAsserts]
public void CanAddSubtractComplexNumbersUsingOperartor()
{
AssertEx.That(() => (Complex.NaN - Complex.NaN).IsNaN);
AssertEx.That(() => (Complex.Infinity - Complex.One).IsInfinity);
AssertEx.That(() => (Complex.One - Complex.Zero) == Complex.One);
AssertEx.That(() => (new Complex(1.1, -2.2) - new Complex(1.1, -2.2)) == Complex.Zero);
}
[Test]
[MultipleAsserts]
public void CanAddTwoComplexNumbers()
{
AssertEx.That(() => Complex.NaN.Add(Complex.NaN).IsNaN);
AssertEx.That(() => Complex.Infinity.Add(Complex.One).IsInfinity);
AssertEx.That(() => Complex.One.Add(Complex.Zero) == Complex.One);
AssertEx.That(() => new Complex(1.1, -2.2).Add(new Complex(-1.1, 2.2)) == Complex.Zero);
}
[Test]
[MultipleAsserts]
public void CanAddTwoComplexNumbersUsingOperartor()
{
AssertEx.That(() => (Complex.NaN + Complex.NaN).IsNaN);
AssertEx.That(() => (Complex.Infinity + Complex.One).IsInfinity);
AssertEx.That(() => (Complex.One + Complex.Zero) == Complex.One);
AssertEx.That(() => (new Complex(1.1, -2.2) + new Complex(-1.1, 2.2)) == Complex.Zero);
}
[Test]
[MultipleAsserts]
public void CanCalculateHashCode()
{
var complex = new Complex(1, 0);
Assert.AreEqual(1072693248, complex.GetHashCode());
complex = new Complex(0, 1);
Assert.AreEqual(-1072693248, complex.GetHashCode());
complex = new Complex(1, 1);
Assert.AreEqual(-2097152, complex.GetHashCode());
}
[Test]
[Row(0.0, 0.0, 1.0, 0.0)]
@ -102,18 +48,6 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
AssertHelpers.AlmostEqual(expected, value.Exponential(), 15);
}
[Test]
[Row(0.0, 0.0, 1.0, 0.0)]
[Row(0.0, 1.0, 0.54030230586813977, 0.8414709848078965)]
[Row(-1.0, 1.0, 0.19876611034641295, 0.30955987565311222)]
[Row(-111.1, 111.1, -2.3259065941590448e-49, -5.1181940185795617e-49)]
public void CanComputeExp(double real, double imag, double expectedReal, double expectedImag)
{
var value = new Complex(real, imag);
var expected = new Complex(expectedReal, expectedImag);
AssertHelpers.AlmostEqual(expected, Complex.Exp(value), 15);
}
[Test]
[Row(0.0, 0.0, double.NegativeInfinity, 0.0)]
[Row(0.0, 1.0, 0.0, 1.5707963267948966)]
@ -127,32 +61,6 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
AssertHelpers.AlmostEqual(expected, value.NaturalLogarithm(), 15);
}
[Test]
[Row(0.0, 0.0, double.NegativeInfinity, 0.0)]
[Row(0.0, 1.0, 0.0, 1.5707963267948966)]
[Row(-1.0, 1.0, 0.34657359027997264, 2.3561944901923448)]
[Row(-111.1, 111.1, 5.0570042869255571, 2.3561944901923448)]
[Row(111.1, -111.1, 5.0570042869255571, -0.78539816339744828)]
public void CanComputeLog(double real, double imag, double expectedReal, double expectedImag)
{
var value = new Complex(real, imag);
var expected = new Complex(expectedReal, expectedImag);
AssertHelpers.AlmostEqual(expected, Complex.Log(value), 15);
}
[Test]
[Row(0.0, 0.0, double.NegativeInfinity, 0.0)]
[Row(0.0, 1.0, 0.0, 0.68218817692092071)]
[Row(-1.0, 1.0, 0.1505149978319906, 1.0232822653813811)]
[Row(-111.1, 111.1, 2.1962290567728582, 1.0232822653813811)]
[Row(111.1, -111.1, 2.1962290567728582, -0.34109408846046035)]
public void CanComputeLog10(double real, double imag, double expectedReal, double expectedImag)
{
var value = new Complex(real, imag);
var expected = new Complex(expectedReal, expectedImag);
AssertHelpers.AlmostEqual(expected, Complex.Log10(value), 15);
}
[Test]
[MultipleAsserts]
public void CanComputePower()
@ -193,21 +101,9 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
AssertHelpers.AlmostEqual(new Complex(double.PositiveInfinity, double.PositiveInfinity), a.Power(b), 15);
a = new Complex(0.0, 0.0);
b = new Complex(0.0, 1.0);
AssertEx.That(() => a.Power(b).IsNaN);
AssertEx.That(() => a.Power(b).IsNaN());
}
[Test]
[MultipleAsserts]
public void CanComputePow()
{
var a = new Complex(1.19209289550780998537e-7, 1.19209289550780998537e-7);
var b = new Complex(1.19209289550780998537e-7, 1.19209289550780998537e-7);
AssertHelpers.AlmostEqual(new Complex(9.99998047207974718744e-1, -1.76553541154378695012e-6), Complex.Pow(a,b), 15);
a = new Complex(0.0, -8.388608e6);
AssertHelpers.AlmostEqual(new Complex(1.00000190048219620166, -1.87253870018168043834e-7), Complex.Pow(a, 1.19209289550780998537e-7), 15);
}
[Test]
[MultipleAsserts]
public void CanComputeRoot()
@ -275,79 +171,11 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
AssertHelpers.AlmostEqual(Complex.Zero, complex.SquareRoot(), 15);
}
[Test]
[MultipleAsserts]
public void CanComputeSqrt()
{
var complex = new Complex(1.19209289550780998537e-7, 1.19209289550780998537e-7);
AssertHelpers.AlmostEqual(new Complex(0.00037933934912842666, 0.00015712750315077684), Complex.Sqrt(complex), 15);
complex = new Complex(0.0, 1.19209289550780998537e-7);
AssertHelpers.AlmostEqual(new Complex(0.00024414062499999973, 0.00024414062499999976), Complex.Sqrt(complex), 15);
complex = new Complex(0.0, -1.19209289550780998537e-7);
AssertHelpers.AlmostEqual(new Complex(0.00024414062499999973, -0.00024414062499999976), Complex.Sqrt(complex), 15);
complex = new Complex(0.0, 0.5);
AssertHelpers.AlmostEqual(new Complex(0.5, 0.5), Complex.Sqrt(complex), 15);
complex = new Complex(0.0, -0.5);
AssertHelpers.AlmostEqual(new Complex(0.5, -0.5), Complex.Sqrt(complex), 15);
complex = new Complex(0.0, -8.388608e6);
AssertHelpers.AlmostEqual(new Complex(2048.0, -2048.0), Complex.Sqrt(complex), 15);
complex = new Complex(8.388608e6, 1.19209289550780998537e-7);
AssertHelpers.AlmostEqual(new Complex(2896.3093757400989, 2.0579515874459933e-11), Complex.Sqrt(complex), 15);
complex = new Complex(0.0, 0.0);
AssertHelpers.AlmostEqual(Complex.Zero, Complex.Sqrt(complex), 15);
}
[Test]
[MultipleAsserts]
public void CanConvertDoubleToComplex()
{
AssertEx.That(() => ((Complex)double.NaN).IsNaN);
AssertEx.That(() => ((Complex)double.NegativeInfinity).IsInfinity);
Assert.AreEqual(1.1, new Complex(1.1, 0));
}
[Test]
[MultipleAsserts]
public void CanCreateComplexNumberUsingTheConstructor()
{
var complex = new Complex(1.1, -2.2);
Assert.AreEqual(1.1, complex.Real, "Real part is 1.1.");
Assert.AreEqual(-2.2, complex.Imaginary, "Imaginary part is -2.2.");
}
[Test]
[MultipleAsserts]
public void CanCreateComplexNumberWithModulusArgument()
{
var complex = Complex.WithModulusArgument(2, -Math.PI / 6);
Assert.AreApproximatelyEqual(Math.Sqrt(3), complex.Real, 1e-15, "Real part is Sqrt(3).");
Assert.AreApproximatelyEqual(-1, complex.Imaginary, 1e-15, "Imaginary part is -1.");
}
[Test]
[MultipleAsserts]
public void CanCreateComplexNumberFromPolarCoordinates()
{
var complex = Complex.FromPolarCoordinates(2, -Math.PI / 6);
Assert.AreApproximatelyEqual(Math.Sqrt(3), complex.Real, 1e-15, "Real part is Sqrt(3).");
Assert.AreApproximatelyEqual(-1, complex.Imaginary, 1e-15, "Imaginary part is -1.");
}
[Test]
[MultipleAsserts]
public void CanCreateComplexNumberWithRealImaginaryIntializer()
{
var complex = Complex.WithRealImaginary(1.1, -2.2);
Assert.AreEqual(1.1, complex.Real, "Real part is 1.1.");
Assert.AreEqual(-2.2, complex.Imaginary, "Imaginary part is -2.2.");
}
[Test]
public void CanDetermineIfImaginaryUnit()
{
var complex = new Complex(0, 1);
Assert.IsTrue(complex.IsImaginaryOne, "Imaginary unit");
Assert.IsTrue(complex.IsImaginaryOne(), "Imaginary unit");
}
[Test]
@ -355,11 +183,11 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
public void CanDetermineIfInfinity()
{
var complex = new Complex(double.PositiveInfinity, 1);
Assert.IsTrue(complex.IsInfinity, "Real part is infinity.");
Assert.IsTrue(complex.IsInfinity(), "Real part is infinity.");
complex = new Complex(1, double.NegativeInfinity);
Assert.IsTrue(complex.IsInfinity, "Imaginary part is infinity.");
Assert.IsTrue(complex.IsInfinity(), "Imaginary part is infinity.");
complex = new Complex(double.NegativeInfinity, double.PositiveInfinity);
Assert.IsTrue(complex.IsInfinity, "Both parts are infinity.");
Assert.IsTrue(complex.IsInfinity(), "Both parts are infinity.");
}
[Test]
@ -367,439 +195,39 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
public void CanDetermineIfNaN()
{
var complex = new Complex(double.NaN, 1);
Assert.IsTrue(complex.IsNaN, "Real part is NaN.");
Assert.IsTrue(complex.IsNaN(), "Real part is NaN.");
complex = new Complex(1, double.NaN);
Assert.IsTrue(complex.IsNaN, "Imaginary part is NaN.");
Assert.IsTrue(complex.IsNaN(), "Imaginary part is NaN.");
complex = new Complex(double.NaN, double.NaN);
Assert.IsTrue(complex.IsNaN, "Both parts are NaN.");
Assert.IsTrue(complex.IsNaN(), "Both parts are NaN.");
}
[Test]
public void CanDetermineIfOneValueComplexNumber()
{
var complex = new Complex(1, 0);
Assert.IsTrue(complex.IsOne, "Complex number with a value of one.");
Assert.IsTrue(complex.IsOne(), "Complex number with a value of one.");
}
[Test]
public void CanDetermineIfRealNonNegativeNumber()
{
var complex = new Complex(1, 0);
Assert.IsTrue(complex.IsReal, "Is a real non-negative number.");
Assert.IsTrue(complex.IsReal(), "Is a real non-negative number.");
}
[Test]
public void CanDetermineIfRealNumber()
{
var complex = new Complex(-1, 0);
Assert.IsTrue(complex.IsReal, "Is a real number.");
Assert.IsTrue(complex.IsReal(), "Is a real number.");
}
[Test]
public void CanDetermineIfZeroValueComplexNumber()
{
var complex = new Complex(0, 0);
Assert.IsTrue(complex.IsZero, "Zero complex number.");
}
[Test]
[MultipleAsserts]
public void CanDivideComplexNumberAndDoubleUsingOperators()
{
AssertEx.That(() => (Complex.NaN * 1.0).IsNaN);
Assert.AreEqual(new Complex(-2, 2), new Complex(4, -4) / -2);
Assert.AreEqual(new Complex(0.25, 0.25), 2 / new Complex(4, -4));
Assert.AreEqual(Complex.Infinity, 2.0 / Complex.Zero);
Assert.AreEqual(Complex.Infinity, Complex.One / 0);
}
[Test]
[MultipleAsserts]
public void CanDivideTwoComplexNumbers()
{
AssertEx.That(() => Complex.NaN.Multiply(Complex.One).IsNaN);
Assert.AreEqual(new Complex(-2, 0), new Complex(4, -4).Divide(new Complex(-2, 2)));
Assert.AreEqual(Complex.Infinity, Complex.One.Divide(Complex.Zero));
}
[Test]
[MultipleAsserts]
public void CanDivideTwoComplexNumbersUsingOperators()
{
AssertEx.That(() => (Complex.NaN / Complex.One).IsNaN);
Assert.AreEqual(new Complex(-2, 0), new Complex(4, -4) / new Complex(-2, 2));
Assert.AreEqual(Complex.Infinity, Complex.One / Complex.Zero);
}
[Test]
[MultipleAsserts]
public void CanMultipleComplexNumberAndDoubleUsingOperators()
{
AssertEx.That(() => (Complex.NaN * 1.0).IsNaN);
Assert.AreEqual(new Complex(8, -8), new Complex(4, -4) * 2);
Assert.AreEqual(new Complex(8, -8), 2 * new Complex(4, -4));
}
[Test]
[MultipleAsserts]
public void CanMultipleTwoComplexNumbers()
{
AssertEx.That(() => Complex.NaN.Multiply(Complex.One).IsNaN);
Assert.AreEqual(new Complex(0, 16), new Complex(4, -4).Multiply(new Complex(-2, 2)));
}
[Test]
[MultipleAsserts]
public void CanMultipleTwoComplexNumbersUsingOperators()
{
AssertEx.That(() => (Complex.NaN * Complex.One).IsNaN);
Assert.AreEqual(new Complex(0, 16), new Complex(4, -4) * new Complex(-2, 2));
}
[Test]
public void CanNegateValue()
{
var complex = new Complex(1.1, -2.2);
Assert.AreEqual(new Complex(-1.1, 2.2), complex.Negate());
}
[Test]
public void CanNegateValueUsingOperator()
{
var complex = new Complex(1.1, -2.2);
Assert.AreEqual(new Complex(-1.1, 2.2), -complex);
}
[Test]
[MultipleAsserts]
public void CanSubtractComplexNumberAndDoubleUsingOperartor()
{
AssertEx.That(() => (Complex.NaN - double.NaN).IsNaN);
AssertEx.That(() => (double.NaN - Complex.NaN).IsNaN);
AssertEx.That(() => (double.PositiveInfinity - Complex.One).IsInfinity);
AssertEx.That(() => (Complex.Infinity - 1.0).IsInfinity);
AssertEx.That(() => (Complex.One - 0.0) == Complex.One);
AssertEx.That(() => (0.0 - Complex.One) == -Complex.One);
AssertEx.That(() => (new Complex(1.1, -2.2) - 1.1 == new Complex(0.0, -2.2)));
AssertEx.That(() => -2.2 - new Complex(-1.1, 2.2) == new Complex(-1.1, -2.2));
}
[Test]
[MultipleAsserts]
public void CanSubtractTwoComplexNumbers()
{
AssertEx.That(() => Complex.NaN.Subtract(Complex.NaN).IsNaN);
AssertEx.That(() => Complex.Infinity.Subtract(Complex.One).IsInfinity);
AssertEx.That(() => Complex.One.Subtract(Complex.Zero) == Complex.One);
AssertEx.That(() => new Complex(1.1, -2.2).Subtract(new Complex(1.1, -2.2)) == Complex.Zero);
}
[Test]
[MultipleAsserts]
public void CanTestForEquality()
{
Assert.AreNotEqual(Complex.NaN, Complex.NaN);
Assert.AreEqual(Complex.Infinity, Complex.Infinity);
Assert.AreEqual(new Complex(1.1, -2.2), new Complex(1.1, -2.2));
Assert.AreNotEqual(new Complex(-1.1, 2.2), new Complex(1.1, -2.2));
}
[Test]
[MultipleAsserts]
public void CanTestForEqualityUsingOperators()
{
AssertEx.That(() => Complex.NaN != Complex.NaN);
AssertEx.That(() => Complex.Infinity == Complex.Infinity);
AssertEx.That(() => new Complex(1.1, -2.2) == new Complex(1.1, -2.2));
AssertEx.That(() => new Complex(-1.1, 2.2) != new Complex(1.1, -2.2));
}
[Test]
public void CanUsePlus()
{
var complex = new Complex(1.1, -2.2);
Assert.AreEqual(complex, complex.Plus());
}
[Test]
public void CanUsePlusOperator()
{
var complex = new Complex(1.1, -2.2);
Assert.AreEqual(complex, +complex);
}
[Test]
public void WithModulusArgumentThrowsArgumentOutOfRangeException()
{
Assert.Throws<ArgumentOutOfRangeException>(
() => Complex.WithModulusArgument(-1, 1), "Throws exception because modulus is negative.");
}
[Test]
[Row(0.0, 0.0, 0.0)]
[Row(0.0, 1.0, 1.0)]
[Row(-1.0, 1.0, 1.4142135623730951)]
[Row(-111.1, 111.1, 157.11912677965086)]
public void CanComputeMagnitude(double real, double imag, double expected)
{
Assert.AreEqual(expected, new Complex(real, imag).Magnitude);
}
[Test]
[Row(0.0, 0.0, 0.0)]
[Row(0.0, 1.0, 1.0)]
[Row(-1.0, 1.0, 1.4142135623730951)]
[Row(-111.1, 111.1, 157.11912677965086)]
public void CanComputeAbs(double real, double imag, double expected)
{
Assert.AreEqual(expected, Complex.Abs(new Complex(real, imag)));
}
[Test]
[Row(double.PositiveInfinity, double.PositiveInfinity, Constants.Sqrt1Over2, Constants.Sqrt1Over2)]
[Row(double.PositiveInfinity, double.NegativeInfinity, Constants.Sqrt1Over2, -Constants.Sqrt1Over2)]
[Row(double.NegativeInfinity, double.PositiveInfinity, -Constants.Sqrt1Over2, -Constants.Sqrt1Over2)]
[Row(double.NegativeInfinity, double.NegativeInfinity, -Constants.Sqrt1Over2, Constants.Sqrt1Over2)]
[Row(0.0, 0.0, 0.0, 0.0)]
[Row(-1.0, 1.0, -0.70710678118654746, 0.70710678118654746)]
[Row(-111.1, 111.1, -0.70710678118654746, 0.70710678118654746)]
public void CanComputeSign(double real, double imag, double expectedReal, double expectedImag)
{
Assert.AreEqual(new Complex(expectedReal, expectedImag), new Complex(real, imag).Sign);
}
[Test]
[Row(0.0, 0.0, 1.0, 0.0)]
[Row(8.388608e6, 0.0, -0.90175467375875928, 0.0)]
[Row(-8.388608e6, 0.0, -0.90175467375875928, 0.0)]
[Row(1.19209289550780998537e-7, 0.0, 0.99999999999999289, 0.0)]
[Row(-1.19209289550780998537e-7, 0.0, 0.99999999999999289, 0.0)]
[Row(8.388608e6, 1.19209289550780998537e-7, -0.90175467375876572, -5.1528001100635277e-8)]
[Row(-1.19209289550780998537e-7, -8.388608e6, double.PositiveInfinity, double.NegativeInfinity)]
public void CanComputeCos(double real, double imag, double expectedReal, double expectedImag)
{
var actual = Complex.Cos(new Complex(real, imag));
var expected = new Complex(expectedReal, expectedImag);
AssertHelpers.AlmostEqual(expected, actual, 13);
}
[Test]
[Row(0.0, 0.0, 0.0, 0.0)]
[Row(8.388608e6, 0.0, 0.43224820225679778, 0.0)]
[Row(-8.388608e6, 0.0, -0.43224820225679778, 0.0)]
[Row(1.19209289550780998537e-7, 0.0, 1.19209289550780998537e-7, 0.0)]
[Row(-1.19209289550780998537e-7, 0.0, -1.19209289550780998537e-7, 0.0)]
[Row(8.388608e6, 1.19209289550780998537e-7, 0.43224820225680083, -1.0749753400787824e-7)]
[Row(-1.19209289550780998537e-7, -8.388608e6, double.NegativeInfinity, double.NegativeInfinity)]
public void CanComputeSin(double real, double imag, double expectedReal, double expectedImag)
{
var actual = Complex.Sin(new Complex(real, imag));
var expected = new Complex(expectedReal, expectedImag);
AssertHelpers.AlmostEqual(expected, actual, 13);
}
[Test]
[Row(0.0, 0.0, 0.0, 0.0)]
[Row(8.388608e6, 0.0, -0.47934123862654288, 0.0)]
[Row(-8.388608e6, 0.0, 0.47934123862654288, 0.0)]
[Row(1.19209289550780998537e-7, 0.0, 1.1920928955078157e-7, 0.0)]
[Row(-1.19209289550780998537e-7, 0.0, -1.1920928955078157e-7, 0.0)]
[Row(8.388608e6, 1.19209289550780998537e-7, -0.47934123862653449, 1.4659977233982276e-7)]
[Row(-8.388608e6, -1.19209289550780998537e-7, 0.47934123862653449, -1.4659977233982276e-7)]
public void CanComputeTan(double real, double imag, double expectedReal, double expectedImag)
{
var actual = Complex.Tan(new Complex(real, imag));
var expected = new Complex(expectedReal, expectedImag);
AssertHelpers.AlmostEqual(expected, actual, 13);
}
[Test]
[Row(0.0, 0.0, 0.0, 0.0)]
[Row(8.388608e6, 0.0, double.PositiveInfinity, 0.0)]
[Row(-8.388608e6, 0.0, double.NegativeInfinity, 0.0)]
[Row(1.19209289550780998537e-7, 0.0, 1.1920928955078128e-7, 0.0)]
[Row(-1.19209289550780998537e-7, 0.0, -1.1920928955078128e-7, 0.0)]
[Row(8.388608e6, 1.19209289550780998537e-7, double.PositiveInfinity, double.PositiveInfinity)]
[Row(-8.388608e6, -1.19209289550780998537e-7, double.NegativeInfinity, double.NegativeInfinity)]
[Row(0.5, -0.5, 0.45730415318424922, -0.54061268571315335)]
public void CanComputeSinh(double real, double imag, double expectedReal, double expectedImag)
{
var actual = Complex.Sinh(new Complex(real, imag));
var expected = new Complex(expectedReal, expectedImag);
AssertHelpers.AlmostEqual(expected, actual, 14);
}
[Test]
[Row(0.0, 0.0, 1.0, 0.0)]
[Row(8.388608e6, 0.0, double.PositiveInfinity, 0.0)]
[Row(-8.388608e6, 0.0, double.PositiveInfinity, 0.0)]
[Row(1.19209289550780998537e-7, 0.0, 1.0000000000000071, 0.0)]
[Row(-1.19209289550780998537e-7, 0.0, 1.0000000000000071, 0.0)]
[Row(8.388608e6, 1.19209289550780998537e-7, double.PositiveInfinity, double.PositiveInfinity)]
[Row(-8.388608e6, -1.19209289550780998537e-7, double.PositiveInfinity, double.PositiveInfinity)]
[Row(0.5, -0.5, 0.9895848833999199, -0.24982639750046154)]
public void CanComputeCosh(double real, double imag, double expectedReal, double expectedImag)
{
var actual = Complex.Cosh(new Complex(real, imag));
var expected = new Complex(expectedReal, expectedImag);
AssertHelpers.AlmostEqual(expected, actual, 14);
}
[Test]
[Row(0.0, 0.0, 0.0, 0.0)]
[Row(8.388608e6, 0.0, 1.0, 0.0)]
[Row(-8.388608e6, 0.0, -1.0, 0.0)]
[Row(1.19209289550780998537e-7, 0.0, 1.1920928955078043e-7, 0.0)]
[Row(-1.19209289550780998537e-7, 0.0, -1.1920928955078043e-7, 0.0)]
[Row(8.388608e6, 1.19209289550780998537e-7, 1.0, 0.0)]
[Row(-8.388608e6, -1.19209289550780998537e-7, -1.0, 0.0)]
[Row(0.5, -0.5, 0.56408314126749848, -0.40389645531602575)]
public void CanComputeTanh(double real, double imag, double expectedReal, double expectedImag)
{
var actual = Complex.Tanh(new Complex(real, imag));
var expected = new Complex(expectedReal, expectedImag);
AssertHelpers.AlmostEqual(expected, actual, 14);
}
[Test]
[Row(0.0, 0.0, 0.0, 0.0)]
[Row(8.388608e6, 0.0, 1.5707963267948966, -16.635532333438682)]
[Row(-8.388608e6, 0.0, -1.5707963267948966, 16.635532333438682)]
[Row(1.19209289550780998537e-7, 0.0, 1.1920928955078128e-7, 0.0)]
[Row(-1.19209289550780998537e-7, 0.0, -1.1920928955078128e-7, 0.0)]
[Row(8.388608e6, 1.19209289550780998537e-7, 1.5707963267948966, 16.635532333438682)]
[Row(-8.388608e6, -1.19209289550780998537e-7, -1.5707963267948966, -16.635532333438682)]
[Row(0.5, -0.5, 0.4522784471511907, -0.53063753095251787)]
public void CanComputeAsin(double real, double imag, double expectedReal, double expectedImag)
{
var actual = Complex.Asin(new Complex(real, imag));
var expected = new Complex(expectedReal, expectedImag);
AssertHelpers.AlmostEqual(expected, actual, 14);
}
[Test]
[Row(0.0, 0.0, 1.5707963267948966, 0.0)]
[Row(8.388608e6, 0.0, 0.0, 16.635532333438682)]
[Row(-8.388608e6, 0.0, 3.1415926535897931, -16.635532333438682)]
[Row(1.19209289550780998537e-7, 0.0, 1.570796207585607, 0.0)]
[Row(-1.19209289550780998537e-7, 0.0, 1.5707964460041861, 0.0)]
[Row(8.388608e6, 1.19209289550780998537e-7, 1.4210854715202073e-14, -16.635532333438682)]
[Row(-8.388608e6, -1.19209289550780998537e-7, 3.1415926535897789, 16.63553233343868)]
[Row(0.5, -0.5, 1.1185178796437059, 0.53063753095251787)]
public void CanComputeAcos(double real, double imag, double expectedReal, double expectedImag)
{
var actual = Complex.Acos(new Complex(real, imag));
var expected = new Complex(expectedReal, expectedImag);
AssertHelpers.AlmostEqual(expected, actual, 14);
}
[Test]
[Row(0.0, 0.0, 0.0, 0.0)]
[Row(8.388608e6, 0.0, 1.570796207585607, 0.0)]
[Row(-8.388608e6, 0.0, -1.570796207585607, 0.0)]
[Row(1.19209289550780998537e-7, 0.0, 1.1920928955078043e-7, 0.0)]
[Row(-1.19209289550780998537e-7, 0.0, -1.1920928955078043e-7, 0.0)]
[Row(8.388608e6, 1.19209289550780998537e-7, 1.570796207585607, 0.0)]
[Row(-8.388608e6, -1.19209289550780998537e-7, -1.570796207585607, 0.0)]
[Row(0.5, -0.5, 0.5535743588970452, -0.40235947810852507)]
public void CanComputeAtan(double real, double imag, double expectedReal, double expectedImag)
{
var actual = Complex.Atan(new Complex(real, imag));
var expected = new Complex(expectedReal, expectedImag);
AssertHelpers.AlmostEqual(expected, actual, 14);
}
[Test]
[Row(0.0, 0.0, 0.0, 0.0)]
[Row(0, 8.388608e6, 0.0, -1.1920928955078125e-7)]
[Row(-8.388608e6, 8.388608e6, -5.9604644775390625e-8, -5.9604644775390625e-8)]
public void CanComputeReciprocal(double real, double imag, double expectedReal, double expectedImag)
{
var actual = Complex.Reciprocal(new Complex(real, imag));
var expected = new Complex(expectedReal, expectedImag);
AssertHelpers.AlmostEqual(expected, actual, 15);
}
[Test]
public void CanConvertDecimalToComplex()
{
var orginal = new decimal(1.234567890);
var complex = (Complex)orginal;
Assert.AreEqual(1.234567890, complex.Real);
Assert.AreEqual(0.0, complex.Imaginary);
}
[Test]
public void CanConvertByteToComplex()
{
const byte orginal = 123;
var complex = (Complex)orginal;
Assert.AreEqual(123, complex.Real);
Assert.AreEqual(0.0, complex.Imaginary);
}
[Test]
public void CanConvertShortToComplex()
{
const short orginal = 123;
var complex = (Complex)orginal;
Assert.AreEqual(123, complex.Real);
Assert.AreEqual(0.0, complex.Imaginary);
}
[Test]
public void CanConvertIntToComplex()
{
const int orginal = 123;
var complex = (Complex)orginal;
Assert.AreEqual(123, complex.Real);
Assert.AreEqual(0.0, complex.Imaginary);
}
[Test]
public void CanConvertLongToComplex()
{
const long orginal = 123;
var complex = (Complex)orginal;
Assert.AreEqual(123, complex.Real);
Assert.AreEqual(0.0, complex.Imaginary);
}
[Test]
public void CanConvertUIntToComplex()
{
const uint orginal = 123;
var complex = (Complex)orginal;
Assert.AreEqual(123, complex.Real);
Assert.AreEqual(0.0, complex.Imaginary);
}
[Test]
public void CanConvertULongToComplex()
{
const ulong orginal = 123;
var complex = (Complex)orginal;
Assert.AreEqual(123, complex.Real);
Assert.AreEqual(0.0, complex.Imaginary);
}
[Test]
public void CanConvertFloatToComplex()
{
const float orginal = 123.456789f;
var complex = (Complex)orginal;
Assert.AreEqual(123.456789f, (float)complex.Real);
Assert.AreEqual(0.0, complex.Imaginary);
}
[Test]
public void CanConvertComplex32ToComplex()
{
var complex32 = new Complex32(123.456f, -78.9f);
var complex = (Complex)complex32;
Assert.AreEqual(123.456f, (float)complex.Real);
Assert.AreEqual(-78.9f, (float)complex.Imaginary);
Assert.IsTrue(complex.IsZero(), "Zero complex number.");
}
}
}
}

1
src/UnitTests/IntegralTransformsTests/FourierTest.cs

@ -34,6 +34,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
using IntegralTransforms.Algorithms;
using MbUnit.Framework;
using Sampling;
using System.Numerics;
[TestFixture]
public class FourierTest

1
src/UnitTests/IntegralTransformsTests/HartleyTest.cs

@ -29,6 +29,7 @@
namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{
using System;
using System.Numerics;
using Distributions;
using IntegralTransforms;
using IntegralTransforms.Algorithms;

1
src/UnitTests/IntegralTransformsTests/InverseTransformTest.cs

@ -29,6 +29,7 @@
namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{
using System;
using System.Numerics;
using Distributions;
using IntegralTransforms;
using IntegralTransforms.Algorithms;

1
src/UnitTests/IntegralTransformsTests/MatchingNaiveTransformTest.cs

@ -29,6 +29,7 @@
namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{
using System;
using System.Numerics;
using Distributions;
using IntegralTransforms;
using IntegralTransforms.Algorithms;

5
src/UnitTests/IntegralTransformsTests/ParsevalTheoremTest.cs

@ -35,6 +35,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
using MbUnit.Framework;
using Sampling;
using Statistics;
using System.Numerics;
[TestFixture]
public class ParsevalTheoremTest
@ -48,7 +49,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
{
var samples = Sample.Random((u, v) => new Complex(u, v), _uniform, count);
var timeSpaceEnergy = (from s in samples select s.MagnitudeSquared).Mean();
var timeSpaceEnergy = (from s in samples select s.MagnitudeSquared()).Mean();
var work = new Complex[samples.Length];
samples.CopyTo(work, 0);
@ -56,7 +57,7 @@ namespace MathNet.Numerics.UnitTests.IntegralTransformsTests
// Default -> Symmetric Scaling
Transform.FourierForward(work);
var frequencySpaceEnergy = (from s in work select s.MagnitudeSquared).Mean();
var frequencySpaceEnergy = (from s in work select s.MagnitudeSquared()).Mean();
Assert.AreApproximatelyEqual(timeSpaceEnergy, frequencySpaceEnergy, 1e-12);
}

2
src/UnitTests/TrigonometryTest.cs

@ -1,7 +1,7 @@
namespace MathNet.Numerics.UnitTests
{
using System;
using System.Numerics;
using MbUnit.Framework;
[TestFixture]

1
src/UnitTests/UnitTests.csproj

@ -71,6 +71,7 @@
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>

Loading…
Cancel
Save