Модуль python sympy noconvergence: сбой схождения к корневому каталогу; попробуйте n <15 или maxsteps> 50

Я столкнулся с проблемой при использовании 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), я действительно хочу знать, почему уравнение с числом с плавающей запятой не может быть вычислено, и как я могу это исправить (потому что мне нужно, чтобы это было более точным, поэтому я не могу просто игнорируйте число после точки) Огромное спасибо!

0
0
706
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Вы правы, теперь я знаю, что Sympy - неправильный выбор для решения моей проблемы, и я использовал Scipy, о котором вы упомянули выше, и решил свои проблемы, и он отлично работает, ваше описание настолько четкое и подробное, большое спасибо !! !

Jasper Zhou 14.09.2018 06:39

Другие вопросы по теме