【问题标题】:Sympy won't simplify or expand exponential with decimalsSympy 不会用小数简化或扩展指数
【发布时间】:2019-01-17 20:30:52
【问题描述】:

我正在尝试简化 n 幂的巨大表达,而 sympy 的结果之一抛出 (n+1)^1.0 ,我注意到

f=n*((n+1)**1.0) sympy.expand(f)

不起作用,它保持不变而不是给出 n^2+n,所以我想知道是否有任何方法可以执行这样的操作

【问题讨论】:

  • 你能澄清一下 Sympy 抛出了什么吗?例外?
  • 不,它只是返回 f 完全相同,但如果我有 1 而不是 1.0 它实际上扩展了术语

标签: python math sympy symbolic-math polynomial-math


【解决方案1】:

当幂是整数时,Sympy 将按预期扩展您的表达式。如果功率存储为有理数或浮点数,它将不起作用。您的选择是使用整数重写您的表达式,或者编写一些代码来自动检查浮点数是否存储整数(直到数值精度错误)并采取相应措施。

这是一个起点:

def rewrite_polynomial(p):

    args_list = []

    if not p.is_Mul:
        return None
    for m in p.args:
        if not m.is_Pow:
            args_list.append(m)
        else:
            pow_val = m.args[1]
            if pow_val.is_Float:
                pow_val_int = int(pow_val)
                if pow_val.epsilon_eq(pow_val_int):
                    args_list.append(Pow(m.args[0],Integer(pow_val_int)))
                else:
                    args_list.append(m)
            else:
                args_list.append(m)                


    return Mul(*args_list)

n = Symbol('n')
f= n*((n+1)**1.0)
g = rewrite_polynomial(f)
print(g)

【讨论】:

  • 你知道他们是否正在努力解决这个问题吗?
  • 不幸的是我不知道
【解决方案2】:

根据 Yakovs 的回答,我制定了一个重写规则,对表达式树进行 DFS 遍历,并将幂替换为浮点类型的整数。

代码可能效率不高,但它适用于我的用例。

由于我不是 sympy 专家,我猜在某些极端情况下这段代码会出错。

不管怎样,给你!

import sympy as s


def recurse_replace(expr,pred,func):
    if len(expr.args) == 0:
        return expr
    else: 
        new_args = tuple(recurse_replace(a,pred,func) for a in expr.args)
        if pred(expr):
            return func(expr,new_args)
        else: 
            return type(expr)(*new_args)

def rewrite(expr,new_args):
    new_args = list(new_args)
    pow_val = new_args[1]
    pow_val_int = int(new_args[1])
    if pow_val.epsilon_eq(pow_val_int):
        new_args[1] = s.Integer(pow_val_int)
    new_node = type(expr)(*new_args)
    return new_node

def isfloatpow(expr):
    out = expr.is_Pow and expr.args[1].is_Float
    return out

def clean_exponents(expr):
    return recurse_replace(expr,isfloatpow,rewrite)

x=s.symbols('x')
expr = (1+x) ** 1.0
s.pprint(expr)
expr2 = recurse_replace(expr,isfloatpow,rewrite)
s.pprint(expr2)

有输出

       1.0
(x + 1)   
x + 1

【讨论】:

  • 最后,我不需要代码。在将其他一些表达式更改为整数后,浮点指数就再也没有出现过,我也不需要这些简化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-15
  • 1970-01-01
相关资源
最近更新 更多