В любом случае, чтобы избавиться от `math.floor` для положительных нечетных целых чисел с помощью `sympy.simplify`?

Я пытаюсь упростить некоторые выражения положительных нечетных целых чисел с помощью 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.

Что я пробовал до сих пор:

  1. Упрощайте (x - 1) // 2 - (x - 1) / 2. Оказывается 0.
  2. Умножьте все это на 2: 2 * (x // 2 - (x - 1) / 2). Дает мне: -x + 2*floor(x/2) + 1.
  3. Попробуйте придать больший вес FLOOR операции, настроивmeasure. Не повезло.
  4. Используйте контекст sympy.core.evaluate(False) при создании выражения. Нух.
  5. Настройте другие параметры, такие как ratio, rational, и поиграйте с другими функциями, такими как expand, factor, collect. Тоже не работает.

Обновлено: Wolfram alpha может сделать это.

Я пытался выглядеть как предположения x вместе с некоторыми выражениями. Меня удивляет, что (x - 1) / 2).is_integer возвращает None, что означает неизвестно.

У меня заканчиваются подсказки. Я даже ищу альтернативу sympy. Есть идеи, ребята?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
0
69
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Я не понимаю, почему 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 работает.

Вероятно, следует использовать 2k-1 вместо 2k+1, поскольку мы требуем, чтобы k было положительным, а x == 2k+1 означает, что мы не можем представить x == 1. (Конечно, если убрать положительные ограничения, это не имеет значения.)

Andrew McClement 25.01.2023 17:27

Да, ты прав. Мне нужно positive, так как ОП использовал positive вместо x. Но на самом деле, если k — это то, что в моей стране мы называем «строго положительным», а по-английски — просто «положительным», то 2k+1 равно 3 или больше. Это один из редких примеров того, что математика не является универсальным языком. В английском (и в питоне) 0 не является ни положительным, ни отрицательным. В моей стране 0 является как положительным, так и отрицательным (но не «строго положительным» и не «строго отрицательным»). Отсюда частое употребление в английском языке слова «неотрицательный» (которое на моем языке переводится как «положительный»).

chrslg 25.01.2023 17:35

@AndrewMcClement Это видно даже с определением набора натуральных чисел. На моем языке ℕ содержит 0, а ℕ* — нет. В то время как в английском ℕ нет, а ℕ₀ есть (но в настоящее время, чтобы избежать путаницы, в математической статье никогда не используется ℕ, и только ℕ₀ или ℕ* однозначны - очевидно избыточны для половины читателей, но, по крайней мере, недвусмысленны для всех - обозначения. Но, ну, даже если я хорошо осведомлен об этих международных двусмысленностях, как вы видите, я все же позволяю им время от времени обманывать себя.Так что пост исправлен.

chrslg 25.01.2023 17:41

Я думаю, это гениальное решение! Хотя это требует некоторой хакерской замены пользовательского ввода в моем сценарии, по крайней мере, это спасает мой день! Интересно видеть, что sympy требует некоторых «методов», чтобы добиться цели...

Scott Chang 25.01.2023 17:48

Достаточно составить k и целое число. И если после подстановки остались k(x, 2*k+1), вы можете произвести обратную замену kexpr.subs(k,(x - 1)/2), чтобы восстановить переменную x.

smichr 26.01.2023 02:02

Есть некоторое нежелание делать слишком много автоматического в 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

smichr 26.01.2023 01:56

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