Click here to Skip to main content
Click here to Skip to main content

Complex math library for C# and VB.NET

By , 15 Dec 2002
 

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</CODE>
 
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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

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

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionS....L....O....W....membermattsoundworld14 Oct '11 - 3:34 
That is all...
NewsUpdates and extensionsmemberbitzblitz14 Sep '10 - 3:54 
Thanks for the library. I have updated it a bit and added a couple extensions. Here is the code:
complex.h:
// complex.h
//
// copywrite(c) Karl Tarbet  2002
//
// karltarbet@hotmail.com
//  
/* 
 
Complex number class for .NET platform languages.
Complex numbers have a real and imaginary part.
each is represented as a double with 8 bytes.
This is like the FORTRAN complex*16.  Eight bytes 
for the real part; 8 bytes for the imaginary.
 
This complex number class may be used and 
distributed without charge. There is no warranty.
 
This is a value type class.
It is implemented as a simple wrapper around the standard C++
library complex number class.
 
*/
#pragma once
using namespace System;
#include <complex>
 
namespace ComplexMath
	{
	public  value  class Complex
		{
		private:
			double _real;
			double _imag;
			static Complex Convert(std::complex<double> c);// simplify code with this method
		public:
			Complex(double real, double imag);
			Complex(double real):_real(real),_imag(0)
				{
				}
			Complex(std::complex<double>& Other);
			virtual System::String^  ToString() override; 
			virtual System::String^  ToString(System::String^ Format); 
 
			/*********
			*  Operators
			*********/
			//	op_Decrement (--) 
			//  op_Increment (++) 

			static Complex operator +(Complex cLeft);
			static Complex operator -(Complex cLeft);
 
			static Complex Plus(Complex cLeft)
				{return operator +(cLeft);}
			static Complex Negative(Complex cLeft)
				{return operator -(cLeft);}
 
			static bool operator ==( Complex cLeft, Complex cRight);
			static bool operator ==( Complex cLeft, double right);
			static bool operator ==( double left, Complex cRight);
 
			// for vb.
			bool Equals( double number)
				{return operator ==( *this,number);}
			bool Equals( Complex c)
				{return operator ==( *this,c);}
 
			// for vb.
			static bool Equals( Complex cLeft, Complex cRight)
				{return operator ==( cLeft, cRight);}
			static bool Equals( Complex cLeft, double right)
				{return operator ==( cLeft, right);}
			static bool Equals( double left, Complex cRight)
				{return  operator ==( left, cRight);}
 
			static bool operator != ( Complex cLeft, Complex cRight)
				{ return !operator ==(cLeft,cRight); }
			static bool operator !=( Complex cLeft, double right)
				{ return !operator ==(cLeft,right); }
			static bool operator !=( double left, Complex cRight)
				{ return !operator ==(left,cRight); }
 
			// for vb.
			static bool NotEqual( Complex cLeft, Complex cRight)
				{ return !operator ==(cLeft,cRight); }
			static bool NotEqual( Complex cLeft, double right)
				{ return !operator ==(cLeft,right); }
			static bool NotEqual( double left, Complex cRight)
				{ return !operator ==(left,cRight); }
 

			static Complex operator *( Complex cLeft, Complex cRight);
			static Complex operator *( Complex cLeft, double right);
			static Complex operator *( double left , Complex cRight);
 
			// for vb.
			static Complex Multiply( Complex cLeft, Complex cRight)
				{ return  operator *( cLeft, cRight); }
			static Complex Multiply( Complex cLeft, double right)
				{ return  operator *( cLeft, right);}
			static Complex Multiply( double left , Complex cRight)
				{ return  operator *( left , cRight); }
 
			static Complex operator /( Complex cLeft , Complex cRight);
			static Complex operator /( Complex cLeft , double right);
			static Complex operator /( double left   , Complex cRight);
 
			// for vb.
			static Complex Divide( Complex cLeft, Complex cRight)
				{ return  operator /( cLeft, cRight); }
			static Complex Divide( Complex cLeft, double right)
				{ return  operator /( cLeft, right);}
			static Complex Divide( double left , Complex cRight)
				{ return  operator /( left , cRight); }
 

			static Complex operator +( Complex cLeft, Complex cRight);
			static Complex operator +( Complex cLeft, double right);
			static Complex operator +( double left, Complex cRight);
 
			// for vb.
			static Complex Add( Complex cLeft, Complex cRight)
				{ return  operator +( cLeft, cRight); }
			static Complex Add( Complex cLeft, double right)
				{ return  operator +( cLeft, right);}
			static Complex Add( double left , Complex cRight)
				{ return  operator +( left , cRight); }
 

			static Complex operator -( Complex cLeft, Complex cRight);
			static Complex operator -( Complex cLeft, double right);
			static Complex operator -( double left, Complex cRight);
 
			// for vb.
			static Complex Subtract( Complex cLeft, Complex cRight)
				{ return  operator -( cLeft, cRight); }
			static Complex Subtract( Complex cLeft, double right)
				{ return  operator -( cLeft, right);}
			static Complex Subtract( double left , Complex cRight)
				{ return  operator -( left , cRight); }
			/******
			* Properties
			*******/
			property double x
				{
				double get()
					{
					return _real;
					}
				void set(double value)
					{
					_real=value;
					}
				}
			property double y
				{
				double get()
					{
					return _imag;
					}
				void set(double value)
					{
					_imag=value;
					}
				}
			property double Magnitude
				{
				double get()
					{
					return _real*_real+_imag*_imag;
					}
				void set(double value)
					{
					double arg = Complex::Arg(*this);
					std::complex<double> c = std::polar(value,arg);
					_real=c.real();
					_imag=c.imag();
					}
				}
 
			/*******
			* Methods
			*********/
			static double Abs(Complex c);
			static double Arg(Complex c);
			static Complex Conj(Complex c);
			static double Imag(Complex c) 
				{ return c._imag;}
			static double Real(Complex c) 
				{ return c._real;}
			static Complex Polar(double r, double theta);
			static Complex Polar(double r); // theta = 0
			static Complex Cos(Complex c);
			static Complex Cosh(Complex c);
			static Complex Exp(Complex c);
			static Complex Log(Complex c);
			static Complex Log10(Complex c);
			static double Norm(Complex c);
			static Complex Pow(Complex base, double power);
			static Complex Pow(Complex base, Complex power);
			static Complex Pow(double base, Complex power);
			static Complex Sin(Complex c);
			static Complex Sinh(Complex c);
			static Complex Sqrt(Complex c);
 
			static Complex Tan(Complex c);
			static Complex Tanh(Complex c);
			static Complex Parse(String^ Text);
		};
	}
 
complex.cpp:
 
// (c) Karl Tarbet 2002

#include "stdafx.h"
#include "complex.h"
 
using namespace System;
using namespace std;
 
namespace ComplexMath
	{
	Complex::Complex(double real, double imag):_real(real),_imag(imag)
		{
		}
	Complex::Complex(std::complex<double>& Other):_real(Other.real()),_imag(Other.imag())
		{
		}
	System::String^ Complex::ToString()
		{   // examples:
		// '(3,4)'
		// '(-0.761594,-8.68604e-14)'
		return String::Format("({0:g6},{1:g6})",_real,_imag);
		}
 
	System::String^ Complex::ToString(System::String^ Format)
		{   // examples:
		// '(3,4)'
		// '(-0.761594,-8.68604e-14)'
		return String::Format(Format,_real,_imag);
		}
 
	Complex Complex::operator +(Complex cLeft)
		{
		return cLeft;
		}
 
	Complex Complex::operator -(Complex cLeft)
		{
		cLeft._imag=-cLeft._imag;
		cLeft._real=-cLeft._real;
		return cLeft;
		}
 
	bool Complex::operator ==( Complex cLeft, Complex cRight)
		{
		return (cLeft._imag == cRight._imag) && (cLeft._real == cRight._real);
		}
 
	bool Complex::operator ==( Complex cLeft, double right)
		{
		return (cLeft._real == right) && (cLeft._imag == 0);
		}
	bool Complex::operator ==( double left, Complex cRight)
		{
		return (left == cRight._real) && (cRight._imag == 0);
		}
 
	Complex Complex::operator +(Complex cLeft, Complex cRight)
		{
		cLeft._real+=cRight._real;
		cLeft._imag+=cRight._imag;
		return cLeft;
		}
 
	Complex Complex::operator +( Complex cLeft, double right)
		{
		cLeft._real+=right;
		return cLeft;
		}
 
	Complex Complex::operator +( double left, Complex cRight)
		{
		cRight._real+=left;
		return cRight;
		}
 
	Complex Complex::operator -( Complex cLeft, Complex cRight)
		{
		cLeft._real-=cRight._real;
		cLeft._imag-=cRight._imag;
		return cLeft;
		}
 
	Complex Complex::operator -( Complex cLeft, double right)
		{
		cLeft._real-=right;
		return cLeft;
		}
 
	Complex Complex::operator -( double left, Complex cRight)
		{
		return -cRight+left;
		}
 
	Complex Complex::operator *(Complex c1, Complex c2)
		{
		return Complex(c1._real*c2._real-c1._imag*c2._imag,c1._real*c2._imag+c2._real*c1._imag);
		}
	Complex Complex::operator *(Complex cLeft, double right)
		{
		return Complex(right*cLeft._real,right*cLeft._imag);
		}
	Complex Complex::operator *( double left , Complex cRight)
		{
		complex<double> C1(cRight._real,cRight._imag);
		return Complex(left*C1);
		}
 
	Complex Complex::operator /(Complex c1, Complex c2)
		{
		complex<double> C1(c1._real,c1._imag);
		complex<double> C2(c2._real,c2._imag);
		return Convert(C1/C2);
		}
	Complex Complex::operator /( Complex cLeft, double right)
		{
		complex<double> C1(cLeft._real,cLeft._imag);
		return Convert(C1/right);
		}
	Complex Complex::operator /( double left , Complex cRight)
		{
		complex<double> C1(cRight._real,cRight._imag);
		return Convert(left/C1);
		}
 
	double Complex::Abs(Complex c)
		{
		std::complex<double> c1(c._real,c._imag);
		double rval = abs(c1);
		return rval;
		}
	double Complex::Arg(Complex c)
		{
		std::complex<double> c1(c._real,c._imag);
		double rval = arg(c1);
		return rval;
		}
	Complex Complex::Conj(Complex c)
		{
		std::complex<double> c1(c._real,c._imag);
		std::complex<double> c2 = conj(c1);
		return Convert(c2);
		}
 
	Complex Complex::Cos(Complex c)
		{
		std::complex<double> c1(c._real,c._imag);
		std::complex<double> c2 = cos(c1);
		return Convert(c2);
		}
	Complex Complex::Cosh(Complex c)
		{
		std::complex<double> c1(c._real,c._imag);
		std::complex<double> c2 = cosh(c1);
		return Convert(c2);
		}
	Complex Complex::Exp(Complex c)
		{
		std::complex<double> c1(c._real,c._imag);
		std::complex<double> c2 = exp(c1);
		return Convert(c2);
		}
	Complex Complex::Log(Complex c)
		{
		std::complex<double> c1(c._real,c._imag);
		std::complex<double> c2 = log(c1);
		return Convert(c2);
		}
 
	Complex Complex::Log10(Complex c)
		{
		std::complex<double> c1(c._real,c._imag);
		std::complex<double> c2 = std::log10(c1);
		return Convert(c2);
		}
	double Complex::Norm(Complex c)
		{
		std::complex<double> c1(c._real,c._imag);
		return std::norm(c1);
		}
	Complex Complex::Polar(double r)
		{
		return Polar(r,0);
		}
	Complex Complex::Polar(double r, double theta)
		{
		std::complex <double> c1 ( polar (r,theta ) );  
		return Convert(c1);
		}
 
	Complex Complex::Pow(Complex base, double power)
		{
		std::complex<double> c1(base._real,base._imag);
		return Convert(std::pow(c1,power));
		}
	Complex Complex::Pow(Complex base, Complex power)
		{
		std::complex<double> c1(base._real,base._imag);
		std::complex<double> c2(power._real,power._imag);
		return Convert(std::pow(c1,c2));
		}
	Complex Complex::Pow(double base, Complex power)
		{
		std::complex<double> c1(power._real,power._imag);
		return Convert(std::pow(base,c1));
		}
 
	Complex Complex::Sin(Complex c)
		{
		std::complex<double> c1(c._real,c._imag);
		std::complex<double> c2 = sin(c1);
		return Convert(c2);
		}
	Complex Complex::Sinh(Complex c)
		{
		std::complex<double> c1(c._real,c._imag);
		std::complex<double> c2 = sinh(c1);
		return Convert(c2);
		}
	Complex Complex::Sqrt(Complex c)
		{
		std::complex<double> c1(c._real,c._imag);
		std::complex<double> c2 = sqrt(c1);
		return Convert(c2);
		}
	Complex Complex::Tan(Complex c)
		{
		std::complex<double> c1(c._real,c._imag);
		std::complex<double> c2 = tan(c1);
		return Convert(c2);
		}
	Complex Complex::Tanh(Complex c)
		{
		std::complex<double> c1(c._real,c._imag);
		std::complex<double> c2 = tanh(c1);
		return Convert(c2);
		}
 
	Complex Complex::Parse(String^ Text)
		{
		String^ txt = Text->Replace("(","");
		txt=txt->Replace(")","");
		array<String^>^ parts = txt->Split(',');
		return Complex(Double::Parse(parts[0]),Double::Parse(parts[1]));
		}
	//Converts std::complex<double> to ComplexMath::Complex
	Complex Complex::Convert(complex<double> c)
		{
		Complex rval = Complex(real(c),imag(c));
		return rval;
		}
	}// namespace ComplexMath

GeneralCoolmemberHard Coder15 Feb '10 - 9:01 
I like it.
GeneralhimemberJay20003229 Mar '09 - 12:18 
please how can i write codes to set up maths test for 5 people and save their results in a database?
GeneralNorm of 3 and 4 won`t be 25.membervitamine19831 Nov '08 - 20:51 
The norm of 3 and 4 won`t be 25. It will be equal 5.
AnswerRe: Norm of 3 and 4 won`t be 25.memberbitzblitz14 Sep '10 - 4:09 
The norm is the square of the modulus, so 25 is correct.
GeneralConvert Double PrecisionmemberTrupti Mehta7 Oct '08 - 20:45 
Hi,
 
I have a Fortran program which I have to convert into Java originally. I have converted the code completely but can't get appropriate resutls. The code contains lot of arithmetic calculations using double precision data type of Fortran.
 
I believe the data types of C++ and Java are based on same whereas of Fortran double precision is based on IEEE756. I want to know how to convert these double precision calculations into C++ normally. For example:
double precision d1 = 0.3648564D0;
d1**2 // ** indicates exponent
DSIN(d1) // sin of double precision
DCOS(d1) // cos of double precision
 
The above are my main concerns which I find very difficult to convert. I use sin & cos for DSIN & DCOS. But Fortran 77 deals somthing differntly with double precision. How to convert/translate that into our normal C++ application is what I am looking for.
 
If you can provide the same for Java that would be a plus for me, otherwise I will use the code accordingly of C++ in my Java application. I hope help from you.
 
Please help me out. Am stuck up very badly.
 
Thanks
 
Terry

GeneralHelpmemberVucina7 Aug '08 - 12:30 
This command don't work in Command Window in VS 2008.
Command "c:\>vbc" is not valid.
What I am doing wrong ?
GeneralRe: HelpmemberKarl Tarbet9 Aug '08 - 8:23 
Use the visual studio command prompt.
 

Start -> All Programs -> Visual Studio 2008 -->Visual Studio Tools --> Visual Studio command prompt.
GeneralThank youmemberdavoodrajabi2 Nov '07 - 20:35 
Hello my dear.
Thank you very much.
I could finish a C# programs with your code.
Thank you,you could help me in my thesis.
I hope you have very nice time every day.
Kind regard.
Big Grin | :-D Big Grin | :-D
GeneralA Simple Pure C# Complex Classmemberbossin8 Jun '06 - 16:29 
//========================================================================
// Copyright (c) 2005-2006, Boxing Wang. All rights reserved.
//========================================================================
 
using System;
using System.Diagnostics;
 

namespace Wbx.Math
{
   [DebuggerDisplay("{Real} + {Imag}i")]
   public struct Complex
   {
         public double Real;
 
         public double Imag;
 
         [DebuggerStepThrough()]
         public Complex(double real, double imag)
         {
            this.Real = real;
            this.Imag = imag;
         }
 
         [DebuggerBrowsableAttribute(DebuggerBrowsableState.Never)]
         public Complex Conjugate
         {
            [DebuggerStepThrough()]
            get { return new Complex(Real, -Imag); }
         }
 
         [DebuggerBrowsableAttribute(DebuggerBrowsableState.Never)]
         public double Norm
         {
            [DebuggerStepThrough()]
            get { return Real * Real + Imag * Imag; }
         }
 
         [DebuggerBrowsableAttribute(DebuggerBrowsableState.Never)]
         public double Modulus
         {
            [DebuggerStepThrough()]
            get { return System.Math.Sqrt(Real * Real + Imag * Imag); }
         }
 
      [DebuggerBrowsableAttribute(DebuggerBrowsableState.Never)]
         public double Argument
         {
            [DebuggerStepThrough()]
            get { return System.Math.Atan2(Imag, Real); }
         }
 
         [DebuggerStepThrough()]
         public static Complex Polar(double modulus, double argument)
         {
            return new Complex(
                  modulus * System.Math.Cos(argument),
                  modulus * System.Math.Sin(argument));
         }
 
         public static Complex operator +(Complex z1, Complex z2)
         {
            return new Complex(z1.Real + z2.Real, z1.Imag + z2.Imag);
         }
 
         public static Complex operator -(Complex z1, Complex z2)
         {
            return new Complex(z1.Real - z2.Real, z1.Imag - z2.Imag);
         }
 
         public static Complex operator *(Complex z1, Complex z2)
         {
            return new Complex(
                  z1.Real * z2.Real - z1.Imag * z2.Imag,
                  z1.Real * z2.Imag + z1.Imag * z2.Real);
         }
 
         public static Complex operator /(Complex z1, Complex z2)
         {
            double value = z2.Real * z2.Real + z2.Imag * z2.Imag;
 
            return new Complex(
                  (z1.Real * z2.Real + z1.Imag * z2.Imag) / value,
                  (z1.Imag * z2.Real - z1.Real * z2.Imag) / value);
         }
 
         public static bool operator ==(Complex z1, Complex z2)
         {
            return (z1.Real == z2.Real && z1.Imag == z2.Imag);
         }
 
         public static bool operator !=(Complex z1, Complex z2)
         {
            return (z1.Real != z2.Real || z1.Imag == z2.Imag);
         }
 
         public static Complex Cos(Complex z)
         {
            Complex z1 = Exp(new Complex(-z.Imag, z.Real));
            Complex z2 = Exp(new Complex(z.Imag, -z.Real));
 
            return new Complex(0.5 * (z1.Real + z2.Real), 0.5 * (z1.Imag + z2.Imag));
         }
 
         public static Complex Cosh(Complex z)
         {
            Complex z1 = Exp(z);
            Complex z2 = Exp(new Complex(-z.Real, -z.Imag));
 
            return new Complex(0.5 * (z1.Real + z2.Real), 0.5 * (z1.Imag + z2.Imag));
         }
 
         public static Complex Sin(Complex z)
         {
            Complex z1 = Exp(new Complex(-z.Imag, z.Real));
            Complex z2 = Exp(new Complex(z.Imag, -z.Real));
 
            return new Complex(0.5 * (z1.Imag - z2.Imag), 0.5 * (z2.Real - z1.Real));
         }
 
         public static Complex Sinh(Complex z)
         {
            Complex z1 = Exp(z);
            Complex z2 = Exp(new Complex(-z.Real, -z.Imag));
 
            return new Complex(0.5 * (z1.Real - z2.Real), 0.5 * (z1.Imag - z2.Imag));
         }
 
         public static Complex Tan(Complex z)
         {
            return Sin(z) / Cos(z);
         }
 
         public static Complex Tanh(Complex z)
         {
            return Sinh(z) / Cosh(z);
         }
 
         public static Complex Exp(Complex z)
         {
            double value = System.Math.Exp(z.Real);
 
            return new Complex(
                  value * System.Math.Cos(z.Imag),
                  value * System.Math.Sin(z.Imag));
         }
 
         public static Complex Log(Complex z)
         {
            return new Complex(System.Math.Log(z.Modulus), z.Argument);
         }
 
         public static Complex Log10(Complex z)
         {
            const double log10 = 2.3025850929940459;
 
            Complex value = Log(z);
 
            value.Real /= log10;
            value.Imag /= log10;
 
            return value;
         }
 
         public static Complex Pow(Complex baseNumber, Complex index)
         {
            return Exp(index * Log(baseNumber));
         }
 
         public static Complex Sqrt(Complex z)
         {
            double value = System.Math.Sqrt(z.Real * z.Real + z.Imag * z.Imag) + z.Real;
 
            return new Complex(
                  System.Math.Sqrt(0.5 * value),
                  System.Math.Sqrt(0.5 / value) * z.Imag);
         }
 
         public override string ToString()
         {
            return (String.Format("{0} + {1}i", Real, Imag));
         }
 
         public override bool Equals(object obj)
         {
            return base.Equals(obj);
         }
 
         public override int GetHashCode()
         {
            return Real.GetHashCode() ^ Imag.GetHashCode();
         }
   }
}

GeneralRe: A Simple Pure C# Complex Classmemberboaza14 Nov '07 - 21:17 
Very nice.
Note the error in the != operator:
should be:
 
public static bool operator !=(Complex z1, Complex z2)
{
return (z1.Real != z2.Real || z1.Imag != z2.Imag);
}
 

GeneralRe: A Simple Pure C# Complex Classmemberleppie12 Aug '08 - 0:19 
Your sqrt function is also wrong, but thanks for the rest, proved very helpful Smile | :)
 
Correct sqrt:
public static Complex Sqrt(Complex z)
{
  return Polar(System.Math.Sqrt(z.Modulus), z.Argument * 0.5);
}

 
xacc.ide - now with TabsToSpaces support
IronScheme - 1.0 alpha 4a out now (29 May 2008)

GeneralRe: A Simple Pure C# Complex Classmemberthefellow3j18 Oct '10 - 5:17 
You should either mark the Real and Imag fields as readonly, or make them public properties with private setters. You can append " : this()" to the constructor's signature to make C# allow property assignments in the constructor.
QuestionWindows Forms support?memberBill200531 Dec '05 - 20:24 

Can this run with Windows Forms instead of console? I tried adding complex.dll as a reference (in Visual Studio 2005) but got the following error ar runtime:
 
LoaderLock was detected
 
DLL 'C:\Documents and Settings\Bill\My Documents\Visual Studio 2005\Projects\TestComplex\TestComplex\bin\Release\complex.dll' is attempting managed execution inside OS Loader lock. Do not attempt to run managed code inside a DllMain or image initialization function since doing so can cause the application to hang.
AnswerRe: Windows Forms support?memberKarl Tarbet2 Jan '06 - 4:17 
Bill,
 
I recompiled with VS 2005, and it fixes the problems.
 
The version on codeproject was compiled with the old VS 2002.
 
You might want to try the Nmath library. It is pure managd code and can be downloaded from nmath.sourceforge.net It has a good complex math library, see the file src\Complex.cs (MathNet.Numerics-v0.3)
 

 

 

-- modified at 10:18 Monday 2nd January, 2006
QuestionVisual Studio 2005 support?memberBill200531 Dec '05 - 20:18 
Looks very promising however:
 
I tried the test app in Visual Studio 2005 console mode and while no errors were generated it did not display the line of output at all.
 
Is it supposed to work with Visual Studio 2005?
 
Thanks
 
Bill.
AnswerRe: Visual Studio 2005 support?memberKarl Tarbet1 Jan '06 - 4:46 
Sorry this library has not been tested with visual studio 2005.
 
I will test and make a new version for 2005 if needed. VB now supports operator overloading so that should eliminate the need for the methods Add() Subract(), Multiply(), And Divide().
 
Thanks,
Karl
 


GeneralRe: Visual Studio 2005 support?memberBill20051 Jan '06 - 14:42 
Thank you Karl, appreciated. I'm using C# and Windows Forms.
 
-- Bill.
GeneralI must say it's very good piece of workmemberpiotr.kolodziej11 Dec '05 - 8:45 
I have been writing NUMERICAL METHOD algorithm ( finding roots of polynomials ) and your dll saved my from rewriting program into C++
Gratz
GeneralYou don't have tomemberDoker20 Oct '05 - 21:51 
You don't have to write this to allow vb to use this.
Generalamerican history indiansussAnonymous7 Mar '05 - 13:31 
american history indian
General&lt;complex&gt; and managed codememberPDHB12 Oct '03 - 15:43 
I'm having serious trouble getting the standard library to work in a c++.net DLL. I can't use the one here because speed is a priority in my
application. But any time I use #include , my code won't compile. I get errors like:
"wasteoftime error LNK2020: unresolved token (0A000006) _CxxThrowException"
and
"wasteoftime error LNK2020: unresolved token (0A000016) delete".
 
As a test I even started a new class library project, and pasted every bit of code from the download here into mine, and still got the same problem. (the original compiles fine)
Help!!
And make it simple please. I'm not a Programmer by trade. I'm just a Physicist.
GeneralThis seems, well, too complexmemberMarc Clifton16 Dec '02 - 3:37 
First of all, it's managed C++. This could be written entirely using straight C#.
 
Secondly, why are you using std::complex?. You're instantiated the template using a double in the C++ section, so the C# and VB side doesn't benefit from the point of a template, which is to instantiate whatever type you want. Therefore, this supports the previous point that this should have been written in C# to begin with.
 
BTW, C++ doesn't inherently support complex types (last time I checked). This is provided by STL.
 
You might want to look at this link for some simplistic examples:
 
http://www.csharphelp.com/archives/archive135.html[^]
 
As this article discusses, you might also want to overload the equality operators so we can compare complex numbers.
 
Finally, as you say, there's a major performance hit using complex numbers with managed C++. If I were writing a complicated math function with lots of complex number calculations, I really wouldn't want to incur these performance hits.
 
Marc
 
Help! I'm an AI running around in someone's f*cked up universe simulator.

sensitivity and ethnic diversity means celebrating difference, not hiding from it. - Christian Graus

GeneralRe: This seems, well, too complexmemberKarl Tarbet16 Dec '02 - 13:24 
Thanks for the comment.
You are right it could be in straight C# and that would be nice.
 
My goal was full functionality, which is where managed C++ is great. C# and VB get to use the STL indirectly to get full functionality. The tradeoff is losing some flexibility and performance in non trivial cases. For the easy cases I am NOT using STL!
 
I use STL to handle non-trivial cases letting it worry about significant bits, as needed. With time more functions could be converted away from the STL wrapper. At that point it would be an easy port to C# if desired.

I HAVE overloaded the equality and other operators. I was hoping for feedback on why I needed to create redundant functions like Equals() to make it work in VB. The overloaded stuff works great in C++ and C#, but not everything maps to VB.
 
Ok STL is not “built” into the language but any good C++ compiler has STL, hence you can do complex math with C++ and FORTRAN.

 
Karl
GeneralRe: This seems, well, too complexmemberMarc Clifton17 Dec '02 - 1:18 
I HAVE overloaded the equality and other operators.
 
Oops, sorry!
 
Not to be nitpicky:
 
Ok STL is not “built” into the language but any good C++ compiler has STL, hence you can do complex math with C++ and FORTRAN.
 
Any good C++ compiler supports templates, which therefore allows you to use STL.
 
And not to be sarcastic:
 
I was hoping for feedback on why I needed to create redundant functions like Equals() to make it work in VB. The overloaded stuff works great in C++ and C#, but not everything maps to VB.
 
Another reason why VB is pathetic (Marc tones it down from a vast selection of words beginning with the letter 's').
 
Marc
 
Help! I'm an AI running around in someone's f*cked up universe simulator.
Sensitivity and ethnic diversity means celebrating difference, not hiding from it. - Christian Graus
Every line of code is a liability - Taka Muraoka

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 16 Dec 2002
Article Copyright 2002 by Karl Tarbet
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid