Julia Complex and Rational Numbers
In this chapter, we will mainly learn about Julia's complex and rational numbers.
The Julia language includes predefined complex and rational number types, and supports various standard mathematical operations and elementary functions on them.
Complex Numbers
Complex numbers are an extension of real numbers, enabling any polynomial equation to have roots.
We call numbers of the formz=a+bi(where a and b are both real numbers) complex numbers. Here, a is called the real part, b is called the imaginary part, and i is called the imaginary unit, which has the property. When the imaginary part b of z equals 0, z is a real number; when the imaginary part b of z is not equal to 0 and the real part a equals 0, z is often called a pure imaginary number.
The global constant im is bound to the complex number i, representing the principal square root of -1.
Since Julia allows numeric literals as numeric literal coefficients, this binding is sufficient to provide a very convenient syntax for complex numbers, similar to traditional mathematical notation:
Examples
1 + 2im
We can also perform various arithmetic operations on complex numbers:
Examples
8 + 1im
julia> (1 + 2im)/(1 - 2im)
-0.6 + 0.8im
julia> (1 + 2im) + (1 - 2im)
2 + 0im
julia> (-3 + 2im) - (5 - 1im)
-8 + 3im
julia> (-1 + 2im)^2
-3 - 4im
julia> (-1 + 2im)^2.5
2.729624464784009 - 6.9606644595719im
julia> (-1 + 2im)^(1 + 1im)
-0.27910381075826657 + 0.08708053414102428im
julia> 3(2 - 5im)
6 - 15im
julia> 3(2 - 5im)^2
-63 - 60im
julia> 3(2 - 5im)^-1.0
0.20689655172413796 + 0.5172413793103449im
The type promotion mechanism also ensures that you can use combinations of operands of different types:
Examples
2 - 2im
julia> (2 + 3im) - 1
1 + 3im
julia> (1 + 2im) + 0.5
1.5 + 2.0im
julia> (2 + 3im) - 0.5im
2.0 + 2.5im
julia> 0.75(1 + 2im)
0.75 + 1.5im
julia> (2 + 3im) / 2
1.0 + 1.5im
julia> (1 - 3im) / (2 + 2im)
-0.5 - 1.0im
julia> 2im^2
-2 + 0im
julia> 1 + 3/4im
1.0 - 0.75im
Note3/4im == 3/(4*im) == -(3/4*im), because the coefficient has a higher precedence than division.
Julia provides some standard functions for operating on complex numbers:
Examples
1 + 2im
julia> real(1 + 2im) # the real part of z
1
julia> imag(1 + 2im) # the imaginary part of z
2
julia> conj(1 + 2im) # the complex conjugate of z
1 - 2im
julia> abs(1 + 2im) # the absolute value of z
2.23606797749979
julia> abs2(1 + 2im) # the squared absolute value
5
julia> angle(1 + 2im) # the phase angle in radians
1.1071487177940904
By convention, the absolute value (abs) of a complex number is its distance from zero. abs2 gives the square of the absolute value, which is very useful when applied to complex numbers because it avoids taking a square root. angle returns the phase angle in radians (also called the argument function). All other elementary functions are also fully defined on complex numbers:
Examples
0.7071067811865476 + 0.7071067811865475im
julia> sqrt(1 + 2im)
1.272019649514069 + 0.7861513777574233im
julia> cos(1 + 2im)
2.0327230070196656 - 3.0518977991517997im
julia> exp(1 + 2im)
-1.1312043837568135 + 2.4717266720048188im
julia> sinh(1 + 2im)
-0.4890562590412937 + 1.4031192506220405im
Note that mathematical functions usually return real values when applied to real numbers, and return complex values when applied to complex numbers. For example, sqrt behaves differently when applied to -1 and -1 + 0im, even though -1 == -1 + 0im:
Examples
ERROR: DomainError with -1.0:
sqrt will only return a complex result if called with a complex argument. Try sqrt(Complex(x)).
Stacktrace:
[...]
julia> sqrt(-1 + 0im)
0.0 + 1.0im
When constructing complex numbers from variables, the literal numeric coefficient notation no longer applies. Instead, multiplication must be written explicitly:
Examples
1 + 2im
However, this is not recommended. Instead, you should use the more efficient complex function to directly construct a complex value from the real and imaginary parts:
Examples
1 + 2im
This construction avoids multiplication and addition operations.
Inf and NaN may appear in the real and imaginary parts of complex numbers, as described in the special floating-point values section:
Examples
1.0 + Inf*im
julia> 1 + NaN*im
1.0 + NaN*im
Rational Numbers
Rational numbers are the collective term for integers (positive integers, 0, negative integers) and fractions, and are the set of integers and fractions.
Mathematically, numbers that can be expressed as the ratio of two integers (Julia has a fraction type for representing exact ratios of integers. Fractions are constructed using the//operator:
Examples
2//3
If the numerator and denominator of a fraction have common factors, they are reduced to the simplest form and the denominator is non-negative:
Examples
2//3
julia> -4//8
-1//2
julia> 5//-15
-1//3
julia> -4//-12
1//3
This standardized form of integer ratios is unique, so equality of fraction values can be tested by checking that both the numerators and denominators are equal. The standardized numerator and denominator of a fraction value can be obtained using the numerator and denominator functions:
Examples
2
julia> denominator(2//3)
3
Direct comparison of numerators and denominators is usually unnecessary, because standard arithmetic and comparison operations are also defined for fraction values:
Examples
true
julia> 2//3 == 9//27
false
julia> 3//7 < 1//2
true
julia> 3//4 > 2//3
true
julia> 2//4 + 1//6
2//3
julia> 5//12 - 1//4
1//6
julia> 5//8 * 3//12
5//32
julia> 6//5 / 10//7
21//25
Fractions can be easily converted to floating-point numbers:
Examples
0.75
For any integer values a and b (except when a == 0 and b == 0), the conversion from fractions to floating-point numbers follows the following consistency:
Examples
julia> isequal(float(a//b), a/b)
true
Julia accepts constructing infinite fraction values:
Examples
1//0
julia> x = -3//0
-1//0
julia> typeof(x)
Rational{Int64}
But it does not accept attempting to construct a NaN fraction value:
Examples
ERROR: ArgumentError: invalid rational: zero(Int64)//zero(Int64)
Stacktrace:
[...]
As usual, the type promotion system makes it easy for fractions to interact with other numeric types:
Examples
8//5
julia> 3//5 - 0.5
0.09999999999999998
julia> 2//7 * (1 + 2im)
2//7 + 4//7*im
julia> 2//7 * (1.5 + 2im)
0.42857142857142855 + 0.5714285714285714im
julia> 3//2 / (1 + 2im)
3//10 - 3//5*im
julia> 1//2 + 2im
1//2 + 2//1*im
julia> 1 + 2//3im
1//1 - 2//3*im
julia> 0.5 == 1//2
true
julia> 0.33 == 1//3
false
julia> 0.33 < 1//3
true
julia> 1//3 - 0.33
0.0033333333333332993