Skip to content

Commit

Permalink
Addede mixed Complex/double arithmetic operators to Complex
Browse files Browse the repository at this point in the history
Implementation of simplified cases for performing math operations on the Complex
Closes dotnet/corefx#15927


Commit migrated from dotnet/corefx@68c127e
  • Loading branch information
kant2002 authored and tannergooding committed Sep 11, 2018
1 parent 72205f9 commit ece1143
Show file tree
Hide file tree
Showing 3 changed files with 246 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,16 @@ public partial struct Complex : System.IEquatable<System.Numerics.Complex>, Syst
public static double Abs(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Acos(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Add(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
public static System.Numerics.Complex Add(System.Numerics.Complex left, double right) { throw null; }
public static System.Numerics.Complex Add(double left, System.Numerics.Complex right) { throw null; }
public static System.Numerics.Complex Asin(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Atan(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Conjugate(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Cos(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Cosh(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Divide(System.Numerics.Complex dividend, System.Numerics.Complex divisor) { throw null; }
public static System.Numerics.Complex Divide(System.Numerics.Complex dividend, double divisor) { throw null; }
public static System.Numerics.Complex Divide(double dividend, System.Numerics.Complex divisor) { throw null; }
public bool Equals(System.Numerics.Complex value) { throw null; }
public override bool Equals(object obj) { throw null; }
public static System.Numerics.Complex Exp(System.Numerics.Complex value) { throw null; }
Expand All @@ -193,9 +197,15 @@ public partial struct Complex : System.IEquatable<System.Numerics.Complex>, Syst
public static System.Numerics.Complex Log(System.Numerics.Complex value, double baseValue) { throw null; }
public static System.Numerics.Complex Log10(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Multiply(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
public static System.Numerics.Complex Multiply(System.Numerics.Complex left, double right) { throw null; }
public static System.Numerics.Complex Multiply(double left, System.Numerics.Complex right) { throw null; }
public static System.Numerics.Complex Negate(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex operator +(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
public static System.Numerics.Complex operator +(System.Numerics.Complex left, double right) { throw null; }
public static System.Numerics.Complex operator +(double left, System.Numerics.Complex right) { throw null; }
public static System.Numerics.Complex operator /(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
public static System.Numerics.Complex operator /(System.Numerics.Complex left, double right) { throw null; }
public static System.Numerics.Complex operator /(double left, System.Numerics.Complex right) { throw null; }
public static bool operator ==(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
public static explicit operator System.Numerics.Complex (decimal value) { throw null; }
public static explicit operator System.Numerics.Complex (System.Numerics.BigInteger value) { throw null; }
Expand All @@ -215,7 +225,11 @@ public partial struct Complex : System.IEquatable<System.Numerics.Complex>, Syst
public static implicit operator System.Numerics.Complex (ulong value) { throw null; }
public static bool operator !=(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
public static System.Numerics.Complex operator *(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
public static System.Numerics.Complex operator *(System.Numerics.Complex left, double right) { throw null; }
public static System.Numerics.Complex operator *(double left, System.Numerics.Complex right) { throw null; }
public static System.Numerics.Complex operator -(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
public static System.Numerics.Complex operator -(System.Numerics.Complex left, double right) { throw null; }
public static System.Numerics.Complex operator -(double left, System.Numerics.Complex right) { throw null; }
public static System.Numerics.Complex operator -(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Pow(System.Numerics.Complex value, double power) { throw null; }
public static System.Numerics.Complex Pow(System.Numerics.Complex value, System.Numerics.Complex power) { throw null; }
Expand All @@ -224,6 +238,8 @@ public partial struct Complex : System.IEquatable<System.Numerics.Complex>, Syst
public static System.Numerics.Complex Sinh(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Sqrt(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Subtract(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; }
public static System.Numerics.Complex Subtract(System.Numerics.Complex left, double right) { throw null; }
public static System.Numerics.Complex Subtract(double left, System.Numerics.Complex right) { throw null; }
public static System.Numerics.Complex Tan(System.Numerics.Complex value) { throw null; }
public static System.Numerics.Complex Tanh(System.Numerics.Complex value) { throw null; }
public override string ToString() { throw null; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,21 +62,61 @@ public static Complex Add(Complex left, Complex right)
return left + right;
}

public static Complex Add(Complex left, double right)
{
return left + right;
}

public static Complex Add(double left, Complex right)
{
return left + right;
}

public static Complex Subtract(Complex left, Complex right)
{
return left - right;
}

public static Complex Subtract(Complex left, double right)
{
return left - right;
}

public static Complex Subtract(double left, Complex right)
{
return left - right;
}

public static Complex Multiply(Complex left, Complex right)
{
return left * right;
}

public static Complex Multiply(Complex left, double right)
{
return left * right;
}

public static Complex Multiply(double left, Complex right)
{
return left * right;
}

public static Complex Divide(Complex dividend, Complex divisor)
{
return dividend / divisor;
}


public static Complex Divide(Complex dividend, double divisor)
{
return dividend / divisor;
}

public static Complex Divide(double dividend, Complex divisor)
{
return dividend / divisor;
}

public static Complex operator -(Complex value) /* Unary negation of a complex number */
{
return new Complex(-value.m_real, -value.m_imaginary);
Expand All @@ -86,12 +126,32 @@ public static Complex Divide(Complex dividend, Complex divisor)
{
return new Complex(left.m_real + right.m_real, left.m_imaginary + right.m_imaginary);
}

public static Complex operator +(Complex left, double right)
{
return new Complex(left.m_real + right, left.m_imaginary);
}

public static Complex operator +(double left, Complex right)
{
return new Complex(left + right.m_real, right.m_imaginary);
}

public static Complex operator -(Complex left, Complex right)
{
return new Complex(left.m_real - right.m_real, left.m_imaginary - right.m_imaginary);
}

public static Complex operator -(Complex left, double right)
{
return new Complex(left.m_real - right, left.m_imaginary);
}

public static Complex operator -(double left, Complex right)
{
return new Complex(left - right.m_real, -right.m_imaginary);
}

public static Complex operator *(Complex left, Complex right)
{
// Multiplication: (a + bi)(c + di) = (ac -bd) + (bc + ad)i
Expand All @@ -100,6 +160,16 @@ public static Complex Divide(Complex dividend, Complex divisor)
return new Complex(result_realpart, result_imaginarypart);
}

public static Complex operator *(Complex left, double right)
{
return new Complex(left.m_real * right, left.m_imaginary * right);
}

public static Complex operator *(double left, Complex right)
{
return new Complex(left * right.m_real, left * right.m_imaginary);
}

public static Complex operator /(Complex left, Complex right)
{
// Division : Smith's formula.
Expand All @@ -120,6 +190,30 @@ public static Complex Divide(Complex dividend, Complex divisor)
}
}

public static Complex operator /(Complex left, double right)
{
return new Complex(left.m_real / right, left.m_imaginary / right);
}

public static Complex operator /(double left, Complex right)
{
// Division : Smith's formula.
double a = left;
double c = right.m_real;
double d = right.m_imaginary;

if (Math.Abs(d) < Math.Abs(c))
{
double doc = d / c;
return new Complex(a / (c + d * doc), (-a * doc) / (c + d * doc));
}
else
{
double cod = c / d;
return new Complex(a * cod / (d + c * cod), -a / (d + c * cod));
}
}

public static double Abs(Complex value)
{
return Hypot(value.m_real, value.m_imaginary);
Expand Down
135 changes: 135 additions & 0 deletions src/libraries/System.Runtime.Numerics/tests/ComplexTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,34 @@ public static void Add(double realLeft, double imaginaryLeft, double realRight,
VerifyRealImaginaryProperties(result, expectedReal, expectedImaginary);
}

[Theory]
[MemberData(nameof(Add_TestData))]
[MemberData(nameof(Random_4_TestData))]
[MemberData(nameof(Invalid_4_TestData))]
public static void AddDouble(double realLeft, double imaginaryLeft, double realRight, double imaginaryRight)
{
var left = new Complex(realLeft, imaginaryLeft);
var right = realRight;

// Calculate the expected results
double expectedReal = realLeft + realRight;
double expectedImaginary = imaginaryLeft;

// Operator
Complex result = left + right;
VerifyRealImaginaryProperties(result, expectedReal, expectedImaginary);

result = right + left;
VerifyRealImaginaryProperties(result, expectedReal, expectedImaginary);

// Static method
result = Complex.Add(left, right);
VerifyRealImaginaryProperties(result, expectedReal, expectedImaginary);

result = Complex.Add(right, left);
VerifyRealImaginaryProperties(result, expectedReal, expectedImaginary);
}

[Theory]
[MemberData(nameof(Primitives_2_TestData))]
[MemberData(nameof(SmallRandom_2_TestData))]
Expand Down Expand Up @@ -745,6 +773,58 @@ public static void Divide(double realLeft, double imaginaryLeft, double realRigh
VerifyRealImaginaryProperties(result, expectedReal, expectedImaginary);
}

[Theory]
[MemberData(nameof(Divide_TestData))]
[MemberData(nameof(SmallRandom_4_TestData))]
[MemberData(nameof(Invalid_4_TestData))]
public static void DivideByDouble(double realLeft, double imaginaryLeft, double realRight, double imaginaryRight)
{
var dividend = new Complex(realLeft, imaginaryLeft);
var divisor = realRight;

double expectedReal = dividend.Real / divisor;
double expectedImaginary = dividend.Imaginary / divisor;

// Operator
Complex result = dividend / divisor;
VerifyRealImaginaryProperties(result, expectedReal, expectedImaginary);

// Static method
result = Complex.Divide(dividend, divisor);
VerifyRealImaginaryProperties(result, expectedReal, expectedImaginary);
}

[Theory]
[MemberData(nameof(Divide_TestData))]
[MemberData(nameof(SmallRandom_4_TestData))]
[MemberData(nameof(Invalid_4_TestData))]
public static void DivideByComplex(double realLeft, double imaginaryLeft, double realRight, double imaginaryRight)
{
var dividend = realLeft;
var divisor = new Complex(realRight, imaginaryRight);

Complex expected = dividend * Complex.Conjugate(divisor);
double expectedReal = expected.Real;
double expectedImaginary = expected.Imaginary;

if (!double.IsInfinity(expectedReal))
{
expectedReal = expectedReal / (divisor.Magnitude * divisor.Magnitude);
}
if (!double.IsInfinity(expectedImaginary))
{
expectedImaginary = expectedImaginary / (divisor.Magnitude * divisor.Magnitude);
}

// Operator
Complex result = dividend / divisor;
VerifyRealImaginaryProperties(result, expectedReal, expectedImaginary);

// Static method
result = Complex.Divide(dividend, divisor);
VerifyRealImaginaryProperties(result, expectedReal, expectedImaginary);
}

[Fact]
[SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)]
public static void Equals_netcore()
Expand Down Expand Up @@ -1218,6 +1298,33 @@ public static void Multiply(double realLeft, double imaginaryLeft, double realRi
VerifyRealImaginaryProperties(result, expectedReal, expectedImaginary);
}

[Theory]
[MemberData(nameof(Multiply_TestData))]
[MemberData(nameof(SmallRandom_4_TestData))]
[MemberData(nameof(Invalid_4_TestData))]
public static void MultiplyDouble(double realLeft, double imaginaryLeft, double realRight, double imaginaryRight)
{
var left = new Complex(realLeft, imaginaryLeft);
var right = realRight;

double expectedReal = realLeft * realRight;
double expectedImaginary = imaginaryLeft * realRight;

// Operator
Complex result = left * right;
VerifyRealImaginaryProperties(result, expectedReal, expectedImaginary);

result = right * left;
VerifyRealImaginaryProperties(result, expectedReal, expectedImaginary);

// Static method
result = Complex.Multiply(left, right);
VerifyRealImaginaryProperties(result, expectedReal, expectedImaginary);

result = Complex.Multiply(right, left);
VerifyRealImaginaryProperties(result, expectedReal, expectedImaginary);
}

[Theory]
[MemberData(nameof(Valid_2_TestData))]
[MemberData(nameof(Random_2_TestData))]
Expand Down Expand Up @@ -1532,6 +1639,34 @@ public static void Subtract(double realLeft, double imaginaryLeft, double realRi
VerifyRealImaginaryProperties(result, expectedReal, expectedImaginary);
}

[Theory]
[MemberData(nameof(Subtract_TestData))]
[MemberData(nameof(Random_4_TestData))]
[MemberData(nameof(Invalid_4_TestData))]
public static void SubtractDouble(double realLeft, double imaginaryLeft, double realRight, double imaginaryRight)
{
var left = new Complex(realLeft, imaginaryLeft);
var right = realRight;

// calculate the expected results
double expectedReal = realLeft - realRight;
double expectedImaginary = imaginaryLeft;

// Operator
Complex result = left - right;
VerifyRealImaginaryProperties(result, expectedReal, expectedImaginary);

result = right - left;
VerifyRealImaginaryProperties(result, -expectedReal, -expectedImaginary);

// Static method
result = Complex.Subtract(left, right);
VerifyRealImaginaryProperties(result, expectedReal, expectedImaginary);

result = Complex.Subtract(right, left);
VerifyRealImaginaryProperties(result, -expectedReal, -expectedImaginary);
}

public static IEnumerable<object[]> Sqrt_TestData()
{
// Simple known values.
Expand Down

0 comments on commit ece1143

Please sign in to comment.