Addede mixed Complex/double arithmetic operators to Complex
authorAndrii Kurdiumov <kant2002@gmail.com>
Sat, 2 Jun 2018 12:17:50 +0000 (18:17 +0600)
committerTanner Gooding <tagoo@outlook.com>
Tue, 11 Sep 2018 14:27:21 +0000 (07:27 -0700)
Implementation of simplified cases for performing math operations on the Complex
Closes dotnet/corefx#15927

Commit migrated from https://github.com/dotnet/corefx/commit/68c127e5017500d24d6fb6ddfe6f7d0c31636c09

src/libraries/System.Runtime.Numerics/ref/System.Runtime.Numerics.cs
src/libraries/System.Runtime.Numerics/src/System/Numerics/Complex.cs
src/libraries/System.Runtime.Numerics/tests/ComplexTests.cs

index c24590a..3ee8be5 100644 (file)
@@ -178,12 +178,16 @@ namespace System.Numerics
         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; }
@@ -193,9 +197,15 @@ namespace System.Numerics
         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; }
@@ -215,7 +225,11 @@ namespace System.Numerics
         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; }
@@ -224,6 +238,8 @@ namespace System.Numerics
         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; }
index f42f22b..8591891 100644 (file)
@@ -62,21 +62,61 @@ namespace System.Numerics
             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);
@@ -86,12 +126,32 @@ namespace System.Numerics
         {
             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
@@ -100,6 +160,16 @@ namespace System.Numerics
             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.
@@ -120,6 +190,30 @@ namespace System.Numerics
             }
         }
 
+        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);
index c05876a..f0a69a9 100644 (file)
@@ -398,6 +398,34 @@ namespace System.Numerics.Tests
         }
 
         [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))]
         public static void ASin_Basic(double real, double imaginary)
@@ -745,6 +773,58 @@ namespace System.Numerics.Tests
             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()
@@ -1219,6 +1299,33 @@ namespace System.Numerics.Tests
         }
 
         [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))]
         [MemberData(nameof(Invalid_2_TestData))]
@@ -1532,6 +1639,34 @@ namespace System.Numerics.Tests
             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.