Browse Source

Realign complex types with System.Numerics

v2
Christoph Ruegg 14 years ago
parent
commit
f5b6500668
  1. 2
      MathNet.Numerics.sln.DotSettings
  2. 9
      src/FSharpUnitTests/SparseMatrixTests.fs
  3. 1049
      src/Numerics/Complex32.cs
  4. 1197
      src/Numerics/Complex64.cs
  5. 281
      src/Numerics/ComplexExtensions.cs
  6. 1
      src/Numerics/Numerics.csproj
  7. 16
      src/Numerics/TargetedPatchingOptOutAttribute.cs
  8. 3
      src/Portable/Portable.csproj
  9. 4
      src/UnitTests/ComplexTests/Complex32Test.TextHandling.cs
  10. 82
      src/UnitTests/ComplexTests/Complex32Test.cs
  11. 20
      src/UnitTests/ComplexTests/ComplexTest.cs
  12. 2
      src/UnitTests/LinearAlgebraTests/Complex32/VectorTests.cs

2
MathNet.Numerics.sln.DotSettings

@ -11,5 +11,7 @@
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_ANONYMOUS_METHOD_BLOCK/@EntryValue">False</s:Boolean> <s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_ANONYMOUS_METHOD_BLOCK/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_EMBRACED_INITIALIZER_BLOCK/@EntryValue">False</s:Boolean> <s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_EMBRACED_INITIALIZER_BLOCK/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/LINE_FEED_AT_FILE_END/@EntryValue">True</s:Boolean> <s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/LINE_FEED_AT_FILE_END/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_BINARY_OPSIGN/@EntryValue">True</s:Boolean> <s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_BEFORE_BINARY_OPSIGN/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LINES/@EntryValue">False</s:Boolean></wpf:ResourceDictionary> <s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LINES/@EntryValue">False</s:Boolean></wpf:ResourceDictionary>

9
src/FSharpUnitTests/SparseMatrixTests.fs

@ -12,16 +12,17 @@ module SparseMatrixTests =
let smallM = DenseMatrix.init 4 4 (fun i j -> if i = 1 && j = 2 then 1.0 else 0.0) :> Matrix<float> let smallM = DenseMatrix.init 4 4 (fun i j -> if i = 1 && j = 2 then 1.0 else 0.0) :> Matrix<float>
[<Test>] [<Test>]
let ``SparseMatrix.ofList`` () = let ``SparseMatrix.ofList`` () =
(SparseMatrix.ofList 4 4 [(1,2,1.0)] :> Matrix<float>) |> should equal smallM (SparseMatrix.ofList 4 4 [(1,2,1.0)] :> Matrix<float>) |> should equal smallM
[<Test>] [<Test>]
let ``SparseMatrix.ofSeq`` () = let ``SparseMatrix.ofSeq`` () =
(SparseMatrix.ofSeq 4 4 (Seq.ofList [(1,2,1.0)]) :> Matrix<float>) |> should equal smallM (SparseMatrix.ofSeq 4 4 (Seq.ofList [(1,2,1.0)]) :> Matrix<float>) |> should equal smallM
[<Test>] [<Test>]
let ``SparseMatrix.constDiag`` () = let ``SparseMatrix.constDiag`` () =
SparseMatrix.constDiag 100 2.0 |> should equal (2.0 * (SparseMatrix.Identity 100)) SparseMatrix.constDiag 100 2.0 |> should equal (2.0 * (SparseMatrix.Identity 100))
[<Test>] let ``SparseMatrix.diag`` () = [<Test>]
let ``SparseMatrix.diag`` () =
SparseMatrix.diag (new DenseVector(100, 2.0)) |> should equal (2.0 * (SparseMatrix.Identity 100)) SparseMatrix.diag (new DenseVector(100, 2.0)) |> should equal (2.0 * (SparseMatrix.Identity 100))

1049
src/Numerics/Complex32.cs

File diff suppressed because it is too large

1197
src/Numerics/Complex64.cs

File diff suppressed because it is too large

281
src/Numerics/ComplexExtensions.cs

@ -34,92 +34,59 @@ namespace MathNet.Numerics
using System.Collections.Generic; using System.Collections.Generic;
using System.Numerics; using System.Numerics;
#if !PORTABLE
using System.Runtime;
#endif
/// <summary> /// <summary>
/// Extension methods /// Extension methods for the Complex type provided by System.Numerics
/// </summary> /// </summary>
public static class ComplexExtensions public static class ComplexExtensions
{ {
/// <summary> /// <summary>
/// Gets a value indicating whether the <c>Complex32</c> is zero. /// Gets the squared magnitude of the <c>Complex</c> number.
/// </summary> /// </summary>
/// <param name="complex">The <see cref="Complex"/> number to perfom this operation on.</param> /// <param name="complex">The <see cref="Complex"/> number to perfom this operation on.</param>
/// <returns><c>true</c> if this instance is zero; otherwise, <c>false</c>.</returns> /// <returns>The squared magnitude of the <c>Complex</c> number.</returns>
public static bool IsZero(this Complex complex) public static double MagnitudeSquared(this Complex complex)
{ {
return complex.Real == 0.0 && complex.Imaginary == 0.0; return (complex.Real * complex.Real) + (complex.Imaginary * complex.Imaginary);
} }
/// <summary> /// <summary>
/// Gets a value indicating whether the <c>Complex32</c> is one. /// Gets the unity of this complex (same argument, but on the unit circle; exp(I*arg))
/// </summary> /// </summary>
/// <param name="complex">The <see cref="Complex"/> number to perfom this operation on.</param> /// <returns>The unity of this <c>Complex</c>.</returns>
/// <returns><c>true</c> if this instance is one; otherwise, <c>false</c>.</returns> public static Complex Sign(this Complex complex)
public static bool IsOne(this Complex complex)
{ {
return complex.Real == 1.0 && complex.Imaginary == 0.0; if (double.IsPositiveInfinity(complex.Real) && double.IsPositiveInfinity(complex.Imaginary))
} {
return new Complex(Constants.Sqrt1Over2, Constants.Sqrt1Over2);
}
/// <summary> if (double.IsPositiveInfinity(complex.Real) && double.IsNegativeInfinity(complex.Imaginary))
/// Gets a value indicating whether the <c>Complex32</c> is the imaginary unit. {
/// </summary> return new Complex(Constants.Sqrt1Over2, -Constants.Sqrt1Over2);
/// <returns><c>true</c> if this instance is ImaginaryOne; otherwise, <c>false</c>.</returns> }
/// <param name="complex">The <see cref="Complex"/> number to perfom this operation on.</param>
public static bool IsImaginaryOne(this Complex complex)
{
return complex.Real == 0.0 && complex.Imaginary == 1.0;
}
/// <summary> if (double.IsNegativeInfinity(complex.Real) && double.IsPositiveInfinity(complex.Imaginary))
/// Gets a value indicating whether the provided <c>Complex32</c>evaluates {
/// to a value that is not a number. return new Complex(-Constants.Sqrt1Over2, -Constants.Sqrt1Over2);
/// </summary> }
/// <param name="complex">The <see cref="Complex"/> number to perfom this operation on.</param>
/// <returns>
/// <c>true</c> if this instance is <c>NaN</c>; otherwise,
/// <c>false</c>.
/// </returns>
public static bool IsNaN(this Complex complex)
{
return double.IsNaN(complex.Real) || double.IsNaN(complex.Imaginary);
}
/// <summary> if (double.IsNegativeInfinity(complex.Real) && double.IsNegativeInfinity(complex.Imaginary))
/// Gets a value indicating whether the provided <c>Complex32</c> evaluates to an {
/// infinite value. return new Complex(-Constants.Sqrt1Over2, Constants.Sqrt1Over2);
/// </summary> }
/// <param name="complex">The <see cref="Complex"/> number to perfom this operation on.</param>
/// <returns>
/// <c>true</c> if this instance is infinite; otherwise, <c>false</c>.
/// </returns>
/// <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> // don't replace this with "Magnitude"!
/// Gets a value indicating whether the provided <c>Complex32</c> is real. var mod = SpecialFunctions.Hypotenuse(complex.Real, complex.Imaginary);
/// </summary> if (mod == 0.0d)
/// <param name="complex">The <see cref="Complex"/> number to perfom this operation on.</param> {
/// <returns><c>true</c> if this instance is a real number; otherwise, <c>false</c>.</returns> return Complex.Zero;
public static bool IsReal(this Complex complex) }
{
return complex.Imaginary == 0.0;
}
/// <summary> return new Complex(complex.Real / mod, complex.Imaginary / mod);
/// Gets a value indicating whether the provided <c>Complex32</c> is real and not negative, that is &gt;= 0.
/// </summary>
/// <param name="complex">The <see cref="Complex"/> number to perfom this operation on.</param>
/// <returns>
/// <c>true</c> if this instance is real nonnegative number; otherwise, <c>false</c>.
/// </returns>
public static bool IsRealNonNegative(this Complex complex)
{
return complex.Imaginary == 0.0f && complex.Real >= 0;
} }
/// <summary> /// <summary>
@ -139,19 +106,19 @@ namespace MathNet.Numerics
/// </code> /// </code>
/// </remarks> /// </remarks>
/// <returns>The conjugate of the <see cref="Complex"/> number.</returns> /// <returns>The conjugate of the <see cref="Complex"/> number.</returns>
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public static Complex Conjugate(this Complex complex) public static Complex Conjugate(this Complex complex)
{ {
return new Complex(complex.Real, -complex.Imaginary); return Complex.Conjugate(complex);
} }
/// <summary> /// <summary>
/// Gets the squared magnitude of the <c>Complex</c> number. /// Returns the multiplicative inverse of a complex number.
/// </summary> /// </summary>
/// <param name="complex">The <see cref="Complex"/> number to perfom this operation on.</param> [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
/// <returns>The squared magnitude of the <c>Complex</c> number.</returns> public static Complex Reciprocal(this Complex complex)
public static double MagnitudeSquared(this Complex complex)
{ {
return (complex.Real * complex.Real) + (complex.Imaginary * complex.Imaginary); return Complex.Reciprocal(complex);
} }
/// <summary> /// <summary>
@ -161,15 +128,10 @@ namespace MathNet.Numerics
/// <returns> /// <returns>
/// The exponential of this complex number. /// The exponential of this complex number.
/// </returns> /// </returns>
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public static Complex Exponential(this Complex complex) public static Complex Exponential(this Complex complex)
{ {
var exp = Math.Exp(complex.Real); return Complex.Exp(complex);
if (complex.IsReal())
{
return new Complex(exp, 0.0);
}
return new Complex(exp * Trig.Cosine(complex.Imaginary), exp * Trig.Sine(complex.Imaginary));
} }
/// <summary> /// <summary>
@ -179,14 +141,30 @@ namespace MathNet.Numerics
/// <returns> /// <returns>
/// The natural logarithm of this complex number. /// The natural logarithm of this complex number.
/// </returns> /// </returns>
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public static Complex NaturalLogarithm(this Complex complex) public static Complex NaturalLogarithm(this Complex complex)
{ {
if (complex.IsRealNonNegative()) return Complex.Log(complex);
{ }
return new Complex(Math.Log(complex.Real), 0.0);
}
return new Complex(0.5 * Math.Log(complex.MagnitudeSquared()), complex.Phase); /// <summary>
/// Common Logarithm of this <c>Complex</c> (Base 10).
/// </summary>
/// <returns>The common logarithm of this complex number.</returns>
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public static Complex CommonLogarithm(this Complex complex)
{
return Complex.Log10(complex);
}
/// <summary>
/// Logarithm of this <c>Complex</c> with custom base.
/// </summary>
/// <returns>The logarithm of this complex number.</returns>
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public static Complex Logarithm(this Complex complex, double baseValue)
{
return Complex.Log(complex, baseValue);
} }
/// <summary> /// <summary>
@ -208,25 +186,22 @@ namespace MathNet.Numerics
return Complex.One; return Complex.One;
} }
if (exponent.Real > 0.0) if (exponent.Real > 0d)
{ {
return Complex.Zero; return Complex.Zero;
} }
if (exponent.Real < 0) if (exponent.Real < 0d)
{ {
if (exponent.Imaginary == 0.0) return exponent.Imaginary == 0d
{ ? new Complex(double.PositiveInfinity, 0d)
return new Complex(double.PositiveInfinity, 0.0); : new Complex(double.PositiveInfinity, double.PositiveInfinity);
}
return new Complex(double.PositiveInfinity, double.PositiveInfinity);
} }
return double.NaN; return new Complex(double.NaN, double.NaN);
} }
return (exponent * complex.NaturalLogarithm()).Exponential(); return Complex.Pow(complex, exponent);
} }
/// <summary> /// <summary>
@ -241,7 +216,7 @@ namespace MathNet.Numerics
/// </returns> /// </returns>
public static Complex Root(this Complex complex, Complex rootExponent) public static Complex Root(this Complex complex, Complex rootExponent)
{ {
return Power(complex, 1 / rootExponent); return Complex.Pow(complex, 1 / rootExponent);
} }
/// <summary> /// <summary>
@ -268,43 +243,93 @@ namespace MathNet.Numerics
/// <returns> /// <returns>
/// The square root of this complex number. /// The square root of this complex number.
/// </returns> /// </returns>
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public static Complex SquareRoot(this Complex complex) public static Complex SquareRoot(this Complex complex)
{ {
if (complex.IsRealNonNegative()) return Complex.Sqrt(complex);
{ }
return new Complex(Math.Sqrt(complex.Real), 0.0);
}
Complex result; /// <summary>
/// Gets a value indicating whether the <c>Complex32</c> is zero.
/// </summary>
/// <param name="complex">The <see cref="Complex"/> number to perfom this operation on.</param>
/// <returns><c>true</c> if this instance is zero; otherwise, <c>false</c>.</returns>
public static bool IsZero(this Complex complex)
{
return complex.Real == 0.0 && complex.Imaginary == 0.0;
}
var absReal = Math.Abs(complex.Real); /// <summary>
var absImag = Math.Abs(complex.Imaginary); /// Gets a value indicating whether the <c>Complex32</c> is one.
double w; /// </summary>
if (absReal >= absImag) /// <param name="complex">The <see cref="Complex"/> number to perfom this operation on.</param>
{ /// <returns><c>true</c> if this instance is one; otherwise, <c>false</c>.</returns>
var ratio = complex.Imaginary / complex.Real; public static bool IsOne(this Complex complex)
w = Math.Sqrt(absReal) * Math.Sqrt(0.5 * (1.0 + Math.Sqrt(1.0 + (ratio * ratio)))); {
} return complex.Real == 1.0 && complex.Imaginary == 0.0;
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) /// <summary>
{ /// Gets a value indicating whether the <c>Complex32</c> is the imaginary unit.
result = new Complex(w, complex.Imaginary / (2.0 * w)); /// </summary>
} /// <returns><c>true</c> if this instance is ImaginaryOne; otherwise, <c>false</c>.</returns>
else if (complex.Imaginary >= 0.0) /// <param name="complex">The <see cref="Complex"/> number to perfom this operation on.</param>
{ public static bool IsImaginaryOne(this Complex complex)
result = new Complex(absImag / (2.0 * w), w); {
} return complex.Real == 0.0 && complex.Imaginary == 1.0;
else }
{
result = new Complex(absImag / (2.0 * w), -w); /// <summary>
} /// Gets a value indicating whether the provided <c>Complex32</c>evaluates
/// to a value that is not a number.
/// </summary>
/// <param name="complex">The <see cref="Complex"/> number to perfom this operation on.</param>
/// <returns>
/// <c>true</c> if this instance is <c>NaN</c>; otherwise,
/// <c>false</c>.
/// </returns>
public static bool IsNaN(this Complex complex)
{
return double.IsNaN(complex.Real) || double.IsNaN(complex.Imaginary);
}
return result; /// <summary>
/// Gets a value indicating whether the provided <c>Complex32</c> evaluates to an
/// infinite value.
/// </summary>
/// <param name="complex">The <see cref="Complex"/> number to perfom this operation on.</param>
/// <returns>
/// <c>true</c> if this instance is infinite; otherwise, <c>false</c>.
/// </returns>
/// <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>
/// <param name="complex">The <see cref="Complex"/> number to perfom this operation on.</param>
/// <returns><c>true</c> if this instance is a real number; otherwise, <c>false</c>.</returns>
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>
/// <param name="complex">The <see cref="Complex"/> number to perfom this operation on.</param>
/// <returns>
/// <c>true</c> if this instance is real nonnegative number; otherwise, <c>false</c>.
/// </returns>
public static bool IsRealNonNegative(this Complex complex)
{
return complex.Imaginary == 0.0f && complex.Real >= 0;
} }
/// <summary> /// <summary>

1
src/Numerics/Numerics.csproj

@ -104,6 +104,7 @@
<Compile Include="Constants.cs" /> <Compile Include="Constants.cs" />
<Compile Include="Control.cs" /> <Compile Include="Control.cs" />
<Compile Include="Complex32.cs" /> <Compile Include="Complex32.cs" />
<Compile Include="TargetedPatchingOptOutAttribute.cs" />
<Compile Include="Distributions\Continuous\Cauchy.cs" /> <Compile Include="Distributions\Continuous\Cauchy.cs" />
<Compile Include="Distributions\Continuous\Chi.cs" /> <Compile Include="Distributions\Continuous\Chi.cs" />
<Compile Include="Distributions\Continuous\ChiSquare.cs" /> <Compile Include="Distributions\Continuous\ChiSquare.cs" />

16
src/Numerics/TargetedPatchingOptOutAttribute.cs

@ -0,0 +1,16 @@
#if PORTABLE
using System;
namespace MathNet.Numerics
{
[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class TargetedPatchingOptOutAttribute : Attribute
{
public string Reason { get; private set; }
public TargetedPatchingOptOutAttribute(string reason)
{
Reason = reason;
}
}
}
#endif

3
src/Portable/Portable.csproj

@ -1032,6 +1032,9 @@
<Compile Include="..\Numerics\Statistics\Statistics.cs"> <Compile Include="..\Numerics\Statistics\Statistics.cs">
<Link>Statistics\Statistics.cs</Link> <Link>Statistics\Statistics.cs</Link>
</Compile> </Compile>
<Compile Include="..\Numerics\TargetedPatchingOptOutAttribute.cs">
<Link>TargetedPatchingOptOutAttribute.cs</Link>
</Compile>
<Compile Include="..\Numerics\Threading\CommonParallel.cs"> <Compile Include="..\Numerics\Threading\CommonParallel.cs">
<Link>Threading\CommonParallel.cs</Link> <Link>Threading\CommonParallel.cs</Link>
</Compile> </Compile>

4
src/UnitTests/ComplexTests/Complex32Test.TextHandling.cs

@ -90,7 +90,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
var infinity = double.PositiveInfinity.ToString(provider); var infinity = double.PositiveInfinity.ToString(provider);
Assert.AreEqual("(" + nan + ", " + nan + ")", Complex32.NaN.ToString(provider)); Assert.AreEqual("(" + nan + ", " + nan + ")", Complex32.NaN.ToString(provider));
Assert.AreEqual("(" + infinity + ", " + infinity + ")", Complex32.Infinity.ToString(provider)); Assert.AreEqual("(" + infinity + ", " + infinity + ")", Complex32.PositiveInfinity.ToString(provider));
Assert.AreEqual("(0, 0)", Complex32.Zero.ToString(provider)); Assert.AreEqual("(0, 0)", Complex32.Zero.ToString(provider));
Assert.AreEqual("(" + String.Format("{0}", number) + ", 0)", new Complex32(1.1f, 0.0f).ToString(provider)); Assert.AreEqual("(" + String.Format("{0}", number) + ", 0)", new Complex32(1.1f, 0.0f).ToString(provider));
Assert.AreEqual("(" + String.Format("-{0}", number) + ", 0)", new Complex32(-1.1f, 0f).ToString(provider)); Assert.AreEqual("(" + String.Format("-{0}", number) + ", 0)", new Complex32(-1.1f, 0f).ToString(provider));
@ -133,7 +133,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
Assert.AreEqual("(1.100, 1.100)", String.Format(culture, "{0:.000}", new Complex32(1.1f, 1.1f))); Assert.AreEqual("(1.100, 1.100)", String.Format(culture, "{0:.000}", new Complex32(1.1f, 1.1f)));
Assert.AreEqual("(NaN, NaN)", Complex32.NaN.ToString("#.000", culture)); Assert.AreEqual("(NaN, NaN)", Complex32.NaN.ToString("#.000", culture));
Assert.AreEqual("(Infinity, Infinity)", Complex32.Infinity.ToString("#.000", culture)); Assert.AreEqual("(Infinity, Infinity)", Complex32.PositiveInfinity.ToString("#.000", culture));
Assert.AreEqual("(.000, .000)", Complex32.Zero.ToString("#.000", culture)); Assert.AreEqual("(.000, .000)", Complex32.Zero.ToString("#.000", culture));
Assert.AreEqual("(1.100, .000)", new Complex32(1.1f, 0.0f).ToString("#.000", culture)); Assert.AreEqual("(1.100, .000)", new Complex32(1.1f, 0.0f).ToString("#.000", culture));
Assert.AreEqual("(.000, -1.100)", new Complex32(0.0f, -1.1f).ToString("#.000", culture)); Assert.AreEqual("(.000, -1.100)", new Complex32(0.0f, -1.1f).ToString("#.000", culture));

82
src/UnitTests/ComplexTests/Complex32Test.cs

@ -45,7 +45,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
Assert.That((Complex32.NaN + float.NaN).IsNaN()); Assert.That((Complex32.NaN + float.NaN).IsNaN());
Assert.That((float.NaN + Complex32.NaN).IsNaN()); Assert.That((float.NaN + Complex32.NaN).IsNaN());
Assert.That((float.PositiveInfinity + Complex32.One).IsInfinity()); Assert.That((float.PositiveInfinity + Complex32.One).IsInfinity());
Assert.That((Complex32.Infinity + 1.0f).IsInfinity()); Assert.That((Complex32.PositiveInfinity + 1.0f).IsInfinity());
Assert.That((Complex32.One + 0.0f) == Complex32.One); Assert.That((Complex32.One + 0.0f) == Complex32.One);
Assert.That((0.0f + Complex32.One) == Complex32.One); Assert.That((0.0f + Complex32.One) == Complex32.One);
Assert.That(new Complex32(1.1f, -2.2f) + 1.1f == new Complex32(2.2f, -2.2f)); Assert.That(new Complex32(1.1f, -2.2f) + 1.1f == new Complex32(2.2f, -2.2f));
@ -59,7 +59,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
public void CanAddSubtractComplexNumbersUsingOperator() public void CanAddSubtractComplexNumbersUsingOperator()
{ {
Assert.That((Complex32.NaN - Complex32.NaN).IsNaN()); Assert.That((Complex32.NaN - Complex32.NaN).IsNaN());
Assert.That((Complex32.Infinity - Complex32.One).IsInfinity()); Assert.That((Complex32.PositiveInfinity - Complex32.One).IsInfinity());
Assert.That((Complex32.One - Complex32.Zero) == Complex32.One); Assert.That((Complex32.One - Complex32.Zero) == Complex32.One);
Assert.That((new Complex32(1.1f, -2.2f) - new Complex32(1.1f, -2.2f)) == Complex32.Zero); Assert.That((new Complex32(1.1f, -2.2f) - new Complex32(1.1f, -2.2f)) == Complex32.Zero);
} }
@ -70,10 +70,10 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[Test] [Test]
public void CanAddTwoComplexNumbers() public void CanAddTwoComplexNumbers()
{ {
Assert.That(Complex32.NaN.Add(Complex32.NaN).IsNaN()); Assert.That(Complex32.Add(Complex32.NaN, (Complex32.NaN)).IsNaN());
Assert.That(Complex32.Infinity.Add(Complex32.One).IsInfinity()); Assert.That(Complex32.Add(Complex32.PositiveInfinity, Complex32.One).IsInfinity());
Assert.That(Complex32.One.Add(Complex32.Zero) == Complex32.One); Assert.That(Complex32.Add(Complex32.One, Complex32.Zero) == Complex32.One);
Assert.That(new Complex32(1.1f, -2.2f).Add(new Complex32(-1.1f, 2.2f)) == Complex32.Zero); Assert.That(Complex32.Add(new Complex32(1.1f, -2.2f), new Complex32(-1.1f, 2.2f)) == Complex32.Zero);
} }
/// <summary> /// <summary>
@ -83,7 +83,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
public void CanAddTwoComplexNumbersUsingOperator() public void CanAddTwoComplexNumbersUsingOperator()
{ {
Assert.That((Complex32.NaN + Complex32.NaN).IsNaN()); Assert.That((Complex32.NaN + Complex32.NaN).IsNaN());
Assert.That((Complex32.Infinity + Complex32.One).IsInfinity()); Assert.That((Complex32.PositiveInfinity + Complex32.One).IsInfinity());
Assert.That((Complex32.One + Complex32.Zero) == Complex32.One); Assert.That((Complex32.One + Complex32.Zero) == Complex32.One);
Assert.That((new Complex32(1.1f, -2.2f) + new Complex32(-1.1f, 2.2f)) == Complex32.Zero); Assert.That((new Complex32(1.1f, -2.2f) + new Complex32(-1.1f, 2.2f)) == Complex32.Zero);
} }
@ -94,12 +94,11 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[Test] [Test]
public void CanCalculateHashCode() public void CanCalculateHashCode()
{ {
var complex = new Complex32(1, 0); Assert.AreEqual(new Complex32(1, 2).GetHashCode(), new Complex32(1, 2).GetHashCode());
Assert.AreEqual(1065353216, complex.GetHashCode()); Assert.AreNotEqual(new Complex32(1, 0).GetHashCode(), new Complex32(0, 1).GetHashCode());
complex = new Complex32(0, 1); Assert.AreNotEqual(new Complex32(1, 1).GetHashCode(), new Complex32(2, 2).GetHashCode());
Assert.AreEqual(-1065353216, complex.GetHashCode()); Assert.AreNotEqual(new Complex32(1, 0).GetHashCode(), new Complex32(-1, 0).GetHashCode());
complex = new Complex32(1, 1); Assert.AreNotEqual(new Complex32(0, 1).GetHashCode(), new Complex32(0, -1).GetHashCode());
Assert.AreEqual(-16777216, complex.GetHashCode());
} }
/// <summary> /// <summary>
@ -285,7 +284,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[Test] [Test]
public void CanCreateComplexNumberWithModulusArgument() public void CanCreateComplexNumberWithModulusArgument()
{ {
var complex = Complex32.WithModulusArgument(2, (float)-Math.PI / 6); var complex = Complex32.FromPolarCoordinates(2, (float)-Math.PI / 6);
Assert.AreEqual((float)Math.Sqrt(3), complex.Real, 1e-7f, "Real part is Sqrt(3)."); Assert.AreEqual((float)Math.Sqrt(3), complex.Real, 1e-7f, "Real part is Sqrt(3).");
Assert.AreEqual(-1.0f, complex.Imaginary, 1e-7f, "Imaginary part is -1."); Assert.AreEqual(-1.0f, complex.Imaginary, 1e-7f, "Imaginary part is -1.");
} }
@ -296,7 +295,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[Test] [Test]
public void CanCreateComplexNumberWithRealImaginaryInitializer() public void CanCreateComplexNumberWithRealImaginaryInitializer()
{ {
var complex = Complex32.WithRealImaginary(1.1f, -2.2f); var complex = new Complex32(1.1f, -2.2f);
Assert.AreEqual(1.1f, complex.Real, "Real part is 1.1f."); Assert.AreEqual(1.1f, complex.Real, "Real part is 1.1f.");
Assert.AreEqual(-2.2f, complex.Imaginary, "Imaginary part is -2.2f."); Assert.AreEqual(-2.2f, complex.Imaginary, "Imaginary part is -2.2f.");
} }
@ -388,8 +387,8 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
Assert.That((Complex32.NaN * 1.0f).IsNaN()); Assert.That((Complex32.NaN * 1.0f).IsNaN());
Assert.AreEqual(new Complex32(-2, 2), new Complex32(4, -4) / -2); 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(new Complex32(0.25f, 0.25f), 2 / new Complex32(4, -4));
Assert.AreEqual(Complex32.Infinity, 2.0f / Complex32.Zero); Assert.AreEqual(Complex32.PositiveInfinity, 2.0f / Complex32.Zero);
Assert.AreEqual(Complex32.Infinity, Complex32.One / 0); Assert.AreEqual(Complex32.PositiveInfinity, Complex32.One / 0);
} }
/// <summary> /// <summary>
@ -398,9 +397,9 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[Test] [Test]
public void CanDivideTwoComplexNumbers() public void CanDivideTwoComplexNumbers()
{ {
Assert.That(Complex32.NaN.Multiply(Complex32.One).IsNaN()); Assert.That(Complex32.Divide(Complex32.NaN, Complex32.One).IsNaN());
Assert.AreEqual(new Complex32(-2, 0), new Complex32(4, -4).Divide(new Complex32(-2, 2))); Assert.AreEqual(new Complex32(-2, 0), Complex32.Divide(new Complex32(4, -4), new Complex32(-2, 2)));
Assert.AreEqual(Complex32.Infinity, Complex32.One.Divide(Complex32.Zero)); Assert.AreEqual(Complex32.PositiveInfinity, Complex32.Divide(Complex32.One, Complex32.Zero));
} }
/// <summary> /// <summary>
@ -411,7 +410,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
{ {
Assert.That((Complex32.NaN / Complex32.One).IsNaN()); Assert.That((Complex32.NaN / Complex32.One).IsNaN());
Assert.AreEqual(new Complex32(-2, 0), new Complex32(4, -4) / new Complex32(-2, 2)); Assert.AreEqual(new Complex32(-2, 0), new Complex32(4, -4) / new Complex32(-2, 2));
Assert.AreEqual(Complex32.Infinity, Complex32.One / Complex32.Zero); Assert.AreEqual(Complex32.PositiveInfinity, Complex32.One / Complex32.Zero);
} }
/// <summary> /// <summary>
@ -431,8 +430,8 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[Test] [Test]
public void CanMultipleTwoComplexNumbers() public void CanMultipleTwoComplexNumbers()
{ {
Assert.That(Complex32.NaN.Multiply(Complex32.One).IsNaN()); Assert.That(Complex32.Multiply(Complex32.NaN, Complex32.One).IsNaN());
Assert.AreEqual(new Complex32(0, 16), new Complex32(4, -4).Multiply(new Complex32(-2, 2))); Assert.AreEqual(new Complex32(0, 16), Complex32.Multiply(new Complex32(4, -4), new Complex32(-2, 2)));
} }
/// <summary> /// <summary>
@ -452,7 +451,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
public void CanNegateValue() public void CanNegateValue()
{ {
var complex = new Complex32(1.1f, -2.2f); var complex = new Complex32(1.1f, -2.2f);
Assert.AreEqual(new Complex32(-1.1f, 2.2f), complex.Negate()); Assert.AreEqual(new Complex32(-1.1f, 2.2f), Complex32.Negate(complex));
} }
/// <summary> /// <summary>
@ -474,7 +473,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
Assert.That((Complex32.NaN - float.NaN).IsNaN()); Assert.That((Complex32.NaN - float.NaN).IsNaN());
Assert.That((float.NaN - Complex32.NaN).IsNaN()); Assert.That((float.NaN - Complex32.NaN).IsNaN());
Assert.That((float.PositiveInfinity - Complex32.One).IsInfinity()); Assert.That((float.PositiveInfinity - Complex32.One).IsInfinity());
Assert.That((Complex32.Infinity - 1.0f).IsInfinity()); Assert.That((Complex32.PositiveInfinity - 1.0f).IsInfinity());
Assert.That((Complex32.One - 0.0f) == Complex32.One); Assert.That((Complex32.One - 0.0f) == Complex32.One);
Assert.That((0.0f - Complex32.One) == -Complex32.One); Assert.That((0.0f - Complex32.One) == -Complex32.One);
Assert.That(new Complex32(1.1f, -2.2f) - 1.1f == new Complex32(0.0f, -2.2f)); Assert.That(new Complex32(1.1f, -2.2f) - 1.1f == new Complex32(0.0f, -2.2f));
@ -487,10 +486,10 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[Test] [Test]
public void CanSubtractTwoComplexNumbers() public void CanSubtractTwoComplexNumbers()
{ {
Assert.That(Complex32.NaN.Subtract(Complex32.NaN).IsNaN()); Assert.That(Complex32.Subtract(Complex32.NaN, Complex32.NaN).IsNaN());
Assert.That(Complex32.Infinity.Subtract(Complex32.One).IsInfinity()); Assert.That(Complex32.Subtract(Complex32.PositiveInfinity, Complex32.One).IsInfinity());
Assert.That(Complex32.One.Subtract(Complex32.Zero) == Complex32.One); Assert.That(Complex32.Subtract(Complex32.One, Complex32.Zero) == Complex32.One);
Assert.That(new Complex32(1.1f, -2.2f).Subtract(new Complex32(1.1f, -2.2f)) == Complex32.Zero); Assert.That(Complex32.Subtract(new Complex32(1.1f, -2.2f), new Complex32(1.1f, -2.2f)) == Complex32.Zero);
} }
/// <summary> /// <summary>
@ -500,7 +499,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
public void CanTestForEquality() public void CanTestForEquality()
{ {
Assert.AreNotEqual(Complex32.NaN, Complex32.NaN); Assert.AreNotEqual(Complex32.NaN, Complex32.NaN);
Assert.AreEqual(Complex32.Infinity, Complex32.Infinity); Assert.AreEqual(Complex32.PositiveInfinity, Complex32.PositiveInfinity);
Assert.AreEqual(new Complex32(1.1f, -2.2f), new Complex32(1.1f, -2.2f)); Assert.AreEqual(new Complex32(1.1f, -2.2f), new Complex32(1.1f, -2.2f));
Assert.AreNotEqual(new Complex32(-1.1f, 2.2f), new Complex32(1.1f, -2.2f)); Assert.AreNotEqual(new Complex32(-1.1f, 2.2f), new Complex32(1.1f, -2.2f));
} }
@ -512,23 +511,13 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
public void CanTestForEqualityUsingOperators() public void CanTestForEqualityUsingOperators()
{ {
Assert.That(Complex32.NaN != Complex32.NaN); Assert.That(Complex32.NaN != Complex32.NaN);
Assert.That(Complex32.Infinity == Complex32.Infinity); Assert.That(Complex32.PositiveInfinity == Complex32.PositiveInfinity);
Assert.That(new Complex32(1.1f, -2.2f) == new Complex32(1.1f, -2.2f)); Assert.That(new Complex32(1.1f, -2.2f) == new Complex32(1.1f, -2.2f));
Assert.That(new Complex32(-1.1f, 2.2f) != new Complex32(1.1f, -2.2f)); Assert.That(new Complex32(-1.1f, 2.2f) != new Complex32(1.1f, -2.2f));
} }
/// <summary> /// <summary>
/// Can use Plus. /// Can use unary "+" operator.
/// </summary>
[Test]
public void CanUsePlus()
{
var complex = new Complex32(1.1f, -2.2f);
Assert.AreEqual(complex, complex.Plus());
}
/// <summary>
/// Can use "+" operator.
/// </summary> /// </summary>
[Test] [Test]
public void CanUsePlusOperator() public void CanUsePlusOperator()
@ -537,15 +526,6 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
Assert.AreEqual(complex, +complex); Assert.AreEqual(complex, +complex);
} }
/// <summary>
/// With negative modulus argument throws <c>ArgumentOutOfRangeException</c>.
/// </summary>
[Test]
public void WithNegativeModulusArgumentThrowsArgumentOutOfRangeException()
{
Assert.Throws<ArgumentOutOfRangeException>(() => Complex32.WithModulusArgument(-1, 1), "Throws exception because modulus is negative.");
}
/// <summary> /// <summary>
/// Can compute magnitude. /// Can compute magnitude.
/// </summary> /// </summary>

20
src/UnitTests/ComplexTests/ComplexTest.cs

@ -106,6 +106,7 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
a = new Complex(0.0, 0.0); a = new Complex(0.0, 0.0);
b = new Complex(1.0, 0.0); b = new Complex(1.0, 0.0);
AssertHelpers.AlmostEqual(new Complex(0.0, 0.0), a.Power(b), 15); AssertHelpers.AlmostEqual(new Complex(0.0, 0.0), a.Power(b), 15);
a = new Complex(0.0, 0.0); a = new Complex(0.0, 0.0);
b = new Complex(-1.0, 0.0); b = new Complex(-1.0, 0.0);
AssertHelpers.AlmostEqual(new Complex(double.PositiveInfinity, 0.0), a.Power(b), 15); AssertHelpers.AlmostEqual(new Complex(double.PositiveInfinity, 0.0), a.Power(b), 15);
@ -123,21 +124,22 @@ namespace MathNet.Numerics.UnitTests.ComplexTests
[Test] [Test]
public void CanComputeRoot() public void CanComputeRoot()
{ {
var a = new Complex(1.19209289550780998537e-7, 1.19209289550780998537e-7); var a = new Complex(0.0, -1.19209289550780998537e-7);
var b = new Complex(1.19209289550780998537e-7, 1.19209289550780998537e-7); var b = new Complex(0.0, 0.5);
AssertHelpers.AlmostEqual(new Complex(0.0, 0.0), a.Root(b), 15); AssertHelpers.AlmostEqual(new Complex(0.038550761943650161, 0.019526430428319544), a.Root(b), 14);
a = new Complex(0.0, -1.19209289550780998537e-7);
b = new Complex(0.0, 0.5);
AssertHelpers.AlmostEqual(new Complex(0.038550761943650161, 0.019526430428319544), a.Root(b), 15);
a = new Complex(0.0, 0.5); a = new Complex(0.0, 0.5);
b = new Complex(0.0, -0.5); b = new Complex(0.0, -0.5);
AssertHelpers.AlmostEqual(new Complex(0.007927894711475968, -0.042480480425152213), a.Root(b), 15); AssertHelpers.AlmostEqual(new Complex(0.007927894711475968, -0.042480480425152213), a.Root(b), 14);
a = new Complex(0.0, -0.5); a = new Complex(0.0, -0.5);
b = new Complex(0.0, 1.0); b = new Complex(0.0, 1.0);
AssertHelpers.AlmostEqual(new Complex(0.15990905692806806, 0.13282699942462053), a.Root(b), 15); AssertHelpers.AlmostEqual(new Complex(0.15990905692806806, 0.13282699942462053), a.Root(b), 14);
a = new Complex(0.0, 2.0); a = new Complex(0.0, 2.0);
b = new Complex(0.0, -2.0); b = new Complex(0.0, -2.0);
AssertHelpers.AlmostEqual(new Complex(0.42882900629436788, 0.15487175246424678), a.Root(b), 15); AssertHelpers.AlmostEqual(new Complex(0.42882900629436788, 0.15487175246424678), a.Root(b), 14);
//a = new Complex(1.19209289550780998537e-7, 1.19209289550780998537e-7);
//b = new Complex(1.19209289550780998537e-7, 1.19209289550780998537e-7);
//AssertHelpers.AlmostEqual(new Complex(0.0, 0.0), a.Root(b), 15);
a = new Complex(0.0, -8.388608e6); a = new Complex(0.0, -8.388608e6);
b = new Complex(1.19209289550780998537e-7, 0.0); b = new Complex(1.19209289550780998537e-7, 0.0);
AssertHelpers.AlmostEqual(new Complex(double.PositiveInfinity, double.NegativeInfinity), a.Root(b), 15); AssertHelpers.AlmostEqual(new Complex(double.PositiveInfinity, double.NegativeInfinity), a.Root(b), 15);

2
src/UnitTests/LinearAlgebraTests/Complex32/VectorTests.cs

@ -230,7 +230,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32
public void CanGetHashCode() public void CanGetHashCode()
{ {
var vector = CreateVector(new[] { new Complex32(1, 1), new Complex32(2, 1), new Complex32(3, 1), new Complex32(4, 1), new Complex32(5, 1) }); var vector = CreateVector(new[] { new Complex32(1, 1), new Complex32(2, 1), new Complex32(3, 1), new Complex32(4, 1), new Complex32(5, 1) });
Assert.AreEqual(-1051736064, vector.GetHashCode()); Assert.AreEqual(-1042380805, vector.GetHashCode());
} }
/// <summary> /// <summary>

Loading…
Cancel
Save