Introduction

Although the C# language has been used quite successfully in many kinds of projects, it still remains to be proven proficient for scientific computing. Questions remain as to whether or not C# can measure up to the likes of FORTRAN and C++ for scientific and mathematical projects.

Complex Arithmetic

Arithmetic and algebra on complex numbers is important in many fields of science and engineering. Even though C# does not support an intrinsic complex number data type, it doesn't stop you from creating your own. You can do so using a struct, which has value semantics. The purpose of this article is to present my attempt to fashion a complex arithmetic class for C#.

Using the Code

The struct Complex is completely contained within the namespace ComplexMath in the file Complex.cs. There are three separate program files included in the download as well as a documented help file for the project. You can run the program either by using the ComplexMath.dll reference, or by using the ComplexMath library code directly by simply adding the Complex.cs file to a project. You must, in either case, add the header using ComplexMath; to the main project file. If you decide to go the DLL route, first build the library (DLL) by running the CompexMath.sln file from which you can generate two ComplexMath.dll files, one each in bin/Release and bin/Debug.

Steps to Use the Library as a DLL

Start a new C# console application.

Build both the Debug and Release versions.

Place the Debug and Release versions of the ComplexMath.dll in their respective bin folders.

From Project/Add Reference menus, find the ComplexMath.dll for the version (debug or release) and add it to the project.

Add the header: using ComplexMath; to your program file.

Use the accompanying TestComplexMath.cs file as a prototype for your own program.

Your test program should look something like the one below which briefly demonstrates many of the capabilities of the library:

The accompanying TestLib program demonstrates all of the capabilities of the Complex struct. One point worth making is that complex numbers can be expressed both in a rectangular form that most high-school algebra students are familiar with and in the more sophisticated polar form which requires some more advanced understanding of trigonometry, De Moivre's Theorem and Euler's Identity. If you are interested, check them out on the Web.

Note that all of the initialization input assumes that you are using the rectangular form of the complex number, which implies that real is measured along the x-axis of the Argand plane and imaginary is measured along the y-axis of that plane. However, the program has the capacity to output the components of the polar form -- that is, the modulus |z| and the argument (theta) -- by using the ShowPolar() and Polar() methods and the Argument and Modulus properties (see above).

Since complex numbers can be added, subtracted, multiplied and divided, it is convenient to have operators to accomplish those ends. Thus, we have incorporated those operators.

History

There appears to be no shortage of postings offering C# code for dealing with complex numbers. These include:

There are software companies selling extensive collections of C# scientific and engineering software for around $1000.00

Although I have been involved in scientific mathematical and statistical programming for over 10 years, this article is the first that I have attempted to post. I quickly learned that there are many smarter and better programmers out there who have done a much better job at using C#. For me, this was an excellent learning experience, both in terms of learning some of the pitfalls of scientific computing with C# and having to explain to others what my code does.

Pitfalls

The fact that C# class assignment operators which are automatically generated and cannot be overridden create something of a problem, particularly if one is coming from a C++ background. Once an assignment is made, the assignor and the assignee are locked together by a common pointer. Change one, you change the other. In order to work around that, one would have to implement ICloneable which can be rather tedious and complicated. For that reason, I chose to use the structrather than a class. I am still learning about C#.

I plan to update and improve this code for my own use and for any others who wish to use it, and to do a better job in the future. You may use this code in any manner that you wish. It is always polite and professional to give the original author credit. Please report any comments, criticisms or bugs to the forum below.

congrats on a very nicely implemented complex number library. I am doing some work on wavelets and I need to add the complex arc tangent. What would be the best way to implement and add the complex inverse sin, cos and tan to your excellent library? Any help appreciated.

joerghaus. Thankyou for your suggestion of implementing complex inverse trigonometric fuction casin, cacos, and catan. I have done that in an updated version, at your suggestion. The update has been posted at http://www.pliatech.com/software/complexmath3.zip. Unfortunately, I have not figured out how to update the link in this article.

Please note that casin, cacos, and catan are referred to in the updated library simply as Asin, Acos, and Atan, since it is already a Complex library and adding a prefix 'c' would make it more cumbersome and less clear.

I could not find any clear explanation for the existence of an analog to the 2 argument arc tangent function that exists for real numbers. Since there are so many analogues between real and complex numbers and functions, I suspect that a complex arc tangent function that takes 2 complex arguments might be possible. Perhaps some eavesdropping mathematician might shed some light on this.

If you have trouble reading the Sandcastle generated help file, it may be possible to unblock the file so that it can be viewed by right-clicking on it, selecting Properties and clicking the Unblock button on the General tab if it is there.

Thanks for uploading your complex class. It is always useful to see alternative implementations regardless of what others might say. My one question is what license are you releasing the code under? Something like BSD? If so I'd like to use in a University research project. I realize you hold copyright.

Thank you for your kind words. Feel free to use this code in any manner that you wish. I am pleased that you find it useful. In the spirit of community, I would appreciate it if you or your colleagues find bugs, have criticisms, or suggestions regarding the code, that you post them here.

I don't mean to be mean, but, seriously, why would anyone write a complex class (matrix library, correlation function, ...) in C# considering that there are existing, already tested APIs out there to do precisely the same thing?

To be perfectly honest, I wanted to see if I could make one better than the others that are available as open source. Hopefully, some others will try it, test it, improve upon it, and feed back their ideas to the community. That's what community is all about. The manner in which you ask the question suggests to me that no answer that I might provide would be satisfactory to you. But I thank you for you input.