Table of contents
The following article contains a list of the following sections and their sub-sections.
- Introduction
- Complex numbers in real
- Programming a complex number
- Creating the class
- Members of the complex number
- Functions of the complex number
- From cartesian to a polar complex number
- Converting the polar to a cartesian complex number
- Getting the logarithm value of complex number
- Conjugate of the complex number
- Cartesian conjugate
- Polar conjugate
- Reciprocal of complex number
- Object-based function
- Arithmetic operations
- Binary operators
- Operations for cartesian complex numbers
- Addition
- Subtraction
- Operations for polar as well as cartesian complex numbers
- Multiplication
- Cartesian compex number
- Polar complex number
- Division
- Cartesian compex number
- Polar complex number
- Equality Check
- Unary operator
- Negate
- Points of interest
- History
Introduction
This article is about programming an application that makes a use of complex numbers and their properties. This article would provide an overview of complex numbers, and how to create an object that can handle the complex numbers in multiple and different programming languages, ranging from C++, C#, Java to VB.NET.
The functions that are to be executed over complex numbers would also be shared, their underlying process and so on. This article would provide an overview of all of the functions in complex numbers, their conversions from one form to another and so on. The article would also cover a slight section of operators that are used in mathematics for complex numbers e.g. +, - etc.
In a few languages this functionality to overload an operator is available, in a few such as Java, this is not available and we have to create a function to perform these tasks, such as a + b
of C++ or C# can be written as a.add(b)
in Java. As we cover this article, we will understand how to do these.
If you're reading this article to learn doing this in only one language, then you don't need to read the code for other languages. Just read the code specific to your framework (or language).
Complex numbers in real
Complex numbers are the numbers that contain an imaginary part. For example, the numbers that can be expressed in, x + iy form, where i is an imaginary number. These numbers are called complex numbers. In the equation, x and y both are real numbers, only i is an imaginary number.
The imaginary number doesn't exist, in a way, such as, √(-1), there is no such possible answer of a square root of a negative number.
So, by definition, an "i" (pronounced as iota) is an imaginary number, its value is a square root of negative one. Here it is also to be mentioned, that a complex number that doesn't have a real part (such as zero value for x and/or y) is called a pure imaginary number, because it doesn't exist. The value iota is square root of minus one, that doesn't exist. No number multiplied by itself results in a negative one. Square of iota can be evaluated to minus one.
As stated in the comments, the square root of -1 would result in -i and i. So, it is good to state that square of iota has a value of negative one.
The overview part of the article on Wikipedia about Complex numbers have a great example of where these numbers are of great use in practical life; Physics, Chemistry, Biology etc.
Programming a complex number
Now let us consider talking about our programming languages and how to create such objects that actually can be processes as complex numbers, behave as them and can have their properties in real-life. In a programming language, we can create class objects that can behave as data type of objects, can have members and different functions can be called over them. These functions, members and types are being used in our programming language to create different real-life objects in programming languages.
We will define a similar class, to describe our complex numbers, and a few properties of it and the functions of it. Let us first check what would be this like,
In the above diagram, the object complex number has two sub-categories, polar or a cartesian type. In these two types, there are quite different members; properties, that we yet have to define.
For a polar complex number,
- An angle: Which is also known as the argument of the complex number.
- A radius: Also known as the magnitude of the complex number.
A complex number in this notation, is represented by usage of trigonometric functions e.g. cos and sin.
For a cartesian (sometimes known as co-ordinate or rectangular) complex number,
- A real part.
- An imaginary part.
In the above image, the i is the imaginary part, whereas others (x and y) are real; a shows the complex number. And with this, there is no need for more details of the complex number now.
Note: Before we start, I needed to say that the C++ code is being replaced by a title C only, the code is yet for C++ and not for C. I know that doesn't make such difference, but still the code is C++. I am not able to use C++, because if I would set the title to C++ the tabs would break; breaking the interface of the article. One more thing, is that I used NetBeans IDE for Java development, Eclipse has a different File system for the packages (com.example.app namespacing and the packaging settings) so make sure you've got that correct.
Creating the class
To implement the above object in our language, we can create a class in project, for that I am using a header-file (in C++, in other langauges you can create a class file e.g. .cs file in C# and .java file in Java and so on) to store all of the logic of class in a separate header (package in Java, namespace in C#) file instead of the main file. The code in the class at the instance reflects the constructors; and a desctructor in C++.
class ComplexNumber
{
public ComplexNumber()
{
Real = 0;
Imaginary = 0;
}
public ComplexNumber(double firstVal, double secondVal)
{
Real = firstVal;
Imaginary = secondVal;
}
}
class ComplexNumber {
public ComplexNumber() {
Real = 0;
Imaginary = 0;
}
public ComplexNumber(double firstVal, double secondVal) {
this.Real = firstVal;
this.Imaginary = secondVal;
}
}
Class ComplexNumber
Public Sub New()
Real = 0
Imaginary = 0
End Sub
Public Sub New(firstVal As Double, secondVal As Double)
Real = firstVal
Imaginary = secondVal
End Sub
End Class
class ComplexNumber {
public:
ComplexNumber() {
real = 0;
imaginary = 0;
};
ComplexNumber(int firstVal, int secondVal){
real = firstVal;
imaginary = secondVal;
};
~ComplexNumber() {
};
};
A complex number holds two values, a real part and an imaginary part. We should store these two variables, and then upon requirement, we can calculate the angle and/or the radius of the complex number if we want the complex number in a polar form.
Members of the complex number
Like I said, we can create functions to extract the values for our complex numbers class, have a look at the following code.
Note that only VB.NET requires you to create private members, for getters and setters. In other languages setting the variable to be public is enough to let the developers use the members of the class.
public double Real { get; set; }
public double Imaginary { get; set; }
public double Radius()
{
return Math.Sqrt(Real * Real + Imaginary * Imaginary);
}
public double Angle()
{
return Math.Atan2(Imaginary, Real);
}
private double real;
private double imaginary;
double getRadius() {
return Math.sqrt((real * real) + (imaginary * imaginary));
}
double getAngle() {
return Math.atan2(imaginary, real);
}
double getReal() {
return real;
}
void setReal(double r) {
real = r;
}
double getImaginary() {
return imaginary;
}
void setImaginary(double i) {
imaginary = i;
}
Private m_Imaginary As Double
Private m_Real As Double
Public Property Real() As Double
Get
Return m_Real
End Get
Set(value As Double)
m_Real = value
End Set
End Property
Public Property Imaginary() As Double
Get
Return m_Imaginary
End Get
Set(value As Double)
m_Imaginary = value
End Set
End Property
Public Function Radius() As Double
Return (Real * Real + Imaginary * Imaginary)
End Function
Public Function Angle() As Double
If Real <> 0 Then
Return Math.Atan(Imaginary / Real)
Else
Return 0.0
End If
End Function
private:
double real;
double imaginary;
double getAngle() const {
return atan2(this->imaginary, this->real);
}
double getRadius() const {
return sqrt((real * real) + (imaginary * imaginary));
}
double getReal() const {
return real;
}
void setReal(double r) {
real = r;
}
double getImaginary() const {
return imaginary;
}
void setImaginary(double i) {
imaginary = i;
}
A great point raised in the comments, to check the real part before doing anything at all, that is to check whether the real part of the number is zero or not. If the number is zero, there would be a chance of DivideByZeroException; exception title depends on which language or framework you're using. That is why, a condition is being passed before passing the value to arctan function.
Since we're having public members in our class, that is why we don't need to create setter or getter methods for these members, public properties can be captured directly. Only that in VB.NET, we're required to create private members to return their values in the getter or setter.
Functions for Complex Numbers
This leaves the discussion for the propertis of the complex numbers. Coming next, are the functions that can be executed on complex numbers for different purposes. Properties are much less, as compared to the functions of a complex number. As I have already said a complex number can be a polar as well as rectangular complex number, so before performing any other function first thing to see is whether the number is a polar or a rectangular; you will find out why in the operators section.
Note: The code requires the Mathematical libraries for functions like finding the sine of an angle. In C++, you need to explicitly include the library like #include <math.h>
, whereas in other languages (Java, C#, VB.NET) you get it inside the System
(C# or VB.NET) namespace and java.lang.Math
package, so that you can call the functions.
From cartesian to a polar complex number
The conversion of a cartesian complex number to a polar complex number undergoes following process.
- The radius of the polar complex number can be found by the relation of,
Then taking a square root on both sides, to get the radius. Which sometimes is also called the magnitude (length and/or norm) of the complex number. - The angle of the polar complex number can be found by the relation of,
A polar complex number is a complex number after all.
Converting the polar to a cartesian complex number
Similar to the above function, the polar number be converted to a cartesian complex number; having a real and imaginary part. The logic for this is,
- The real part of the complex number, can be found by multiplying the radius with cosine of angle.
- The imaginary part of the complex number can be found by multiplying the radius with sine of angle.
Getting the logarithm value of complex number
A logarithm can be applied to a complex number too, but the answer (underlying logic) of it quite different, and the return is also a cartesian complex number; it contains an imaginary number (iota) in it.
For a complex number to undergo a logarithm it is not defined or required to be in a polar or a cartesian form. You can use either of them, but the formula must be kept same,
Converting the above rule in function form would be something like this,
ComplexNumber Logarithm()
{
return new ComplexNumber()
{
Real = Math.Log(this.Radius()),
Imaginary = this.Angle()
};
}
ComplexNumber getLogarithm() {
return new ComplexNumber() {{
this.setReal(Math.log(getRadius()));
this.setImaginary(getAngle());
}};
}
Private Function Logarithm() As ComplexNumber
Dim number As New ComplexNumber()
number.Real = Math.Log(Me.Radius())
number.Imaginary = Me.Angle()
Return number
End Function
ComplexNumber getLogarithm() const {
return ComplexNumber::ComplexNumber(
log(this->getRadius()),
this->getAngle()
);
}
Conjugate of the complex number
Conjugate of a complex number is a very interesting topic to discuss, and to be noted, the conjugate of both, polar and cartesian, is different.
1. Cartesian conjugate
For a cartesian complex number, the conjugate is pretty simple. You just multiply the imaginary part with a negative one; or just change the sign of the imaginary part.
2. Polar conjugate
For a polar number, similarly, the only change is in the angle of the complex number. Take it as,
Excuse me: I was not able to find a perfect solution for an exp^(-itheta), and MS Powerpoint wouldn't let me write it in any other format, so I had to write it as it is. Point to consider here is, that the minus is with the iota and theta.
So from above conclusions, the logic to convert the above logic into function, we would be using the following function,
ComplexNumber Conjugate()
{
return new ComplexNumber(this.Real, -this.Imaginary);
}
ComplexNumber getConjugate() {
return new ComplexNumber() {{
this.setReal(this.getReal());
this.setImaginary(-this.getImaginary());
}};
}
Private Function Conjugate() As ComplexNumber
Return New ComplexNumber(Me.Real, -Me.Imaginary)
End Function
ComplexNumber getConjugate() const {
return ComplexNumber::ComplexNumber(
this->real,
-this->imaginary
);
}
After this, we can convert the numbers to polar notation using their functions, for getting angle or for getting the radii.
Reciprocal of complex number
A complex number must never be in the denominator, that is why we rationalize a complex number, to remove the iota from denominator; once that has been done the denominator can be written under both the real and imaginary parts making it a new complex number.
The new complex number, then looks like the following complex number after the rationalization process has done undergone.
So, the code for this is as simple as the following code,
ComplexNumber Reciprocal()
{
return new ComplexNumber() {
Real = (this.Real) / (this.Real * this.Real + this.Imaginary * this.Imaginary),
Imaginary = -(this.Imaginary) / (this.Real * this.Real + this.Imaginary * this.Imaginary)
};
}
ComplexNumber getReciprocal() {
return new ComplexNumber() {{
this.setReal(this.getReal() /
(this.getReal() * this.getReal()) +
(this.getImaginary() * this.getImaginary()));
this.setImaginary(-this.getImaginary() /
(this.getReal() * this.getReal()) +
(this.getImaginary() * this.getImaginary()));
}};
}
Private Function Reciprocal() As ComplexNumber
Dim number As New ComplexNumber()
number.Real = (Me.Real) / (Me.Real * Me.Real + Me.Imaginary * Me.Imaginary)
number.Imaginary = -(Me.Imaginary) / (Me.Real * Me.Real + Me.Imaginary * Me.Imaginary)
Return number
End Function
ComplexNumber getReciprocal() const {
return ComplexNumber::ComplexNumber(
(this->real) / (this->real * this->real + this->imaginary * this->imaginary),
-(this->imaginary) / (this->real * this->real + this->imaginary * this->imaginary)
);
}
The above code performs the same action as does the expression in the above equation. Then it returns the number.
Object-based function; not a complex number function
Another function that I created, in this is that the object should be represented in the form it belongs to, polar must be represented in trig functions, and cartesian must be represented in real and imaginary parts. Let us create a toString
function; everyone knows the function of this. We would be passing a flag, asPolar
, to determine whether to represent the number as a cartesian complex number or a polar complex number.
Language based: In Java, you need to override the function because every function is marked virtual and in java.lang.Object
a toString public function is present, so you can Override it. In other languages, you can, or cannot. In C++ you can create a function to convert the object to its string notation. In C++, it is good approach to use a StringStream to create a stream of characters and then call the .str()
function to convert it to a string.
public string ToString(bool asPolar)
{
string str = "";
if (asPolar)
{
if (this.Angle() > 0)
{
str = this.Radius() + "(cos" + this.Angle() + " + isin" + this.Angle() + ")";
}
else
{
str = this.Radius() + "(cos" + this.Angle() + " - isin" + -this.Angle() + ")";
}
}
else
{
if (this.Imaginary > 0)
{
str = this.Real + " + i" + this.Imaginary;
}
else
{
str = this.Real + " - i" + -this.Imaginary;
}
}
return str;
}
public String toString(boolean asPolar) {
String str;
if(asPolar) {
if(this.getAngle() > 0) {
str = this.getRadius() + "(cos" + this.getAngle() +
" + isin" + this.getAngle() + ")";
} else {
str = this.getRadius() + "(cos" + this.getAngle() +
" - isin" + -this.getAngle() + ")";
}
} else {
if(this.imaginary > 0) {
str = this.real + " + i" + this.imaginary;
} else {
str = this.real + " + -" + -this.imaginary;
}
}
return str;
}
Public Function ToString(asPolar As Boolean) As String
Dim str As String = ""
If asPolar Then
If Me.Angle() > 0 Then
str = Me.Radius() + "(cos" + Me.Angle() + " + isin" + Me.Angle() + ")"
Else
str = Me.Radius() + "(cos" + Me.Angle() + " - isin" + -Me.Angle() + ")"
End If
Else
If Me.Imaginary > 0 Then
str = Me.Real + " + i" + Me.Imaginary
Else
str = Me.Real + " - i" + -Me.Imaginary
End If
End If
Return str
End Function
std::string toString(bool asPolar) {
std::stringstream stream;
if (asPolar) {
if (this->getAngle() > 0) {
stream << this->getRadius() << "(cos" << this->getAngle() << " + isin" << this->getAngle() << ")";
}
else {
stream << this->getRadius() << "(cos" << this->getAngle() << " - isin" << -(this->getAngle()) << ")";
}
}
else {
if (this->imaginary > 0) {
stream << this->real << " + i" << this->imaginary;
}
else {
stream << this->real << " - i" << -(this->imaginary);
}
}
return stream.str();
}
Now it would return the information. It would be useful to always simply write an output command with this .toString()
function, instead of always concatenating the strings and making up the representation.
Arithmetic operations
Since mathematics is involved in this process, it is obvious that arithmetic operators would also be used to add, subtract, multiply or divide the number by another number. In most of the programming languages, such as C++, C# you can overload the operator to make sure that you get a very mathematical interface of adding the numbers. Whereas in some languages, such as Java, you get to create an interface; by interface I mean a function, to perform addition, subtraction and/or other arithmetic operations. In the following sections, you can find out how Java differs from other Object-oriented programming languages in the case of operator overloading.
Now, we will be using these functions to perform different operations in our code, let us go through all of these operations and see how to implement such functionality in our case.
Binary operators
First of all let us talk about the binary operators that can be used against a complex number to perform arithmetic operations, which can be enlisted as,
- Addition
- Subtraction
- Multiplication
- Division
Upcoming section talks about the operators themself and their usage in multiple programming languages.
Operations for cartesian complex numbers
First of all, we need to understand the operations that are executed over cartesian complex numbers only. Only cartesian complex numbers can be added or subtracted, their real and imaginary parts are involved in this part. Polar complex numbers do not undergo these operations, however they do undergo the multiplication and division operations. We will study them in the next section.
Addition
We can overload the addition operator, and allow addition of two complex numbers. The logic for two complex numbers addition is like following,
- Real parts get added to each other.
- Imaginary parts are added to each other.
- The answer is again created into a form of complex number, x + iy.
The code for this algorithm; overloading the operator or defining a function is like,
public static ComplexNumber operator +(ComplexNumber a, ComplexNumber b) {
return new ComplexNumber(a.Real + b.Real, a.Imaginary + b.Imaginary);
}
ComplexNumber add(final ComplexNumber a) {
return new ComplexNumber()
{{
this.setReal(this.getReal() + a.real);
this.setImaginary(this.getImaginary() + a.imaginary);
\}};
}
Public Shared Operator +(a As ComplexNumber, b As ComplexNumber) As ComplexNumber
Return New ComplexNumber(a.Real + b.Real, a.Imaginary + b.Imaginary)
End Operator
ComplexNumber operator + (ComplexNumber a) {
return ComplexNumber::ComplexNumber(
this->real + a.real,
this->imaginary + a.imaginary);
}
The above code would yield the additive results for the complex numbers.
Subtraction
Similarly, we can also create a function or overload the operator of subtraction, to subtract a complex number from any other complex number. The logic is similar, a slight difference is the usage of subtraction sign, instead of addition of real and imaginary values.
- Real parts are subtracted from each other.
- Imaginary parts are subtracted from each other too.
- The answer is again created into a form of complex number, x + iy.
The code for this is again similar, just the change in the sign; minus instead of addition.
public static ComplexNumber operator -(ComplexNumber a, ComplexNumber b)
{
return new ComplexNumber(a.Real - b.Real, a.Imaginary - b.Imaginary);
}
ComplexNumber subtract(final ComplexNumber a) {
return new ComplexNumber() {{
this.setReal(this.getReal() - a.getReal());
this.setImaginary(this.getImaginary() - a.getImaginary());
}};
}
Public Shared Operator -(a As ComplexNumber, b As ComplexNumber) As ComplexNumber
Return New ComplexNumber(a.Real - b.Real, a.Imaginary - b.Imaginary)
End Operator
ComplexNumber operator - (ComplexNumber a) {
ComplexNumber number;
number.real = this->real - a.real;
number.imaginary = this->imaginary - a.imaginary;
return number;
}
Operations for polar as well as cartesian complex numbers
Now there are two other operations that get performed over complex numbers, on both.
- Cartesian complex numbers.
The operations involve their real and imaginary parts. - Polar complex numbers.
The operations are performed on the angle and the magnitude of the complex numbers.
These functions can be evaluated by first determining whether the complex number is a polar or a cartesian complex number. This would help us create a code block that would be for a particular type of the complex number.
Multiplication
In complex numbers, it depends on what type of a number it is, to continue the process of multiplication. So, first of all a condition has to be met, to check whether we're mutliplying a cartesian type or a polar type complex number.
You cannot multiply a cartesian to a polar or vice versa.
We first identify the type of the complex number, once that has been done, we can then continue to process. Let us divide this into two sub-sections now, and process them as their own types.
Cartesian compex number
In a cartesian complex number, we multiply the numbers as we would multiply a simple a + b equation to some other of similar type.
The last value has a minus sign because square of iota is equal to minus one.
Polar complex number
Before we move to the code, let me talk about the polar complex numbers too. The multiplication of a polar complex number involves their radius and the angles that they hold. The logic for this is,
- The radii of the complex numbers are multiplied.
- The angles are added and the result is set as the angle for their cis notation.
Code
Now the code to evaluate this one, should also be similar to the above equations. We can derive each of the value from our object, by either directly calling their properties, or calling their functions to get their values of radii or angle.
public static ComplexNumber operator *(ComplexNumber a, ComplexNumber b)
{
return new ComplexNumber()
{
Real = (a.Real * b.Real) - (a.Imaginary * b.Imaginary),
Imaginary = (a.Real * b.Imaginary) + (a.Imaginary * b.Real)
};
}
ComplexNumber multiply(final ComplexNumber a) {
return new ComplexNumber() {{
this.setReal((this.getReal() * a.real) - (this.getImaginary() * a.imaginary));
this.setImaginary((this.getReal() * a.imaginary) + (this.getImaginary() * a.real));
}};
}
Public Shared Operator *(a As ComplexNumber, b As ComplexNumber) As ComplexNumber
Dim number As New ComplexNumber()
number.Real = (a.Real * b.Real) - (a.Imaginary * b.Imaginary)
number.Imaginary = (a.Real * b.Imaginary) + (a.Imaginary * b.Real)
Return number
End Operator
ComplexNumber operator * (ComplexNumber a) {
return ComplexNumber::ComplexNumber(
(this->real * a.real) - (this->imaginary * a.imaginary),
(this->real * a.imaginary) + (this->imaginary * a.real)
);
}
Division
Let us now take example of the division process of the complex numbers. The process is different for both the polar and the cartesian complex numbers and thus we cannot talk about the first step, until, changing the section into sub-sections.
Cartesian complex number
The division first has to undergo rationalization, because a complex number can never be in the denomenator. So first of all we have to rationalize the complex number. Once the fraction has been rationalized and the imaginary part is in the numerator only, we can then continue to process the division.
The division then continues following the given rule,
Note: The second part of the equation is imaginary, I missed an i while creating this, sorry for this.
The above equation shows that the complex number in the denomenator first undergoes rationalization; multiplication by its complex conjugate and then real division. These are some rules of mathematics that you don't want to argue with of course. You can read the Wikipedia articles for more or read the mathematical encyclopedias for proofs of these rules.
Polar complex number
In a polar form, the division is somewhat simple. There is just angle and radius to take care of. Just like multiplication, the angle and radii take part, well in an opposite manner. Now the following rules applies.
- Radii are divided.
- Angles are subtracted from the first complex number. Then put in the cis notation.
The angles must be taken care of while subtracting, if the result is a negative number (e.g. in example of 20-30 = -10) then the sign with the sin function must be changed, because sin(-10) = - sin(10).
Code
Now let us convert the above stuff in the form of code.
public static ComplexNumber operator /(ComplexNumber a, ComplexNumber b)
{
return new ComplexNumber()
{
Real = (a.Real * b.Real) + (a.Imaginary * b.Imaginary) /
((b.Real * b.Real) + (b.Imaginary * b.Imaginary)),
Imaginary = (a.Real * b.Real) - (a.Imaginary * b.Imaginary) /
((b.Real * b.Real) + (b.Imaginary * b.Imaginary))
};
}
ComplexNumber divide(final ComplexNumber a) {
return new ComplexNumber() {{
this.setReal((this.getReal() * a.real) + (this.getImaginary() * a.imaginary)
/ (a.real * a.real) + (a.imaginary * a.imaginary));
this.setImaginary((this.getImaginary() * a.real) - (this.getReal() * a.imaginary)
/ (a.real * a.real) + (a.imaginary * a.imaginary));
}};
}
Public Shared Operator /(a As ComplexNumber, b As ComplexNumber) As ComplexNumber
Dim number As New ComplexNumber()
number.Real = (a.Real * b.Real) + (a.Imaginary * b.Imaginary) / ((b.Real * b.Real) + (b.Imaginary * b.Imaginary))
number.Imaginary = (a.Real * b.Real) - (a.Imaginary * b.Imaginary) / ((b.Real * b.Real) + (b.Imaginary * b.Imaginary))
Return number
End Operator
ComplexNumber operator / (ComplexNumber a) {
return ComplexNumber::ComplexNumber(
(this->real * a.real) + (this->imaginary * a.imaginary) /
((a.real * a.real) + (a.imaginary * a.imaginary)),
(this->real * a.real) - (this->imaginary * a.imaginary) /
((a.real * a.real) + (a.imaginary * a.imaginary))
);
}
Equality check
Another major functionality that must be implement is to check whether both the objects are equal or not. Of course, in some languages you can implement the .Equals()
function, but let us create our own overloaded functions for the ==
operator.
public static bool operator ==(ComplexNumber a, ComplexNumber b)
{
return (b.Real == a.Real && b.Imaginary == a.Imaginary);
}
public static bool operator !=(ComplexNumber a, ComplexNumber b)
{
return !(b.Real == a.Real && b.Imaginary == a.Imaginary);
}
boolean equals(ComplexNumber a) {
return (this.real == a.real && this.imaginary == a.imaginary);
}
Public Shared Operator =(a As ComplexNumber, b As ComplexNumber) As Boolean
Return (b.Real = a.Real AndAlso b.Imaginary = a.Imaginary)
End Operator
Public Shared Operator <>(a As ComplexNumber, b As ComplexNumber) As Boolean
Return Not (b.Real = a.Real AndAlso b.Imaginary = a.Imaginary)
End Operator
bool operator == (ComplexNumber a) {
return (this->real == a.real && this->imaginary == a.imaginary);
}
bool operator != (ComplexNumber a) {
return !(this->real == a.real && this->imaginary == a.imaginary);
}
This would check for all possible means in which an object can be equal to another object, and if any a required value is not correct, then the result would be a false; thus can be used in an if...else
block.
Unary operator
We can also apply a unary operator over a complex number; cartesian, to get the value in negative form.
Please note that this is not the conjugate of the complex number, but a total negative (both signs are changed for real and imaginary values).
Negate
We can negate the values of the complex number, to make it an opposite of itself; not a conjugate. A simple negative sign can do the thing.
public static ComplexNumber operator -(ComplexNumber a)
{
return new ComplexNumber(-a.Real, -a.Imaginary);
}
ComplexNumber negate() {
return new ComplexNumber() {{
this.setReal(-this.getReal());
this.setImaginary(-this.getImaginary());
}};
}
Public Shared Operator -(a As ComplexNumber) As ComplexNumber
Return New ComplexNumber(-a.Real, -a.Imaginary)
End Operator
ComplexNumber operator - () {
ComplexNumber number;
number.real = -(this->real);
number.imaginary = -(this->imaginary);
return number;
}
Points of Interest
A few points about this article above can not explain the actual concept of this article, however they can provide an idea of what I meant of felt while writing the article and creating the entire library; in multiple languages.
A complex number is a number that can be represented in the form of x + iy. We can use these numbers in many ways, and in many fields not only mathematics but in physics, chemistry and biology etc. A complex number is a special type of number, which contains an imaginary value, thus differentiating it from other numbers.
We can (in programming languages) create a class, to contain these numbers, and then we can create members to specify the values for these numbers. The complex number is of two types,
- Polar
- Cartesian
A polar complex number contains an angle and a radius, whereas a cartesian complex number consists a real and an imaginary number.
The arithmentic operations that get performed over these differ in many ways and the polar number don't undergo addition or subtraction. There are some rules for polar complex number, one of them in Euler's formula, which is used to extract different functions for the complex numbers.
In programming languages, you can overload the operators such as addition, subtraction etc to perform different tasks on these numbers. In particular languages, such as Java, operator overloading is not allowed, developer has to create an interface for objects and then perform those actions in a way specified.
Source code
This article, libraries, code samples and all other resources are owned by me, and they will be made publicly available for everyone to reproduce and share in applications. Source code is available on GitHub repositories.
Humble request
If you find any glitch in the article (including the interface and the layout of the article), source code and the method of teaching, you can kindly add it as a suggestion to let me know where I lack good stuff. You can add a suggestion too if you want to add something to the library or the article. I am not best mathematician, so any error in equations and/or any missed equation for basic complex number functions can also be shared in the comments below.
Thanks.
History
First version of the article; library.
Second version: Added a table of contents
Third version: Changed the class, removed unused and non-required class members, converted them into functions to be called on the run-time for properly getting the values.
Fourth version: Removed a mistake, radius should be square root, and added the cmath library instead of math.h. Used type initialization for all of the objects that are to be returned.