Addition of complex numbers in Python
# Two complex numbers are added by adding their
# real components and their imaginary components
# separately.
#
# If
#
#     w = a + bj
#
# and
#
#     z = c + dj,
#
# then
#
#     w + z = (a + c) + (b + d)j.
#
# Complex-number addition is commutative, just
# like addition of real numbers:
#
#     w + z = z + w.

w = 5.3 + 3.2j
z = 3.2 - 4.7j

print( "\nCalculations with 'w' and 'z':" )

print( w + z )
print( z + w )

# We can see how this addition is performed by
# separately adding the real components and the
# imaginary components.

print( z.real + w.real )
print( z.imag + w.imag )

print( "Re(z) + Re(w) =",
       z.real + w.real )

print( "Im(z) + Im(w) =",
       z.imag + w.imag )

# The imaginary component is multiplied by j
# when reconstructing the complex number.

print( "j(Im(z) + Im(w)) =",
       1j*(z.imag + w.imag) )

# Putting the real and imaginary components
# back together gives the sum of the two
# complex numbers.

print( "(Re(w) + Re(z)) + j(Im(w) + Im(z)) =",
       (z.real + w.real)
       + 1j*(z.imag + w.imag) )

# Thus, adding complex numbers is equivalent to
# separately adding their real and imaginary
# components:
#
#     Re(w + z) = Re(w) + Re(z)
#
# and
#
#     Im(w + z) = Im(w) + Im(z).


# Now consider the following five complex
# numbers.

w1 = -0.217 + 8.326j
w2 = -9.653 + 3.757j
w3 = -1.592 + 5.909j
w4 =  5.608 - 4.460j
w5 =  0.928 + 0.350j

# Based on the results below, what do you think
# is the actual sum of these five complex
# numbers?
#
# Mathematically, addition is associative:
#
#     (a + b) + c = a + (b + c).
#
# Consequently, changing the order in which
# additions are performed should not change
# the result.
#
# On a computer, however, real numbers are
# usually represented using floating-point
# numbers. Most decimal fractions cannot be
# represented exactly using the finite binary
# representation used by the computer.
#
# Consequently, small rounding errors can be
# introduced during each arithmetic operation.
# Changing the order of the operations may
# therefore change these small rounding errors.
#
# Thus, floating-point addition is not always
# exactly associative, even though mathematical
# addition is associative.
#
# Fortunately, these errors are generally very
# small for calculations such as these.

print( "\nDifferent ways of calculating w1 + ... + w5:" )

print( w1 + w2 + w3 + w4 + w5 )

print( (w1 + w2) + (w3 + (w4 + w5)) )

print( w1 + (w2 + ((w3 + w4) + w5)) )

print( (w1 + w2) + (w3 + w4) + w5 )