如何让 SymPy 将 1.0 之类的整数替换为 1
how to get SymPy to replace ints like 1.0 with 1
抱歉新手问题,但到目前为止我还没有在其他地方找到答案。
假设我们有一个符号,我们将它乘以浮点数一:
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
。是否有可能以用浮点数 1 解决所有乘法的方式简化表达式?我应该将这个浮点数转换为另一种数据类型吗?
看起来是因为 floating-point 与整数 1 - 如果可以不用 1,就不要使用 1.0,也许吧?
您可以检查它是否与 if f.as_integer_ratio() == (1, 1)
相同 1.0,如果是,则不要在前面添加不必要的“1.0”:
>>> xf = 1.0 * x
>>> xi = 1 * x
>>> xf
1.0*x
>>> xi
x
>>> pprint(xf)
1.0*x
>>> pprint(xi)
x
可能是floating-point不准确(我不太了解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
我找到了解决办法。有一个特殊的函数 nsimplify()
可以完成这项工作。
如果 nsimplify
比您预期的更激进——它会将 Floats 简化为 接近 但不完全相同的值——那么您可以考虑以下函数仅针对以浮点数表示的整数。
>>> def flint(eq):
... """convert floats that are ints to ints"""
... reps = {}
... e = eq.replace(
... lambda x: x.is_Float and x == int(x),
... lambda x: reps.setdefault(x, Dummy()))
... return e.xreplace({v: int(k) for k, v in reps.items()})
>>> flint(1.0*x)
x
>>> flint(1.0*x+x**2.0)
x**2 + x
抱歉新手问题,但到目前为止我还没有在其他地方找到答案。
假设我们有一个符号,我们将它乘以浮点数一:
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
。是否有可能以用浮点数 1 解决所有乘法的方式简化表达式?我应该将这个浮点数转换为另一种数据类型吗?
看起来是因为 floating-point 与整数 1 - 如果可以不用 1,就不要使用 1.0,也许吧?
您可以检查它是否与 if f.as_integer_ratio() == (1, 1)
相同 1.0,如果是,则不要在前面添加不必要的“1.0”:
>>> xf = 1.0 * x
>>> xi = 1 * x
>>> xf
1.0*x
>>> xi
x
>>> pprint(xf)
1.0*x
>>> pprint(xi)
x
可能是floating-point不准确(我不太了解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
我找到了解决办法。有一个特殊的函数 nsimplify()
可以完成这项工作。
如果 nsimplify
比您预期的更激进——它会将 Floats 简化为 接近 但不完全相同的值——那么您可以考虑以下函数仅针对以浮点数表示的整数。
>>> def flint(eq):
... """convert floats that are ints to ints"""
... reps = {}
... e = eq.replace(
... lambda x: x.is_Float and x == int(x),
... lambda x: reps.setdefault(x, Dummy()))
... return e.xreplace({v: int(k) for k, v in reps.items()})
>>> flint(1.0*x)
x
>>> flint(1.0*x+x**2.0)
x**2 + x