diff --git a/concepts/complex-numbers/.meta/config.json b/concepts/complex-numbers/.meta/config.json index e49f8494e2..ca6ccc8811 100644 --- a/concepts/complex-numbers/.meta/config.json +++ b/concepts/complex-numbers/.meta/config.json @@ -1,5 +1,5 @@ { "blurb": "Complex numbers are a fundamental data type in Python, along with int and float. Further support is added with the cmath module, which is part of the Python standard library.", - "authors": ["bethanyg", "colinleach"], + "authors": ["BethanyG", "colinleach"], "contributors": [] } diff --git a/concepts/complex-numbers/introduction.md b/concepts/complex-numbers/introduction.md index 0ac61d5987..587223db46 100644 --- a/concepts/complex-numbers/introduction.md +++ b/concepts/complex-numbers/introduction.md @@ -1,27 +1,25 @@ -# Introduction +# About `Complex numbers` are not complicated. They just need a less alarming name. -They are so useful, especially in engineering and science, that Python includes [`complex`][complex] as a standard type alongside integers and floating-point numbers. +They are so useful, especially in engineering and science (_everything from JPEG compression to quantum mechanics_), that Python includes [`complex`][complex] as a standard numeric type alongside integers ([`int`s][ints]) and floating-point numbers ([`float`s][floats]). -## Basics - -A `complex` value in Python is essentially a pair of floating-point numbers. -These are called the "real" and "imaginary" parts. - -There are two common ways to create them. -The `complex(real, imag)` constructor takes two `float` parameters: +A `complex` value in Python is essentially a pair of floating-point numbers: ```python ->>> z1 = complex(1.5, 2.0) ->>> z1 -(1.5+2j) +>>> my_complex = 5.443+6.77j +(5.443+6.77j) ``` -There are two rules for an imaginary part: -- It is designated with `j` (not `i`, which you may see in textbooks). -- The `j` must immediately follow a number, to prevent Python seeing it as a variable name. If necessary, use `1j`. +These are called the "real" and "imaginary" parts. +You may have heard that "`i` (or `j`) is the square root of -1". +For now, all this means is that the imaginary part _by definition_ satisfies the equality `1j * 1j == -1`. +This is a simple idea, but it leads to interesting mathematical consequences. + +In Python, the "imaginary" part is designated with `j` (_not `i` as you would see in math textbooks_), and +the `j` must immediately follow a number, to prevent Python seeing it as a variable name: + ```python >>> j @@ -36,95 +34,60 @@ NameError: name 'j' is not defined ``` -With this, we have a second way to create a complex number: -```python ->>> z2 = 2.0 + 1.5j ->>> z2 -(2+1.5j) -``` -The end result is identical to using a constructor. -To access the parts individually: -```python ->>> z2.real -2.0 ->>> z2.imag -1.5 -``` +There are two common ways to create complex numbers. -## Arithmetic +1) The [`complex(real, imag)`][complex] constructor takes two `float` parameters: -Most of the [`operators`][operators] used with `float` also work with `complex`: + ```python + >>> z1 = complex(1.5, 2.0) + >>> z1 + (1.5+2j) + ``` -```python ->>> z1, z2 -((1.5+2j), (2+1.5j)) + The constructor can also parse string input. + This has the odd limitation that it fails if the string contains spaces. ->>> z1 + z2 # addition -(3.5+3.5j) + ```python + >>> complex('4+2j') + (4+2j) + + >>> complex('4 + 2j') + Traceback (most recent call last): + File "", line 1, in + ValueError: complex() arg is a malformed string + ``` ->>> z1 - z2 # subtraction -(-0.5+0.5j) ->>> z1 * z2 # multiplication -6.25j +2) The complex number can be specified as ` + j` literal, or just `j` if the real part is zero: ->>> z1 / z2 # division -(0.96+0.28j) ->>> z1 ** 2 # exponentiation -(-1.75+6j) + ```python + >>> z2 = 2.0 + 1.5j + >>> z2 + (2+1.5j) + ``` + The end result is identical to using the `complex()` constructor. ->>> 2 ** z1 # another exponentiation -(0.5188946835878313+2.7804223253571183j) ->>> 1j ** 2 # j is the square root of -1 -(-1+0j) -``` - -Explaining the rules for complex multiplication and division is out of scope here. -Any introduction to complex numbers will cover this. -Alternatively, Exercism has a `Complex Numbers` practice exercise where you can implement this from first principles. - -There are two functions that are useful with complex numbers: -- `conjugate()` simply flips the sign of the complex part. -- `abs()` is guaranteed to return a real number with no imaginary part. - -```python ->>> z1 -(1.5+2j) - ->>> z1.conjugate() # flip the z1.imag sign -(1.5-2j) - ->>> abs(z1) # sqrt(z1.real ** 2 + z1.imag ** 2) -2.5 -``` +## Arithmetic -## The `cmath` module +Most of the [`operators`][operators] used with floats and ints also work with complex numbers. -The Python standard library has a `math` module full of useful functionality for working with real numbers. -It also has an equivalent `cmath` module for complex numbers. +Integer division is _**not**_ possible on complex numbers, so the `//` and `%` operators and `divmod()` functions will fail for the complex number type. -Details are available in the [`cmath`][cmath] module documents, but the main categories are: -- conversion between Cartesian and polar coordinates -- exponential and log functions -- trig functions -- hyperbolic functions -- classification functions -- useful constants +Explaining the rules for complex number multiplication and division is out of scope for this concept (_and you are unlikely to have to perform those operations "by hand" very often_). -```python ->>> import cmath +Any [mathematical][math-complex] or [electrical engineering][engineering-complex] introduction to complex numbers will cover these scenarios, should you want to dig into the topic. ->>> euler = cmath.exp(1j * cmath.pi) # Euler's equation +The Python standard library has a [`math`][math-module] module full of useful functionality for working with real numbers and the [`cmath`][cmath] module is its equivalent for working with complex numbers. ->>> euler.real --1.0 ->>> round(euler.imag, 15) # round to 15 decimal places -0.0 -``` -[complex]: https://docs.python.org/3/library/functions.html#complex [cmath]: https://docs.python.org/3/library/cmath.html +[complex]: https://docs.python.org/3/library/functions.html#complex +[engineering-complex]: https://www.khanacademy.org/science/electrical-engineering/ee-circuit-analysis-topic/ee-ac-analysis/v/ee-complex-numbers +[floats]: https://docs.python.org/3/library/functions.html#float +[ints]: https://docs.python.org/3/library/functions.html#int +[math-complex]: https://www.nagwa.com/en/videos/143121736364/ +[math-module]: https://docs.python.org/3/library/math.html [operators]: https://docs.python.org/3/library/stdtypes.html#numeric-types-int-float-complex diff --git a/concepts/complex-numbers/links.json b/concepts/complex-numbers/links.json index 5428d4c8d2..759ef1689f 100644 --- a/concepts/complex-numbers/links.json +++ b/concepts/complex-numbers/links.json @@ -10,5 +10,9 @@ { "url": "https://docs.python.org/3/library/cmath.html/", "description": "Module documentation for cmath." + }, + { + "url": "https://docs.python.org/3/library/math.html/", + "description": "Module documentation for math." } ]