Я пытаюсь упростить некоторые выражения положительных нечетных целых чисел с помощью sympy. Но sympy отказывается расширяться floor
, что затрудняет дальнейшее упрощение.
Чтобы быть точным, x
— это положительное нечетное целое число (на самом деле в моем конкретном случае ограничения еще более строгие. Но sympy может делать только нечетные и положительные числа, что нормально). x // 2
всегда должно быть равно (x - 1) / 2
. Пример кода здесь:
from sympy import Symbol, simplify
x = Symbol('x', odd=True, positive=True)
expr = x // 2 - (x - 1) / 2
print(simplify(expr))
распечатки -x/2 + floor(x/2) + 1/2
. В идеале должно быть напечатано 0
.
Что я пробовал до сих пор:
(x - 1) // 2 - (x - 1) / 2
. Оказывается 0.2 * (x // 2 - (x - 1) / 2)
. Дает мне: -x + 2*floor(x/2) + 1
.FLOOR
операции, настроивmeasure
. Не повезло.sympy.core.evaluate(False)
при создании выражения. Нух.ratio
, rational
, и поиграйте с другими функциями, такими как expand
, factor
, collect
. Тоже не работает.Обновлено: Wolfram alpha может сделать это.
Я пытался выглядеть как предположения x
вместе с некоторыми выражениями. Меня удивляет, что (x - 1) / 2).is_integer
возвращает None, что означает неизвестно.
У меня заканчиваются подсказки. Я даже ищу альтернативу sympy. Есть идеи, ребята?
Я не понимаю, почему sympy не может упростить это.
Но, с другой стороны, я обнаружил существование параметра odd
только сейчас, с вашим вопросом.
Что бы я сделал, не зная odd
, это
k = Symbol('k', positive=True, integer=True)
x = 2*k-1
expr = x // 2 - (x - 1) / 2
Тогда expr равно 0, даже без необходимости упрощения.
Итак, не могу сказать, почему ваш способ не работает (и почему этот параметр odd
существует, если он не используется правильно, чтобы угадать, что x-1
четное и, следовательно, (x-1)/2
целое число). Но тем временем мой способ определения нечетного числа x
работает.
Да, ты прав. Мне нужно positive
, так как ОП использовал positive
вместо x
. Но на самом деле, если k — это то, что в моей стране мы называем «строго положительным», а по-английски — просто «положительным», то 2k+1 равно 3 или больше. Это один из редких примеров того, что математика не является универсальным языком. В английском (и в питоне) 0 не является ни положительным, ни отрицательным. В моей стране 0 является как положительным, так и отрицательным (но не «строго положительным» и не «строго отрицательным»). Отсюда частое употребление в английском языке слова «неотрицательный» (которое на моем языке переводится как «положительный»).
@AndrewMcClement Это видно даже с определением набора натуральных чисел. На моем языке ℕ содержит 0, а ℕ* — нет. В то время как в английском ℕ нет, а ℕ₀ есть (но в настоящее время, чтобы избежать путаницы, в математической статье никогда не используется ℕ, и только ℕ₀ или ℕ* однозначны - очевидно избыточны для половины читателей, но, по крайней мере, недвусмысленны для всех - обозначения. Но, ну, даже если я хорошо осведомлен об этих международных двусмысленностях, как вы видите, я все же позволяю им время от времени обманывать себя.Так что пост исправлен.
Я думаю, это гениальное решение! Хотя это требует некоторой хакерской замены пользовательского ввода в моем сценарии, по крайней мере, это спасает мой день! Интересно видеть, что sympy требует некоторых «методов», чтобы добиться цели...
Достаточно составить k
и целое число. И если после подстановки остались k
(x, 2*k+1)
, вы можете произвести обратную замену kexpr.subs(k,(x - 1)/2)
, чтобы восстановить переменную x
.
Есть некоторое нежелание делать слишком много автоматического в SymPy, но это похоже на случай, который можно решить (поскольку (x-1)/2
проще, чем floor(x/2)
. Однако до тех пор вы можете запустить замену своего выражения, которая сделает это преобразование для вас.
Давайте определим предпочтительную версию floor
:
def _floor(x):
n, d = x.as_numer_denom()
if d == 2:
if n.is_odd:
return (n - 1)/2
if n.is_even:
return n/2
return floor(x)
Когда у вас есть выражение с floor
, которое вы хотите оценить, замените floor
на _floor
:
>>> x = Symbol('x', odd=True)
>>> eq=x // 2 - (x - 1) / 2
>>> eq.replace(floor, _floor)
0
открыт как выпуск на сайте SymPy
Вероятно, следует использовать
2k-1
вместо2k+1
, поскольку мы требуем, чтобы k было положительным, аx == 2k+1
означает, что мы не можем представитьx == 1
. (Конечно, если убрать положительные ограничения, это не имеет значения.)