Привет!
Очередной очерк. На этот раз поиграемся с комплексными числами, с формулами и их визуализацией.
![](https://habrastorage.org/webt/re/ue/8w/reue8wmtymosj0i8teu6udqkt2q.png)
Комплексное число — это некоторое расширение вещественного числа, по сути вектор, для которого определено целое множество аксиом. Любое комплексное (а значит и вещественное) число можно записать в виде , где a — вещественная часть, b — мнимая, i — корень уравнения . Для него определено много операций, которые определены для вещественного числа, к примеру, . Интересно, что если проделывать различные операции с ними, возводить в степень, умножать и т. д. а затем брать (вещественную часть) для оси Ox, а (мнимую часть) для оси Oy, можно получать забавные картинки.
Кстати все следующие формулы я сам придумал.
Рутина. Функция, которая по данной итеративной функции рисует все на поле:
Все наши функции зависят от двух параметров A и B. Причем по B мы итерируемся внутри vis(), а A — глобальный параметр функции.
Ее объявление в python:
И запустим
И результат для A=121.5:
![](https://habrastorage.org/webt/ze/_q/c3/ze_qc3rsiek2yo6tryjzgvx9xzg.jpeg)
И для A=221.5:
![](https://habrastorage.org/webt/cv/nv/iq/cvnviqbqnptgpe7o-gyfinfjr-w.jpeg)
Заметьте, эти числа вовсе не следуют из расчета какого-нибудь определенного интеграла на гладком многообразии и других умных бессмысленных в этом контексте слов. Это действительно рандомные числа, и существует еще ровно бесконечность разных A, в результате которых получается красота.
Объявим функцию цвета (такую функцию, которая по координатам возвращает tuple из трех чисел):
Выберем рандомный параметр A, пусть будет 149:
![](https://habrastorage.org/webt/a8/4u/0e/a84u0erl-emjaczbyx1kz0dj3hi.jpeg)
Гуси описываются так:
Объявление на python:
Ее результат для A=106:
![](https://habrastorage.org/webt/7w/br/dl/7wbrdlyc1in1uezm-ck_bf5qvui.jpeg)
![](https://habrastorage.org/webt/ze/ri/k3/zerik3sudihshoowzkmgneppwso.jpeg)
![](https://habrastorage.org/webt/sl/o_/jm/slo_jmbgjsl9jnbj7elh3yahy8c.jpeg)
![](https://habrastorage.org/webt/74/69/uv/7469uvlqo2p7p64znmv6nqbdgxy.jpeg)
![](https://habrastorage.org/webt/s7/wp/79/s7wp79nbo5kcdyo3wl3w1jpeo7u.jpeg)
![](https://habrastorage.org/webt/se/eq/rb/seeqrb3_pgdmkvaiz3x1rdkvleo.jpeg)
![](https://habrastorage.org/webt/hu/wq/jf/huwqjfetpv8r-xnkyd8viffbfi0.jpeg)
Пока все.
Очередной очерк. На этот раз поиграемся с комплексными числами, с формулами и их визуализацией.
![](https://habrastorage.org/webt/re/ue/8w/reue8wmtymosj0i8teu6udqkt2q.png)
Идея
Комплексное число — это некоторое расширение вещественного числа, по сути вектор, для которого определено целое множество аксиом. Любое комплексное (а значит и вещественное) число можно записать в виде , где a — вещественная часть, b — мнимая, i — корень уравнения . Для него определено много операций, которые определены для вещественного числа, к примеру, . Интересно, что если проделывать различные операции с ними, возводить в степень, умножать и т. д. а затем брать (вещественную часть) для оси Ox, а (мнимую часть) для оси Oy, можно получать забавные картинки.
Кстати все следующие формулы я сам придумал.
Функция визуализации
Рутина. Функция, которая по данной итеративной функции рисует все на поле:
import random
import numpy as np
def vis(A, f, step=1.0, c=None):
x = []
y = []
for B in np.arange(0, A, step):
v = f(A, B)
x.append(v.real)
y.append(v.imag)
plt.figure(figsize=[8, 8])
mxabs = max([i[0] ** 2 + i[1] ** 2 for i in zip(x, y)]) ** 0.5
x = np.array(x) / mxabs
y = np.array(y) / mxabs
if c is None:
plt.scatter(x, y)
else:
plt.scatter(x, y, color=[c(x[i], y[i]) for i in range(len(x))])
plt.show()
Все наши функции зависят от двух параметров A и B. Причем по B мы итерируемся внутри vis(), а A — глобальный параметр функции.
Функция «Завитушки»
Ее объявление в python:
def func_1(A, B):
return math.sin(B) * B * math.e ** (1j * (B * math.cos(A)))
И запустим
A = 121.5
vis(A, func_1, step=0.1)
И результат для A=121.5:
![](https://habrastorage.org/webt/ze/_q/c3/ze_qc3rsiek2yo6tryjzgvx9xzg.jpeg)
И для A=221.5:
![](https://habrastorage.org/webt/cv/nv/iq/cvnviqbqnptgpe7o-gyfinfjr-w.jpeg)
Заметьте, эти числа вовсе не следуют из расчета какого-нибудь определенного интеграла на гладком многообразии и других умных бессмысленных в этом контексте слов. Это действительно рандомные числа, и существует еще ровно бесконечность разных A, в результате которых получается красота.
Надо покрасить
Объявим функцию цвета (такую функцию, которая по координатам возвращает tuple из трех чисел):
def sigm(x): # Эта функция позволяет нормализировать все что угодно от 0 до 1
return (1 / (1 + 1.2 ** (-x*50)) - 0.5) * 2
color_1 = lambda x, y: (0.2, sigm(x ** 2 + y ** 2) / 1.4, 1 - sigm(x ** 2 + y ** 2))
color_2 = lambda x, y: (sigm(x ** 2 + y ** 2), 0.5, 0.5)
Выберем рандомный параметр A, пусть будет 149:
vis(149, func_1, step=0.1, c=color_1)
![](https://habrastorage.org/webt/a8/4u/0e/a84u0erl-emjaczbyx1kz0dj3hi.jpeg)
Функция «Гуси»
Гуси описываются так:
Объявление на python:
def func_2(A, B):
return math.cos(B) * math.sin(B) * B * math.e ** (1j * (B * math.cos(A)))
Ее результат для A=106:
![](https://habrastorage.org/webt/7w/br/dl/7wbrdlyc1in1uezm-ck_bf5qvui.jpeg)
Функция «Фокачча»
def func_3(A, B):
return math.cos((A + 1) * B) * math.e ** (1j * (B * math.cos(A)))
vis(246, func_3, step=0.1, c=color_2)
![](https://habrastorage.org/webt/ze/ri/k3/zerik3sudihshoowzkmgneppwso.jpeg)
vis(246, func_3, step=0.1, c=color_2)
![](https://habrastorage.org/webt/sl/o_/jm/slo_jmbgjsl9jnbj7elh3yahy8c.jpeg)
Функция «Без названия»
color_3 = lambda x, y: (0.5, 0.5, sigm(x ** 2 + y ** 2))
vis(162, func_4, step=0.1, c=color_3)
![](https://habrastorage.org/webt/74/69/uv/7469uvlqo2p7p64znmv6nqbdgxy.jpeg)
vis(179, func_4, step=0.1, c=color_3)
![](https://habrastorage.org/webt/s7/wp/79/s7wp79nbo5kcdyo3wl3w1jpeo7u.jpeg)
Формула красоты
def func_5(A, B):
return math.cos((A + 1) * B) ** 1.5 * math.e ** (1j * (B * math.cos(A)))
color_4 = lambda x, y: (sigm(x ** 2 + y ** 2) / 2, 0.5, 1 - sigm(x ** 2 + y ** 2))
vis(345, func_5, step=0.1, c=color_4)
![](https://habrastorage.org/webt/se/eq/rb/seeqrb3_pgdmkvaiz3x1rdkvleo.jpeg)
vis(350, func_5, step=0.1, c=color_4)
![](https://habrastorage.org/webt/hu/wq/jf/huwqjfetpv8r-xnkyd8viffbfi0.jpeg)
Пока все.
Весь код
import numpy as np
import random
import matplotlib.pyplot as plt
import math
def vis(A, f, step=1.0, c=None):
x = []
y = []
for B in np.arange(0, A, step):
v = f(A, B)
x.append(v.real)
y.append(v.imag)
plt.figure(figsize=[7, 7])
mxabs = max([i[0] ** 2 + i[1] ** 2 for i in zip(x, y)]) ** 0.5
x = np.array(x) / mxabs
y = np.array(y) / mxabs
if c is None:
plt.scatter(x, y)
else:
plt.scatter(x, y, color=[c(x[i], y[i]) for i in range(len(x))])
plt.show()
def func_1(A, B):
return math.sin(B) * B * math.e ** (1j * (B * math.cos(A)))
def func_2(A, B):
return math.cos(B) * math.sin(B) * B * math.e ** (1j * (B * math.cos(A)))
def func_3(A, B):
return math.cos((A + 1) * B) * math.e ** (1j * (B * math.cos(A)))
def func_4(A, B):
return math.sin(A + B) * B * math.e ** (1j * B * math.sin(A))
def func_5(A, B):
return math.cos((A + 1) * B) ** 1.5 * math.e ** (1j * (B * math.cos(A)))
def sigm(x):
return (1 / (1 + 1.2 ** (-x*50)) - 0.5) * 2
color_1 = lambda x, y: (0.2, sigm(x ** 2 + y ** 2) / 1.4, 1 - sigm(x ** 2 + y ** 2))
color_2 = lambda x, y: (sigm(x ** 2 + y ** 2), 0.5, 0.5)
color_3 = lambda x, y: (0.5, 0.5, sigm(x ** 2 + y ** 2))
color_4 = lambda x, y: (sigm(x ** 2 + y ** 2) / 2, 0.5, 1 - sigm(x ** 2 + y ** 2))
colors = [color_1, color_2, color_3, color_4]
funcs = [func_1, func_2, func_3, func_4, func_5]
while True:
col = random.choice(colors)
func = random.choice(funcs)
vis(random.random() * 200 + 100, func, step=0.1, c=col)
if input() == "exit":
break
Еще скриншоты![](https://habrastorage.org/webt/za/pb/0h/zapb0hqg4n6fhu1t3g7xx-hprem.jpeg)
![](https://habrastorage.org/webt/e9/4o/pi/e94opirnwhwm5uhvttqxl09yc2g.jpeg)
![](https://habrastorage.org/webt/ba/0a/7w/ba0a7wckolnak16lvi1ture6m0y.jpeg)
![](https://habrastorage.org/webt/gp/lw/qo/gplwqogse_vgg_tdzcfjcb8nze8.jpeg)
![](https://habrastorage.org/webt/gg/lx/pe/gglxpe3gx4d8-bylgzkzqeclopa.jpeg)
![](https://habrastorage.org/webt/bg/xo/f3/bgxof3kkru1lglozmlihr6mpjpw.jpeg)
![](https://habrastorage.org/webt/u3/y0/cx/u3y0cxfmtwv2sywmzmeodibf0su.jpeg)
![](https://habrastorage.org/webt/0j/to/bt/0jtobtnsx80ka3np9877nxgzkqc.jpeg)
![](https://habrastorage.org/webt/l0/aw/3j/l0aw3jq0xthz2_aiogrlvaj-yuo.jpeg)
![](https://habrastorage.org/webt/za/pb/0h/zapb0hqg4n6fhu1t3g7xx-hprem.jpeg)
![](https://habrastorage.org/webt/e9/4o/pi/e94opirnwhwm5uhvttqxl09yc2g.jpeg)
![](https://habrastorage.org/webt/ba/0a/7w/ba0a7wckolnak16lvi1ture6m0y.jpeg)
![](https://habrastorage.org/webt/gp/lw/qo/gplwqogse_vgg_tdzcfjcb8nze8.jpeg)
![](https://habrastorage.org/webt/gg/lx/pe/gglxpe3gx4d8-bylgzkzqeclopa.jpeg)
![](https://habrastorage.org/webt/bg/xo/f3/bgxof3kkru1lglozmlihr6mpjpw.jpeg)
![](https://habrastorage.org/webt/u3/y0/cx/u3y0cxfmtwv2sywmzmeodibf0su.jpeg)
![](https://habrastorage.org/webt/0j/to/bt/0jtobtnsx80ka3np9877nxgzkqc.jpeg)
![](https://habrastorage.org/webt/l0/aw/3j/l0aw3jq0xthz2_aiogrlvaj-yuo.jpeg)
Sychuan
Bookvarenko
Красиво, пёстренько! Код есть?
Sychuan
Конкретно эту функцию я не помню. Но идея очень простая, называется domain coloring:
1. Покрасить комплексную плоскость в какие-нибудь цвета. В данном случае (я точно не помню, но скорее всего) фаза комплексного числа превращается в HUE, а модуль в Lightness.
2. Подействовать на плоскость какой-нибудь функцией.
3. Покрасить в зависимости от значения
В википедии все объяснено очень хорошо
vin2809
Большое спасибо. Красотища то какая!
qpy
а интересно, как часто используется matplotlib в data science, в аналитике? И какие альтернативы vs matplotlib, которые наиболее популярны для этих целей?
Насчет статьи, на мой взгляд, крупные изображения в ней мешают восприятию кода. Хотелось бы, чтобы Вы спрятали все изображения в виде спойлеров.
Drammm
А можно ли построить график функции Вейерштрасса? https://ibb.co/bdh2mcw, где: k_n= k^n; k и ? – произвольные числа; z – комплексная переменная.
Sychuan
Я попробовал сделать в лоб, но после нескольких суммирований большинство значений получились NaN. Вряд ли у этой функции какой-то интересный график на комплексной плоскости получится.Есть много очень интересных функций, но эта вряд ли из их числа. (но может я ошибся, от программирования я далек). И я взял формулу из википедии. Мне там показалось понятнее
onground
Наверное имеет смысл добавить в первый листинг две строчки