Вопрос или проблема
Я использую версию SymPy 1.13.3 для интегрирования выражения, содержащего тригонометрические функции. Моя цель — линейризовать тригонометрические произведения с помощью функции TR8
из sympy.simplify.fu
. Однако результаты с линейризацией и без нее должны быть идентичными, но они различаются.
Вот упрощенная версия моего кода:
import sympy as sp
import numpy as np
import matplotlib.pyplot as plt
from sympy.simplify.fu import TR8 as linearize_trigo_expr
from sympy import cos, sin
# Определения
JMax = 3
nb_vals_t = 100
t_vals = np.linspace(0, 0.2, nb_vals_t)
s, t = sp.symbols('s t')
u = -12.33203125*sin(t) + 5.6064453125*sin(4*t) - 2.2708740234375*sin(9*t) + sin(12*t) - 0.103253126144409*sin(16*t) - 1.39863395690918*cos(t) + 1.81103515625*cos(4*t) - 0.4464111328125*cos(9*t) + 0.0336227416992188*cos(16*t)
integrand = u * (u.subs(t, s) * sum(sp.sin(j**2 * (t - s)) / j**4 for j in range(1, JMax + 1)))
# Без тригонометрической линейризации
integral = sp.integrate(integrand, (s, 0, t))
integral_values = []
for t_val in t_vals:
integral_values.append(integral.subs(t, t_val))
plt.plot(t_vals, integral_values)
plt.xlabel('t')
plt.ylabel('Интеграл')
plt.title("Тест без тригонометрической линейризации")
plt.grid(True)
plt.show()
# С тригонометрической линейризацией
integrand_simple = linearize_trigo_expr(integrand)
integral_simple = sp.integrate(integrand_simple, (s, 0, t))
integral_simple_values = []
for t_val in t_vals:
integral_simple_values.append(integral_simple.subs(t, t_val))
plt.plot(t_vals, integral_simple_values)
plt.xlabel('t')
plt.ylabel('Интеграл')
plt.title("Тест с тригонометрической линейризацией")
plt.grid(True)
plt.show()
Обе графики должны быть идентичны, но они различаются. Кто-нибудь знает, почему тригонометрическая линейризация не работает так, как ожидалось, и есть ли решение, чтобы она функционировала правильно?
П.С.: это, вероятно, не минимальный рабочий пример, но я пытался найти простой пример, показывающий ошибки, которые делает функция TR8.
Вот графики:
Ответ или решение
К сожалению, в вашем использовании функции TR8 из библиотеки SymPy возникают проблемы с ожидаемыми результатами при линейной интерпретации тригонометрических функций. Давайте проанализируем ваш код и попытаемся понять, почему результаты интеграции отличаются при использовании линейного преобразования и без него.
Причины разницы в результатах
-
Линейная аппроксимация: Функция TR8 применяет линейные приближения к тригонометрическим функциям, что может значительно изменить форму выражения. Если натуральные функции сильно колеблются, линейная интерпретация может не захватывать все нюансы поведения оригинальных функций, особенно если они комбинируются в произведения.
-
Алгебраические преобразования: При применении TR8 к выражению могут происходить дополнительные алгебраические преобразования, которые не сохранены при интегрировании. Это может привести к изменению или искажению выражения и, соответственно, к разным результатам.
Решение проблемы
Чтобы получить более ожидаемые результаты с использованием функции TR8, вы можете попробовать следующие шаги:
-
Проверка тригонометрических функций: Убедитесь, что ваши тригонометрические функции действительно подходят для линейной аппроксимации. Линейные приближения работают лучше для функций, которые по своей природе изменяются постепенно.
-
Сравнение отдельных частей: Попробуйте разбить ваше интегральное выражение на более мелкие компоненты и проследить, как каждый компонент реагирует на линейное преобразование. Это поможет вам понять, где именно происходят искажения.
-
Использование других методов упрощения: Вместо TR8 вы можете рассмотреть применение других методов упрощения, таких как
expand_trig()
илиsimplify()
, которые могут не так агрессивно изменять структуру выражения. -
Проверка на более поздних версиях SymPy: Иногда обновление библиотеки до последней версии помогает решить проблемы. Проверьте, были ли исправлены ошибки в более поздних релизах SymPy, по сравнению с 1.13.3.
Пример кода с альтернативным подходом
Вы можете изменить ваш подход следующим образом, чтобы визуально проверить результаты:
# Проверка независимых функций и их линейного вывода
simplified_integrand = sp.simplify(integrand)
integral = sp.integrate(simplified_integrand, (s, 0, t))
integral_values = [integral.subs(t, t_val).evalf() for t_val in t_vals]
# Использование более простого метода
integrand_linear = sp.expand_trig(integrand)
integral_simple = sp.integrate(integrand_linear, (s, 0, t))
integral_simple_values = [integral_simple.subs(t, t_val).evalf() for t_val in t_vals]
# Визуализация
plt.plot(t_vals, integral_values, label='Без линейной интерпретации')
plt.plot(t_vals, integral_simple_values, label='С линейной интерпретацией', linestyle='dashed')
plt.xlabel('t')
plt.ylabel('Интеграл')
plt.title("Сравнение результатов")
plt.legend()
plt.grid(True)
plt.show()
Заключение
Линейное преобразование тригонометрических функций может быть сложным и не всегда дает ожидаемые результаты. Понимание внутреннего механизма работы библиотек, таких как SymPy, и осторожное использование линейных аппроксимаций поможет избежать путаницы. Постарайтесь сравнить результаты нескольких методов и выберите наиболее подходящий для вашей задачи подход.