11,567,926 members (44,610 online)

# Complex math library for C# and VB.NET

, 15 Dec 2002 CPOL 179.3K 2.8K 39
 Rate this:
Complex math library for C# and VB.NET.

## Introduction

The .NET platform doesn't have complex numbers built in. If you do scientific calculations such as groundwater modeling, complex numbers are essential. This article describes a full implementation of complex numbers for .NET, and how to use it with VB or C#.

Complex numbers have a real and imaginary part. Math operations are performed on complex numbers using special rules to keep track of the real and imaginary parts. Fortran and C++ have complex numbers built in.

## C# Example (cs_complex.cs)

```using System;
using KarlsTools;

class TestComplex{
static void Main(string[] args)
{
Complex c1 = new Complex(3.0, 4.0);
double d = Complex.Abs(c1);
Console.WriteLine("Test Complex,  d = "+ d);
}
}```

Compile and run the above code with the following commands:

```c:\>csc cs_complex.cs /r:complex.dll
C:\>cs_complex
Test Complex, d = 5```
 Complex Number Class for .NET List of Functionality C# Example```using System; using KarlsTools;``` C# output Constructor `Complex(double real, double imag)` `Complex c1 = new Complex(3,4);` c1 = (3,4) Methods `String ToString()` `string s = "c1 = "+c1.ToString();` s = c1 = (3,4) `Static double Abs(Complex c)` `double d = Complex.Abs(c1);` d = 5 `Static double Arg(Complex c)` `double d2 = Complex.Arg(c1);` d2 = 0.927295218001612 `Static Complex Conj(Complex c)` `Complex c2 = Complex.Conj(c1);` c2 = (3,-4) `Static double Imag(Complex c)` `double imag =Complex.Imag(c2);` imag = -4 `Static double Real(Complex c) ` `double real =Complex.Real(c1);` real = 3 `Double Imag()` `double imag2 = c1.Imag();` imag2 = 4 `Double Real() ` `double real2 = c1.Real();` real2 = 3 `Static Complex Polar(double r, double theta)` `Complex p = Complex.Polar(5,Math.PI/180);` p = (4.99924,0.087262) `Static Complex Cos(Complex c)` `Complex c3 = Complex.Cos(p);` c3 = (0.28401,0.0838028) `Static Complex Cosh(Complex c)` `Complex c4 = Complex.Cosh(p);` c4 = (73.8713,6.46199) `Static Complex Exp(Complex c)` `Complex c5 = Complex.Exp(p);` c5 = (147.736,12.9246) `Static Complex Log(Complex c)` `Complex c6 = Complex.Log(p);` c6 = (1.60944,0.0174533) `Static Complex Log10(Complex c)` `Complex c7 = Complex.Log10(p);` c7 = (0.69897,0.00757987) `Static double Norm(Complex c)` `double n = Complex.Norm(p);` n = 25 `Static Complex Pow(Complex base, double power)` `Complex c9 = Complex.Pow(p,4);` c9 = (623.478,43.5978) `Static Complex Pow(Complex base, Complex power)` `Complex c10 = Complex.Pow(p,p);` c10 = (3035.98,703.481) `Static Complex Pow(double base, Complex power)` `Complex c11 = Complex.Pow(2,p);` c11 = (31.9246,1.93333) `Static Complex Sin(Complex c)` `Complex c12 = Complex.Sin(p);` c12 = (-0.962794,0.0247206) `Static Complex Sinh(Complex c)` `Complex c13 = Complex.Sinh(p);` c13 = (73.8646,6.46257) `Static Complex Sqrt(Complex c)` `Complex c14 = Complex.Sqrt(p);` c14 = (2.23598,0.0195131) `Static Complex Tan(Complex c)` `Complex c15 = Complex.Tan(p);` c15 = (-3.09486,1.00024) `Static Complex Tanh(Complex c)` `Complex c15a = Complex.Tanh(p);` c15a = (0.99991,1.57891e-05) Operators `-` (Unary) `Complex c16 = -c15;` c16 = (3.09486,-1.00024) `+` (Unary) `Complex c17 = +c16;` c17 = (3.09486,-1.00024) `==` `bool eq = (c16 == -c15);` eq = True `==` (overloaded) `bool eq2 = ( new Complex(2,0) == 2);` eq2 = True `==` (overloaded) `bool eq3 = ( 2 == new Complex(2,0));` eq3 = True `!=` `bool ne = (c16 != c16);` ne = False `!=` (overloaded) `bool ne2 = ( new Complex(2,0) != 2);` ne2 = False `!=` (overloaded) `bool ne3 = ( 2 != new Complex(2,0));` ne3 = False `*` `Complex c18 = c1*c1;` c18 = (-7,24) `*` (overloaded) `Complex c19 = c1*double.PositiveInfinity;` c19 = (Infinity,Infinity) `*` (overloaded) `Complex c20 = 12*c1;` c20 = (36,48) `/` `Complex c21 = c1/c1;` c21 = (1,0) `/` (overloaded) `Complex c22 = c1/double.PositiveInfinity;` c22 = (0,0) `/` (overloaded) `Complex c23 = 1/c1;` c23 = (0.12,-0.16) `+` `Complex c24 = c1+c1;` c24 = (6,8) `+` (overloaded) `Complex c25 = c1+double.PositiveInfinity;` c25 = (Infinity,4) `+` (overloaded) `Complex c26 = 1+c1;` c26 = (4,4) `-` `Complex c27 = c1-c1;` c27 = (0,0) `-` (overloaded) `Complex c28 = c1-double.PositiveInfinity;` c28 = (-Infinity,4) `-` (overloaded) `Complex c29 = 1-c1;` c29 = (-2,-4)

## VB .NET Example (vb_complex.vb)

```Imports System
Imports KarlsTools

Module Module1

Sub Main()
Dim c1 As Complex = New Complex(3.0, 4.0)
dim d as Double = Complex.Abs(c1)
Console.WriteLine("Test Complex,  d = "& d.ToString())
End Sub
End Module```

Compile and run the above code with the following commands:

```c:\>vbc vb_complex.vb /r:complex.dll /r:System.dll
c:\>vb_complex.exe
Test Complex, d = 5```
 Complex Number Class for .NET List of Functionality Visual Basic Example VB output `Imports KarlsTools` Constructor `Complex(double real, double imag)` `Dim c1 As Complex = New Complex(3, 4)` c1 = (3,4) Methods `String ToString()` `Dim s As String = "c1 = " + c1.ToString()` s = c1 = (3,4) `shared double Abs(Complex c)` `Dim d As Double = Complex.Abs(c1)` d = 5 `shared double Arg(Complex c)` `Dim d2 As Double = Complex.Arg(c1)` d2 = 0.927295218001612 `shared Complex Conj(Complex c)` `Dim c2 As Complex = Complex.Conj(c1)` c2 = (3,-4) `shared double Imag(Complex c)` `Dim imag As Double = Complex.Imag(c2)` imag = -4 `shared double Real(Complex c) ` `Dim real As Double = Complex.Real(c1)` real = 3 `double Imag()` `Dim imag2 As Double = c1.Imag()` imag2 = 4 `double Real() ` `Dim real2 As Double = c1.Real()` real2 = 3 `shared Complex Polar(double r, double theta)` `Dim p As Complex = Complex.Polar(5, Math.PI / 180)` p = (4.99924,0.087262) `shared Complex Cos(Complex c)` `Dim c3 As Complex = Complex.Cos(p)` c3 = (0.28401,0.0838028) `shared Complex Cosh(Complex c)` `Dim c4 As Complex = Complex.Cosh(p)` c4 = (73.8713,6.46199) `shared Complex Exp(Complex c)` `Dim c5 As Complex = Complex.Exp(p)` c5 = (147.736,12.9246) `shared Complex Log(Complex c)` `Dim c6 As Complex = Complex.Log(p)` c6 = (1.60944,0.0174533) `shared Complex Log10(Complex c)` `Dim c7 As Complex = Complex.Log10(p)` c7 = (0.69897,0.00757987) `shared double Norm(Complex c)` `Dim n As Double = Complex.Norm(p)` n = 25 `shared Complex Pow(Complex base, double power)` `Dim c9 As Complex = Complex.Pow(p, 4)` c9 = (623.478,43.5978) `shared Complex Pow(Complex base, Complex power)` `Dim c10 As Complex = Complex.Pow(p, p)` c10 = (3035.98,703.481) `shared Complex Pow(double base, Complex power)` `Dim c11 As Complex = Complex.Pow(2, p)` c11 = (31.9246,1.93333) `shared Complex Sin(Complex c)` `Dim c12 As Complex = Complex.Sin(p)` c12 = (-0.962794,0.0247206) `shared Complex Sinh(Complex c)` `Dim c13 As Complex = Complex.Sinh(p)` c13 = (73.8646,6.46257) `shared Complex Sqrt(Complex c)` `Dim c14 As Complex = Complex.Sqrt(p)` c14 = (2.23598,0.0195131) `shared Complex Tan(Complex c)` `Dim c15 As Complex = Complex.Tan(p)` c15 = (-3.09486,1.00024) `shared Complex Tanh(Complex c)` `Dim c15a As Complex = Complex.Tanh(p)` c15a = (0.99991,1.57891e-05) Operators `-` (Unary) `Dim c16 As Complex = Complex.Negative(c15)` c16 = (3.09486,-1.00024) `+` (Unary) `Dim c17 As Complex = Complex.Plus(c16)` c17 = (3.09486,-1.00024) `==` `Dim eq As Boolean = c16.Equals(c17)` eq = True `==` (overloaded) `Dim eq2 As Boolean = (New Complex(2, 0)).Equals(2)` eq2 = True `==` (overloaded) `Dim eq3 As Boolean = Complex.Equals(2, New Complex(2, 0))` eq3 = True `!=` `Dim ne As Boolean = Complex.NotEqual(c16, c16)` ne = False `!=` (overloaded) `Dim ne2 As Boolean = Complex.NotEqual(New Complex(2, 0), 2)` ne2 = False `!=` (overloaded) `Dim ne3 As Boolean = Complex.NotEqual(2, New Complex(2, 0))` ne3 = False `*` `Dim c18 As Complex = Complex.Multiply(c1, c1)` c18 = (-7,24) `*` (overloaded) `Dim c19 As Complex = Complex.Multiply(c1, Double.PositiveInfinity)` c19 = (Infinity,Infinity) `*` (overloaded) `Dim c20 As Complex = Complex.Multiply(12, c1)` c20 = (36,48) `/` `Dim c21 As Complex = Complex.Divide(c1, c1)` c21 = (1,0) `/` (overloaded) `Dim c22 As Complex = Complex.Divide(c1, Double.PositiveInfinity)` c22 = (0,0) `/` (overloaded) `Dim c23 As Complex = Complex.Divide(1, c1)` c23 = (0.12,-0.16) `+` `Dim c24 As Complex = Complex.Add(c1, c1)` c24 = (6,8) `+` (overloaded) `Dim c25 As Complex = Complex.Add(c1, Double.PositiveInfinity)` c25 = (Infinity,4) `+` (overloaded) `Dim c26 As Complex = Complex.Add(1, c1)` c26 = (4,4) `-` `Dim c27 As Complex = Complex.Subtract(c1, c1)` c27 = (0,0) `-` (overloaded) `Dim c28 As Complex = Complex.Subtract(c1, Double.PositiveInfinity)` c28 = (-Infinity,4) `-` (overloaded) `Dim c29 As Complex = Complex.Subtract(1, c1)` c29 = (-2,-4)

## Implementation

This class is implemented using Managed C++. It duplicates the capabilities of the Fortran complex*16 type, and is a value type class with static (shared) math functions. This is how the .NET `Math` class is designed. Non-trivial methods are wrappers around the Standard Template Library (STL) `<complex>` class. The library has been tested with C# against all C++ STL <complex> sample output on Microsoft's web site.

Use either Visual Studio or the make file to compile the library (complex.dll). If you have Visual C++, open complex.vcproj and build. An alternate way to compile is by typing 'nmake' from a command prompt. A make file is included with the download.

## Issues when wrapping a C++ STL class for use with VB and C#

An easy way to provide complete functionality is to wrap the C++ STL <complex> class using Managed C++. This works well but wrapped methods run twice as slow as a method written from scratch. This is because the MSIL code generated by the C++ compiler has calls to the `System.Runtime.CompilerServices` to access the STL. I compromised by writing trivial methods from scratch and relied on the STL implementation otherwise.

This class duplicates the FORTRAN complex*16 type. Eight bytes for the real part, and 8 bytes for the imaginary part, by using `std::complex<double>`. This is not as flexible as the C++ STL class which allows `double`, `float`, or `int` to be used.

Extra code was added to provide VB functionality. The C++/C# operators `!=`, `==`, `+`, `-`, `*` and `/` didn't directly work in VB. I added methods: `NotEqual`, `Equals`, `Add`, `Subtract`, `Multiply` and `Divide` to provide complete functionality in VB. I do not understand why I needed to do this - please comment.

## About the Author

 Other United States
Karl is a Water Resources Engineer and Programmer. He holds a Masters degree in Civil Engineering, and is a Microsoft Certified Solution Developer.

## Comments and Discussions

 First Prev Next
 S....L....O....W.... mattsoundworld14-Oct-11 3:34 mattsoundworld 14-Oct-11 3:34
 Updates and extensions bitzblitz14-Sep-10 3:54 bitzblitz 14-Sep-10 3:54
 Cool Hard Coder15-Feb-10 9:01 Hard Coder 15-Feb-10 9:01
 hi Jay20003229-Mar-09 12:18 Jay200032 29-Mar-09 12:18
 Norm of 3 and 4 won`t be 25. vitamine19831-Nov-08 20:51 vitamine1983 1-Nov-08 20:51
 Re: Norm of 3 and 4 won`t be 25. bitzblitz14-Sep-10 4:09 bitzblitz 14-Sep-10 4:09
 Convert Double Precision Trupti Mehta7-Oct-08 20:45 Trupti Mehta 7-Oct-08 20:45
 Thank you davoodrajabi2-Nov-07 20:35 davoodrajabi 2-Nov-07 20:35
 A Simple Pure C# Complex Class bossin8-Jun-06 16:29 bossin 8-Jun-06 16:29
 Re: A Simple Pure C# Complex Class boaza14-Nov-07 21:17 boaza 14-Nov-07 21:17
 Re: A Simple Pure C# Complex Class `leppie`12-Aug-08 0:19 `leppie` 12-Aug-08 0:19
 Re: A Simple Pure C# Complex Class thefellow3j18-Oct-10 5:17 thefellow3j 18-Oct-10 5:17
 Windows Forms support? Bill200531-Dec-05 20:24 Bill2005 31-Dec-05 20:24
 Re: Windows Forms support? Karl Tarbet2-Jan-06 4:17 Karl Tarbet 2-Jan-06 4:17
 Visual Studio 2005 support? Bill200531-Dec-05 20:18 Bill2005 31-Dec-05 20:18
 Re: Visual Studio 2005 support? Karl Tarbet1-Jan-06 4:46 Karl Tarbet 1-Jan-06 4:46
 Re: Visual Studio 2005 support? Bill20051-Jan-06 14:42 Bill2005 1-Jan-06 14:42
 I must say it's very good piece of work piotr.kolodziej11-Dec-05 8:45 piotr.kolodziej 11-Dec-05 8:45
 You don't have to Doker20-Oct-05 21:51 Doker 20-Oct-05 21:51
 american history indian Anonymous7-Mar-05 13:31 Anonymous 7-Mar-05 13:31
 <complex> and managed code PDHB12-Oct-03 15:43 PDHB 12-Oct-03 15:43
 This seems, well, too complex Marc Clifton16-Dec-02 3:37 Marc Clifton 16-Dec-02 3:37
 Re: This seems, well, too complex Karl Tarbet16-Dec-02 13:24 Karl Tarbet 16-Dec-02 13:24
 Re: This seems, well, too complex Marc Clifton17-Dec-02 1:18 Marc Clifton 17-Dec-02 1:18
 Last Visit: 31-Dec-99 18:00     Last Update: 30-Jun-15 6:55 Refresh 1

General    News    Suggestion    Question    Bug    Answer    Joke    Rant    Admin

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.