Модуль Python Sympy NoConvergence: сбой сходимости к корню;попробуйте n <15 или maxsteps> 50 - PullRequest
0 голосов
/ 13 сентября 2018

Я столкнулся с проблемой при использовании Sympy для решения проблем. Вот мой код:

from math import pi, hypot
from sympy import solve, solveset, sqrt, Symbol
one_x=-0.08
one_y=1.28
second_x=0
second_y=0
second_r=7
one_r=7.3
slopes=-16.0000000000  (maybe more trailing 0s)
intercepts=0.0
x=Symbol('x')
solveset(sqrt((x-second_x)**2+(slope*x+intercept-second_y)**2)+second_r-one_r-sqrt((x-one_x)**2+(slope*x+intercept-one_y)**2),x)

Это только часть моего кода, но возникает много ошибок, но вместо этого я заменил все переменныесо значением, например

x=Symbol('x')

solveset(sqrt((x)**2+((-16)*x)**2)+7-7.3-sqrt((x+0.08)**2+((-16)*x-1.28)**2),x)

Работает хорошо, и я могу получить вывод {-0.0493567429232771}

Я думаю, это из-за типа уклонов (-16 по сравнению с -16.000000),Я действительно хочу знать, почему уравнение с числом с плавающей запятой не может быть вычислено, и как я могу это исправить (потому что мне нужно, чтобы оно было более точным, чтобы я не мог просто игнорировать число после точки) Большое спасибо!

1 Ответ

0 голосов
/ 13 сентября 2018

SymPy + алгебраическое уравнение + числа с плавающей запятой => проблема.Математика с плавающей точкой не работает как обычная математика , и SymPy предназначен для последнего.Маленькие вещи, такие как 16 (целое число) против 16.0 (число с плавающей запятой) имеют большое значение при решении уравнений с помощью SymPy: в идеале у вас не должно быть чисел с плавающей запятой, вместо этого создаются точные рациональные числа , как здесь.

from sympy import S 
one_x = S('-0.08')

Однако у вас есть данные с плавающей запятой и вы ищете решение с плавающей запятой.Это делает SymPy неподходящим инструментом для работы.SymPy предназначен для математических операций с символами, а не для вычисления чисел с плавающей запятой.Правильное решение - использовать соответствующее решение от SciPy, например brentq.В качестве входных данных используется интервал брекетинга (где функция имеет разные знаки на обоих концах).Например:

from scipy.optimize import brentq
eq = lambda x: np.sqrt((x-second_x)**2 + (slope*x+intercept-second_y)**2) + second_r - one_r - np.sqrt((x-one_x)**2 + (slope*x + intercept - one_y)**2)
brentq(eq, -10, 10)   # returns -0.049356742923277075

Если вы придерживаетесь SymPy, это означает, что ваше уравнение передается на аутсорсинг в библиотеку mpmath, которая гораздо более ограничена в поиске и оптимизации числовых корней.Чтобы решение сходилось с его методами, вам понадобится действительно хорошая отправная точка: очевидно, one_x/2 - это такая точка.

from sympy import sqrt, Symbol, nsolve
# ... as in your code
nsolve(sqrt((x-second_x)**2+(slope*x+intercept-second_y)**2)+second_r-one_r-sqrt((x-one_x)**2+(slope*x+intercept-one_y)**2), one_x/2)

возвращает -0.0493567429232771.

Используя sympy.solveset, который предназначен для символического решения, вы лишаете себя не только мощных числовых решателей SciPy, но и возможности установить хорошее начальное значение для числового поиска, который обеспечивает sympy.nsolve,Отсюда и отсутствие сходимости в этой численно сложной задаче.Кстати, это то, что делает его численно хитрым: функция почти постоянна в большинстве случаев с одним быстрым изменением.

tricky

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...