-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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": [] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,25 @@ | ||
# Introduction | ||
# About | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
BethanyG
Author
Member
|
||
|
||
`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 | |
<class 'complex'> | ||
``` | ||
|
||
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 "<stdin>", line 1, in <module> | ||
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 `<real part> + <complex part>j` literal, or just `<complex part>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 |
1 comment
on commit f648017
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like it, except the top heading
Why change this in
introduction.md
?