SymPy: есть проблемы с упрощением выражения, содержащего множитель один

Извините за вопрос новичка, но я пока не нашел ответа в другом месте.

Скажем, у нас есть символ, и мы умножаем его на число с плавающей запятой:

import sympy

x = sympy.Symbol('x')
x = 1.0 * x

Все выражения, содержащие это x, также будут содержать фактор один, что бы я ни делал:

from pprint import pprint
pprint(x)
pprint(sympy.simplify(x))

Выход:

1.0⋅x
1.0⋅x

В приведенном выше примере я хочу вывести x вместо 1.0⋅x. Можно ли упростить выражение так, чтобы оно решало все умножения на число с плавающей запятой? Должен ли я преобразовать это число с плавающей запятой в другой тип данных?


person freude    schedule 10.11.2020    source источник


Ответы (2)


Похоже, это связано с плавающей точкой и целым числом 1 - не используйте 1.0, если вы можете обойтись с 1, возможно?

Вы можете проверить, идентично ли он 1.0 с помощью if f.as_integer_ratio() == (1, 1), и если да, не добавляйте ненужный "1.0":

>>> xf = 1.0 * x
>>> xi = 1 * x

>>> xf
1.0*x
>>> xi
x

>>> pprint(xf)
1.0*x
>>> pprint(xi)
x

Это может быть из-за неточности с плавающей запятой (я не очень разбираюсь в sympy, не могу сказать больше).

РЕДАКТИРОВАТЬ: время выполнения float.as_integer_ratio() крошечное, в ответ на ваш вопрос:

>>> python -m timeit -n 1000000 '(1.0).as_integer_ratio() == (1,1)'
1000000 loops, best of 5: 172 nsec per loop

>>> python -m timeit -n 1000000 '(1.1).as_integer_ratio() == (1,1)'
1000000 loops, best of 5: 327 nsec per loop

>>> python -m timeit -n 1000000 '(1.01).as_integer_ratio() == (1,1)'
1000000 loops, best of 5: 331 nsec per loop

>>> python -m timeit -n 1000000 '(0.999999999999).as_integer_ratio() == (1,1)'
1000000 loops, best of 5: 329 nsec per loop
person smci    schedule 10.11.2020
comment
Спасибо. Я не могу привести его к int, потому что иногда это число с плавающей запятой, не равное единице. Но когда это так, я хочу упростить. Может быть, лучше проверить, равно ли оно единице, используя оператор if. Последний вариант мне кажется немного грязным. - person freude; 10.11.2020
comment
Ну, вы можете проверить, идентично ли он 1.0 с if f.as_integer_ratio() == (1, 1) - person smci; 10.11.2020
comment
Это трудоемкая функция? Что вы чувствуете? - person freude; 10.11.2020
comment
Что, сравнивая float.as_integer_ratio(), например, с sympy.simplify.simplify.nsimplify(..., tolerance)? Я сомневаюсь, что их время выполнения вообще имеет значение. Если хотите, можете подправить tolerance. - person smci; 10.11.2020
comment
@freude: Я измерил время выполнения с помощью timeit и подтвердил, что он крошечный. - person smci; 15.12.2020

Я нашел решение. Есть специальная функция nsimplify() это делает свою работу.

person freude    schedule 10.11.2020