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