Реализация математических конструкций при помощи Python

Раздел: Основы Python -> Математические операции и модули

Математические формулы: подходы и инструменты

Python предоставляет несколько уровней для работы с математическими выражениями: от базовых арифметических операторов до специализированных модулей math, cmath и библиотеки символьных вычислений sympy. Выбор подхода зависит от требуемой точности, скорости и сложности формулы.

Наиболее эффективное решение для большинства повседневных задач - использование стандартного модуля math в сочетании с встроенными арифметическими операторами. Он покрывает тригонометрию, логарифмы, степенные функции, округление и константы.


import math

# Пример: формула дискриминанта
# D = b^2 - 4ac
def discriminant(a, b, c):
    return b**2 - 4 * a * c

# Вычисление корней через math.sqrt

a, b, c = 1, -3, 2
D = discriminant(a, b, c)
if D >= 0:
    x1 = (-b + math.sqrt(D)) / (2 * a)
    x2 = (-b - math.sqrt(D)) / (2 * a)
    print(f"Корни уравнения: {x1:.3f}, {x2:.3f}")
else:
    print("Действительных корней нет")
  

Python математические формулы (математические формулы в python)

Модуль math реализован на C и обеспечивает высокую скорость вычислений с плавающей точкой двойной точности (binary64).

Как вычислить квадратный корень без использования math.sqrt?

Оператор возведения в степень ** позволяет извлечь корень любой степени:


number = 25
root = number ** 0.5  # квадратный корень
print(root)  # 5.0

cube_root = 27 ** (1/3)
print(cube_root)  # 3.0
  

Проблема: вычисление (1/3) с плавающей точкой может давать неточный результат для некоторых чисел. Лучше использовать math.cbrt (кубический корень) из Python 3.11+ или метод pow(x, 1/3).

Цель: быстрая однострочная запись без импорта модуля.

Как избежать потери точности при работе с большими/малыми числами?

Для критических расчётов (финансы, наука) применяют модуль decimal или fractions:


from decimal import Decimal, getcontext
getcontext().prec = 50  # 50 значащих цифр

x = Decimal('1.0') / Decimal('7.0')
print(x)  # 0.142857... с нужной точностью
  

Типичная ошибка: передача в Decimal числа с плавающей точкой (Decimal(0.1)) - это пронесёт ошибку двоичного представления. Всегда используйте строку: Decimal('0.1').

Случай использования: расчёты с рекуррентными формулами, где накапливается погрешность.

Как записать тригонометрическую формулу в одну строку?

Функции math.sin, cos, tan, asin, acos, atan работают в радианах. Для преобразования градусов в радианы - math.radians:


import math

angle_deg = 45
sin45 = math.sin(math.radians(angle_deg))
print(f"sin(45°) = {sin45:.4f}")  # 0.7071
  

Проблема: при последовательных вычислениях забывают конвертировать градусы. Рекомендуется всегда хранить углы в радианах и конвертировать только на входе/выходе.

Использование: обработка сигналов, физика, графика (pygame, matplotlib).

Как найти факториал большого числа без переполнения?

Встроенная функция math.factorial работает с целыми числами произвольной длины (только в Python 3):


import math

f100 = math.factorial(100)
print(len(str(f100)))  # 158 цифр в 100!
  

Ошибка: попытка вычислить факториал отрицательного числа или нецелого - ValueError. Для чисел с плавающей точкой используйте math.gamma(n+1).

Типичные ошибки и способы их устранения

  • Division by zero. Проверяйте знаменатель перед делением или используйте try/except ZeroDivisionError.
  • Переполнение (overflow). Функции math.exp, math.pow для очень больших чисел возвращают inf. Для контроля применяйте math.isfinite.
  • Сравнение чисел с плавающей точкой. Используйте math.isclose(a, b, rel_tol=1e-9) вместо a == b.

Случаи применения

Набор инструментов Python покрывает широкий спектр задач: от школьных формул (площади, объёмы) до сложных моделей машинного обучения (активационные функции, градиенты). Модуль math незаменим при написании парсеров математических выражений, построении графиков через matplotlib и реализации численных методов.

Расширенные примеры работы с формулами

Площадь треугольника по формуле Герона

Формула: S = sqrt(p * (p - a) * (p - b) * (p - c)), где p – полупериметр.

Пример

import math

def heron(a, b, c):
    # проверка существования треугольника
    if a + b > c and a + c > b and b + c > a:
        p = (a + b + c) / 2
        temp = p * (p - a) * (p - b) * (p - c)
        if temp < 0:  # из-за погрешности может быть отрицательным
            temp = 0
        return math.sqrt(temp)
    else:
        return None

# пример
S = heron(3, 4, 5)
print(f"Площадь треугольника 3,4,5: {S:.2f}")  # 6.00
  
Площадь треугольника 3,4,5: 6.00
  

Вычисление экспоненты через ряд Тейлора

Использование собственного разложения для демонстрации контроля точности.

Пример

import math

def taylor_exp(x, n=20):
    """exp(x) через ряд Тейлора с n слагаемыми."""
    result = 0.0
    term = 1.0  # x^0 / 0!
    for k in range(n):
        result += term
        term *= x / (k + 1)
    return result

x = 2.0
approx = taylor_exp(x)
exact = math.exp(x)
print(f"Приближение: {approx:.10f}, точное: {exact:.10f}, разница: {abs(approx - exact):.2e}")
  
Приближение: 7.3890560989, точное: 7.3890560989, разница: 4.12e-15
  

Использование math.comb и math.perm (Python 3.8+)

Вычисление числа сочетаний и размещений без ручного написания факториалов.

Пример

import math

# C(10,3) = 120
comb = math.comb(10, 3)
print("Число сочетаний:", comb)

# P(10,3) = 720
perm = math.perm(10, 3)
print("Число размещений:", perm)
  
Число сочетаний: 120
Число размещений: 720
  

Функция активации (сигмоида) с защитой от переполнения

Пример

import math

def sigmoid(x):
    # ограничение аргумента для предотвращения переполнения math.exp
    if x < -709:  # exp(-709) ~ 1e-308, меньше - почти ноль
        return 0.0
    elif x > 709:
        return 1.0
    else:
        return 1.0 / (1.0 + math.exp(-x))

for t in [-800, -10, 0, 10, 800]:
    print(f"sigmoid({t:4d}) = {sigmoid(t):.6f}")
  
sigmoid(-800) = 0.000000
sigmoid( -10) = 0.000045
sigmoid(   0) = 0.500000
sigmoid(  10) = 0.999955
sigmoid( 800) = 1.000000
  

Работа с комплексными числами: формула Эйлера

Пример

import cmath

theta = math.pi / 2
z = cmath.exp(1j * theta)  # e^(i*theta)
print(f"e^(i·π/2) = {z:.4f}")  # примерно 0+1j

# модуль комплексного числа
magnitude = abs(z)
print(f"Модуль: {magnitude}")
  
e^(i·π/2) = (0.0000+1.0000j)
Модуль: 1.0
  

Наименьшее число больше заданного (ulp - unit in the last place)

Пример

import math

x = 1.0
# следующее представимое число в большую сторону
next_x = math.nextafter(x, float('inf'))
print(f"Для x=1.0 ulp = {next_x - x:.2e}")  # ~2.22e-16

# проверка, конечно ли число
print(math.isfinite(1e400))  # False, так как это inf
  
Для x=1.0 ulp = 2.22e-16
False
  

Математические формулы в Python - comments

En
Python математические формулы (python)