Пример использования библиотеки sympy для поиска экстремума функции
Рассмотрим алгоритм поиска экстремума функции одной переменной при помощи библиотеки sympy. Дана следующая функция от \(x\): \[f(x) = \frac{\sqrt{x^2+a^2} + k \sqrt{b^2+(h-x)^2}}{v_1}\]
Для нахождения экстремума функции найдем ее производную по \(x\), используя библиотеку sympy, и решив уравнение \[\frac{df(x)}{dx} = 0,\]
найдем значение x, которому соответсвует минимум или максимум функции.
Поключаем библиотеки
# numpy всегда пригодится
import numpy as np
# Для построения графиков
import matplotlib.pyplot as plt
# Научный питон
from scipy import optimize
# Символьный питон
from sympy import *
Объявляем используемые в функции символьные параметры
a, b, h, k, x, v1 = symbols('a, b, h, k, x, v1')
Объявляем функцию
f = (sqrt(x**2+a**2) + k*sqrt(b**2+(h-x)**2))/v1
Найдем её производную при помощи функции библиотеки sympy diff. Первый аргумент функции diff – дифференцируемое выражение, второй – переменная, по которой необходимо найти производную:
df = diff(f, x)
В результате переменная df будет содержать следующее выражение
>> df
(k*(-h + x)/sqrt(b**2 + (h - x)**2) + x/sqrt(a**2 + x**2))/v1
В полученном выражении для производной заменим символы (параметры) a, b, h, k, v1 их значениями (a=10, b=10, h=10, k=5, v1=5). Для этого создаем словарь
params = {a:10, b:10, h:10.0, k:5, v1: 5}
который подставим в найденную производную, используя метод subs
df_par = df.subs(params)
Результатом будет выражение, которое зависит только от x:
>> df_par
x/(5*sqrt(x**2 + 100)) + (x - 10.0)/sqrt((-x + 10.0)**2 + 100)
Создадим на основе символьного вращения f_par лямбда-функцию от x
df_num = lambda xnum: df_par.subs( {x: xnum} )
Численным методом найдем значение x, при котором производная обращается в 0. Для этого используем функцию root модуля scipy.optimize, передав этой функции имя лямбда-функции и начальное приближение \(x_0 = 5\):
sol = optimize.root(df_num, 5.0)
Результатом будет следующее значение \(x\):
>> sol.x
array([8.6777724])